diff options
author | Andrew Bartlett <abartlet@samba.org> | 2011-06-24 16:26:23 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2011-06-24 16:26:23 +1000 |
commit | 6da26870e0ae5acd6ff49a30ec2f6886b44d095e (patch) | |
tree | 850c71039563c16a5d563c47e7ba2ab645baf198 /source4 | |
parent | 6925a799d04c6fa59dd2ddef1f5510f9bb7d17d1 (diff) | |
parent | 2610c05b5b95cc7036b3d6dfb894c6cfbdb68483 (diff) | |
download | samba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.tar.gz samba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.tar.bz2 samba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.zip |
Merge 2610c05b5b95cc7036b3d6dfb894c6cfbdb68483 as Samba-4.0alpha16
Diffstat (limited to 'source4')
353 files changed, 10102 insertions, 7681 deletions
diff --git a/source4/NEWS b/source4/NEWS index b441bc784f..f7c03c60bf 100644 --- a/source4/NEWS +++ b/source4/NEWS @@ -56,8 +56,7 @@ that can be either 'domain controller', 'member server' or 'standalone'. Note th member server support does not work yet. The following parameters have been removed: -- passdb backend: accounts are now stored in a LDB-based SAM database, - see 'sam database' below. +- passdb backend: accounts are now stored in a LDB-based SAM database - update encrypted - public - guest ok @@ -401,12 +400,6 @@ The following parameters have been added: Default: smb rpc nbt wrepl ldap cldap web kdc -+ sam database - Location of the SAM (account database) database. This should be a - LDB URL. - - Default: set at compile-time - + spoolss database Spoolss (printer) DCE/RPC server database. This should be a LDB URL. diff --git a/source4/auth/auth.h b/source4/auth/auth.h index 9eb3e7db6f..04731af019 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -43,7 +43,7 @@ struct loadparm_context; /* version 3 - subsequent samba4 version - abartlet */ /* version 4 - subsequent samba4 version - metze */ /* version 0 - till samba4 is stable - metze */ -#define AUTH_INTERFACE_VERSION 0 +#define AUTH4_INTERFACE_VERSION 0 #define AUTH_SESSION_INFO_DEFAULT_GROUPS 0x01 /* Add the user to the default world and network groups */ #define AUTH_SESSION_INFO_AUTHENTICATED 0x02 /* Add the user to the 'authenticated users' group */ @@ -51,7 +51,7 @@ struct loadparm_context; struct auth_method_context; struct auth_check_password_request; -struct auth_context; +struct auth4_context; struct auth_session_info; struct ldb_dn; @@ -78,7 +78,7 @@ struct auth_operations { /* Lookup a 'session info interim' return based only on the principal or DN */ NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx, - struct auth_context *auth_context, + struct auth4_context *auth_context, const char *principal, struct ldb_dn *user_dn, struct auth_user_info_dc **interim_info); @@ -86,13 +86,13 @@ struct auth_operations { struct auth_method_context { struct auth_method_context *prev, *next; - struct auth_context *auth_ctx; + struct auth4_context *auth_ctx; const struct auth_operations *ops; int depth; void *private_data; }; -struct auth_context { +struct auth4_context { struct { /* Who set this up in the first place? */ const char *set_by; @@ -109,7 +109,7 @@ struct auth_context { struct tevent_context *event_ctx; /* the messaging context which can be used by backends */ - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; /* loadparm context */ struct loadparm_context *lp_ctx; @@ -117,25 +117,25 @@ struct auth_context { /* SAM database for this local machine - to fill in local groups, or to authenticate local NTLM users */ struct ldb_context *sam_ctx; - NTSTATUS (*check_password)(struct auth_context *auth_ctx, + NTSTATUS (*check_password)(struct auth4_context *auth_ctx, TALLOC_CTX *mem_ctx, const struct auth_usersupplied_info *user_info, struct auth_user_info_dc **user_info_dc); - NTSTATUS (*get_challenge)(struct auth_context *auth_ctx, uint8_t chal[8]); + NTSTATUS (*get_challenge)(struct auth4_context *auth_ctx, uint8_t chal[8]); - bool (*challenge_may_be_modified)(struct auth_context *auth_ctx); + bool (*challenge_may_be_modified)(struct auth4_context *auth_ctx); - NTSTATUS (*set_challenge)(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by); + NTSTATUS (*set_challenge)(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by); NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx, - struct auth_context *auth_ctx, + struct auth4_context *auth_ctx, const char *principal, struct ldb_dn *user_dn, struct auth_user_info_dc **user_info_dc); NTSTATUS (*generate_session_info)(TALLOC_CTX *mem_ctx, - struct auth_context *auth_context, + struct auth4_context *auth_context, struct auth_user_info_dc *user_info_dc, uint32_t session_info_flags, struct auth_session_info **session_info); @@ -151,7 +151,7 @@ struct auth_critical_sizes { int sizeof_auth_user_info_dc; }; - NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, + NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context, enum auth_password_state to_state, const struct auth_usersupplied_info *user_info_in, const struct auth_usersupplied_info **user_info_encrypted); @@ -165,7 +165,7 @@ struct ldb_context; struct gensec_security; struct cli_credentials; -NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8]); +NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t chal[8]); NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, uint32_t logon_parameters, @@ -175,10 +175,7 @@ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, const char *name_for_logs, bool allow_domain_trust, bool password_change); -NTSTATUS authsam_expand_nested_groups(struct ldb_context *sam_ctx, - struct ldb_val *dn_val, const bool only_childs, const char *filter, - TALLOC_CTX *res_sids_ctx, struct dom_sid ***res_sids, - unsigned int *num_res_sids); + struct auth_session_info *system_session(struct loadparm_context *lp_ctx); NTSTATUS authsam_make_user_info_dc(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, const char *netbios_name, @@ -193,20 +190,20 @@ NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx, NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **methods, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, struct ldb_context *sam_ctx, - struct auth_context **auth_ctx); + struct auth4_context **auth_ctx); const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, - struct auth_context **auth_ctx); -NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx); + struct auth4_context **auth_ctx); +NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth4_context **auth_ctx); -NTSTATUS auth_check_password(struct auth_context *auth_ctx, +NTSTATUS auth_check_password(struct auth4_context *auth_ctx, TALLOC_CTX *mem_ctx, const struct auth_usersupplied_info *user_info, struct auth_user_info_dc **user_info_dc); @@ -215,7 +212,7 @@ NTSTATUS auth_register(const struct auth_operations *ops); NTSTATUS server_service_auth_init(void); NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, const char *nt4_domain, const char *nt4_username, @@ -225,24 +222,24 @@ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct auth_context *auth_ctx, + struct auth4_context *auth_ctx, const struct auth_usersupplied_info *user_info); NTSTATUS auth_check_password_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct auth_user_info_dc **user_info_dc); -bool auth_challenge_may_be_modified(struct auth_context *auth_ctx); -NTSTATUS auth_context_set_challenge(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by); +bool auth_challenge_may_be_modified(struct auth4_context *auth_ctx); +NTSTATUS auth_context_set_challenge(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by); NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx, - struct auth_context *auth_ctx, + struct auth4_context *auth_ctx, const char *principal, struct ldb_dn *user_dn, struct auth_user_info_dc **user_info_dc); NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx, struct tevent_context *event_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, struct loadparm_context *lp_ctx, struct cli_credentials *server_credentials, const char *target_service, diff --git a/source4/auth/credentials/credentials.c b/source4/auth/credentials/credentials.c index 015c549693..83e90344bf 100644 --- a/source4/auth/credentials/credentials.c +++ b/source4/auth/credentials/credentials.c @@ -64,6 +64,7 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx) cred->principal = NULL; cred->salt_principal = NULL; cred->impersonate_principal = NULL; + cred->self_service = NULL; cred->target_service = NULL; cred->bind_dn = NULL; diff --git a/source4/auth/credentials/credentials.h b/source4/auth/credentials/credentials.h index 0b0de59752..f8fa2f864b 100644 --- a/source4/auth/credentials/credentials.h +++ b/source4/auth/credentials/credentials.h @@ -84,6 +84,7 @@ struct cli_credentials { const char *principal; char *salt_principal; char *impersonate_principal; + char *self_service; char *target_service; const char *bind_dn; @@ -277,10 +278,13 @@ bool cli_credentials_parse_password_fd(struct cli_credentials *credentials, void cli_credentials_invalidate_ccache(struct cli_credentials *cred, enum credentials_obtained obtained); void cli_credentials_set_salt_principal(struct cli_credentials *cred, const char *principal); -void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal); +void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, + const char *principal, + const char *self_service); void cli_credentials_set_target_service(struct cli_credentials *cred, const char *principal); const char *cli_credentials_get_salt_principal(struct cli_credentials *cred); const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred); +const char *cli_credentials_get_self_service(struct cli_credentials *cred); const char *cli_credentials_get_target_service(struct cli_credentials *cred); enum credentials_use_kerberos cli_credentials_get_kerberos_state(struct cli_credentials *creds); enum credentials_krb_forwardable cli_credentials_get_krb_forwardable(struct cli_credentials *creds); diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c index d3925a01f6..1643197004 100644 --- a/source4/auth/credentials/credentials_krb5.c +++ b/source4/auth/credentials/credentials_krb5.c @@ -235,9 +235,15 @@ static int cli_credentials_new_ccache(struct cli_credentials *cred, if (!ccache_name) { must_free_cc_name = true; - ccache_name = talloc_asprintf(ccc, "MEMORY:%p", - ccc); - + + if (lpcfg_parm_bool(lp_ctx, NULL, "credentials", "krb5_cc_file", false)) { + ccache_name = talloc_asprintf(ccc, "FILE:/tmp/krb5_cc_samba_%u_%p", + (unsigned int)getpid(), ccc); + } else { + ccache_name = talloc_asprintf(ccc, "MEMORY:%p", + ccc); + } + if (!ccache_name) { talloc_free(ccc); (*error_string) = strerror(ENOMEM); @@ -288,8 +294,38 @@ _PUBLIC_ int cli_credentials_get_named_ccache(struct cli_credentials *cred, if (cred->ccache_obtained >= cred->ccache_threshold && cred->ccache_obtained > CRED_UNINITIALISED) { - *ccc = cred->ccache; - return 0; + time_t lifetime; + bool expired = false; + ret = krb5_cc_get_lifetime(cred->ccache->smb_krb5_context->krb5_context, + cred->ccache->ccache, &lifetime); + if (ret == KRB5_CC_END) { + /* If we have a particular ccache set, without + * an initial ticket, then assume there is a + * good reason */ + } else if (ret == 0) { + if (lifetime == 0) { + DEBUG(3, ("Ticket in credentials cache for %s expired, will refresh\n", + cli_credentials_get_principal(cred, cred))); + expired = true; + } else if (lifetime < 300) { + DEBUG(3, ("Ticket in credentials cache for %s will shortly expire (%u secs), will refresh\n", + cli_credentials_get_principal(cred, cred), (unsigned int)lifetime)); + expired = true; + } + } else { + (*error_string) = talloc_asprintf(cred, "failed to get ccache lifetime: %s\n", + smb_get_krb5_error_message(cred->ccache->smb_krb5_context->krb5_context, + ret, cred)); + return ret; + } + + DEBUG(5, ("Ticket in credentials cache for %s will expire in %u secs\n", + cli_credentials_get_principal(cred, cred), (unsigned int)lifetime)); + + if (!expired) { + *ccc = cred->ccache; + return 0; + } } if (cli_credentials_is_anonymous(cred)) { (*error_string) = "Cannot get anonymous kerberos credentials"; @@ -351,7 +387,7 @@ void cli_credentials_invalidate_client_gss_creds(struct cli_credentials *cred, } /* Now that we know that the data is 'this specified', then * don't allow something less 'known' to be returned as a - * ccache. Ie, if the username is on the commmand line, we + * ccache. Ie, if the username is on the command line, we * don't want to later guess to use a file-based ccache */ if (obtained > cred->client_gss_creds_threshold) { cred->client_gss_creds_threshold = obtained; @@ -384,7 +420,7 @@ _PUBLIC_ void cli_credentials_invalidate_ccache(struct cli_credentials *cred, } /* Now that we know that the data is 'this specified', then * don't allow something less 'known' to be returned as a - * ccache. Ie, if the username is on the commmand line, we + * ccache. i.e, if the username is on the command line, we * don't want to later guess to use a file-based ccache */ if (obtained > cred->ccache_threshold) { cred->ccache_threshold = obtained; @@ -416,14 +452,41 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, if (cred->client_gss_creds_obtained >= cred->client_gss_creds_threshold && cred->client_gss_creds_obtained > CRED_UNINITIALISED) { - *_gcc = cred->client_gss_creds; - return 0; + bool expired = false; + OM_uint32 lifetime = 0; + gss_cred_usage_t usage = 0; + maj_stat = gss_inquire_cred(&min_stat, cred->client_gss_creds->creds, + NULL, &lifetime, &usage, NULL); + if (maj_stat == GSS_S_CREDENTIALS_EXPIRED) { + DEBUG(3, ("Credentials for %s expired, must refresh credentials cache\n", cli_credentials_get_principal(cred, cred))); + expired = true; + } else if (maj_stat == GSS_S_COMPLETE && lifetime < 300) { + DEBUG(3, ("Credentials for %s will expire shortly (%u sec), must refresh credentials cache\n", cli_credentials_get_principal(cred, cred), lifetime)); + expired = true; + } else if (maj_stat != GSS_S_COMPLETE) { + *error_string = talloc_asprintf(cred, "inquiry of credential lifefime via GSSAPI gss_inquire_cred failed: %s\n", + gssapi_error_string(cred, maj_stat, min_stat, NULL)); + return EINVAL; + } + if (expired) { + cli_credentials_unconditionally_invalidate_client_gss_creds(cred); + } else { + DEBUG(5, ("GSSAPI credentials for %s will expire in %u secs\n", + cli_credentials_get_principal(cred, cred), (unsigned int)lifetime)); + + *_gcc = cred->client_gss_creds; + return 0; + } } ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx, &ccache, error_string); if (ret) { - DEBUG(1, ("Failed to get CCACHE for GSSAPI client: %s\n", error_message(ret))); + if (cli_credentials_get_kerberos_state(cred) == CRED_MUST_USE_KERBEROS) { + DEBUG(1, ("Failed to get kerberos credentials (kerberos required): %s\n", error_message(ret))); + } else { + DEBUG(4, ("Failed to get kerberos credentials: %s\n", error_message(ret))); + } return ret; } @@ -781,26 +844,43 @@ _PUBLIC_ void cli_credentials_set_salt_principal(struct cli_credentials *cred, c cred->salt_principal = talloc_strdup(cred, principal); } -/* The 'impersonate_principal' is used to allow on Kerberos principal +/* The 'impersonate_principal' is used to allow one Kerberos principal * (and it's associated keytab etc) to impersonate another. The * ability to do this is controlled by the KDC, but it is generally * permitted to impersonate anyone to yourself. This allows any * member of the domain to get the groups of a user. This is also * known as S4U2Self */ -const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred) +_PUBLIC_ const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred) { return cred->impersonate_principal; } -_PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal) +/* + * The 'self_service' is the service principal that + * represents the same object (by its objectSid) + * as the client principal (typically our machine account). + * When trying to impersonate 'impersonate_principal' with + * S4U2Self. + */ +_PUBLIC_ const char *cli_credentials_get_self_service(struct cli_credentials *cred) +{ + return cred->self_service; +} + +_PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, + const char *principal, + const char *self_service) { talloc_free(cred->impersonate_principal); cred->impersonate_principal = talloc_strdup(cred, principal); + talloc_free(cred->self_service); + cred->self_service = talloc_strdup(cred, self_service); + cli_credentials_set_kerberos_state(cred, CRED_MUST_USE_KERBEROS); } -/* when impersonating for S4U2Self we need to set the target principal - * to ourself, as otherwise we would need additional rights. +/* + * when impersonating for S4U2proxy we need to set the target principal. * Similarly, we may only be authorized to do general impersonation to * some particular services. * diff --git a/source4/auth/gensec/cyrus_sasl.c b/source4/auth/gensec/cyrus_sasl.c index bd7664878c..4a4422645d 100644 --- a/source4/auth/gensec/cyrus_sasl.c +++ b/source4/auth/gensec/cyrus_sasl.c @@ -99,12 +99,12 @@ static int gensec_sasl_get_password(sasl_conn_t *conn, void *context, int id, *psecret = NULL; return SASL_OK; } - secret = talloc_size(gensec_security, sizeof(sasl_secret_t)+strlen(password)); + secret = talloc_size(gensec_security, sizeof(sasl_secret_t)+strlen(password)+1); if (!secret) { return SASL_NOMEM; } secret->len = strlen(password); - safe_strcpy((char*)secret->data, password, secret->len+1); + strlcpy((char*)secret->data, password, secret->len+1); *psecret = secret; return SASL_OK; } diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c index e632aec2dc..7e6a83d51f 100644 --- a/source4/auth/gensec/gensec.c +++ b/source4/auth/gensec/gensec.c @@ -514,7 +514,7 @@ const char **gensec_security_oids(struct gensec_security *gensec_security, static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct gensec_settings *settings, - struct auth_context *auth_context, + struct auth4_context *auth_context, struct gensec_security **gensec_security) { if (ev == NULL) { @@ -604,7 +604,7 @@ _PUBLIC_ NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx, _PUBLIC_ NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct gensec_settings *settings, - struct auth_context *auth_context, + struct auth4_context *auth_context, struct gensec_security **gensec_security) { NTSTATUS status; @@ -639,7 +639,7 @@ static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) if (gensec_security->ops->client_start) { status = gensec_security->ops->client_start(gensec_security); if (!NT_STATUS_IS_OK(status)) { - DEBUG(2, ("Failed to start GENSEC client mech %s: %s\n", + DEBUG(gensec_security->subcontext?4:2, ("Failed to start GENSEC client mech %s: %s\n", gensec_security->ops->name, nt_errstr(status))); } return status; @@ -1406,7 +1406,7 @@ bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism /* initialise the GENSEC subsystem */ -_PUBLIC_ NTSTATUS gensec_init(struct loadparm_context *lp_ctx) +_PUBLIC_ NTSTATUS gensec_init(void) { static bool initialized = false; #define _MODULE_PROTO(init) extern NTSTATUS init(void); @@ -1417,7 +1417,7 @@ _PUBLIC_ NTSTATUS gensec_init(struct loadparm_context *lp_ctx) if (initialized) return NT_STATUS_OK; initialized = true; - shared_init = load_samba_modules(NULL, lp_ctx, "gensec"); + shared_init = load_samba_modules(NULL, "gensec"); run_init_functions(static_init); run_init_functions(shared_init); diff --git a/source4/auth/gensec/gensec.h b/source4/auth/gensec/gensec.h index 48268c421e..e42b4aa5d2 100644 --- a/source4/auth/gensec/gensec.h +++ b/source4/auth/gensec/gensec.h @@ -165,7 +165,7 @@ struct gensec_security { /* When we are a server, this may be filled in to provide an * NTLM authentication backend, and user lookup (such as if no * PAC is found) */ - struct auth_context *auth_context; + struct auth4_context *auth_context; }; /* this structure is used by backends to determine the size of some critical types */ @@ -179,7 +179,7 @@ struct gensec_critical_sizes { struct gensec_security; struct socket_context; -struct auth_context; +struct auth4_context; struct auth_user_info_dc; NTSTATUS gensec_socket_init(struct gensec_security *gensec_security, @@ -242,7 +242,7 @@ NTSTATUS gensec_start_mech_by_oid(struct gensec_security *gensec_security, const char *mech_oid); const char *gensec_get_name_by_oid(struct gensec_security *gensec_security, const char *oid_string); struct cli_credentials *gensec_get_credentials(struct gensec_security *gensec_security); -NTSTATUS gensec_init(struct loadparm_context *lp_ctx); +NTSTATUS gensec_init(void); NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, @@ -270,7 +270,7 @@ const char *gensec_get_name_by_authtype(struct gensec_security *gensec_security, NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct gensec_settings *settings, - struct auth_context *auth_context, + struct auth4_context *auth_context, struct gensec_security **gensec_security); NTSTATUS gensec_session_info(struct gensec_security *gensec_security, struct auth_session_info **session_info); diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 59029e6fc9..72c6b3f991 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -47,44 +47,6 @@ _PUBLIC_ NTSTATUS gensec_gssapi_init(void); static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security); static size_t gensec_gssapi_max_wrapped_size(struct gensec_security *gensec_security); -static char *gssapi_error_string(TALLOC_CTX *mem_ctx, - OM_uint32 maj_stat, OM_uint32 min_stat, - const gss_OID mech) -{ - OM_uint32 disp_min_stat, disp_maj_stat; - gss_buffer_desc maj_error_message; - gss_buffer_desc min_error_message; - char *maj_error_string, *min_error_string; - OM_uint32 msg_ctx = 0; - - char *ret; - - maj_error_message.value = NULL; - min_error_message.value = NULL; - maj_error_message.length = 0; - min_error_message.length = 0; - - disp_maj_stat = gss_display_status(&disp_min_stat, maj_stat, GSS_C_GSS_CODE, - mech, &msg_ctx, &maj_error_message); - disp_maj_stat = gss_display_status(&disp_min_stat, min_stat, GSS_C_MECH_CODE, - mech, &msg_ctx, &min_error_message); - - maj_error_string = talloc_strndup(mem_ctx, (char *)maj_error_message.value, maj_error_message.length); - - min_error_string = talloc_strndup(mem_ctx, (char *)min_error_message.value, min_error_message.length); - - ret = talloc_asprintf(mem_ctx, "%s: %s", maj_error_string, min_error_string); - - talloc_free(maj_error_string); - talloc_free(min_error_string); - - gss_release_buffer(&disp_min_stat, &maj_error_message); - gss_release_buffer(&disp_min_stat, &min_error_message); - - return ret; -} - - static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_state) { OM_uint32 maj_stat, min_stat; @@ -340,6 +302,10 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); + if (cli_credentials_get_impersonate_principal(creds)) { + gensec_gssapi_state->want_flags &= ~(GSS_C_DELEG_FLAG|GSS_C_DELEG_POLICY_FLAG); + } + gensec_gssapi_state->target_principal = gensec_get_target_principal(gensec_security); if (gensec_gssapi_state->target_principal) { name_type = GSS_C_NULL_OID; @@ -557,6 +523,65 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, gss_release_buffer(&min_stat2, &output_token); return NT_STATUS_MORE_PROCESSING_REQUIRED; + } else if (maj_stat == GSS_S_CONTEXT_EXPIRED) { + gss_cred_id_t creds; + gss_name_t name; + gss_buffer_desc buffer; + OM_uint32 lifetime = 0; + gss_cred_usage_t usage; + const char *role = NULL; + DEBUG(0, ("GSS %s Update(krb5)(%d) Update failed, credentials expired during GSSAPI handshake!\n", + role, + gensec_gssapi_state->gss_exchange_count)); + + + switch (gensec_security->gensec_role) { + case GENSEC_CLIENT: + creds = gensec_gssapi_state->client_cred->creds; + role = "client"; + case GENSEC_SERVER: + creds = gensec_gssapi_state->server_cred->creds; + role = "server"; + } + + maj_stat = gss_inquire_cred(&min_stat, + creds, + &name, &lifetime, &usage, NULL); + + if (maj_stat == GSS_S_COMPLETE) { + const char *usage_string; + switch (usage) { + case GSS_C_BOTH: + usage_string = "GSS_C_BOTH"; + break; + case GSS_C_ACCEPT: + usage_string = "GSS_C_ACCEPT"; + break; + case GSS_C_INITIATE: + usage_string = "GSS_C_INITIATE"; + break; + } + maj_stat = gss_display_name(&min_stat, name, &buffer, NULL); + if (maj_stat) { + buffer.value = NULL; + buffer.length = 0; + } + if (lifetime > 0) { + DEBUG(0, ("GSSAPI gss_inquire_cred indicates expiry of %*.*s in %u sec for %s\n", + (int)buffer.length, (int)buffer.length, (char *)buffer.value, + lifetime, usage_string)); + } else { + DEBUG(0, ("GSSAPI gss_inquire_cred indicates %*.*s has already expired for %s\n", + (int)buffer.length, (int)buffer.length, (char *)buffer.value, + usage_string)); + } + gss_release_buffer(&min_stat, &buffer); + gss_release_name(&min_stat, &name); + } else if (maj_stat != GSS_S_COMPLETE) { + DEBUG(0, ("inquiry of credential lifefime via GSSAPI gss_inquire_cred failed: %s\n", + gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); + } + return NT_STATUS_INVALID_PARAMETER; } else if (gss_oid_equal(gensec_gssapi_state->gss_oid, gss_mech_krb5)) { switch (min_stat) { case KRB5KRB_AP_ERR_TKT_NYV: @@ -1262,7 +1287,6 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi struct auth_user_info_dc *user_info_dc = NULL; struct auth_session_info *session_info = NULL; OM_uint32 maj_stat, min_stat; - gss_buffer_desc pac; DATA_BLOB pac_blob; struct PAC_SIGNATURE_DATA *pac_srv_sig = NULL; struct PAC_SIGNATURE_DATA *pac_kdc_sig = NULL; @@ -1277,25 +1301,15 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi mem_ctx = talloc_named(gensec_gssapi_state, 0, "gensec_gssapi_session_info context"); NT_STATUS_HAVE_NO_MEMORY(mem_ctx); - maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, - gensec_gssapi_state->gssapi_context, - KRB5_AUTHDATA_WIN2K_PAC, - &pac); - - - if (maj_stat == 0) { - pac_blob = data_blob_talloc(mem_ctx, pac.value, pac.length); - gss_release_buffer(&min_stat, &pac); - - } else { - pac_blob = data_blob(NULL, 0); - } + nt_status = gssapi_obtain_pac_blob(mem_ctx, gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->client_name, + &pac_blob); /* IF we have the PAC - otherwise we need to get this * data from elsewere - local ldb, or (TODO) lookup of some * kind... */ - if (pac_blob.length) { + if (NT_STATUS_IS_OK(nt_status)) { pac_srv_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA); if (!pac_srv_sig) { talloc_free(mem_ctx); diff --git a/source4/auth/gensec/pygensec.c b/source4/auth/gensec/pygensec.c index fd9726eb75..503974aaa3 100644 --- a/source4/auth/gensec/pygensec.c +++ b/source4/auth/gensec/pygensec.c @@ -127,7 +127,7 @@ static PyObject *py_gensec_start_client(PyTypeObject *type, PyObject *args, PyOb return NULL; } - status = gensec_init(settings->lp_ctx); + status = gensec_init(); if (!NT_STATUS_IS_OK(status)) { PyErr_SetNTSTATUS(status); PyObject_DEL(self); @@ -156,7 +156,7 @@ static PyObject *py_gensec_start_server(PyTypeObject *type, PyObject *args, PyOb PyObject *py_auth_context = Py_None; struct tevent_context *ev; struct gensec_security *gensec; - struct auth_context *auth_context = NULL; + struct auth4_context *auth_context = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", discard_const_p(char *, kwnames), &py_settings, &py_auth_context)) return NULL; @@ -201,7 +201,7 @@ static PyObject *py_gensec_start_server(PyTypeObject *type, PyObject *args, PyOb } if (py_auth_context != Py_None) { - auth_context = py_talloc_get_type(py_auth_context, struct auth_context); + auth_context = py_talloc_get_type(py_auth_context, struct auth4_context); if (!auth_context) { PyErr_Format(PyExc_TypeError, "Expected auth.AuthContext for auth_context argument, got %s", @@ -210,7 +210,7 @@ static PyObject *py_gensec_start_server(PyTypeObject *type, PyObject *args, PyOb } } - status = gensec_init(settings->lp_ctx); + status = gensec_init(); if (!NT_STATUS_IS_OK(status)) { PyErr_SetNTSTATUS(status); PyObject_DEL(self); diff --git a/source4/auth/kerberos/kerberos.c b/source4/auth/kerberos/kerberos.c index 0db0dd3ced..0fc9d143ab 100644 --- a/source4/auth/kerberos/kerberos.c +++ b/source4/auth/kerberos/kerberos.c @@ -81,86 +81,387 @@ The impersonate_principal is the principal if NULL, or the principal to impersonate - The target_service defaults to the krbtgt if NULL, but could be kpasswd/realm or the local service (if we are doing s4u2self) + The self_service, should be the local service (for S4U2Self if impersonate_principal is given). + + The target_service defaults to the krbtgt if NULL, but could be kpasswd/realm or a remote service (for S4U2Proxy) */ - krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, - krb5_principal principal, const char *password, - krb5_principal impersonate_principal, const char *target_service, + krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache store_cc, + krb5_principal init_principal, + const char *init_password, + krb5_principal impersonate_principal, + const char *self_service, + const char *target_service, krb5_get_init_creds_opt *krb_options, time_t *expire_time, time_t *kdc_time) { krb5_error_code code = 0; - krb5_creds my_creds; - krb5_creds *impersonate_creds; krb5_get_creds_opt options; + krb5_principal store_principal; + krb5_creds store_creds; + krb5_creds *s4u2self_creds; + Ticket s4u2self_ticket; + size_t s4u2self_ticketlen; + krb5_creds *s4u2proxy_creds; + krb5_principal self_princ; + bool s4u2proxy; + krb5_principal target_princ; + krb5_ccache tmp_cc; + const char *self_realm; + krb5_principal blacklist_principal = NULL; + krb5_principal whitelist_principal = NULL; - /* If we are not impersonating, then get this ticket for the + if (impersonate_principal && self_service == NULL) { + return EINVAL; + } + + /* + * If we are not impersonating, then get this ticket for the * target service, otherwise a krbtgt, and get the next ticket - * for the target */ - if ((code = krb5_get_init_creds_password(ctx, &my_creds, principal, password, - NULL, NULL, - 0, - impersonate_principal ? NULL : target_service, - krb_options))) { + * for the target + */ + code = krb5_get_init_creds_password(ctx, &store_creds, + init_principal, + init_password, + NULL, NULL, + 0, + impersonate_principal ? NULL : target_service, + krb_options); + if (code != 0) { return code; } - if ((code = krb5_cc_initialize(ctx, cc, principal))) { - krb5_free_cred_contents(ctx, &my_creds); + store_principal = init_principal; + + if (impersonate_principal == NULL) { + goto store; + } + + /* + * We are trying S4U2Self now: + * + * As we do not want to expose our TGT in the + * krb5_ccache, which is also holds the impersonated creds. + * + * Some low level krb5/gssapi function might use the TGT + * identity and let the client act as our machine account. + * + * We need to avoid that and use a temporary krb5_ccache + * in order to pass our TGT to the krb5_get_creds() function. + */ + code = krb5_cc_new_unique(ctx, NULL, NULL, &tmp_cc); + if (code != 0) { + krb5_free_cred_contents(ctx, &store_creds); return code; } - - if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) { - krb5_free_cred_contents(ctx, &my_creds); + + code = krb5_cc_initialize(ctx, tmp_cc, store_creds.client); + if (code != 0) { + krb5_cc_destroy(ctx, tmp_cc); + krb5_free_cred_contents(ctx, &store_creds); return code; } - - if (expire_time) { - *expire_time = (time_t) my_creds.times.endtime; + + code = krb5_cc_store_cred(ctx, tmp_cc, &store_creds); + if (code != 0) { + krb5_free_cred_contents(ctx, &store_creds); + krb5_cc_destroy(ctx, tmp_cc); + return code; } - if (kdc_time) { - *kdc_time = (time_t) my_creds.times.starttime; + /* + * we need to remember the client principal of our + * TGT and make sure the KDC does not return this + * in the impersonated tickets. This can happen + * if the KDC does not support S4U2Self and S4U2Proxy. + */ + blacklist_principal = store_creds.client; + store_creds.client = NULL; + krb5_free_cred_contents(ctx, &store_creds); + + /* + * Check if we also need S4U2Proxy or if S4U2Self is + * enough in order to get a ticket for the target. + */ + if (target_service == NULL) { + s4u2proxy = false; + } else if (strcmp(target_service, self_service) == 0) { + s4u2proxy = false; + } else { + s4u2proxy = true; } - krb5_free_cred_contents(ctx, &my_creds); - - if (code == 0 && impersonate_principal) { - krb5_principal target_princ; - if ((code = krb5_get_creds_opt_alloc(ctx, &options))) { - return code; - } + /* + * For S4U2Self we need our own service principal, + * which belongs to our own realm (available on + * our client principal). + */ + self_realm = krb5_principal_get_realm(ctx, init_principal); - if ((code = krb5_get_creds_opt_set_impersonate(ctx, options, impersonate_principal))) { - krb5_get_creds_opt_free(ctx, options); - return code; - } + code = krb5_parse_name(ctx, self_service, &self_princ); + if (code != 0) { + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } - if ((code = krb5_parse_name(ctx, target_service, &target_princ))) { - krb5_get_creds_opt_free(ctx, options); - return code; - } + code = krb5_principal_set_realm(ctx, self_princ, self_realm); + if (code != 0) { + krb5_free_principal(ctx, blacklist_principal); + krb5_free_principal(ctx, self_princ); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } - if ((code = krb5_principal_set_realm(ctx, target_princ, krb5_principal_get_realm(ctx, principal)))) { - krb5_get_creds_opt_free(ctx, options); - krb5_free_principal(ctx, target_princ); - return code; - } + code = krb5_get_creds_opt_alloc(ctx, &options); + if (code != 0) { + krb5_free_principal(ctx, blacklist_principal); + krb5_free_principal(ctx, self_princ); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } - if ((code = krb5_get_creds(ctx, options, cc, target_princ, &impersonate_creds))) { - krb5_free_principal(ctx, target_princ); - krb5_get_creds_opt_free(ctx, options); + if (s4u2proxy) { + /* + * If we want S4U2Proxy, we need the forwardable flag + * on the S4U2Self ticket. + */ + krb5_get_creds_opt_set_options(ctx, options, KRB5_GC_FORWARDABLE); + } + + code = krb5_get_creds_opt_set_impersonate(ctx, options, + impersonate_principal); + if (code != 0) { + krb5_get_creds_opt_free(ctx, options); + krb5_free_principal(ctx, blacklist_principal); + krb5_free_principal(ctx, self_princ); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + code = krb5_get_creds(ctx, options, tmp_cc, + self_princ, &s4u2self_creds); + krb5_get_creds_opt_free(ctx, options); + krb5_free_principal(ctx, self_princ); + if (code != 0) { + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + if (!s4u2proxy) { + krb5_cc_destroy(ctx, tmp_cc); + + /* + * Now make sure we store the impersonated principal + * and creds instead of the TGT related stuff + * in the krb5_ccache of the caller. + */ + code = krb5_copy_creds_contents(ctx, s4u2self_creds, + &store_creds); + krb5_free_creds(ctx, s4u2self_creds); + if (code != 0) { return code; } + /* + * It's important to store the principal the KDC + * returned, as otherwise the caller would not find + * the S4U2Self ticket in the krb5_ccache lookup. + */ + store_principal = store_creds.client; + goto store; + } + + /* + * We are trying S4U2Proxy: + * + * We need the ticket from the S4U2Self step + * and our TGT in order to get the delegated ticket. + */ + code = decode_Ticket((const uint8_t *)s4u2self_creds->ticket.data, + s4u2self_creds->ticket.length, + &s4u2self_ticket, + &s4u2self_ticketlen); + if (code != 0) { + krb5_free_creds(ctx, s4u2self_creds); + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + /* + * we need to remember the client principal of the + * S4U2Self stage and as it needs to match the one we + * will get for the S4U2Proxy stage. We need this + * in order to detect KDCs which does not support S4U2Proxy. + */ + whitelist_principal = s4u2self_creds->client; + s4u2self_creds->client = NULL; + krb5_free_creds(ctx, s4u2self_creds); + + /* + * For S4U2Proxy we also got a target service principal, + * which also belongs to our own realm (available on + * our client principal). + */ + code = krb5_parse_name(ctx, target_service, &target_princ); + if (code != 0) { + free_Ticket(&s4u2self_ticket); + krb5_free_principal(ctx, whitelist_principal); + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + code = krb5_principal_set_realm(ctx, target_princ, self_realm); + if (code != 0) { + free_Ticket(&s4u2self_ticket); krb5_free_principal(ctx, target_princ); + krb5_free_principal(ctx, whitelist_principal); + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + code = krb5_get_creds_opt_alloc(ctx, &options); + if (code != 0) { + free_Ticket(&s4u2self_ticket); + krb5_free_principal(ctx, target_princ); + krb5_free_principal(ctx, whitelist_principal); + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + krb5_get_creds_opt_set_options(ctx, options, KRB5_GC_FORWARDABLE); + krb5_get_creds_opt_set_options(ctx, options, KRB5_GC_CONSTRAINED_DELEGATION); - code = krb5_cc_store_cred(ctx, cc, impersonate_creds); + code = krb5_get_creds_opt_set_ticket(ctx, options, &s4u2self_ticket); + free_Ticket(&s4u2self_ticket); + if (code != 0) { krb5_get_creds_opt_free(ctx, options); - krb5_free_creds(ctx, impersonate_creds); + krb5_free_principal(ctx, target_princ); + krb5_free_principal(ctx, whitelist_principal); + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; } + code = krb5_get_creds(ctx, options, tmp_cc, + target_princ, &s4u2proxy_creds); + krb5_get_creds_opt_free(ctx, options); + krb5_free_principal(ctx, target_princ); + krb5_cc_destroy(ctx, tmp_cc); + if (code != 0) { + krb5_free_principal(ctx, whitelist_principal); + krb5_free_principal(ctx, blacklist_principal); + return code; + } + + /* + * Now make sure we store the impersonated principal + * and creds instead of the TGT related stuff + * in the krb5_ccache of the caller. + */ + code = krb5_copy_creds_contents(ctx, s4u2proxy_creds, + &store_creds); + krb5_free_creds(ctx, s4u2proxy_creds); + if (code != 0) { + krb5_free_principal(ctx, whitelist_principal); + krb5_free_principal(ctx, blacklist_principal); + return code; + } + + /* + * It's important to store the principal the KDC + * returned, as otherwise the caller would not find + * the S4U2Self ticket in the krb5_ccache lookup. + */ + store_principal = store_creds.client; + + store: + if (blacklist_principal && + krb5_principal_compare(ctx, store_creds.client, blacklist_principal)) { + char *sp = NULL; + char *ip = NULL; + + code = krb5_unparse_name(ctx, blacklist_principal, &sp); + if (code != 0) { + sp = NULL; + } + code = krb5_unparse_name(ctx, impersonate_principal, &ip); + if (code != 0) { + ip = NULL; + } + DEBUG(1, ("kerberos_kinit_password_cc: " + "KDC returned self principal[%s] while impersonating [%s]\n", + sp?sp:"<no memory>", + ip?ip:"<no memory>")); + + SAFE_FREE(sp); + SAFE_FREE(ip); + + krb5_free_principal(ctx, whitelist_principal); + krb5_free_principal(ctx, blacklist_principal); + krb5_free_cred_contents(ctx, &store_creds); + return KRB5_FWD_BAD_PRINCIPAL; + } + if (blacklist_principal) { + krb5_free_principal(ctx, blacklist_principal); + } + + if (whitelist_principal && + !krb5_principal_compare(ctx, store_creds.client, whitelist_principal)) { + char *sp = NULL; + char *ep = NULL; + + code = krb5_unparse_name(ctx, store_creds.client, &sp); + if (code != 0) { + sp = NULL; + } + code = krb5_unparse_name(ctx, whitelist_principal, &ep); + if (code != 0) { + ep = NULL; + } + DEBUG(1, ("kerberos_kinit_password_cc: " + "KDC returned wrong principal[%s] we expected [%s]\n", + sp?sp:"<no memory>", + ep?ep:"<no memory>")); + + SAFE_FREE(sp); + SAFE_FREE(ep); + + krb5_free_principal(ctx, whitelist_principal); + krb5_free_cred_contents(ctx, &store_creds); + return KRB5_FWD_BAD_PRINCIPAL; + } + if (whitelist_principal) { + krb5_free_principal(ctx, whitelist_principal); + } + + code = krb5_cc_initialize(ctx, store_cc, store_principal); + if (code != 0) { + krb5_free_cred_contents(ctx, &store_creds); + return code; + } + + code = krb5_cc_store_cred(ctx, store_cc, &store_creds); + if (code != 0) { + krb5_free_cred_contents(ctx, &store_creds); + return code; + } + + if (expire_time) { + *expire_time = (time_t) store_creds.times.endtime; + } + + if (kdc_time) { + *kdc_time = (time_t) store_creds.times.starttime; + } + + krb5_free_cred_contents(ctx, &store_creds); + return 0; } diff --git a/source4/auth/kerberos/kerberos.h b/source4/auth/kerberos/kerberos.h index c712569e5d..31794b8e03 100644 --- a/source4/auth/kerberos/kerberos.h +++ b/source4/auth/kerberos/kerberos.h @@ -97,7 +97,9 @@ krb5_error_code ads_krb5_mk_req(krb5_context context, bool get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt); krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, krb5_principal principal, const char *password, - krb5_principal impersonate_principal, const char *target_service, + krb5_principal impersonate_principal, + const char *self_service, + const char *target_service, krb5_get_init_creds_opt *krb_options, time_t *expire_time, time_t *kdc_time); krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc, diff --git a/source4/auth/kerberos/kerberos_pac.c b/source4/auth/kerberos/kerberos_pac.c index 5bc80c9a58..8ce970e486 100644 --- a/source4/auth/kerberos/kerberos_pac.c +++ b/source4/auth/kerberos/kerberos_pac.c @@ -448,14 +448,14 @@ NTSTATUS kerberos_pac_blob_to_user_info_dc(TALLOC_CTX *mem_ctx, pac_blob.data, pac_blob.length, &pac); if (ret) { - return map_nt_error_from_unix(ret); + return map_nt_error_from_unix_common(ret); } ret = kerberos_pac_to_user_info_dc(mem_ctx, pac, context, user_info_dc, pac_srv_sig, pac_kdc_sig); krb5_pac_free(context, pac); if (ret) { - return map_nt_error_from_unix(ret); + return map_nt_error_from_unix_common(ret); } return NT_STATUS_OK; } diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c index 45b0b07e13..9a48e95c6d 100644 --- a/source4/auth/kerberos/kerberos_util.c +++ b/source4/auth/kerberos/kerberos_util.c @@ -173,7 +173,7 @@ static krb5_error_code principals_from_msg(TALLOC_CTX *parent_ctx, return ret; } - /* This song-and-dance effectivly puts the principal + /* This song-and-dance effectively puts the principal * into talloc, so we can't loose it. */ talloc_set_destructor(principals[i], free_principal); i++; @@ -262,7 +262,7 @@ static krb5_error_code salt_principal_from_msg(TALLOC_CTX *parent_ctx, upper_realm, "host", salt_body, NULL); if (ret == 0) { - /* This song-and-dance effectivly puts the principal + /* This song-and-dance effectively puts the principal * into talloc, so we can't loose it. */ mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context); mem_ctx->principal = *salt_princ; @@ -338,7 +338,9 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, const char **error_string) { krb5_error_code ret; - const char *password, *target_service; + const char *password; + const char *self_service; + const char *target_service; time_t kdc_time = 0; krb5_principal princ; krb5_principal impersonate_principal; @@ -363,6 +365,7 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, return ret; } + self_service = cli_credentials_get_self_service(credentials); target_service = cli_credentials_get_target_service(credentials); password = cli_credentials_get_password(credentials); @@ -403,7 +406,9 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, if (password) { ret = kerberos_kinit_password_cc(smb_krb5_context->krb5_context, ccache, princ, password, - impersonate_principal, target_service, + impersonate_principal, + self_service, + target_service, krb_options, NULL, &kdc_time); } else if (impersonate_principal) { @@ -733,7 +738,7 @@ static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx, /* Release the enumeration. We are going to * have to start this from the top again, * because deletes during enumeration may not - * always be consistant. + * always be consistent. * * Also, the enumeration locks a FILE: keytab */ diff --git a/source4/auth/kerberos/krb5_init_context.c b/source4/auth/kerberos/krb5_init_context.c index db3a5375c9..fbcaad29d9 100644 --- a/source4/auth/kerberos/krb5_init_context.c +++ b/source4/auth/kerberos/krb5_init_context.c @@ -415,7 +415,7 @@ smb_krb5_init_context_basic(TALLOC_CTX *tmp_ctx, return ret; } - config_file = config_path(tmp_ctx, lp_ctx, "krb5.conf"); + config_file = lpcfg_config_path(tmp_ctx, lp_ctx, "krb5.conf"); if (!config_file) { krb5_free_context(krb5_ctx); return ENOMEM; diff --git a/source4/auth/kerberos/wscript_build b/source4/auth/kerberos/wscript_build index 586366d422..90e8560573 100644 --- a/source4/auth/kerberos/wscript_build +++ b/source4/auth/kerberos/wscript_build @@ -4,7 +4,7 @@ bld.SAMBA_LIBRARY('authkrb5', source='kerberos.c kerberos_heimdal.c kerberos_pac.c gssapi_parse.c krb5_init_context.c keytab_copy.c', autoproto='proto.h', public_deps='krb5 ndr-krb5pac samba_socket LIBCLI_RESOLVE com_err asn1', - deps='asn1util auth_sam_reply tevent LIBPACKET ndr ldb KRB5_WRAP', + deps='asn1util auth_sam_reply tevent LIBPACKET ndr ldb KRB5_WRAP errors', private_library=True ) diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c index e2deab78bc..d2464c3cbf 100644 --- a/source4/auth/ntlm/auth.c +++ b/source4/auth/ntlm/auth.c @@ -31,7 +31,7 @@ /*************************************************************************** Set a fixed challenge ***************************************************************************/ -_PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by) +_PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by) { auth_ctx->challenge.set_by = talloc_strdup(auth_ctx, set_by); NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.set_by); @@ -45,7 +45,7 @@ _PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth_context *auth_ctx, cons /*************************************************************************** Set a fixed challenge ***************************************************************************/ -_PUBLIC_ bool auth_challenge_may_be_modified(struct auth_context *auth_ctx) +_PUBLIC_ bool auth_challenge_may_be_modified(struct auth4_context *auth_ctx) { return auth_ctx->challenge.may_be_modified; } @@ -54,7 +54,7 @@ _PUBLIC_ bool auth_challenge_may_be_modified(struct auth_context *auth_ctx) Try to get a challenge out of the various authentication modules. Returns a const char of length 8 bytes. ****************************************************************************/ -_PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8]) +_PUBLIC_ NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t chal[8]) { NTSTATUS nt_status; struct auth_method_context *method; @@ -104,7 +104,7 @@ PAC isn't available, and for tokenGroups in the DSDB stack. Supply either a principal or a DN ****************************************************************************/ _PUBLIC_ NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx, - struct auth_context *auth_ctx, + struct auth4_context *auth_ctx, const char *principal, struct ldb_dn *user_dn, struct auth_user_info_dc **user_info_dc) @@ -155,7 +155,7 @@ _PUBLIC_ NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx, * **/ -_PUBLIC_ NTSTATUS auth_check_password(struct auth_context *auth_ctx, +_PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx, TALLOC_CTX *mem_ctx, const struct auth_usersupplied_info *user_info, struct auth_user_info_dc **user_info_dc) @@ -188,7 +188,7 @@ _PUBLIC_ NTSTATUS auth_check_password(struct auth_context *auth_ctx, } struct auth_check_password_state { - struct auth_context *auth_ctx; + struct auth4_context *auth_ctx; const struct auth_usersupplied_info *user_info; struct auth_user_info_dc *user_info_dc; struct auth_method_context *method; @@ -225,7 +225,7 @@ static void auth_check_password_async_trigger(struct tevent_context *ev, _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct auth_context *auth_ctx, + struct auth4_context *auth_ctx, const struct auth_usersupplied_info *user_info) { struct tevent_req *req; @@ -409,7 +409,7 @@ _PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req, /* Wrapper because we don't want to expose all callers to needing to * know that session_info is generated from the main ldb */ static NTSTATUS auth_generate_session_info_wrapper(TALLOC_CTX *mem_ctx, - struct auth_context *auth_context, + struct auth4_context *auth_context, struct auth_user_info_dc *user_info_dc, uint32_t session_info_flags, struct auth_session_info **session_info) @@ -425,13 +425,13 @@ static NTSTATUS auth_generate_session_info_wrapper(TALLOC_CTX *mem_ctx, ***************************************************************************/ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **methods, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, struct ldb_context *sam_ctx, - struct auth_context **auth_ctx) + struct auth4_context **auth_ctx) { int i; - struct auth_context *ctx; + struct auth4_context *ctx; auth4_init(); @@ -440,7 +440,7 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char ** return NT_STATUS_INTERNAL_ERROR; } - ctx = talloc(mem_ctx, struct auth_context); + ctx = talloc(mem_ctx, struct auth4_context); NT_STATUS_HAVE_NO_MEMORY(ctx); ctx->challenge.set_by = NULL; ctx->challenge.may_be_modified = false; @@ -487,19 +487,21 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char ** const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) { - const char **auth_methods = NULL; + char **auth_methods = NULL; + switch (lpcfg_server_role(lp_ctx)) { case ROLE_STANDALONE: - auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "standalone", NULL); + auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain", NULL); break; case ROLE_DOMAIN_MEMBER: - auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "member server", NULL); + auth_methods = str_list_make(mem_ctx, "anonymous sam winbind", NULL); break; - case ROLE_DOMAIN_CONTROLLER: - auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "domain controller", NULL); + case ROLE_DOMAIN_BDC: + case ROLE_DOMAIN_PDC: + auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain winbind", NULL); break; } - return auth_methods; + return (const char **) auth_methods; } /*************************************************************************** @@ -508,9 +510,9 @@ const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context * ***************************************************************************/ _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, - struct auth_context **auth_ctx) + struct auth4_context **auth_ctx) { NTSTATUS status; const char **auth_methods; @@ -533,7 +535,7 @@ _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, This allows us not to re-open the LDB when we need to do a some authentication logic (such as tokenGroups) */ -NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx) +NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth4_context **auth_ctx) { NTSTATUS status; const char **auth_methods; @@ -620,10 +622,10 @@ const struct auth_operations *auth_backend_byname(const char *name) const struct auth_critical_sizes *auth_interface_version(void) { static const struct auth_critical_sizes critical_sizes = { - AUTH_INTERFACE_VERSION, + AUTH4_INTERFACE_VERSION, sizeof(struct auth_operations), sizeof(struct auth_method_context), - sizeof(struct auth_context), + sizeof(struct auth4_context), sizeof(struct auth_usersupplied_info), sizeof(struct auth_user_info_dc) }; diff --git a/source4/auth/ntlm/auth_anonymous.c b/source4/auth/ntlm/auth_anonymous.c index 6b21225aad..4b0fff03cc 100644 --- a/source4/auth/ntlm/auth_anonymous.c +++ b/source4/auth/ntlm/auth_anonymous.c @@ -24,7 +24,7 @@ #include "auth/ntlm/auth_proto.h" #include "param/param.h" -_PUBLIC_ NTSTATUS auth_anonymous_init(void); +_PUBLIC_ NTSTATUS auth4_anonymous_init(void); /** * Return a anonymous logon for anonymous users (username = "") @@ -66,7 +66,7 @@ static const struct auth_operations anonymous_auth_ops = { .check_password = anonymous_check_password }; -_PUBLIC_ NTSTATUS auth_anonymous_init(void) +_PUBLIC_ NTSTATUS auth4_anonymous_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/auth_developer.c b/source4/auth/ntlm/auth_developer.c index da842c98ba..bc27f27fa2 100644 --- a/source4/auth/ntlm/auth_developer.c +++ b/source4/auth/ntlm/auth_developer.c @@ -24,7 +24,7 @@ #include "auth/ntlm/auth_proto.h" #include "libcli/security/security.h" -_PUBLIC_ NTSTATUS auth_developer_init(void); +_PUBLIC_ NTSTATUS auth4_developer_init(void); static NTSTATUS name_to_ntstatus_want_check(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, @@ -185,7 +185,7 @@ static const struct auth_operations fixed_challenge_auth_ops = { .check_password = fixed_challenge_check_password }; -_PUBLIC_ NTSTATUS auth_developer_init(void) +_PUBLIC_ NTSTATUS auth4_developer_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c index f76057a6df..87a7d27559 100644 --- a/source4/auth/ntlm/auth_sam.c +++ b/source4/auth/ntlm/auth_sam.c @@ -72,7 +72,7 @@ static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, struct ldb_context * Do a specific test for an smb password being correct, given a smb_password and the lanman and NT responses. ****************************************************************************/ -static NTSTATUS authsam_password_ok(struct auth_context *auth_context, +static NTSTATUS authsam_password_ok(struct auth4_context *auth_context, TALLOC_CTX *mem_ctx, uint16_t acct_flags, const struct samr_Password *lm_pwd, @@ -142,7 +142,7 @@ static NTSTATUS authsam_password_ok(struct auth_context *auth_context, send a message to the drepl server telling it to initiate a REPL_SECRET getncchanges extended op to fetch the users secrets */ -static void auth_sam_trigger_repl_secret(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, +static void auth_sam_trigger_repl_secret(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context, struct ldb_dn *user_dn) { struct dcerpc_binding_handle *irpc_handle; @@ -170,7 +170,7 @@ static void auth_sam_trigger_repl_secret(TALLOC_CTX *mem_ctx, struct auth_contex } -static NTSTATUS authsam_authenticate(struct auth_context *auth_context, +static NTSTATUS authsam_authenticate(struct auth4_context *auth_context, TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, struct ldb_dn *domain_dn, struct ldb_message *msg, @@ -357,7 +357,7 @@ static NTSTATUS authsam_want_check(struct auth_method_context *ctx, /* Wrapper for the auth subsystem pointer */ static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx, - struct auth_context *auth_context, + struct auth4_context *auth_context, const char *principal, struct ldb_dn *user_dn, struct auth_user_info_dc **user_info_dc) @@ -381,7 +381,7 @@ static const struct auth_operations sam_ops = { .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper }; -_PUBLIC_ NTSTATUS auth_sam_init(void) +_PUBLIC_ NTSTATUS auth4_sam_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/auth_server.c b/source4/auth/ntlm/auth_server.c index 7efeb9242a..9e1ceae0ca 100644 --- a/source4/auth/ntlm/auth_server.c +++ b/source4/auth/ntlm/auth_server.c @@ -27,7 +27,7 @@ #include "param/param.h" #include "libcli/resolve/resolve.h" -_PUBLIC_ NTSTATUS auth_server_init(void); +_PUBLIC_ NTSTATUS auth4_server_init(void); /* This version of 'security=server' rewirtten from scratch for Samba4 * libraries in 2008 */ @@ -223,7 +223,7 @@ static const struct auth_operations server_auth_ops = { .check_password = server_check_password }; -_PUBLIC_ NTSTATUS auth_server_init(void) +_PUBLIC_ NTSTATUS auth4_server_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c index 75eabe855b..241906e281 100644 --- a/source4/auth/ntlm/auth_simple.c +++ b/source4/auth/ntlm/auth_simple.c @@ -30,7 +30,7 @@ */ _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, const char *nt4_domain, const char *nt4_username, @@ -38,7 +38,7 @@ _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, const uint32_t logon_parameters, struct auth_session_info **session_info) { - struct auth_context *auth_context; + struct auth4_context *auth_context; struct auth_usersupplied_info *user_info; struct auth_user_info_dc *user_info_dc; NTSTATUS nt_status; diff --git a/source4/auth/ntlm/auth_unix.c b/source4/auth/ntlm/auth_unix.c index 743cb8103d..d79ebc1772 100644 --- a/source4/auth/ntlm/auth_unix.c +++ b/source4/auth/ntlm/auth_unix.c @@ -28,7 +28,7 @@ #include "../libcli/auth/pam_errors.h" #include "param/param.h" -_PUBLIC_ NTSTATUS auth_unix_init(void); +_PUBLIC_ NTSTATUS auth4_unix_init(void); /* TODO: look at how to best fill in parms retrieveing a struct passwd info * except in case USER_INFO_DONT_CHECK_UNIX_ACCOUNT is set @@ -607,12 +607,10 @@ static NTSTATUS check_unix_password(TALLOC_CTX *ctx, struct loadparm_context *lp { char *username; char *password; - char *pwcopy; char *salt; char *crypted; struct passwd *pws; NTSTATUS nt_status; - int level = lpcfg_passwordlevel(lp_ctx); *ret_passwd = NULL; @@ -737,46 +735,11 @@ static NTSTATUS check_unix_password(TALLOC_CTX *ctx, struct loadparm_context *lp return nt_status; } - if ( user_info->flags | USER_INFO_CASE_INSENSITIVE_PASSWORD) { - return nt_status; - } - - /* if the password was given to us with mixed case then we don't - * need to proceed as we know it hasn't been case modified by the - * client */ - if (strhasupper(password) && strhaslower(password)) { - return nt_status; - } - - /* make a copy of it */ - pwcopy = talloc_strdup(ctx, password); - if (!pwcopy) - return NT_STATUS_NO_MEMORY; - - /* try all lowercase if it's currently all uppercase */ - if (strhasupper(pwcopy)) { - strlower(pwcopy); - nt_status = password_check(username, pwcopy, crypted, salt); - if NT_STATUS_IS_OK(nt_status) { - *ret_passwd = pws; - return nt_status; - } - } - - /* give up? */ - if (level < 1) { - return NT_STATUS_WRONG_PASSWORD; - } - - /* last chance - all combinations of up to level chars upper! */ - strlower(pwcopy); + /* we no longer try different case combinations here. The use + * of this code is now web auth, where trying different case + * combinations makes no sense + */ -#if 0 - if (NT_STATUS_IS_OK(nt_status = string_combinations(pwcopy, password_check, level))) { - *ret_passwd = pws; - return nt_status; - } -#endif return NT_STATUS_WRONG_PASSWORD; } @@ -839,7 +802,7 @@ static const struct auth_operations unix_ops = { .check_password = authunix_check_password }; -_PUBLIC_ NTSTATUS auth_unix_init(void) +_PUBLIC_ NTSTATUS auth4_unix_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/auth_util.c b/source4/auth/ntlm/auth_util.c index 17bfa32167..c19b5cfd42 100644 --- a/source4/auth/ntlm/auth_util.c +++ b/source4/auth/ntlm/auth_util.c @@ -99,7 +99,7 @@ NTSTATUS map_user_info(TALLOC_CTX *mem_ctx, Create an auth_usersupplied_data structure after appropriate mapping. ****************************************************************************/ -NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, +NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context, enum auth_password_state to_state, const struct auth_usersupplied_info *user_info_in, const struct auth_usersupplied_info **user_info_encrypted) diff --git a/source4/auth/ntlm/auth_winbind.c b/source4/auth/ntlm/auth_winbind.c index dfb8fce2a6..da152e718a 100644 --- a/source4/auth/ntlm/auth_winbind.c +++ b/source4/auth/ntlm/auth_winbind.c @@ -31,7 +31,7 @@ #include "nsswitch/libwbclient/wbclient.h" #include "libcli/security/security.h" -_PUBLIC_ NTSTATUS auth_winbind_init(void); +_PUBLIC_ NTSTATUS auth4_winbind_init(void); static NTSTATUS get_info3_from_wbcAuthUserInfo(TALLOC_CTX *mem_ctx, struct wbcAuthUserInfo *info, @@ -324,7 +324,7 @@ static const struct auth_operations winbind_wbclient_ops = { .check_password = winbind_check_password_wbclient }; -_PUBLIC_ NTSTATUS auth_winbind_init(void) +_PUBLIC_ NTSTATUS auth4_winbind_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/wscript_build b/source4/auth/ntlm/wscript_build index 2ac2773c85..d954ec0086 100644 --- a/source4/auth/ntlm/wscript_build +++ b/source4/auth/ntlm/wscript_build @@ -3,7 +3,7 @@ bld.SAMBA_MODULE('auth4_sam_module', source='auth_sam.c', subsystem='auth4', - init_function='auth_sam_init', + init_function='auth4_sam_init', deps='samdb auth4_sam NTLMSSP_COMMON samba-hostconfig' ) @@ -11,7 +11,7 @@ bld.SAMBA_MODULE('auth4_sam_module', bld.SAMBA_MODULE('auth4_anonymous', source='auth_anonymous.c', subsystem='auth4', - init_function='auth_anonymous_init', + init_function='auth4_anonymous_init', deps='talloc' ) @@ -19,7 +19,7 @@ bld.SAMBA_MODULE('auth4_anonymous', bld.SAMBA_MODULE('auth4_server', source='auth_server.c', subsystem='auth4', - init_function='auth_server_init', + init_function='auth4_server_init', deps='samba-util LIBCLI_SMB CREDENTIALS_NTLM' ) @@ -27,7 +27,7 @@ bld.SAMBA_MODULE('auth4_server', bld.SAMBA_MODULE('auth4_winbind', source='auth_winbind.c', subsystem='auth4', - init_function='auth_winbind_init', + init_function='auth4_winbind_init', deps='RPC_NDR_WINBIND MESSAGING wbclient' ) @@ -35,7 +35,7 @@ bld.SAMBA_MODULE('auth4_winbind', bld.SAMBA_MODULE('auth4_developer', source='auth_developer.c', subsystem='auth4', - init_function='auth_developer_init', + init_function='auth4_developer_init', deps='talloc' ) @@ -43,7 +43,7 @@ bld.SAMBA_MODULE('auth4_developer', bld.SAMBA_MODULE('auth4_unix', source='auth_unix.c', subsystem='auth4', - init_function='auth_unix_init', + init_function='auth4_unix_init', deps='pam PAM_ERRORS LIBTSOCKET' ) diff --git a/source4/auth/ntlmssp/ntlmssp.h b/source4/auth/ntlmssp/ntlmssp.h index ff30317f55..00439e68dd 100644 --- a/source4/auth/ntlmssp/ntlmssp.h +++ b/source4/auth/ntlmssp/ntlmssp.h @@ -26,7 +26,7 @@ struct gensec_ntlmssp_context { struct gensec_security *gensec_security; struct ntlmssp_state *ntlmssp_state; - struct auth_context *auth_context; + struct auth4_context *auth_context; struct auth_user_info_dc *user_info_dc; }; diff --git a/source4/auth/ntlmssp/ntlmssp_server.c b/source4/auth/ntlmssp/ntlmssp_server.c index 9db3b560c1..240edbeaad 100644 --- a/source4/auth/ntlmssp/ntlmssp_server.c +++ b/source4/auth/ntlmssp/ntlmssp_server.c @@ -88,7 +88,7 @@ static NTSTATUS auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_s struct gensec_ntlmssp_context *gensec_ntlmssp = talloc_get_type_abort(ntlmssp_state->callback_private, struct gensec_ntlmssp_context); - struct auth_context *auth_context = gensec_ntlmssp->auth_context; + struct auth4_context *auth_context = gensec_ntlmssp->auth_context; NTSTATUS status; status = auth_context->get_challenge(auth_context, chal); @@ -111,7 +111,7 @@ static bool auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_s struct gensec_ntlmssp_context *gensec_ntlmssp = talloc_get_type_abort(ntlmssp_state->callback_private, struct gensec_ntlmssp_context); - struct auth_context *auth_context = gensec_ntlmssp->auth_context; + struct auth4_context *auth_context = gensec_ntlmssp->auth_context; return auth_context->challenge_may_be_modified(auth_context); } @@ -125,7 +125,7 @@ static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, struct gensec_ntlmssp_context *gensec_ntlmssp = talloc_get_type_abort(ntlmssp_state->callback_private, struct gensec_ntlmssp_context); - struct auth_context *auth_context = gensec_ntlmssp->auth_context; + struct auth4_context *auth_context = gensec_ntlmssp->auth_context; NTSTATUS nt_status; const uint8_t *chal; @@ -155,7 +155,7 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, struct gensec_ntlmssp_context *gensec_ntlmssp = talloc_get_type_abort(ntlmssp_state->callback_private, struct gensec_ntlmssp_context); - struct auth_context *auth_context = gensec_ntlmssp->auth_context; + struct auth4_context *auth_context = gensec_ntlmssp->auth_context; NTSTATUS nt_status; struct auth_usersupplied_info *user_info; @@ -308,26 +308,26 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) ntlmssp_state->server.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx); { - char dnsdomname[MAXHOSTNAMELEN], dnsname[MAXHOSTNAMELEN]; - - /* Find out the DNS domain name */ - dnsdomname[0] = '\0'; - safe_strcpy(dnsdomname, lpcfg_dnsdomain(gensec_security->settings->lp_ctx), sizeof(dnsdomname) - 1); + const char *dnsdomain = lpcfg_dnsdomain(gensec_security->settings->lp_ctx); + char *dnsname, *lower_netbiosname; + lower_netbiosname = strlower_talloc(ntlmssp_state, ntlmssp_state->server.netbios_name); /* Find out the DNS host name */ - safe_strcpy(dnsname, ntlmssp_state->server.netbios_name, sizeof(dnsname) - 1); - if (dnsdomname[0] != '\0') { - safe_strcat(dnsname, ".", sizeof(dnsname) - 1); - safe_strcat(dnsname, dnsdomname, sizeof(dnsname) - 1); + if (dnsdomain && dnsdomain[0] != '\0') { + dnsname = talloc_asprintf(ntlmssp_state, "%s.%s", + lower_netbiosname, + dnsdomain); + talloc_free(lower_netbiosname); + ntlmssp_state->server.dns_name = dnsname; + } else { + ntlmssp_state->server.dns_name = lower_netbiosname; } - strlower_m(dnsname); - ntlmssp_state->server.dns_name = talloc_strdup(ntlmssp_state, - dnsname); NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_name); - ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state, - dnsdomname); + ntlmssp_state->server.dns_domain + = talloc_strdup(ntlmssp_state, + lpcfg_dnsdomain(gensec_security->settings->lp_ctx)); NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_domain); } diff --git a/source4/auth/pyauth.c b/source4/auth/pyauth.c index a4ba88c581..6b3948970f 100644 --- a/source4/auth/pyauth.c +++ b/source4/auth/pyauth.c @@ -205,7 +205,7 @@ static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list, return ret; } -static PyObject *PyAuthContext_FromContext(struct auth_context *auth_context) +static PyObject *PyAuthContext_FromContext(struct auth4_context *auth_context) { return py_talloc_reference(&PyAuthContext, auth_context); } @@ -214,12 +214,12 @@ static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObjec { PyObject *py_lp_ctx = Py_None; PyObject *py_ldb = Py_None; - PyObject *py_messaging_ctx = Py_None; + PyObject *py_imessaging_ctx = Py_None; PyObject *py_auth_context = Py_None; PyObject *py_methods = Py_None; TALLOC_CTX *mem_ctx; - struct auth_context *auth_context; - struct messaging_context *messaging_context = NULL; + struct auth4_context *auth_context; + struct imessaging_context *imessaging_context = NULL; struct loadparm_context *lp_ctx; struct tevent_context *ev; struct ldb_context *ldb; @@ -230,7 +230,7 @@ static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObjec if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOO", discard_const_p(char *, kwnames), - &py_lp_ctx, &py_messaging_ctx, &py_ldb, &py_methods)) + &py_lp_ctx, &py_imessaging_ctx, &py_ldb, &py_methods)) return NULL; mem_ctx = talloc_new(NULL); @@ -251,12 +251,12 @@ static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObjec return NULL; } - if (py_messaging_ctx != Py_None) { - messaging_context = py_talloc_get_type(py_messaging_ctx, struct messaging_context); + if (py_imessaging_ctx != Py_None) { + imessaging_context = py_talloc_get_type(py_imessaging_ctx, struct imessaging_context); } if (py_methods == Py_None && py_ldb == Py_None) { - nt_status = auth_context_create(mem_ctx, ev, messaging_context, lp_ctx, &auth_context); + nt_status = auth_context_create(mem_ctx, ev, imessaging_context, lp_ctx, &auth_context); } else { if (py_methods != Py_None) { methods = PyList_AsStringList(mem_ctx, py_methods, "methods"); @@ -268,7 +268,7 @@ static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObjec methods = auth_methods_from_lp(mem_ctx, lp_ctx); } nt_status = auth_context_create_methods(mem_ctx, methods, ev, - messaging_context, lp_ctx, + imessaging_context, lp_ctx, ldb, &auth_context); } diff --git a/source4/auth/samba_server_gensec.c b/source4/auth/samba_server_gensec.c index 07b9b15e17..24b658ad32 100644 --- a/source4/auth/samba_server_gensec.c +++ b/source4/auth/samba_server_gensec.c @@ -29,7 +29,7 @@ NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx, struct tevent_context *event_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, struct loadparm_context *lp_ctx, struct cli_credentials *server_credentials, const char *target_service, @@ -37,7 +37,7 @@ NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx, { NTSTATUS nt_status; struct gensec_security *gensec_ctx; - struct auth_context *auth_context; + struct auth4_context *auth_context; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { diff --git a/source4/auth/system_session.c b/source4/auth/system_session.c index 54b8f514cf..3b9edd779d 100644 --- a/source4/auth/system_session.c +++ b/source4/auth/system_session.c @@ -190,7 +190,7 @@ static NTSTATUS auth_domain_admin_user_info_dc(TALLOC_CTX *mem_ctx, sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX], DOMAIN_RID_ADMINISTRATOR); user_info_dc->sids[PRIMARY_GROUP_SID_INDEX] = *domain_sid; - sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX], DOMAIN_RID_USERS); + sid_append_rid(&user_info_dc->sids[PRIMARY_GROUP_SID_INDEX], DOMAIN_RID_USERS); user_info_dc->sids[2] = global_sid_Builtin_Administrators; diff --git a/source4/cldap_server/cldap_server.c b/source4/cldap_server/cldap_server.c index 43eadf5aff..d3e8b7fffa 100644 --- a/source4/cldap_server/cldap_server.c +++ b/source4/cldap_server/cldap_server.c @@ -116,7 +116,7 @@ static NTSTATUS cldapd_add_socket(struct cldapd_server *cldapd, struct loadparm_ lpcfg_cldap_port(lp_ctx), &socket_address); if (ret != 0) { - status = map_nt_error_from_unix(errno); + status = map_nt_error_from_unix_common(errno); DEBUG(0,("invalid address %s:%d - %s:%s\n", address, lpcfg_cldap_port(lp_ctx), gai_strerror(ret), nt_errstr(status))); @@ -153,19 +153,24 @@ static NTSTATUS cldapd_startup_interfaces(struct cldapd_server *cldapd, struct l TALLOC_CTX *tmp_ctx = talloc_new(cldapd); NTSTATUS status; - num_interfaces = iface_count(ifaces); + num_interfaces = iface_list_count(ifaces); /* if we are allowing incoming packets from any address, then we need to bind to the wildcard address */ if (!lpcfg_bind_interfaces_only(lp_ctx)) { - status = cldapd_add_socket(cldapd, lp_ctx, "0.0.0.0"); - NT_STATUS_NOT_OK_RETURN(status); + const char **wcard = iface_list_wildcard(cldapd, lp_ctx); + NT_STATUS_HAVE_NO_MEMORY(wcard); + for (i=0; wcard[i]; i++) { + status = cldapd_add_socket(cldapd, lp_ctx, wcard[i]); + NT_STATUS_NOT_OK_RETURN(status); + } + talloc_free(wcard); } /* now we have to also listen on the specific interfaces, so that replies always come from the right IP */ for (i=0; i<num_interfaces; i++) { - const char *address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i)); + const char *address = talloc_strdup(tmp_ctx, iface_list_n_ip(ifaces, i)); status = cldapd_add_socket(cldapd, lp_ctx, address); NT_STATUS_NOT_OK_RETURN(status); } @@ -184,9 +189,9 @@ static void cldapd_task_init(struct task_server *task) NTSTATUS status; struct interface *ifaces; - load_interfaces(task, lpcfg_interfaces(task->lp_ctx), &ifaces); + load_interface_list(task, task->lp_ctx, &ifaces); - if (iface_count(ifaces) == 0) { + if (iface_list_count(ifaces) == 0) { task_server_terminate(task, "cldapd: no network interfaces configured", false); return; } diff --git a/source4/cldap_server/netlogon.c b/source4/cldap_server/netlogon.c index 6e455e46bd..77f50ff3e6 100644 --- a/source4/cldap_server/netlogon.c +++ b/source4/cldap_server/netlogon.c @@ -37,6 +37,7 @@ #include "param/param.h" #include "../lib/tsocket/tsocket.h" #include "libds/common/flag_mapping.h" +#include "lib/util/util_net.h" /* fill in the cldap netlogon union for a given version @@ -291,17 +292,18 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, client_site = samdb_client_site_name(sam_ctx, mem_ctx, src_address, NULL); NT_STATUS_HAVE_NO_MEMORY(client_site); - load_interfaces(mem_ctx, lpcfg_interfaces(lp_ctx), &ifaces); - /* - * TODO: the caller should pass the address which the client - * used to trigger this call, as the client is able to reach - * this ip. - */ + load_interface_list(mem_ctx, lp_ctx, &ifaces); + if (src_address) { - pdc_ip = iface_best_ip(ifaces, src_address); + pdc_ip = iface_list_best_ip(ifaces, src_address); } else { - pdc_ip = iface_n_ip(ifaces, 0); + pdc_ip = iface_list_first_v4(ifaces); + } + if (pdc_ip == NULL || !is_ipaddress_v4(pdc_ip)) { + /* this matches windows behaviour */ + pdc_ip = "127.0.0.1"; } + ZERO_STRUCTP(netlogon); /* check if either of these bits is present */ @@ -325,7 +327,7 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, netlogon->data.nt5_ex.server_site = server_site; netlogon->data.nt5_ex.client_site = client_site; if (version & NETLOGON_NT_VERSION_5EX_WITH_IP) { - /* Clearly this needs to be fixed up for IPv6 */ + /* note that this is always a IPV4 address */ extra_flags = NETLOGON_NT_VERSION_5EX_WITH_IP; netlogon->data.nt5_ex.sockaddr.sockaddr_family = 2; netlogon->data.nt5_ex.sockaddr.pdc_ip = pdc_ip; diff --git a/source4/client/cifsdd.c b/source4/client/cifsdd.c index adf2d72af2..dd6f1377e8 100644 --- a/source4/client/cifsdd.c +++ b/source4/client/cifsdd.c @@ -152,7 +152,7 @@ int set_arg_argv(const char * argv) } break; case ARG_SIZE: - if (!conv_str_size(val, &arg->arg_val.nval)) { + if (!conv_str_size_error(val, &arg->arg_val.nval)) { goto fail; } break; @@ -597,7 +597,7 @@ int main(int argc, const char ** argv) ev = s4_event_context_init(talloc_autofree_context()); - gensec_init(cmdline_lp_ctx); + gensec_init(); dump_args(); if (check_arg_numeric("ibs") == 0 || check_arg_numeric("ibs") == 0) { diff --git a/source4/client/client.c b/source4/client/client.c index c6c0088b3c..2f353aec4e 100644 --- a/source4/client/client.c +++ b/source4/client/client.c @@ -309,12 +309,12 @@ static bool mask_match(struct smbcli_state *c, const char *string, return false; if (is_case_sensitive) - return ms_fnmatch(pattern, string, + return ms_fnmatch_protocol(pattern, string, c->transport->negotiate.protocol) == 0; p2 = strlower_talloc(NULL, pattern); s2 = strlower_talloc(NULL, string); - ret = ms_fnmatch(p2, s2, c->transport->negotiate.protocol) == 0; + ret = ms_fnmatch_protocol(p2, s2, c->transport->negotiate.protocol) == 0; talloc_free(p2); talloc_free(s2); @@ -473,8 +473,8 @@ static void add_to_do_list_queue(const char* entry) } if (do_list_queue) { - safe_strcpy(do_list_queue + do_list_queue_end, entry, - do_list_queue_size - do_list_queue_end - 1); + strlcpy(do_list_queue + do_list_queue_end, entry ? entry : "", + do_list_queue_size - do_list_queue_end); do_list_queue_end = new_end; DEBUG(4,("added %s to do_list_queue (start=%d, end=%d)\n", entry, (int)do_list_queue_start, (int)do_list_queue_end)); @@ -696,11 +696,12 @@ static int do_get(struct smbclient_context *ctx, char *rname, const char *p_lnam char *lname; - lname = talloc_strdup(ctx, p_lname); GetTimeOfDay(&tp_start); if (ctx->lowercase) { - strlower(lname); + lname = strlower_talloc(ctx, p_lname); + } else { + lname = talloc_strdup(ctx, p_lname); } fnum = smbcli_open(ctx->cli->tree, rname, O_RDONLY, DENY_NONE); @@ -884,13 +885,14 @@ static void do_mget(struct smbclient_context *ctx, struct clilist_file_info *fin ctx->remote_cur_dir = talloc_asprintf_append_buffer(NULL, "%s\\", finfo->name); - l_fname = talloc_strdup(ctx, finfo->name); - - string_replace(l_fname, '\\', '/'); if (ctx->lowercase) { - strlower(l_fname); + l_fname = strlower_talloc(ctx, finfo->name); + } else { + l_fname = talloc_strdup(ctx, finfo->name); } + string_replace(l_fname, '\\', '/'); + if (!directory_exist(l_fname) && mkdir(l_fname, 0777) != 0) { d_printf("failed to create directory %s\n", l_fname); @@ -3231,7 +3233,7 @@ static int do_message_op(const char *netbios_name, const char *desthost, } } - gensec_init(cmdline_lp_ctx); + gensec_init(); if(poptPeekArg(pc)) { char *s = strdup(poptGetArg(pc)); diff --git a/source4/cluster/cluster.c b/source4/cluster/cluster.c index 746c004820..757489ebce 100644 --- a/source4/cluster/cluster.c +++ b/source4/cluster/cluster.c @@ -23,7 +23,7 @@ #include "cluster/cluster.h" #include "cluster/cluster_private.h" #include "librpc/gen_ndr/misc.h" -#include "librpc/gen_ndr/server_id4.h" +#include "librpc/gen_ndr/server_id.h" static struct cluster_ops *ops; @@ -50,23 +50,12 @@ static void cluster_init(void) /* create a server_id for the local node */ -struct server_id cluster_id(uint64_t id, uint32_t id2) +struct server_id cluster_id(uint64_t pid, uint32_t task_id) { cluster_init(); - return ops->cluster_id(ops, id, id2); + return ops->cluster_id(ops, pid, task_id); } - -/* - return a server_id as a string -*/ -const char *cluster_id_string(TALLOC_CTX *mem_ctx, struct server_id id) -{ - cluster_init(); - return ops->cluster_id_string(ops, mem_ctx, id); -} - - /* open a temporary tdb in a cluster friendly manner */ @@ -80,7 +69,7 @@ struct tdb_wrap *cluster_tdb_tmp_open(TALLOC_CTX *mem_ctx, struct loadparm_conte /* register a callback function for a messaging endpoint */ -NTSTATUS cluster_message_init(struct messaging_context *msg, struct server_id server, +NTSTATUS cluster_message_init(struct imessaging_context *msg, struct server_id server, cluster_message_fn_t handler) { cluster_init(); diff --git a/source4/cluster/cluster.h b/source4/cluster/cluster.h index 6cfcb9b21b..3dd9f4ce7c 100644 --- a/source4/cluster/cluster.h +++ b/source4/cluster/cluster.h @@ -22,30 +22,29 @@ #ifndef __CLUSTER_H__ #define __CLUSTER_H__ -#include "librpc/gen_ndr/server_id4.h" +#include "librpc/gen_ndr/server_id.h" /* test for same cluster id */ -#define cluster_id_equal(id_1, id_2) ((id_1)->id == (id_2)->id \ - && (id_1)->id2 == (id_2)->id2 \ - && (id_1)->node == (id_2)->node) +#define cluster_id_equal(id_1, id_2) ((id_1)->pid == (id_2)->pid \ + && (id_1)->task_id == (id_2)->task_id \ + && (id_1)->vnn == (id_2)->vnn) /* test for same cluster node */ -#define cluster_node_equal(id1, id2) ((id1)->node == (id2)->node) +#define cluster_node_equal(id1, id2) ((id1)->vnn == (id2)->vnn) -struct messaging_context; -typedef void (*cluster_message_fn_t)(struct messaging_context *, DATA_BLOB); +struct imessaging_context; +typedef void (*cluster_message_fn_t)(struct imessaging_context *, DATA_BLOB); /* prototypes */ -struct server_id cluster_id(uint64_t id, uint32_t id2); -const char *cluster_id_string(TALLOC_CTX *mem_ctx, struct server_id id); +struct server_id cluster_id(uint64_t id, uint32_t task_id); struct tdb_wrap *cluster_tdb_tmp_open(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, const char *dbname, int flags); void *cluster_backend_handle(void); -NTSTATUS cluster_message_init(struct messaging_context *msg, struct server_id server, +NTSTATUS cluster_message_init(struct imessaging_context *msg, struct server_id server, cluster_message_fn_t handler); NTSTATUS cluster_message_send(struct server_id server, DATA_BLOB *data); diff --git a/source4/cluster/cluster_private.h b/source4/cluster/cluster_private.h index e57c983ed0..6f68ad62bd 100644 --- a/source4/cluster/cluster_private.h +++ b/source4/cluster/cluster_private.h @@ -24,15 +24,13 @@ struct cluster_ops { struct server_id (*cluster_id)(struct cluster_ops *ops, uint64_t id, uint32_t id2); - const char *(*cluster_id_string)(struct cluster_ops *ops, - TALLOC_CTX *, struct server_id ); struct tdb_wrap *(*cluster_tdb_tmp_open)(struct cluster_ops *, TALLOC_CTX *, struct loadparm_context *, const char *, int); void *(*backend_handle)(struct cluster_ops *); NTSTATUS (*message_init)(struct cluster_ops *ops, - struct messaging_context *msg, struct server_id server, + struct imessaging_context *msg, struct server_id server, cluster_message_fn_t handler); NTSTATUS (*message_send)(struct cluster_ops *ops, struct server_id server, DATA_BLOB *data); diff --git a/source4/cluster/local.c b/source4/cluster/local.c index a93b0a65ed..0a294b4d1d 100644 --- a/source4/cluster/local.c +++ b/source4/cluster/local.c @@ -22,36 +22,26 @@ #include "includes.h" #include "cluster/cluster.h" #include "cluster/cluster_private.h" -#include <tdb.h> -#include "tdb_wrap.h" +#include "tdb_compat.h" +#include "lib/util/tdb_wrap.h" #include "system/filesys.h" #include "param/param.h" -#include "librpc/gen_ndr/server_id4.h" +#include "librpc/gen_ndr/server_id.h" /* server a server_id for the local node */ -static struct server_id local_id(struct cluster_ops *ops, uint64_t id, uint32_t id2) +static struct server_id local_id(struct cluster_ops *ops, uint64_t pid, uint32_t task_id) { struct server_id server_id; ZERO_STRUCT(server_id); - server_id.id = id; - server_id.id2 = id2; + server_id.pid = pid; + server_id.task_id = task_id; return server_id; } /* - return a server_id as a string -*/ -static const char *local_id_string(struct cluster_ops *ops, - TALLOC_CTX *mem_ctx, struct server_id id) -{ - return talloc_asprintf(mem_ctx, "%u.%llu.%u", id.node, (unsigned long long)id.id, id.id2); -} - - -/* open a tmp tdb for the local node. By using smbd_tmp_path() we don't need TDB_CLEAR_IF_FIRST as the tmp path is wiped at startup */ @@ -80,7 +70,7 @@ static void *local_backend_handle(struct cluster_ops *ops) dummy message init function - not needed as all messages are local */ static NTSTATUS local_message_init(struct cluster_ops *ops, - struct messaging_context *msg, + struct imessaging_context *msg, struct server_id server, cluster_message_fn_t handler) { @@ -98,7 +88,6 @@ static NTSTATUS local_message_send(struct cluster_ops *ops, static struct cluster_ops cluster_local_ops = { .cluster_id = local_id, - .cluster_id_string = local_id_string, .cluster_tdb_tmp_open = local_tdb_tmp_open, .backend_handle = local_backend_handle, .message_init = local_message_init, diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c index 7dd06c1b2c..4873112a11 100644 --- a/source4/dns_server/dlz_bind9.c +++ b/source4/dns_server/dlz_bind9.c @@ -525,7 +525,7 @@ _PUBLIC_ isc_result_t dlz_create(const char *dlzname, if (options.url == NULL) { options.url = talloc_asprintf(tmp_ctx, "ldapi://%s", - private_path(tmp_ctx, state->lp, "ldap_priv/ldapi")); + lpcfg_private_path(tmp_ctx, state->lp, "ldap_priv/ldapi")); if (options.url == NULL) { result = ISC_R_NOMEMORY; goto failed; @@ -533,7 +533,7 @@ _PUBLIC_ isc_result_t dlz_create(const char *dlzname, } ret = ldb_connect(state->samdb, options.url, 0, NULL); - if (ret == -1) { + if (ret != LDB_SUCCESS) { state->log(ISC_LOG_ERROR, "samba_dlz: Failed to connect to %s - %s", options.url, ldb_errstring(state->samdb)); result = ISC_R_FAILURE; diff --git a/source4/dns_server/dns_server.c b/source4/dns_server/dns_server.c index 0e5def15c0..0c36c20773 100644 --- a/source4/dns_server/dns_server.c +++ b/source4/dns_server/dns_server.c @@ -490,7 +490,7 @@ static NTSTATUS dns_add_socket(struct dns_server *dns, address, port, &dns_socket->local_address); if (ret != 0) { - status = map_nt_error_from_unix(errno); + status = map_nt_error_from_unix_common(errno); return status; } @@ -519,7 +519,7 @@ static NTSTATUS dns_add_socket(struct dns_server *dns, dns_udp_socket, &dns_udp_socket->dgram); if (ret != 0) { - status = map_nt_error_from_unix(errno); + status = map_nt_error_from_unix_common(errno); DEBUG(0,("Failed to bind to %s:%u UDP - %s\n", address, port, nt_errstr(status))); return status; @@ -559,10 +559,10 @@ static NTSTATUS dns_startup_interfaces(struct dns_server *dns, struct loadparm_c return NT_STATUS_INTERNAL_ERROR; } - num_interfaces = iface_count(ifaces); + num_interfaces = iface_list_count(ifaces); for (i=0; i<num_interfaces; i++) { - const char *address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i)); + const char *address = talloc_strdup(tmp_ctx, iface_list_n_ip(ifaces, i)); status = dns_add_socket(dns, model_ops, "dns", address, DNS_SERVICE_PORT); NT_STATUS_NOT_OK_RETURN(status); @@ -617,9 +617,9 @@ static void dns_task_init(struct task_server *task) break; } - load_interfaces(task, lpcfg_interfaces(task->lp_ctx), &ifaces); + load_interface_list(task, task->lp_ctx, &ifaces); - if (iface_count(ifaces) == 0) { + if (iface_list_count(ifaces) == 0) { task_server_terminate(task, "dns: no network interfaces configured", false); return; } diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 0c920d7d85..3fa8f67447 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -1762,7 +1762,7 @@ const char *samdb_client_site_name(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, allow_list[0] = l_subnet_name; - if (allow_access(mem_ctx, NULL, allow_list, "", ip_address)) { + if (socket_allow_access(mem_ctx, NULL, allow_list, "", ip_address)) { sites_dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, res->msgs[i], "siteObject"); @@ -3192,7 +3192,7 @@ bool dsdb_dn_is_deleted_val(const struct ldb_val *val) */ bool dsdb_dn_is_upgraded_link_val(struct ldb_val *val) { - return memmem(val->data, val->length, "<RMD_ADDTIME=", 13) != NULL; + return memmem(val->data, val->length, "<RMD_VERSION=", 13) != NULL; } /* diff --git a/source4/dsdb/common/util_samr.c b/source4/dsdb/common/util_samr.c index 7a4f644123..83a8c385af 100644 --- a/source4/dsdb/common/util_samr.c +++ b/source4/dsdb/common/util_samr.c @@ -342,6 +342,11 @@ NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb, TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); + if (ldb_transaction_start(ldb) != LDB_SUCCESS) { + DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(ldb))); + return NT_STATUS_INTERNAL_ERROR; + } + /* Check if alias already exists */ name = samdb_search_string(ldb, tmp_ctx, NULL, "sAMAccountName", @@ -350,12 +355,14 @@ NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb, if (name != NULL) { talloc_free(tmp_ctx); + ldb_transaction_cancel(ldb); return NT_STATUS_ALIAS_EXISTS; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { talloc_free(tmp_ctx); + ldb_transaction_cancel(ldb); return NT_STATUS_NO_MEMORY; } @@ -364,6 +371,7 @@ NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb, ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", alias_name); if (!msg->dn) { talloc_free(tmp_ctx); + ldb_transaction_cancel(ldb); return NT_STATUS_NO_MEMORY; } @@ -378,15 +386,18 @@ NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb, break; case LDB_ERR_ENTRY_ALREADY_EXISTS: talloc_free(tmp_ctx); + ldb_transaction_cancel(ldb); return NT_STATUS_ALIAS_EXISTS; case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: talloc_free(tmp_ctx); + ldb_transaction_cancel(ldb); return NT_STATUS_ACCESS_DENIED; default: DEBUG(0,("Failed to create alias record %s: %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb))); talloc_free(tmp_ctx); + ldb_transaction_cancel(ldb); return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -394,10 +405,17 @@ NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb, alias_sid = samdb_search_dom_sid(ldb, tmp_ctx, msg->dn, "objectSid", NULL); + if (ldb_transaction_commit(ldb) != LDB_SUCCESS) { + DEBUG(0, ("Failed to commit transaction in dsdb_add_domain_alias(): %s\n", + ldb_errstring(ldb))); + return NT_STATUS_INTERNAL_ERROR; + } + *dn = talloc_steal(mem_ctx, msg->dn); *sid = talloc_steal(mem_ctx, alias_sid); talloc_free(tmp_ctx); + return NT_STATUS_OK; } diff --git a/source4/dsdb/dns/dns_update.c b/source4/dsdb/dns/dns_update.c index ede730a8a9..6650534d13 100644 --- a/source4/dsdb/dns/dns_update.c +++ b/source4/dsdb/dns/dns_update.c @@ -79,7 +79,7 @@ static void dnsupdate_rndc_done(struct tevent_req *subreq) ret = samba_runcmd_recv(subreq, &sys_errno); TALLOC_FREE(subreq); if (ret != 0) { - service->confupdate.status = map_nt_error_from_unix(sys_errno); + service->confupdate.status = map_nt_error_from_unix_common(sys_errno); } else { service->confupdate.status = NT_STATUS_OK; } @@ -123,12 +123,12 @@ static void dnsupdate_rebuild(struct dnsupdate_service *service) path = lpcfg_parm_string(service->task->lp_ctx, NULL, "dnsupdate", "path"); if (path == NULL) { - path = private_path(tmp_ctx, service->task->lp_ctx, "named.conf.update"); + path = lpcfg_private_path(tmp_ctx, service->task->lp_ctx, "named.conf.update"); } path_static = lpcfg_parm_string(service->task->lp_ctx, NULL, "dnsupdate", "extra_static_grant_rules"); if (path_static == NULL) { - path_static = private_path(tmp_ctx, service->task->lp_ctx, "named.conf.update.static"); + path_static = lpcfg_private_path(tmp_ctx, service->task->lp_ctx, "named.conf.update.static"); } tmp_path = talloc_asprintf(tmp_ctx, "%s.tmp", path); @@ -242,7 +242,7 @@ static void dnsupdate_nameupdate_done(struct tevent_req *subreq) ret = samba_runcmd_recv(subreq, &sys_errno); TALLOC_FREE(subreq); if (ret != 0) { - service->nameupdate.status = map_nt_error_from_unix(sys_errno); + service->nameupdate.status = map_nt_error_from_unix_common(sys_errno); } else { service->nameupdate.status = NT_STATUS_OK; } @@ -271,7 +271,7 @@ static void dnsupdate_spnupdate_done(struct tevent_req *subreq) ret = samba_runcmd_recv(subreq, &sys_errno); TALLOC_FREE(subreq); if (ret != 0) { - service->nameupdate.status = map_nt_error_from_unix(sys_errno); + service->nameupdate.status = map_nt_error_from_unix_common(sys_errno); } else { service->nameupdate.status = NT_STATUS_OK; } @@ -381,7 +381,7 @@ static void dnsupdate_RODC_callback(struct tevent_req *req) ret = samba_runcmd_recv(req, &sys_errno); talloc_free(req); if (ret != 0) { - st->r->out.result = map_nt_error_from_unix(sys_errno); + st->r->out.result = map_nt_error_from_unix_common(sys_errno); DEBUG(2,(__location__ ": RODC DNS Update failed: %s\n", nt_errstr(st->r->out.result))); } else { st->r->out.result = NT_STATUS_OK; diff --git a/source4/dsdb/pydsdb.c b/source4/dsdb/pydsdb.c index 895bd9a560..5ca6b02608 100644 --- a/source4/dsdb/pydsdb.c +++ b/source4/dsdb/pydsdb.c @@ -331,6 +331,38 @@ static PyObject *py_dsdb_get_attid_from_lDAPDisplayName(PyObject *self, PyObject } /* + return the attribute syntax oid as a string from the attribute name + */ +static PyObject *py_dsdb_get_syntax_oid_from_lDAPDisplayName(PyObject *self, PyObject *args) +{ + PyObject *py_ldb; + struct ldb_context *ldb; + struct dsdb_schema *schema; + const char *ldap_display_name; + const struct dsdb_attribute *attribute; + + if (!PyArg_ParseTuple(args, "Os", &py_ldb, &ldap_display_name)) + return NULL; + + PyErr_LDB_OR_RAISE(py_ldb, ldb); + + schema = dsdb_get_schema(ldb, NULL); + + if (!schema) { + PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb"); + return NULL; + } + + attribute = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name); + if (attribute == NULL) { + PyErr_Format(PyExc_RuntimeError, "Failed to find attribute '%s'", ldap_display_name); + return NULL; + } + + return PyString_FromString(attribute->syntax->ldap_oid); +} + +/* convert a python string to a DRSUAPI drsuapi_DsReplicaAttribute attribute */ static PyObject *py_dsdb_DsReplicaAttribute(PyObject *self, PyObject *args) @@ -423,6 +455,109 @@ static PyObject *py_dsdb_DsReplicaAttribute(PyObject *self, PyObject *args) return ret; } + +/* + normalise a ldb attribute list + */ +static PyObject *py_dsdb_normalise_attributes(PyObject *self, PyObject *args) +{ + PyObject *py_ldb, *el_list, *ret; + struct ldb_context *ldb; + char *ldap_display_name; + const struct dsdb_attribute *a; + struct dsdb_schema *schema; + struct dsdb_syntax_ctx syntax_ctx; + struct ldb_message_element *el; + struct drsuapi_DsReplicaAttribute *attr; + TALLOC_CTX *tmp_ctx; + WERROR werr; + Py_ssize_t i; + + if (!PyArg_ParseTuple(args, "OsO", &py_ldb, &ldap_display_name, &el_list)) { + return NULL; + } + + PyErr_LDB_OR_RAISE(py_ldb, ldb); + + if (!PyList_Check(el_list)) { + PyErr_Format(PyExc_TypeError, "ldif_elements must be a list"); + return NULL; + } + + schema = dsdb_get_schema(ldb, NULL); + if (!schema) { + PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb"); + return NULL; + } + + a = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name); + if (a == NULL) { + PyErr_Format(PyExc_RuntimeError, "Failed to find attribute '%s'", ldap_display_name); + return NULL; + } + + dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema); + syntax_ctx.is_schema_nc = false; + + tmp_ctx = talloc_new(ldb); + if (tmp_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + el = talloc_zero(tmp_ctx, struct ldb_message_element); + if (el == NULL) { + PyErr_NoMemory(); + talloc_free(tmp_ctx); + return NULL; + } + + el->name = ldap_display_name; + el->num_values = PyList_Size(el_list); + + el->values = talloc_array(el, struct ldb_val, el->num_values); + if (el->values == NULL) { + PyErr_NoMemory(); + talloc_free(tmp_ctx); + return NULL; + } + + for (i = 0; i < el->num_values; i++) { + PyObject *item = PyList_GetItem(el_list, i); + if (!PyString_Check(item)) { + PyErr_Format(PyExc_TypeError, "ldif_elements should be strings"); + return NULL; + } + el->values[i].data = (uint8_t *)PyString_AsString(item); + el->values[i].length = PyString_Size(item); + } + + /* first run ldb_to_drsuapi, then convert back again. This has + * the effect of normalising the attributes + */ + + attr = talloc_zero(tmp_ctx, struct drsuapi_DsReplicaAttribute); + if (attr == NULL) { + PyErr_NoMemory(); + talloc_free(tmp_ctx); + return NULL; + } + + werr = a->syntax->ldb_to_drsuapi(&syntax_ctx, a, el, attr, attr); + PyErr_WERROR_IS_ERR_RAISE(werr); + + /* now convert back again */ + werr = a->syntax->drsuapi_to_ldb(&syntax_ctx, a, attr, el, el); + PyErr_WERROR_IS_ERR_RAISE(werr); + + ret = py_return_ndr_struct("ldb", "MessageElement", el, el); + + talloc_free(tmp_ctx); + + return ret; +} + + static PyObject *py_dsdb_set_ntds_invocation_id(PyObject *self, PyObject *args) { PyObject *py_ldb, *py_guid; @@ -699,6 +834,8 @@ static PyMethodDef py_dsdb_methods[] = { METH_VARARGS, NULL }, { "_dsdb_get_attid_from_lDAPDisplayName", (PyCFunction)py_dsdb_get_attid_from_lDAPDisplayName, METH_VARARGS, NULL }, + { "_dsdb_get_syntax_oid_from_lDAPDisplayName", (PyCFunction)py_dsdb_get_syntax_oid_from_lDAPDisplayName, + METH_VARARGS, NULL }, { "_dsdb_set_ntds_invocation_id", (PyCFunction)py_dsdb_set_ntds_invocation_id, METH_VARARGS, NULL }, @@ -723,6 +860,7 @@ static PyMethodDef py_dsdb_methods[] = { NULL }, { "_dsdb_get_partitions_dn", (PyCFunction)py_dsdb_get_partitions_dn, METH_VARARGS, NULL }, { "_dsdb_DsReplicaAttribute", (PyCFunction)py_dsdb_DsReplicaAttribute, METH_VARARGS, NULL }, + { "_dsdb_normalise_attributes", (PyCFunction)py_dsdb_normalise_attributes, METH_VARARGS, NULL }, { NULL } }; @@ -862,4 +1000,10 @@ void initdsdb(void) ADD_DSDB_FLAG(GPO_FLAG_MACHINE_DISABLE); ADD_DSDB_FLAG(GPO_INHERIT); ADD_DSDB_FLAG(GPO_BLOCK_INHERITANCE); + +#define ADD_DSDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(val)) + + ADD_DSDB_STRING(DSDB_SYNTAX_BINARY_DN); + ADD_DSDB_STRING(DSDB_SYNTAX_STRING_DN); + ADD_DSDB_STRING(DSDB_SYNTAX_OR_NAME); } diff --git a/source4/dsdb/repl/drepl_fsmo.c b/source4/dsdb/repl/drepl_fsmo.c index f8f4769f1b..db6385315b 100644 --- a/source4/dsdb/repl/drepl_fsmo.c +++ b/source4/dsdb/repl/drepl_fsmo.c @@ -111,7 +111,7 @@ NTSTATUS drepl_take_FSMO_role(struct irpc_message *msg, if (fsmo_master_equal(ntds_dn, role_owner_dn) || (extended_op == DRSUAPI_EXOP_NONE)) { - DEBUG(0,("FSMO role check failed for DN %s and owner %s ", + DEBUG(0,("FSMO role check failed for DN %s and owner %s \n", ldb_dn_get_linearized(fsmo_role_dn), ldb_dn_get_linearized(role_owner_dn))); r->out.result = WERR_OK; diff --git a/source4/dsdb/repl/drepl_ridalloc.c b/source4/dsdb/repl/drepl_ridalloc.c index 48c208c3cf..53b56b63d2 100644 --- a/source4/dsdb/repl/drepl_ridalloc.c +++ b/source4/dsdb/repl/drepl_ridalloc.c @@ -236,7 +236,7 @@ WERROR dreplsrv_ridalloc_check_rid_pool(struct dreplsrv_service *service) /* called by the samldb ldb module to tell us to ask for a new RID pool */ -void dreplsrv_allocate_rid(struct messaging_context *msg, void *private_data, +void dreplsrv_allocate_rid(struct imessaging_context *msg, void *private_data, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data) { diff --git a/source4/dsdb/repl/drepl_service.c b/source4/dsdb/repl/drepl_service.c index 0931a340b1..ec803f6fdb 100644 --- a/source4/dsdb/repl/drepl_service.c +++ b/source4/dsdb/repl/drepl_service.c @@ -497,7 +497,7 @@ static void dreplsrv_task_init(struct task_server *task) IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSREPLICAMOD, dreplsrv_replica_mod, service); IRPC_REGISTER(task->msg_ctx, irpc, DREPL_TAKEFSMOROLE, drepl_take_FSMO_role, service); IRPC_REGISTER(task->msg_ctx, irpc, DREPL_TRIGGER_REPL_SECRET, drepl_trigger_repl_secret, service); - messaging_register(task->msg_ctx, service, MSG_DREPL_ALLOCATE_RID, dreplsrv_allocate_rid); + imessaging_register(task->msg_ctx, service, MSG_DREPL_ALLOCATE_RID, dreplsrv_allocate_rid); } /* diff --git a/source4/dsdb/samdb/ldb_modules/acl_read.c b/source4/dsdb/samdb/ldb_modules/acl_read.c index 181619ab28..35a840e1f4 100644 --- a/source4/dsdb/samdb/ldb_modules/acl_read.c +++ b/source4/dsdb/samdb/ldb_modules/acl_read.c @@ -47,6 +47,7 @@ struct aclread_context { bool sd; bool instance_type; bool object_sid; + bool indirsync; }; struct aclread_private { @@ -158,18 +159,41 @@ static int aclread_callback(struct ldb_request *req, struct ldb_reply *ares) access_mask, attr); - if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { - /* do not return this entry if attribute is - part of the search filter */ - if (dsdb_attr_in_parse_tree(ac->req->op.search.tree, - msg->elements[i].name)) { - talloc_free(tmp_ctx); - return LDB_SUCCESS; - } - aclread_mark_inaccesslible(&msg->elements[i]); - } else if (ret != LDB_SUCCESS) { - goto fail; - } + /* + * Dirsync control needs the replpropertymetadata attribute + * so return it as it will be removed by the control + * in anycase. + */ + if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { + if (!ac->indirsync) { + /* do not return this entry if attribute is + part of the search filter */ + if (dsdb_attr_in_parse_tree(ac->req->op.search.tree, + msg->elements[i].name)) { + talloc_free(tmp_ctx); + return LDB_SUCCESS; + } + aclread_mark_inaccesslible(&msg->elements[i]); + } else { + /* + * We are doing dirysnc answers + * and the object shouldn't be returned (normally) + * but we will return it without replPropertyMetaData + * so that the dirysync module will do what is needed + * (remove the object if it is not deleted, or return + * just the objectGUID if it's deleted). + */ + if (dsdb_attr_in_parse_tree(ac->req->op.search.tree, + msg->elements[i].name)) { + ldb_msg_remove_attr(msg, "replPropertyMetaData"); + break; + } else { + aclread_mark_inaccesslible(&msg->elements[i]); + } + } + } else if (ret != LDB_SUCCESS) { + goto fail; + } } for (i=0; i < msg->num_elements; i++) { if (!aclread_is_inaccessible(&msg->elements[i])) { @@ -224,6 +248,7 @@ static int aclread_search(struct ldb_module *module, struct ldb_request *req) struct aclread_context *ac; struct ldb_request *down_req; struct ldb_control *as_system = ldb_request_get_control(req, LDB_CONTROL_AS_SYSTEM_OID); + uint32_t flags = ldb_req_get_custom_flags(req); struct ldb_result *res; struct aclread_private *p; bool is_untrusted = ldb_req_is_untrusted(req); @@ -284,6 +309,11 @@ static int aclread_search(struct ldb_module *module, struct ldb_request *req) ac->module = module; ac->req = req; ac->schema = dsdb_get_schema(ldb, req); + if (flags & DSDB_ACL_CHECKS_DIRSYNC_FLAG) { + ac->indirsync = true; + } else { + ac->indirsync = false; + } if (!ac->schema) { return ldb_operr(ldb); } diff --git a/source4/dsdb/samdb/ldb_modules/dirsync.c b/source4/dsdb/samdb/ldb_modules/dirsync.c new file mode 100644 index 0000000000..64c5047798 --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/dirsync.c @@ -0,0 +1,1359 @@ +/* + SAMDB control module + + Copyright (C) Matthieu Patou <mat@matws.net> 2011 + + 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 <http://www.gnu.org/licenses/>. +*/ + + +#include "includes.h" +#include "ldb/include/ldb.h" +#include "ldb/include/ldb_errors.h" +#include "ldb/include/ldb_module.h" +#include "libcli/security/security.h" +#include "librpc/gen_ndr/drsblobs.h" +#include "librpc/gen_ndr/ndr_drsblobs.h" +#include "librpc/ndr/libndr.h" +#include "dsdb/samdb/samdb.h" +#include "util.h" + +#define LDAP_DIRSYNC_OBJECT_SECURITY 0x01 +#define LDAP_DIRSYNC_ANCESTORS_FIRST_ORDER 0x800 +#define LDAP_DIRSYNC_PUBLIC_DATA_ONLY 0x2000 +#define LDAP_DIRSYNC_INCREMENTAL_VALUES 0x80000000 + + +struct dirsync_context { + struct ldb_module *module; + struct ldb_request *req; + + /* + * We keep a track of the number of attributes that we + * add just for the need of the implementation + * it will be usefull to track then entries that needs not to + * be returned because there is no real change + */ + + unsigned int nbDefaultAttrs; + uint64_t highestUSN; + uint64_t fromreqUSN; + uint32_t cursor_size; + bool noextended; + bool linkIncrVal; + bool localonly; + bool partial; + bool assystem; + int functional_level; + const struct GUID *our_invocation_id; + const struct dsdb_schema *schema; + struct ldb_dn *nc_root; + struct drsuapi_DsReplicaCursor *cursors; +}; + + +static int dirsync_filter_entry(struct ldb_request *req, + struct ldb_message *msg, + struct ldb_control **controls, + struct dirsync_context *dsc, + bool referral) +{ + struct ldb_context *ldb; + uint64_t val; + enum ndr_err_code ndr_err; + uint32_t n; + int i; + unsigned int size, j; + uint32_t deletedattr; + struct ldb_val *replMetaData = NULL; + struct replPropertyMetaDataBlob rmd; + const struct dsdb_attribute *attr; + const char **listAttr = NULL; + bool namereturned = false; + bool nameasked = false; + NTSTATUS status; + /* Ajustment for the added attributes, it will reduce the number of + * expected to be here attributes*/ + unsigned int delta = 0; + const char **myaccept = NULL; + const char *emptyaccept[] = { NULL }; + const char *extendedaccept[] = { "GUID", "SID", "WKGUID", NULL }; + const char *rdn = NULL; + struct ldb_message_element *el; + struct ldb_message *newmsg; + bool keep = false; + /* + * Where we asked to do extended dn ? + * if so filter out everything bug GUID, SID, WKGUID, + * if not filter out everything (just keep the dn). + */ + if ( dsc->noextended == true ) { + myaccept = emptyaccept; + } else { + myaccept = extendedaccept; + } + ldb = ldb_module_get_ctx(dsc->module); + + if (msg->num_elements == 0) { + /* + * Entry that we don't really have access to + */ + return LDB_SUCCESS; + } + ldb_dn_extended_filter(msg->dn, myaccept); + + /* + * If the RDN starts with CN then the CN attribute is never returned + */ + rdn = ldb_dn_get_rdn_name(msg->dn); + + deletedattr = 0; + /* + * if objectGUID is asked and we are dealing for the referrals entries and + * the usn searched is 0 then we didn't count the objectGUID as an automatically + * returned attribute, do to so we increament delta. + */ + if (referral == true && + ldb_attr_in_list(req->op.search.attrs, "objectGUID") && + dsc->fromreqUSN == 0) { + delta++; + } + + + /* + * In terms of big O notation this is not the best algorithm, + * but we try our best not to make the worse one. + * We are obliged to run through the n message's elements + * and through the p elements of the replPropertyMetaData. + * + * It turns out that we are crawling twice the message's elements + * the first crawl is to remove the non replicated and generated + * attributes. The second one is to remove attributes that haven't + * a USN > as the requested one. + * + * In the second crawl we are reading the list of elements in the + * replPropertyMetaData for each remaining replicated attribute. + * In order to keep the list small + * + * We have a O(n'*p') complexity, in worse case n' = n and p' = p + * but in most case n' = n/2 (at least half of returned attributes + * are not replicated or generated) and p' is small as we + * list only the attribute that have been modified since last interogation + * + */ + newmsg = talloc_zero(dsc->req, struct ldb_message); + if (newmsg == NULL) { + return ldb_oom(ldb); + } + for (i = msg->num_elements - 1; i >= 0; i--) { + attr = dsdb_attribute_by_lDAPDisplayName(dsc->schema, msg->elements[i].name); + if (ldb_attr_cmp(msg->elements[i].name, "uSNChanged") == 0) { + /* Read the USN it will used at the end of the filtering + * to update the max USN in the cookie if we + * decide to keep this entry + */ + val = strtoull((const char*)msg->elements[i].values[0].data, NULL, 0); + continue; + } + + if (ldb_attr_cmp(msg->elements[i].name, + "replPropertyMetaData") == 0) { + replMetaData = (talloc_steal(dsc, &msg->elements[i].values[0])); + continue; + } + } + + if (replMetaData == NULL) { + bool guidfound = false; + + /* + * We are in the case of deleted object where we don't have the + * right to read it. + */ + if (!ldb_msg_find_attr_as_uint(msg, "isDeleted", 0)) { + /* + * This is not a deleted item and we don't + * have the replPropertyMetaData. + * Do not return it + */ + return LDB_SUCCESS; + } + newmsg->dn = ldb_dn_new(newmsg, ldb, ""); + if (newmsg->dn == NULL) { + return ldb_oom(ldb); + } + + el = ldb_msg_find_element(msg, "objectGUID"); + if ( el != NULL) { + guidfound = true; + } + /* + * We expect to find the GUID in the object, + * if it turns out not to be the case sometime + * well will uncomment the code bellow + */ + SMB_ASSERT(guidfound == true); + /* + if (guidfound == false) { + struct GUID guid; + struct ldb_val *new_val; + DATA_BLOB guid_blob; + + tmp[0] = '\0'; + txt = strrchr(txt, ':'); + if (txt == NULL) { + return ldb_module_done(dsc->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); + } + txt++; + + status = GUID_from_string(txt, &guid); + if (!NT_STATUS_IS_OK(status)) { + return ldb_module_done(dsc->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); + } + + status = GUID_to_ndr_blob(&guid, msg, &guid_blob); + if (!NT_STATUS_IS_OK(status)) { + return ldb_module_done(dsc->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); + } + + new_val = talloc(msg, struct ldb_val); + if (new_val == NULL) { + return ldb_oom(ldb); + } + new_val->data = talloc_steal(new_val, guid_blob.data); + new_val->length = guid_blob.length; + if (ldb_msg_add_value(msg, "objectGUID", new_val, NULL) != 0) { + return ldb_module_done(dsc->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); + } + } + */ + ldb_msg_add(newmsg, el, LDB_FLAG_MOD_ADD); + talloc_steal(newmsg->elements, el->name); + talloc_steal(newmsg->elements, el->values); + + talloc_free(msg); + return ldb_module_send_entry(dsc->req, msg, controls); + } + + ndr_err = ndr_pull_struct_blob(replMetaData, dsc, &rmd, + (ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaDataBlob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + ldb_set_errstring(ldb, "Unable to unmarshall replPropertyMetaData"); + return ldb_module_done(dsc->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); + } + if (ldb_attr_in_list(req->op.search.attrs, "name") || + ldb_attr_in_list(req->op.search.attrs, "*")) { + nameasked = true; + } + + /* + * If we don't have an USN and no updateness array then we skip the + * test phase this is an optimisation for the case when you + * first query the DC without a cookie. + * As this query is most probably the one + * that will return the biggest answer, skipping this part + * will really save time. + */ + if (ldb_dn_compare(dsc->nc_root, msg->dn) == 0) { + /* If we have name then we expect to have parentGUID, + * it will not be the case for the root of the NC + */ + delta++; + } + + if (dsc->fromreqUSN > 0 || dsc->cursors != NULL) { + j = 0; + /* + * Allocate an array of size(replMetaData) of char* + * we know that it will be oversized but it's a short lived element + */ + listAttr = talloc_array(msg, const char*, rmd.ctr.ctr1.count + 1); + if (listAttr == NULL) { + return ldb_oom(ldb); + } + for (n=0; n < rmd.ctr.ctr1.count; n++) { + struct replPropertyMetaData1 *omd = &rmd.ctr.ctr1.array[n]; + if (omd->local_usn > dsc->fromreqUSN) { + const struct dsdb_attribute *a = dsdb_attribute_by_attributeID_id(dsc->schema, + omd->attid); + if (!dsc->localonly) { + struct drsuapi_DsReplicaCursor *tab = dsc->cursors; + uint32_t l; + for (l=0; l < dsc->cursor_size; l++) { + if (GUID_equal(&tab[l].source_dsa_invocation_id, &omd->originating_invocation_id) && + tab[l].highest_usn >= omd->originating_usn) { + /* + * If we have in the uptodateness vector an entry + * with the same invocation id as the originating invocation + * and if the usn in the vector is greater or equal to + * the one in originating_usn, then it means that this entry + * has already been sent (from another DC) to the client + * no need to resend it one more time. + */ + goto skip; + } + } + /* If we are here it's because we have a usn > (max(usn of vectors))*/ + } + if (namereturned == false && + nameasked == true && + ldb_attr_cmp(a->lDAPDisplayName, "name") == 0) { + namereturned = true; + if (ldb_dn_compare(dsc->nc_root, msg->dn) == 0) { + delta++; + } + } + listAttr[j] = a->lDAPDisplayName; + j++; +skip: + continue; + } + } + size = j; + } else { + size = 0; + if (ldb_attr_in_list(req->op.search.attrs, "*") || + ldb_attr_in_list(req->op.search.attrs, "name")) { + namereturned = true; + } + } + + + /* + * Let's loop around the remaining elements + * to see which one are in the listAttr. + * If they are in this array it means that + * their localusn > usn from the request (in the cookie) + * if not we remove the attribute. + */ + for (i = msg->num_elements - 1; i >= 0; i--) { + el = &(msg->elements[i]); + attr = dsdb_attribute_by_lDAPDisplayName(dsc->schema, + el->name); + const char *ldapattrname = el->name; + keep = false; + + if (attr->linkID & 1) { + /* + * Attribute is a backlink so let's remove it + */ + continue; + } + + if (ldb_attr_cmp(msg->elements[i].name, + "replPropertyMetaData") == 0) { + continue; + } + + if ((attr->systemFlags & (DS_FLAG_ATTR_NOT_REPLICATED | DS_FLAG_ATTR_IS_CONSTRUCTED))) { + if (ldb_attr_cmp(attr->lDAPDisplayName, "objectGUID") != 0 && + ldb_attr_cmp(attr->lDAPDisplayName, "parentGUID") != 0) { + /* + * Attribute is constructed or not replicated, let's get rid of it + */ + continue; + } else { + /* Let's keep the attribute that we forced to be added + * even if they are not in the replicationMetaData + * or are just generated + */ + if (namereturned == false && + (ldb_attr_cmp(attr->lDAPDisplayName, "parentGUID") == 0)) { + delta++; + continue; + } + if (ldb_msg_add(newmsg, el, LDB_FLAG_MOD_ADD) != LDB_SUCCESS) { + return ldb_error(ldb, + LDB_ERR_OPERATIONS_ERROR, + "Unable to add attribute"); + } + talloc_steal(newmsg->elements, el->name); + talloc_steal(newmsg->elements, el->values); + continue; + } + } + + if (ldb_attr_cmp(msg->elements[i].name, rdn) == 0) { + /* + * We have an attribute that is the same as the start of the RDN + * (ie. attribute CN with rdn CN=). + */ + continue; + } + + if (ldb_attr_cmp(attr->lDAPDisplayName, "instanceType") == 0) { + if (ldb_msg_add(newmsg, el, LDB_FLAG_MOD_ADD) != LDB_SUCCESS) { + return ldb_error(ldb, + LDB_ERR_OPERATIONS_ERROR, + "Unable to add attribute"); + } + talloc_steal(newmsg->elements, el->name); + talloc_steal(newmsg->elements, el->values); + continue; + } + /* For links, when our functional level > windows 2000 + * we use the RMD_LOCAL_USN information to decide wether + * we return the attribute or not. + * For windows 2000 this information is in the replPropertyMetaData + * so it will be handled like any other replicated attribute + */ + + if (dsc->functional_level > DS_DOMAIN_FUNCTION_2000 && + attr->linkID != 0 ) { + int k; + /* + * Elements for incremental changes on linked attributes + */ + struct ldb_message_element *el_incr_add = NULL; + struct ldb_message_element *el_incr_del = NULL; + /* + * Attribute is a forwardlink so let's remove it + */ + + for (k = el->num_values -1; k >= 0; k--) { + char *dn_ln; + uint32_t flags = 0; + uint32_t tmp_usn = 0; + uint32_t tmp_usn2 = 0; + struct GUID invocation_id = GUID_zero(); + struct dsdb_dn *dn = dsdb_dn_parse(msg, ldb, &el->values[k], attr->syntax->ldap_oid); + if (dn == NULL) { + ldb_set_errstring(ldb, "Cannot parse DN"); + return ldb_module_done(dsc->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); + } + status = dsdb_get_extended_dn_uint32(dn->dn, &tmp_usn, "RMD_LOCAL_USN"); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(dn); + return ldb_module_done(dsc->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); + } + status = dsdb_get_extended_dn_guid(dn->dn, &invocation_id, "RMD_INVOCID"); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(dn); + return ldb_module_done(dsc->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); + } + + status = dsdb_get_extended_dn_uint32(dn->dn, &flags, "RMD_FLAGS"); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(dn); + return ldb_module_done(dsc->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); + } + + status = dsdb_get_extended_dn_uint32(dn->dn, &tmp_usn2, "RMD_ORIGINATING_USN"); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(dn); + return ldb_module_done(dsc->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); + } + + ldb_dn_extended_filter(dn->dn, myaccept); + dn_ln = ldb_dn_get_extended_linearized(dn, dn->dn, 1); + if (dn_ln == NULL) + { + talloc_free(dn); + ldb_set_errstring(ldb, "Cannot linearize dn"); + return ldb_module_done(dsc->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); + } + + talloc_free(el->values[k].data); + el->values[k].data = (uint8_t*)talloc_steal(el->values, dn_ln); + if (el->values[k].data == NULL) { + talloc_free(dn); + return ldb_module_done(dsc->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); + } + el->values[k].length = strlen(dn_ln); + + + if (tmp_usn > dsc->fromreqUSN) { + if (!dsc->localonly) { + struct drsuapi_DsReplicaCursor *tab = dsc->cursors; + uint32_t l; + + for (l=0; l < dsc->cursor_size; l++) { + if (GUID_equal(&tab[l].source_dsa_invocation_id, &invocation_id) && + tab[l].highest_usn >= tmp_usn2) { + /* + * If we have in the uptodateness vector an entry + * with the same invocation id as the originating invocation + * and if the usn in the vector is greater or equal to + * the one in originating_usn, then it means that this entry + * has already been sent (from another DC) to the client + * no need to resend it one more time. + */ + goto skip_link; + } + } + /* If we are here it's because we have a usn > (max(usn of vectors))*/ + keep = true; + } else { + keep = true; + } + /* If we are here it's because the link is more recent than either any + * originating usn or local usn + */ + + if (dsc->linkIncrVal == true) { + struct ldb_message_element *tmpel; + if (flags & DSDB_RMD_FLAG_DELETED) { + tmpel = el_incr_del; + } else { + tmpel = el_incr_add; + } + + if (tmpel == NULL) { + tmpel = talloc_zero(newmsg, struct ldb_message_element); + if (tmpel == NULL) { + return ldb_oom(ldb); + } + tmpel->values = talloc_array(tmpel, struct ldb_val, 1); + if (tmpel->values == NULL) { + return ldb_oom(ldb); + } + if (flags & DSDB_RMD_FLAG_DELETED) { + tmpel->name = talloc_asprintf(tmpel, + "%s;range=0-0", + el->name); + } + else { + tmpel->name = talloc_asprintf(tmpel, + "%s;range=1-1", + el->name); + } + if (tmpel->name == NULL) { + return ldb_oom(ldb); + } + tmpel->num_values = 1; + } else { + tmpel->num_values += 1; + tmpel->values = talloc_realloc(tmpel, + tmpel->values, + struct ldb_val, + tmpel->num_values); + if (tmpel->values == NULL) { + return ldb_oom(ldb); + } + tmpel = tmpel; + } + tmpel->values[tmpel->num_values -1].data =talloc_steal(tmpel->values, el->values[k].data); + tmpel->values[tmpel->num_values -1].length = el->values[k].length; + + if (flags & DSDB_RMD_FLAG_DELETED) { + el_incr_del = tmpel; + } else { + el_incr_add = tmpel; + } + } + } + + if (dsc->linkIncrVal == false) { + if (flags & DSDB_RMD_FLAG_DELETED) { + if (k < (el->num_values - 1)) { + memmove(el->values + k, + el->values + (k + 1), + ((el->num_values - 1) - k)*sizeof(*el->values)); + } + el->num_values--; + } + } +skip_link: + talloc_free(dn); + + } + if (keep == true) { + if (dsc->linkIncrVal == false) { + if (ldb_msg_add(newmsg, el, LDB_FLAG_MOD_ADD) != LDB_SUCCESS) { + return ldb_error(ldb, + LDB_ERR_OPERATIONS_ERROR, + "Unable to add attribute"); + } + talloc_steal(newmsg->elements, el->name); + talloc_steal(newmsg->elements, el->values); + } else { + if (el_incr_del) { + if (ldb_msg_add(newmsg, el_incr_del, LDB_FLAG_MOD_ADD)) + return ldb_error(ldb, + LDB_ERR_OPERATIONS_ERROR, + "Unable to add attribute"); + } + if (el_incr_add) { + if (ldb_msg_add(newmsg, el_incr_add, LDB_FLAG_MOD_ADD)) + return ldb_error(ldb, + LDB_ERR_OPERATIONS_ERROR, + "Unable to add attribute"); + } + } + } + continue; + } + + if (listAttr) { + for (j=0; j<size; j++) { + /* + * We mark attribute that has already been seen well + * as seen. So that after attribute that are still in + * listAttr are attributes that has been modified after + * the requested USN but not present in the attributes + * returned by the ldb search. + * That is to say attributes that have been removed + */ + if (listAttr[j] && ldb_attr_cmp(listAttr[j], ldapattrname) == 0) { + listAttr[j] = NULL; + keep = true; + continue; + } + } + } else { + keep = true; + } + + if (keep == true) { + if (ldb_msg_add(newmsg, el, LDB_FLAG_MOD_ADD) != LDB_SUCCESS) { + return ldb_error(ldb, + LDB_ERR_OPERATIONS_ERROR, + "Unable to add attribute"); + } + talloc_steal(newmsg->elements, el->name); + talloc_steal(newmsg->elements, el->values); + continue; + } + } + + /* + * Here we run through the list of attributes returned + * in the propertyMetaData. + * Entries of this list have usn > requested_usn, + * entries that are also present in the message have been + * replaced by NULL, so at this moment the list contains + * only elements that have a usn > requested_usn and that + * haven't been seen. It's attributes that were removed. + * We add them to the message like empty elements. + */ + for (j=0; j<size; j++) { + if (listAttr[j] && ( + ldb_attr_in_list(req->op.search.attrs, "*") || + ldb_attr_in_list(req->op.search.attrs, listAttr[j])) && + (ldb_attr_cmp(listAttr[j], rdn) != 0) && + (ldb_attr_cmp(listAttr[j], "instanceType") != 0)) { + ldb_msg_add_empty(newmsg, listAttr[j], LDB_FLAG_MOD_DELETE, NULL); + } + } + talloc_free(listAttr); + + if ((newmsg->num_elements - ( dsc->nbDefaultAttrs - delta)) > 0) { + /* + * After cleaning attributes there is still some attributes that were not added just + * for the purpose of the control (objectGUID, instanceType, ...) + */ + + newmsg->dn = talloc_steal(newmsg, msg->dn); + if (val > dsc->highestUSN) { + dsc->highestUSN = val; + } + talloc_free(msg); + return ldb_module_send_entry(dsc->req, newmsg, controls); + } else { + talloc_free(msg); + return LDB_SUCCESS; + } +} + + +static int dirsync_create_vector(struct ldb_request *req, + struct ldb_reply *ares, + struct dirsync_context *dsc, + struct ldapControlDirSyncCookie *cookie, + struct ldb_context *ldb) +{ + struct ldb_result *resVector; + const char* attrVector[] = {"replUpToDateVector", NULL }; + uint64_t highest_usn; + struct ldb_dn *nc_root; + uint32_t count = 1; + int ret; + struct drsuapi_DsReplicaCursor *tab; + + nc_root = ldb_get_default_basedn(ldb); + ret = ldb_sequence_number(ldb, LDB_SEQ_HIGHEST_SEQ, &highest_usn); + if (ret != LDB_SUCCESS) { + return ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "Unable to get highest USN from current NC"); + } + + /* If we have a full answer then the highest USN + * is not the highest USN from the result set but the + * highest of the naming context, unless the sequence is not updated yet. + */ + if (highest_usn > dsc->highestUSN) { + dsc->highestUSN = highest_usn; + } + + + ret = dsdb_module_search_dn(dsc->module, dsc, &resVector, + nc_root, + attrVector, + DSDB_FLAG_NEXT_MODULE, req); + + if (resVector->count != 0) { + DATA_BLOB blob; + uint32_t i; + struct ldb_message_element *el = ldb_msg_find_element(resVector->msgs[0], "replUpToDateVector"); + if (el) { + enum ndr_err_code ndr_err; + struct replUpToDateVectorBlob utd; + blob.data = el->values[0].data; + blob.length = el->values[0].length; + ndr_err = ndr_pull_struct_blob(&blob, dsc, &utd, + (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob); + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, + "Unable to pull replUpToDateVectorBlob structure"); + } + + + count += utd.ctr.ctr2.count; + tab = talloc_array(cookie, struct drsuapi_DsReplicaCursor, count); + if (tab == NULL) { + return ldb_oom(ldb); + } + for (i=1; i < count; i++) { + memset(&tab[i], 0, sizeof(struct drsuapi_DsReplicaCursor)); + tab[i].highest_usn = utd.ctr.ctr2.cursors[i-1].highest_usn; + tab[i].source_dsa_invocation_id = utd.ctr.ctr2.cursors[i-1].source_dsa_invocation_id; + } + } else { + tab = talloc_array(cookie, struct drsuapi_DsReplicaCursor, count); + if (tab == NULL) { + return ldb_oom(ldb); + } + } + } else { + /* + * No replUpToDateVector ? it happens quite often (1 DC, + * other DCs didn't update ... + */ + tab = talloc_array(cookie, struct drsuapi_DsReplicaCursor, count); + if (tab == NULL) { + return ldb_oom(ldb); + } + } + /* Our vector is always the first */ + tab[0].highest_usn = dsc->highestUSN; + tab[0].source_dsa_invocation_id = *(dsc->our_invocation_id); + + + /* We have to add the updateness vector that we have*/ + /* Version is always 1 in dirsync cookies */ + cookie->blob.extra.uptodateness_vector.version = 1; + cookie->blob.extra.uptodateness_vector.reserved = 0; + cookie->blob.extra.uptodateness_vector.ctr.ctr1.count = count; + cookie->blob.extra.uptodateness_vector.ctr.ctr1.reserved = 0; + cookie->blob.extra.uptodateness_vector.ctr.ctr1.cursors = tab; + + return LDB_SUCCESS; +} + +static int dirsync_search_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + int ret; + struct dirsync_context *dsc; + struct ldb_result *res, *res2; + struct ldb_dirsync_control *control; + struct ldapControlDirSyncCookie *cookie; + struct ldb_context *ldb; + struct ldb_dn *dn; + struct ldb_val *val; + DATA_BLOB *blob; + NTTIME now; + const char *attrs[] = { "objectGUID", NULL }; + enum ndr_err_code ndr_err; + char *tmp; + uint32_t flags; + + dsc = talloc_get_type_abort(req->context, struct dirsync_context); + ldb = ldb_module_get_ctx(dsc->module); + if (!ares) { + return ldb_module_done(dsc->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(dsc->req, ares->controls, + ares->response, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + return dirsync_filter_entry(req, ares->message, ares->controls, dsc, false); + + case LDB_REPLY_REFERRAL: + /* Skip the ldap(s):// so up to 8 chars, + * we don't care to be precise as the goal is to be in + * the name of DC, then we search the next '/' + * as it will be the last char before the DN of the referal + */ + if (strncmp(ares->referral, "ldap://", 7) == 0) { + tmp = ares->referral + 7; + } else if (strncmp(ares->referral, "ldaps://", 8) == 0) { + tmp = ares->referral + 8; + } else { + return ldb_operr(ldb); + } + + tmp = strchr(tmp, '/'); + tmp++; + + dn = ldb_dn_new(dsc, ldb, tmp); + if (dn == NULL) { + return ldb_oom(ldb); + } + + flags = DSDB_FLAG_NEXT_MODULE | + DSDB_RMD_FLAG_DELETED | + DSDB_SEARCH_SHOW_EXTENDED_DN; + + if (dsc->assystem) { + flags = flags | DSDB_FLAG_AS_SYSTEM; + } + + ret = dsdb_module_search_tree(dsc->module, dsc, &res, + dn, LDB_SCOPE_BASE, + req->op.search.tree, + req->op.search.attrs, + flags, req); + + if (ret != LDB_SUCCESS) { + talloc_free(dn); + return ret; + } + + if (res->count > 1) { + char *ldbmsg = talloc_asprintf(dn, "LDB returned more than result for dn: %s", tmp); + if (ldbmsg) { + ldb_set_errstring(ldb, ldbmsg); + } + talloc_free(dn); + return ldb_module_done(dsc->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); + } else if (res->count == 0) { + /* if nothing is returned then it means that we don't + * have access to it. + */ + return LDB_SUCCESS; + } + + talloc_free(dn); + /* + * Fetch the objectGUID of the root of current NC + */ + ret = dsdb_module_search_dn(dsc->module, dsc, &res2, + req->op.search.base, + attrs, + DSDB_FLAG_NEXT_MODULE, req); + + if (ret != LDB_SUCCESS) { + return ret; + } + if (res2->msgs[0]->num_elements != 1) { + ldb_set_errstring(ldb, + "More than 1 attribute returned while looking for objectGUID"); + return ldb_module_done(dsc->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); + } + + val = res2->msgs[0]->elements[0].values; + ret = ldb_msg_add_value(res->msgs[0], "parentGUID", val, NULL); + /* + * It *very* important to steal otherwise as val is in a subcontext + * related to res2, when the value will be one more time stolen + * it's elements[x].values that will be stolen, so it's important to + * recreate the context hierrachy as if it was done from a ldb_request + */ + talloc_steal(res->msgs[0]->elements[0].values, val); + if (ret != LDB_SUCCESS) { + return ret; + } + return dirsync_filter_entry(req, res->msgs[0], res->controls, dsc, true); + + case LDB_REPLY_DONE: + /* + * Let's add our own control + */ + + control = talloc_zero(ares->controls, struct ldb_dirsync_control); + if (control == NULL) { + return ldb_oom(ldb); + } + + /* + * When outputing flags is used to say more results. + * For the moment we didn't honnor the size info */ + + control->flags = 0; + + /* + * max_attribute is unused cf. 3.1.1.3.4.1.3 LDAP_SERVER_DIRSYNC_OID in MS-ADTS + */ + + control->max_attributes = 0; + cookie = talloc_zero(control, struct ldapControlDirSyncCookie); + if (cookie == NULL) { + return ldb_oom(ldb); + } + + if (!dsc->partial) { + ret = dirsync_create_vector(req, ares, dsc, cookie, ldb); + if (ret != LDB_SUCCESS) { + return ldb_module_done(dsc->req, NULL, NULL, ret); + } + } + + unix_to_nt_time(&now, time(NULL)); + cookie->blob.time = now; + cookie->blob.highwatermark.highest_usn = dsc->highestUSN; + cookie->blob.highwatermark.tmp_highest_usn = dsc->highestUSN; + cookie->blob.guid1 = *(dsc->our_invocation_id); + + blob = talloc_zero(control, DATA_BLOB); + if (blob == NULL) { + return ldb_oom(ldb); + } + + ndr_err = ndr_push_struct_blob(blob, blob, cookie, + (ndr_push_flags_fn_t)ndr_push_ldapControlDirSyncCookie); + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + ldb_set_errstring(ldb, "Can't marshall ldapControlDirSyncCookie struct"); + return ldb_module_done(dsc->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); + } + control->cookie = (char *)blob->data; + control->cookie_len = blob->length; + ldb_reply_add_control(ares, LDB_CONTROL_DIRSYNC_OID, true, control); + + return ldb_module_done(dsc->req, ares->controls, + ares->response, LDB_SUCCESS); + + } + return LDB_SUCCESS; +} + +static int dirsync_ldb_search(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_control *control; + struct ldb_result *acl_res; + struct ldb_dirsync_control *dirsync_ctl; + struct ldb_request *down_req; + struct dirsync_context *dsc; + struct ldb_context *ldb; + struct ldb_parse_tree *new_tree = req->op.search.tree; + uint32_t flags = 0; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + const char **attrs; + int ret; + + + if (ldb_dn_is_special(req->op.search.base)) { + return ldb_next_request(module, req); + } + + /* + * check if there's an extended dn control + */ + control = ldb_request_get_control(req, LDB_CONTROL_DIRSYNC_OID); + if (control == NULL) { + /* not found go on */ + return ldb_next_request(module, req); + } + + ldb = ldb_module_get_ctx(module); + /* + * This control must always be critical otherwise we return PROTOCOL error + */ + if (!control->critical) { + return ldb_operr(ldb); + } + + dsc = talloc_zero(req, struct dirsync_context); + if (dsc == NULL) { + return ldb_oom(ldb); + } + dsc->module = module; + dsc->req = req; + dsc->nbDefaultAttrs = 0; + + + dirsync_ctl = talloc_get_type(control->data, struct ldb_dirsync_control); + if (dirsync_ctl == NULL) { + return ldb_error(ldb, LDB_ERR_PROTOCOL_ERROR, "No data in dirsync control"); + } + + ret = dsdb_find_nc_root(ldb, dsc, req->op.search.base, &dsc->nc_root); + if (ret != LDB_SUCCESS) { + return ret; + } + + if (ldb_dn_compare(dsc->nc_root, req->op.search.base) != 0) { + if (dirsync_ctl->flags & LDAP_DIRSYNC_OBJECT_SECURITY) { + return ldb_error(ldb, LDB_ERR_UNWILLING_TO_PERFORM, + "DN is not one of the naming context"); + } + else { + return ldb_error(ldb, LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS, + "dN is not one of the naming context"); + } + } + + if (!(dirsync_ctl->flags & LDAP_DIRSYNC_OBJECT_SECURITY)) { + struct dom_sid *sid; + struct security_descriptor *sd = NULL; + const char *acl_attrs[] = { "nTSecurityDescriptor", "objectSid", NULL }; + /* + * If we don't have the flag and if we have the "replicate directory change" granted + * then we upgrade ourself to system to not be blocked by the acl + */ + /* FIXME we won't check the replicate directory change filtered attribute set + * it should be done so that if attr is not empty then we check that the user + * has also this right + */ + + /* + * First change to system to get the SD of the root of current NC + * if we don't the acl_read will forbid us the right to read it ... + */ + ret = dsdb_module_search_dn(module, dsc, &acl_res, + req->op.search.base, + acl_attrs, + DSDB_FLAG_NEXT_MODULE|DSDB_FLAG_AS_SYSTEM, req); + + if (ret != LDB_SUCCESS) { + return ret; + } + + sid = samdb_result_dom_sid(dsc, acl_res->msgs[0], "objectSid"); + /* sid can be null ... */ + ret = dsdb_get_sd_from_ldb_message(ldb_module_get_ctx(module), acl_res, acl_res->msgs[0], &sd); + + if (ret != LDB_SUCCESS) { + return ret; + } + ret = acl_check_extended_right(dsc, sd, acl_user_token(module), GUID_DRS_GET_CHANGES, SEC_ADS_CONTROL_ACCESS, sid); + + if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { + return ret; + } + dsc->assystem = true; + ret = ldb_request_add_control(req, LDB_CONTROL_AS_SYSTEM_OID, false, NULL); + + if (ret != LDB_SUCCESS) { + return ret; + } + talloc_free(acl_res); + } else { + flags |= DSDB_ACL_CHECKS_DIRSYNC_FLAG; + + if (ret != LDB_SUCCESS) { + return ret; + } + + } + + dsc->functional_level = dsdb_functional_level(ldb); + + if (req->op.search.attrs) { + attrs = ldb_attr_list_copy(dsc, req->op.search.attrs); + if (attrs == NULL) { + return ldb_oom(ldb); + } + /* + * Check if we have only "dn" as attribute, if so then + * treat as if "*" was requested + */ + if (attrs && attrs[0]) { + if (ldb_attr_cmp(attrs[0], "dn") == 0 && !attrs[1]) { + attrs = talloc_array(dsc, const char*, 2); + if (attrs == NULL) { + return ldb_oom(ldb); + } + attrs[0] = "*"; + attrs[1] = NULL; + } + } + /* + * When returning all the attributes return also the SD as + * Windws do so. + */ + if (ldb_attr_in_list(attrs, "*")) { + struct ldb_sd_flags_control *sdctr = talloc_zero(dsc, struct ldb_sd_flags_control); + sdctr->secinfo_flags = 0; + ret = ldb_request_add_control(req, LDB_CONTROL_SD_FLAGS_OID, false, sdctr); + if (ret != LDB_SUCCESS) { + return ret; + } + attrs = ldb_attr_list_copy_add(dsc, attrs, "parentGUID"); + if (attrs == NULL) { + return ldb_oom(ldb); + } + attrs = ldb_attr_list_copy_add(dsc, attrs, "replPropertyMetaData"); + if (attrs == NULL) { + return ldb_oom(ldb); + } + /* + * When no attributes are asked we in anycase expect at least 3 attributes: + * * instanceType + * * objectGUID + * * parentGUID + */ + + dsc->nbDefaultAttrs = 3; + } else { + /* + * We will need this two attributes in the callback + */ + attrs = ldb_attr_list_copy_add(dsc, attrs, "usnChanged"); + if (attrs == NULL) { + return ldb_operr(ldb); + } + attrs = ldb_attr_list_copy_add(dsc, attrs, "replPropertyMetaData"); + if (attrs == NULL) { + return ldb_operr(ldb); + } + + if (!ldb_attr_in_list(attrs, "instanceType")) { + attrs = ldb_attr_list_copy_add(dsc, attrs, "instanceType"); + if (attrs == NULL) { + return ldb_operr(ldb); + } + dsc->nbDefaultAttrs++; + } + + if (!ldb_attr_in_list(attrs, "objectGUID")) { + attrs = ldb_attr_list_copy_add(dsc, attrs, "objectGUID"); + if (attrs == NULL) { + return ldb_operr(ldb); + } + } + /* + * Always increment the number of asked attributes as we don't care if objectGUID was asked + * or not for counting the number of "real" attributes returned. + */ + dsc->nbDefaultAttrs++; + + if (!ldb_attr_in_list(attrs, "parentGUID")) { + attrs = ldb_attr_list_copy_add(dsc, attrs, "parentGUID"); + if (attrs == NULL) { + return ldb_operr(ldb); + } + } + dsc->nbDefaultAttrs++; + + } + } else { + struct ldb_sd_flags_control *sdctr = talloc_zero(dsc, struct ldb_sd_flags_control); + sdctr->secinfo_flags = 0; + ret = ldb_request_add_control(req, LDB_CONTROL_SD_FLAGS_OID, false, sdctr); + attrs = talloc_array(dsc, const char*, 4); + if (attrs == NULL) { + return ldb_operr(ldb); + } + attrs[0] = "*"; + attrs[1] = "parentGUID"; + attrs[2] = "replPropertyMetaData"; + attrs[3] = NULL; + if (ret != LDB_SUCCESS) { + return ret; + } + /* + * When no attributes are asked we in anycase expect at least 3 attributes: + * * instanceType + * * objectGUID + * * parentGUID + */ + + dsc->nbDefaultAttrs = 3; + } + + if (!ldb_request_get_control(req, LDB_CONTROL_EXTENDED_DN_OID)) { + ret = ldb_request_add_control(req, LDB_CONTROL_EXTENDED_DN_OID, false, NULL); + if (ret != LDB_SUCCESS) { + return ret; + } + dsc->noextended = true; + } + + if (ldb_request_get_control(req, LDB_CONTROL_REVEAL_INTERNALS) == NULL) { + ret = ldb_request_add_control(req, LDB_CONTROL_REVEAL_INTERNALS, false, NULL); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + if (ldb_request_get_control(req, LDB_CONTROL_SHOW_RECYCLED_OID) == NULL) { + ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_RECYCLED_OID, false, NULL); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + if (ldb_request_get_control(req, LDB_CONTROL_SHOW_DELETED_OID) == NULL) { + ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_DELETED_OID, false, NULL); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + if (dirsync_ctl->flags & LDAP_DIRSYNC_INCREMENTAL_VALUES) { + dsc->linkIncrVal = true; + } else { + dsc->linkIncrVal = false; + } + + dsc->our_invocation_id = samdb_ntds_invocation_id(ldb); + if (dsc->our_invocation_id == NULL) { + return ldb_operr(ldb); + } + + if (dirsync_ctl->cookie_len > 0) { + struct ldapControlDirSyncCookie cookie; + + blob.data = (uint8_t *)dirsync_ctl->cookie; + blob.length = dirsync_ctl->cookie_len; + ndr_err = ndr_pull_struct_blob(&blob, dsc, &cookie, + (ndr_pull_flags_fn_t)ndr_pull_ldapControlDirSyncCookie); + + /* If we can't unmarshall the cookie into the correct structure we return + * unsupported critical extension + */ + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ldb_error(ldb, LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION, + "Unable to unmarshall cookie as a ldapControlDirSyncCookie structure"); + } + + /* + * Let's search for the max usn withing the cookie + */ + if (GUID_equal(&(cookie.blob.guid1), dsc->our_invocation_id)) { + /* + * Ok, it's our invocation ID so we can treat the demand + * Let's take the highest usn from (tmp)highest_usn + */ + dsc->fromreqUSN = cookie.blob.highwatermark.tmp_highest_usn; + dsc->localonly = true; + + if (cookie.blob.highwatermark.highest_usn > cookie.blob.highwatermark.tmp_highest_usn) { + dsc->fromreqUSN = cookie.blob.highwatermark.highest_usn; + } + } else { + dsc->localonly = false; + } + if (cookie.blob.extra_length > 0 && + cookie.blob.extra.uptodateness_vector.ctr.ctr1.count > 0) { + struct drsuapi_DsReplicaCursor cursor; + uint32_t p; + for (p=0; p < cookie.blob.extra.uptodateness_vector.ctr.ctr1.count; p++) { + cursor = cookie.blob.extra.uptodateness_vector.ctr.ctr1.cursors[p]; + if (GUID_equal( &(cursor.source_dsa_invocation_id), dsc->our_invocation_id)) { + if (cursor.highest_usn > dsc->fromreqUSN) { + dsc->fromreqUSN = cursor.highest_usn; + } + } + } + dsc->cursors = talloc_steal(dsc, + cookie.blob.extra.uptodateness_vector.ctr.ctr1.cursors); + if (dsc->cursors == NULL) { + return ldb_oom(ldb); + } + dsc->cursor_size = p; + } + } + + DEBUG(4, ("Dirsync: searching with min usn > %llu\n", + (long long unsigned int)dsc->fromreqUSN)); + if (dsc->fromreqUSN > 0) { + /* FIXME it would be better to use PRId64 */ + char *expression = talloc_asprintf(dsc, "(&%s(uSNChanged>=%llu))", + ldb_filter_from_tree(dsc, + req->op.search.tree), + (long long unsigned int)(dsc->fromreqUSN + 1)); + + if (expression == NULL) { + return ldb_oom(ldb); + } + new_tree = ldb_parse_tree(req, expression); + if (new_tree == NULL) { + return ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, + "Problem while parsing tree"); + } + + } + /* + * Remove our control from the list of controls + */ + if (!ldb_save_controls(control, req, NULL)) { + return ldb_operr(ldb); + } + dsc->schema = dsdb_get_schema(ldb, dsc); + /* + * At the begining we make the hypothesis that we will return a complete + * result set + */ + + dsc->partial = false; + + /* + * 3.1.1.3.4.1.3 of MS-ADTS.pdf specify that if the scope is not subtree + * we treat the search as if subtree was specified + */ + + ret = ldb_build_search_req_ex(&down_req, ldb, dsc, + req->op.search.base, + LDB_SCOPE_SUBTREE, + new_tree, + attrs, + req->controls, + dsc, dirsync_search_callback, + req); + ldb_req_set_custom_flags(down_req, flags); + LDB_REQ_SET_LOCATION(down_req); + if (ret != LDB_SUCCESS) { + return ret; + } + /* perform the search */ + return ldb_next_request(module, down_req); +} + +static int dirsync_ldb_init(struct ldb_module *module) +{ + int ret; + + ret = ldb_mod_register_control(module, LDB_CONTROL_DIRSYNC_OID); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_ERROR, + "dirsync: Unable to register control with rootdse!\n"); + return ldb_operr(ldb_module_get_ctx(module)); + } + + return ldb_next_init(module); +} + +static const struct ldb_module_ops ldb_dirsync_ldb_module_ops = { + .name = "dirsync", + .search = dirsync_ldb_search, + .init_context = dirsync_ldb_init, +}; + +/* + initialise the module + */ +_PUBLIC_ int ldb_dirsync_module_init(const char *version) +{ + int ret; + LDB_MODULE_CHECK_VERSION(version); + ret = ldb_register_module(&ldb_dirsync_ldb_module_ops); + return ret; +} diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_in.c b/source4/dsdb/samdb/ldb_modules/extended_dn_in.c index 3e2004d6f3..9a70d9a3db 100644 --- a/source4/dsdb/samdb/ldb_modules/extended_dn_in.c +++ b/source4/dsdb/samdb/ldb_modules/extended_dn_in.c @@ -103,6 +103,18 @@ static int extended_base_callback(struct ldb_request *req, struct ldb_reply *are switch (ares->type) { case LDB_REPLY_ENTRY: + if (ac->basedn) { + /* we have more than one match! This can + happen as S-1-5-17 appears twice in a + normal provision. We need to return + NO_SUCH_OBJECT */ + const char *str = talloc_asprintf(req, "Duplicate base-DN matches found for '%s'", + ldb_dn_get_extended_linearized(req, ac->req->op.search.base, 1)); + ldb_set_errstring(ldb_module_get_ctx(ac->module), str); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_NO_SUCH_OBJECT); + } + if (!ac->wellknown_object) { ac->basedn = talloc_steal(ac, ares->message->dn); break; @@ -303,30 +315,33 @@ static int extended_dn_in_fix(struct ldb_module *module, struct ldb_request *req guid_val = ldb_dn_get_extended_component(dn, "GUID"); wkguid_val = ldb_dn_get_extended_component(dn, "WKGUID"); - if (sid_val) { + /* + prioritise the GUID - we have had instances of + duplicate SIDs in the database in the + ForeignSecurityPrinciples due to provision errors + */ + if (guid_val) { all_partitions = true; base_dn = ldb_get_default_basedn(ldb_module_get_ctx(module)); - base_dn_filter = talloc_asprintf(req, "(objectSid=%s)", - ldb_binary_encode(req, *sid_val)); + base_dn_filter = talloc_asprintf(req, "(objectGUID=%s)", + ldb_binary_encode(req, *guid_val)); if (!base_dn_filter) { return ldb_oom(ldb_module_get_ctx(module)); } base_dn_scope = LDB_SCOPE_SUBTREE; base_dn_attrs = no_attr; - } else if (guid_val) { - + } else if (sid_val) { all_partitions = true; base_dn = ldb_get_default_basedn(ldb_module_get_ctx(module)); - base_dn_filter = talloc_asprintf(req, "(objectGUID=%s)", - ldb_binary_encode(req, *guid_val)); + base_dn_filter = talloc_asprintf(req, "(objectSid=%s)", + ldb_binary_encode(req, *sid_val)); if (!base_dn_filter) { return ldb_oom(ldb_module_get_ctx(module)); } base_dn_scope = LDB_SCOPE_SUBTREE; base_dn_attrs = no_attr; - } else if (wkguid_val) { char *wkguid_dup; char *tail_str; diff --git a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c index 9df121002f..5639a7a3e3 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c @@ -140,7 +140,8 @@ static int attr_handler(struct oc_context *ac) if (!(msg->elements[i].flags & LDB_FLAG_INTERNAL_DISABLE_VALIDATION)) { werr = attr->syntax->validate_ldb(&syntax_ctx, attr, &msg->elements[i]); - if (!W_ERROR_IS_OK(werr)) { + if (!W_ERROR_IS_OK(werr) && + !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) { ldb_asprintf_errstring(ldb, "objectclass_attrs: attribute '%s' on entry '%s' contains at least one invalid value!", msg->elements[i].name, ldb_dn_get_linearized(msg->dn)); diff --git a/source4/dsdb/samdb/ldb_modules/proxy.c b/source4/dsdb/samdb/ldb_modules/proxy.c index 6fba24fc2d..5f6e56f9d4 100644 --- a/source4/dsdb/samdb/ldb_modules/proxy.c +++ b/source4/dsdb/samdb/ldb_modules/proxy.c @@ -138,7 +138,7 @@ static int load_proxy_info(struct ldb_module *module) ldb_set_opaque(proxy->upstream, "credentials", creds); ret = ldb_connect(proxy->upstream, url, 0, NULL); - if (ret != 0) { + if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_FATAL, "proxy failed to connect to %s\n", url); goto failed; } diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 646abeb771..9d2e5e2ac3 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -254,7 +254,16 @@ static int replmd_process_backlink(struct ldb_module *module, struct la_backlink msg->elements[0].flags |= LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK; ret = dsdb_module_modify(module, msg, DSDB_FLAG_NEXT_MODULE, parent); - if (ret != LDB_SUCCESS) { + if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE && !bl->active) { + /* we allow LDB_ERR_NO_SUCH_ATTRIBUTE as success to + cope with possible corruption where the backlink has + already been removed */ + DEBUG(0,("WARNING: backlink from %s already removed from %s - %s\n", + ldb_dn_get_linearized(target_dn), + ldb_dn_get_linearized(source_dn), + ldb_errstring(ldb))); + ret = LDB_SUCCESS; + } else if (ret != LDB_SUCCESS) { ldb_asprintf_errstring(ldb, "Failed to %s backlink from %s to %s - %s", bl->active?"add":"remove", ldb_dn_get_linearized(source_dn), @@ -1634,7 +1643,8 @@ static int replmd_update_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct d if (old_addtime == NULL) { old_addtime = &tval; } - if (dsdb_dn != old_dsdb_dn) { + if (dsdb_dn != old_dsdb_dn || + ldb_dn_get_extended_component(dn, "RMD_ADDTIME") == NULL) { ret = ldb_dn_set_extended_component(dn, "RMD_ADDTIME", old_addtime); if (ret != LDB_SUCCESS) return ret; } @@ -2488,7 +2498,7 @@ static int replmd_rename_callback(struct ldb_request *req, struct ldb_reply *are if (ret == LDB_ERR_REFERRAL) { struct ldb_dn *olddn = ac->req->op.rename.olddn; struct loadparm_context *lp_ctx; - const char *referral; + char *referral; lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"), struct loadparm_context); diff --git a/source4/dsdb/samdb/ldb_modules/ridalloc.c b/source4/dsdb/samdb/ldb_modules/ridalloc.c index 5051919672..28fade11b1 100644 --- a/source4/dsdb/samdb/ldb_modules/ridalloc.c +++ b/source4/dsdb/samdb/ldb_modules/ridalloc.c @@ -66,14 +66,14 @@ */ static void ridalloc_poke_rid_manager(struct ldb_module *module) { - struct messaging_context *msg; + struct imessaging_context *msg; struct server_id *server; struct ldb_context *ldb = ldb_module_get_ctx(module); struct loadparm_context *lp_ctx = (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm"); TALLOC_CTX *tmp_ctx = talloc_new(module); - msg = messaging_client_init(tmp_ctx, lpcfg_messaging_path(tmp_ctx, lp_ctx), + msg = imessaging_client_init(tmp_ctx, lpcfg_imessaging_path(tmp_ctx, lp_ctx), ldb_get_event_context(ldb)); if (!msg) { DEBUG(3,(__location__ ": Failed to create messaging context\n")); @@ -88,7 +88,7 @@ static void ridalloc_poke_rid_manager(struct ldb_module *module) return; } - messaging_send(msg, server[0], MSG_DREPL_ALLOCATE_RID, NULL); + imessaging_send(msg, server[0], MSG_DREPL_ALLOCATE_RID, NULL); /* we don't care if the message got through */ talloc_free(tmp_ctx); diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index 0fd65f4795..c584a11b2c 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -222,11 +222,10 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms struct loadparm_context); char *ldap_service_name, *hostname; - hostname = talloc_strdup(msg, lpcfg_netbios_name(lp_ctx)); + hostname = strlower_talloc(msg, lpcfg_netbios_name(lp_ctx)); if (hostname == NULL) { goto failed; } - strlower_m(hostname); ldap_service_name = talloc_asprintf(msg, "%s:%s$@%s", samdb_forest_name(ldb, msg), @@ -613,7 +612,11 @@ static int rootdse_filter_controls(struct ldb_module *module, struct ldb_request continue; } - if (is_registered) { + /* If the control is DIRSYNC control then we keep the critical + * flag as the dirsync module will need to act upon it + */ + if (is_registered && strcmp(req->controls[i]->oid, + LDB_CONTROL_DIRSYNC_OID)!= 0) { req->controls[i]->critical = 0; } } @@ -1195,7 +1198,7 @@ static int rootdse_become_master(struct ldb_module *module, struct ldb_request *req, enum drepl_role_master role) { - struct messaging_context *msg; + struct imessaging_context *msg; struct ldb_context *ldb = ldb_module_get_ctx(module); TALLOC_CTX *tmp_ctx = talloc_new(req); struct loadparm_context *lp_ctx = ldb_get_opaque(ldb, "loadparm"); @@ -1223,10 +1226,10 @@ static int rootdse_become_master(struct ldb_module *module, "RODC cannot become a role master."); } - msg = messaging_client_init(tmp_ctx, lpcfg_messaging_path(tmp_ctx, lp_ctx), + msg = imessaging_client_init(tmp_ctx, lpcfg_imessaging_path(tmp_ctx, lp_ctx), ldb_get_event_context(ldb)); if (!msg) { - ldb_asprintf_errstring(ldb, "Failed to generate client messaging context in %s", lpcfg_messaging_path(tmp_ctx, lp_ctx)); + ldb_asprintf_errstring(ldb, "Failed to generate client messaging context in %s", lpcfg_imessaging_path(tmp_ctx, lp_ctx)); return LDB_ERR_OPERATIONS_ERROR; } irpc_handle = irpc_binding_handle_by_name(tmp_ctx, msg, diff --git a/source4/dsdb/samdb/ldb_modules/samba_dsdb.c b/source4/dsdb/samdb/ldb_modules/samba_dsdb.c index 35b323b72f..e4de1524be 100644 --- a/source4/dsdb/samdb/ldb_modules/samba_dsdb.c +++ b/source4/dsdb/samdb/ldb_modules/samba_dsdb.c @@ -163,6 +163,7 @@ static int samba_dsdb_init(struct ldb_module *module) static const char *modules_list[] = {"resolve_oids", "rootdse", "lazy_commit", + "dirsync", "paged_results", "ranged_results", "anr", diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 21341850d9..6533d1006b 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -3,7 +3,7 @@ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005 Copyright (C) Simo Sorce 2004-2008 - Copyright (C) Matthias Dieter Wallnöfer 2009-2010 + Copyright (C) Matthias Dieter Wallnöfer 2009-2011 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 @@ -790,6 +790,8 @@ static int samldb_schema_info_update(struct samldb_ctx *ac) return LDB_SUCCESS; } +static int samldb_prim_group_tester(struct samldb_ctx *ac, uint32_t rid); + /* * "Objectclass" trigger (MS-SAMR 3.1.1.8.1) * @@ -801,10 +803,9 @@ static int samldb_schema_info_update(struct samldb_ctx *ac) static int samldb_objectclass_trigger(struct samldb_ctx *ac) { struct ldb_context *ldb = ldb_module_get_ctx(ac->module); - struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(ldb, - "loadparm"), struct loadparm_context); + void *skip_allocate_sids = ldb_get_opaque(ldb, + "skip_allocate_sids"); struct ldb_message_element *el, *el2; - enum sid_generator sid_generator; struct dom_sid *sid; int ret; @@ -830,12 +831,9 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) } /* but generate a new SID when we do have an add operations */ - if ((sid == NULL) && (ac->req->operation == LDB_ADD)) { - sid_generator = lpcfg_sid_generator(lp_ctx); - if (sid_generator == SID_GENERATOR_INTERNAL) { - ret = samldb_add_step(ac, samldb_allocate_sid); - if (ret != LDB_SUCCESS) return ret; - } + if ((sid == NULL) && (ac->req->operation == LDB_ADD) && !skip_allocate_sids) { + ret = samldb_add_step(ac, samldb_allocate_sid); + if (ret != LDB_SUCCESS) return ret; } if (strcmp(ac->type, "user") == 0) { @@ -897,6 +895,16 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) return LDB_ERR_OTHER; } + /* Workstation and (read-only) DC objects do need objectclass "computer" */ + if ((samdb_find_attribute(ldb, ac->msg, + "objectclass", "computer") == NULL) && + (user_account_control & + (UF_SERVER_TRUST_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT))) { + ldb_set_errstring(ldb, + "samldb: Requested account type does need objectclass 'computer'!"); + return LDB_ERR_OBJECT_CLASS_VIOLATION; + } + account_type = ds_uf2atype(user_account_control); if (account_type == 0) { ldb_set_errstring(ldb, "samldb: Unrecognized account type!"); @@ -911,11 +919,20 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) el2 = ldb_msg_find_element(ac->msg, "sAMAccountType"); el2->flags = LDB_FLAG_MOD_REPLACE; + /* "isCriticalSystemObject" might be set */ if (user_account_control & (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)) { - ret = samdb_msg_set_string(ldb, ac->msg, ac->msg, - "isCriticalSystemObject", - "TRUE"); + ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject", + "TRUE"); + if (ret != LDB_SUCCESS) { + return ret; + } + el2 = ldb_msg_find_element(ac->msg, + "isCriticalSystemObject"); + el2->flags = LDB_FLAG_MOD_REPLACE; + } else if (user_account_control & UF_WORKSTATION_TRUST_ACCOUNT) { + ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject", + "FALSE"); if (ret != LDB_SUCCESS) { return ret; } @@ -927,6 +944,18 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) /* Step 1.4: "userAccountControl" -> "primaryGroupID" mapping */ if (!ldb_msg_find_element(ac->msg, "primaryGroupID")) { uint32_t rid = ds_uf2prim_group_rid(user_account_control); + + /* + * Older AD deployments don't know about the + * RODC group + */ + if (rid == DOMAIN_RID_READONLY_DCS) { + ret = samldb_prim_group_tester(ac, rid); + if (ret != LDB_SUCCESS) { + return ret; + } + } + ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, "primaryGroupID", rid); if (ret != LDB_SUCCESS) { @@ -1009,26 +1038,14 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) * ac->msg contains the "add"/"modify" message */ -static int samldb_prim_group_set(struct samldb_ctx *ac) +static int samldb_prim_group_tester(struct samldb_ctx *ac, uint32_t rid) { struct ldb_context *ldb = ldb_module_get_ctx(ac->module); - uint32_t rid; struct dom_sid *sid; struct ldb_result *res; int ret; const char *noattrs[] = { NULL }; - rid = ldb_msg_find_attr_as_uint(ac->msg, "primaryGroupID", (uint32_t) -1); - if (rid == (uint32_t) -1) { - /* we aren't affected of any primary group set */ - return LDB_SUCCESS; - - } else if (!ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) { - ldb_set_errstring(ldb, - "The primary group isn't settable on add operations!"); - return LDB_ERR_UNWILLING_TO_PERFORM; - } - sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid); if (sid == NULL) { return ldb_operr(ldb); @@ -1054,6 +1071,25 @@ static int samldb_prim_group_set(struct samldb_ctx *ac) return LDB_SUCCESS; } +static int samldb_prim_group_set(struct samldb_ctx *ac) +{ + struct ldb_context *ldb = ldb_module_get_ctx(ac->module); + uint32_t rid; + + rid = ldb_msg_find_attr_as_uint(ac->msg, "primaryGroupID", (uint32_t) -1); + if (rid == (uint32_t) -1) { + /* we aren't affected of any primary group set */ + return LDB_SUCCESS; + + } else if (!ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) { + ldb_set_errstring(ldb, + "The primary group isn't settable on add operations!"); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + return samldb_prim_group_tester(ac, rid); +} + static int samldb_prim_group_change(struct samldb_ctx *ac) { struct ldb_context *ldb = ldb_module_get_ctx(ac->module); @@ -1076,14 +1112,11 @@ static int samldb_prim_group_change(struct samldb_ctx *ac) /* Fetch information from the existing object */ - ret = dsdb_module_search(ac->module, ac, &res, ac->msg->dn, LDB_SCOPE_BASE, attrs, - DSDB_FLAG_NEXT_MODULE, ac->req, NULL); + ret = dsdb_module_search_dn(ac->module, ac, &res, ac->msg->dn, attrs, + DSDB_FLAG_NEXT_MODULE, ac->req); if (ret != LDB_SUCCESS) { return ret; } - if (res->count != 1) { - return ldb_operr(ldb); - } /* Finds out the DN of the old primary group */ @@ -1219,13 +1252,22 @@ static int samldb_prim_group_trigger(struct samldb_ctx *ac) return ret; } + +/** + * This function is called on LDB modify operations. It performs some additions/ + * replaces on the current LDB message when "userAccountControl" changes. + */ static int samldb_user_account_control_change(struct samldb_ctx *ac) { struct ldb_context *ldb = ldb_module_get_ctx(ac->module); - uint32_t user_account_control, account_type; + uint32_t user_account_control, old_user_account_control, account_type; struct ldb_message_element *el; struct ldb_message *tmp_msg; int ret; + struct ldb_result *res; + const char *attrs[] = { "userAccountControl", "objectClass", NULL }; + unsigned int i; + bool is_computer = false; el = dsdb_get_single_valued_attr(ac->msg, "userAccountControl", ac->req->operation); @@ -1253,6 +1295,49 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) return LDB_ERR_OTHER; } + /* Fetch the old "userAccountControl" and "objectClass" */ + ret = dsdb_module_search_dn(ac->module, ac, &res, ac->msg->dn, attrs, + DSDB_FLAG_NEXT_MODULE, ac->req); + if (ret != LDB_SUCCESS) { + return ret; + } + old_user_account_control = ldb_msg_find_attr_as_uint(res->msgs[0], "userAccountControl", 0); + if (old_user_account_control == 0) { + return ldb_operr(ldb); + } + el = ldb_msg_find_element(res->msgs[0], "objectClass"); + if (el == NULL) { + return ldb_operr(ldb); + } + + /* When we do not have objectclass "computer" we cannot switch to a (read-only) DC */ + for (i = 0; i < el->num_values; i++) { + if (ldb_attr_cmp((char *)el->values[i].data, "computer") == 0) { + is_computer = true; + break; + } + } + if (!is_computer && + (user_account_control & (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT))) { + ldb_set_errstring(ldb, + "samldb: Requested account type does need objectclass 'computer'!"); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + /* + * The functions "ds_uf2atype" and "ds_uf2prim_group_rid" are used as + * detectors for account type changes. + * So if the account type does change then we need to adjust the + * "sAMAccountType", the "isCriticalSystemObject" and the + * "primaryGroupID" attribute. + */ + if ((ds_uf2atype(user_account_control) + == ds_uf2atype(old_user_account_control)) && + (ds_uf2prim_group_rid(user_account_control) + == ds_uf2prim_group_rid(old_user_account_control))) { + return LDB_SUCCESS; + } + account_type = ds_uf2atype(user_account_control); if (account_type == 0) { ldb_set_errstring(ldb, "samldb: Unrecognized account type!"); @@ -1266,6 +1351,7 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) el = ldb_msg_find_element(ac->msg, "sAMAccountType"); el->flags = LDB_FLAG_MOD_REPLACE; + /* "isCriticalSystemObject" might be set/changed */ if (user_account_control & (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)) { ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject", @@ -1276,10 +1362,28 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) el = ldb_msg_find_element(ac->msg, "isCriticalSystemObject"); el->flags = LDB_FLAG_MOD_REPLACE; + } else if (user_account_control & UF_WORKSTATION_TRUST_ACCOUNT) { + ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject", + "FALSE"); + if (ret != LDB_SUCCESS) { + return ret; + } + el = ldb_msg_find_element(ac->msg, + "isCriticalSystemObject"); + el->flags = LDB_FLAG_MOD_REPLACE; } if (!ldb_msg_find_element(ac->msg, "primaryGroupID")) { uint32_t rid = ds_uf2prim_group_rid(user_account_control); + + /* Older AD deployments don't know about the RODC group */ + if (rid == DOMAIN_RID_READONLY_DCS) { + ret = samldb_prim_group_tester(ac, rid); + if (ret != LDB_SUCCESS) { + return ret; + } + } + ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, "primaryGroupID", rid); if (ret != LDB_SUCCESS) { @@ -1977,7 +2081,7 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req) el = ldb_msg_find_element(ac->msg, "primaryGroupID"); if (el != NULL) { - ret = samldb_prim_group_change(ac); + ret = samldb_prim_group_trigger(ac); if (ret != LDB_SUCCESS) { return ret; } diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c index 49939e2ff4..7dbf233703 100644 --- a/source4/dsdb/samdb/ldb_modules/util.c +++ b/source4/dsdb/samdb/ldb_modules/util.c @@ -109,39 +109,23 @@ int dsdb_module_search_dn(struct ldb_module *module, return ret; } -/* - search for attrs in the modules below - */ -int dsdb_module_search(struct ldb_module *module, +int dsdb_module_search_tree(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_result **_res, - struct ldb_dn *basedn, enum ldb_scope scope, + struct ldb_dn *basedn, + enum ldb_scope scope, + struct ldb_parse_tree *tree, const char * const *attrs, - int dsdb_flags, - struct ldb_request *parent, - const char *format, ...) _PRINTF_ATTRIBUTE(9, 10) + int dsdb_flags, + struct ldb_request *parent) { int ret; struct ldb_request *req; TALLOC_CTX *tmp_ctx; struct ldb_result *res; - va_list ap; - char *expression; tmp_ctx = talloc_new(mem_ctx); - if (format) { - va_start(ap, format); - expression = talloc_vasprintf(tmp_ctx, format, ap); - va_end(ap); - - if (!expression) { - talloc_free(tmp_ctx); - return ldb_oom(ldb_module_get_ctx(module)); - } - } else { - expression = NULL; - } res = talloc_zero(tmp_ctx, struct ldb_result); if (!res) { @@ -149,10 +133,10 @@ int dsdb_module_search(struct ldb_module *module, return ldb_oom(ldb_module_get_ctx(module)); } - ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx, + ret = ldb_build_search_req_ex(&req, ldb_module_get_ctx(module), tmp_ctx, basedn, scope, - expression, + tree, attrs, NULL, res, @@ -196,6 +180,61 @@ int dsdb_module_search(struct ldb_module *module, } /* + search for attrs in the modules below + */ +int dsdb_module_search(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + struct ldb_result **_res, + struct ldb_dn *basedn, enum ldb_scope scope, + const char * const *attrs, + int dsdb_flags, + struct ldb_request *parent, + const char *format, ...) _PRINTF_ATTRIBUTE(9, 10) +{ + int ret; + TALLOC_CTX *tmp_ctx; + va_list ap; + char *expression; + struct ldb_parse_tree *tree; + + tmp_ctx = talloc_new(mem_ctx); + + if (format) { + va_start(ap, format); + expression = talloc_vasprintf(tmp_ctx, format, ap); + va_end(ap); + + if (!expression) { + talloc_free(tmp_ctx); + return ldb_oom(ldb_module_get_ctx(module)); + } + } else { + expression = NULL; + } + + tree = ldb_parse_tree(tmp_ctx, expression); + if (tree == NULL) { + talloc_free(tmp_ctx); + ldb_set_errstring(ldb_module_get_ctx(module), + "Unable to parse search expression"); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = dsdb_module_search_tree(module, + mem_ctx, + _res, + basedn, + scope, + tree, + attrs, + dsdb_flags, + parent); + + talloc_free(tmp_ctx); + return ret; +} + +/* find a DN given a GUID. This searches across all partitions */ int dsdb_module_dn_by_guid(struct ldb_module *module, TALLOC_CTX *mem_ctx, diff --git a/source4/dsdb/samdb/ldb_modules/wscript_build b/source4/dsdb/samdb/ldb_modules/wscript_build index 8ad893c551..eb9c664c71 100644 --- a/source4/dsdb/samdb/ldb_modules/wscript_build +++ b/source4/dsdb/samdb/ldb_modules/wscript_build @@ -390,3 +390,12 @@ bld.SAMBA_MODULE('ldb_simple_dn', internal_module=False, deps='talloc DSDB_MODULE_HELPERS' ) + +bld.SAMBA_MODULE('ldb_dirsync', + source='dirsync.c', + subsystem='ldb', + init_function='ldb_dirsync_module_init', + module_init_name='ldb_init_module', + internal_module=False, + deps='talloc events security samdb DSDB_MODULE_HELPERS DSDB_MODULE_HELPER_SCHEMA' + ) diff --git a/source4/dsdb/samdb/samdb.c b/source4/dsdb/samdb/samdb.c index 29b454467c..d761107b15 100644 --- a/source4/dsdb/samdb/samdb.c +++ b/source4/dsdb/samdb/samdb.c @@ -96,7 +96,7 @@ struct ldb_context *samdb_connect(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, struct loadparm_context *lp_ctx, struct auth_session_info *session_info, - int flags) + unsigned int flags) { struct ldb_context *ldb; struct dsdb_schema *schema; @@ -104,7 +104,7 @@ struct ldb_context *samdb_connect(TALLOC_CTX *mem_ctx, struct cli_credentials *credentials; int ret; - url = lpcfg_sam_url(lp_ctx); + url = "sam.ldb"; credentials = samdb_credentials(lp_ctx); ldb = ldb_wrap_find(url, ev_ctx, lp_ctx, session_info, credentials, flags); diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h index 8efb5e0af2..96f44c356e 100644 --- a/source4/dsdb/samdb/samdb.h +++ b/source4/dsdb/samdb/samdb.h @@ -192,4 +192,5 @@ struct dsdb_fsmo_extended_op { struct GUID destination_dsa_guid; }; +#define DSDB_ACL_CHECKS_DIRSYNC_FLAG 0x1 #endif /* __SAMDB_H__ */ diff --git a/source4/dsdb/schema/schema_convert_to_ol.c b/source4/dsdb/schema/schema_convert_to_ol.c index 77a9b1f291..0e42f20cf0 100644 --- a/source4/dsdb/schema/schema_convert_to_ol.c +++ b/source4/dsdb/schema/schema_convert_to_ol.c @@ -134,6 +134,7 @@ static char *print_schema_recursive(char *append_to_string, struct dsdb_schema * may, NULL); if (schema_entry == NULL) { + talloc_free(mem_ctx); DEBUG(0, ("failed to generate schema description for %s\n", name)); return NULL; } @@ -145,6 +146,10 @@ static char *print_schema_recursive(char *append_to_string, struct dsdb_schema * case TARGET_FEDORA_DS: out = talloc_asprintf_append(out, "objectClasses: %s\n", schema_entry); break; + default: + talloc_free(mem_ctx); + DEBUG(0,(__location__ " Wrong type of target %u!", (unsigned)target)); + return NULL; } talloc_free(mem_ctx); } while (0); @@ -199,6 +204,7 @@ char *dsdb_convert_schema_to_openldap(struct ldb_context *ldb, char *target_str, } else if (strcasecmp(target_str, "fedora-ds") == 0) { target = TARGET_FEDORA_DS; } else { + talloc_free(mem_ctx); DEBUG(0, ("Invalid target type for schema conversion %s\n", target_str)); return NULL; } @@ -263,6 +269,7 @@ char *dsdb_convert_schema_to_openldap(struct ldb_context *ldb, char *target_str, schema = dsdb_get_schema(ldb, mem_ctx); if (!schema) { + talloc_free(mem_ctx); DEBUG(0, ("No schema on ldb to convert!\n")); return NULL; } @@ -274,6 +281,10 @@ char *dsdb_convert_schema_to_openldap(struct ldb_context *ldb, char *target_str, case TARGET_FEDORA_DS: out = talloc_strdup(mem_ctx, "dn: cn=schema\n"); break; + default: + talloc_free(mem_ctx); + DEBUG(0,(__location__ " Wrong type of target %u!", (unsigned)target)); + return NULL; } for (attribute=schema->attributes; attribute; attribute = attribute->next) { @@ -339,6 +350,7 @@ char *dsdb_convert_schema_to_openldap(struct ldb_context *ldb, char *target_str, false, false); if (schema_entry == NULL) { + talloc_free(mem_ctx); DEBUG(0, ("failed to generate attribute description for %s\n", name)); return NULL; } @@ -350,11 +362,18 @@ char *dsdb_convert_schema_to_openldap(struct ldb_context *ldb, char *target_str, case TARGET_FEDORA_DS: out = talloc_asprintf_append(out, "attributeTypes: %s\n", schema_entry); break; + default: + talloc_free(mem_ctx); + DEBUG(0,(__location__ " Wrong type of target %u!", (unsigned)target)); + return NULL; } } out = print_schema_recursive(out, schema, "top", target, attrs_skip, attr_map, oid_map); + talloc_steal(ldb, out); + talloc_free(mem_ctx); + return out; } diff --git a/source4/dsdb/schema/schema_syntax.c b/source4/dsdb/schema/schema_syntax.c index ea582db68b..a93cdfaaa9 100644 --- a/source4/dsdb/schema/schema_syntax.c +++ b/source4/dsdb/schema/schema_syntax.c @@ -1069,8 +1069,14 @@ static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(const struct dsdb_syntax_ctx * struct ldb_message_element *out) { unsigned int i; + const struct dsdb_schema_prefixmap *prefixmap; - SMB_ASSERT(ctx->pfm_remote); + if (ctx->pfm_remote != NULL) { + prefixmap = ctx->pfm_remote; + } else { + prefixmap = ctx->schema->prefixmap; + } + SMB_ASSERT(prefixmap); out->flags = 0; out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName); @@ -1095,7 +1101,7 @@ static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(const struct dsdb_syntax_ctx * attid = IVAL(in->value_ctr.values[i].blob->data, 0); - status = dsdb_schema_pfm_oid_from_attid(ctx->pfm_remote, attid, + status = dsdb_schema_pfm_oid_from_attid(prefixmap, attid, out->values, &oid); if (!W_ERROR_IS_OK(status)) { DEBUG(0,(__location__ ": Error: Unknown ATTID 0x%08X\n", @@ -1977,20 +1983,21 @@ static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_syntax_ctx W_ERROR_HAVE_NO_MEMORY(dn); } - status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return ntstatus_to_werror(status); - } + if (!GUID_all_zero(&id3.guid)) { + status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return ntstatus_to_werror(status); + } - ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob); - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - return WERR_FOOBAR; + ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return WERR_FOOBAR; + } + talloc_free(guid_blob.data); } - talloc_free(guid_blob.data); - if (id3.__ndr_size_sid) { DATA_BLOB sid_blob; ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, &id3.sid, diff --git a/source4/dsdb/tests/python/dirsync.py b/source4/dsdb/tests/python/dirsync.py new file mode 100755 index 0000000000..96c6950841 --- /dev/null +++ b/source4/dsdb/tests/python/dirsync.py @@ -0,0 +1,713 @@ +#!/usr/bin/env python +# +# Unit tests for dirsync control +# Copyright (C) Matthieu Patou <mat@matws.net> 2011 +# +# +# 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 <http://www.gnu.org/licenses/>. + + +import optparse +import sys +sys.path.insert(0, "bin/python") +import samba +samba.ensure_external_module("testtools", "testtools") +samba.ensure_external_module("subunit", "subunit/python") + +import samba.getopt as options +import base64 + +from ldb import LdbError, SCOPE_BASE +from ldb import Message, MessageElement, Dn +from ldb import FLAG_MOD_ADD, FLAG_MOD_DELETE +from samba.dcerpc import security, misc, drsblobs +from samba.ndr import ndr_unpack, ndr_pack + +from samba.auth import system_session +from samba import gensec, sd_utils +from samba.samdb import SamDB +from samba.credentials import Credentials +import samba.tests +from samba.tests import delete_force +from subunit.run import SubunitTestRunner +import unittest + +parser = optparse.OptionParser("dirsync.py [options] <host>") +sambaopts = options.SambaOptions(parser) +parser.add_option_group(sambaopts) +parser.add_option_group(options.VersionOptions(parser)) + +# use command line creds if available +credopts = options.CredentialsOptions(parser) +parser.add_option_group(credopts) +opts, args = parser.parse_args() + +if len(args) < 1: + parser.print_usage() + sys.exit(1) + +host = args[0] +if not "://" in host: + ldaphost = "ldap://%s" % host + ldapshost = "ldaps://%s" % host +else: + ldaphost = host + start = host.rindex("://") + host = host.lstrip(start+3) + +lp = sambaopts.get_loadparm() +creds = credopts.get_credentials(lp) + +# +# Tests start here +# + +class DirsyncBaseTests(samba.tests.TestCase): + + def setUp(self): + super(DirsyncBaseTests, self).setUp() + self.ldb_admin = ldb + self.base_dn = ldb.domain_dn() + self.domain_sid = security.dom_sid(ldb.get_domain_sid()) + self.user_pass = "samba123@AAA" + self.configuration_dn = self.ldb_admin.get_config_basedn().get_linearized() + self.sd_utils = sd_utils.SDUtils(ldb) + #used for anonymous login + print "baseDN: %s" % self.base_dn + + def get_user_dn(self, name): + return "CN=%s,CN=Users,%s" % (name, self.base_dn) + + def get_ldb_connection(self, target_username, target_password): + creds_tmp = Credentials() + creds_tmp.set_username(target_username) + creds_tmp.set_password(target_password) + creds_tmp.set_domain(creds.get_domain()) + creds_tmp.set_realm(creds.get_realm()) + creds_tmp.set_workstation(creds.get_workstation()) + creds_tmp.set_gensec_features(creds_tmp.get_gensec_features() + | gensec.FEATURE_SEAL) + ldb_target = SamDB(url=ldaphost, credentials=creds_tmp, lp=lp) + return ldb_target + + +#tests on ldap add operations +class SimpleDirsyncTests(DirsyncBaseTests): + + def setUp(self): + super(SimpleDirsyncTests, self).setUp() + # Regular user + self.dirsync_user = "test_dirsync_user" + self.simple_user = "test_simple_user" + self.admin_user = "test_admin_user" + self.ouname = None + + self.ldb_admin.newuser(self.dirsync_user, self.user_pass) + self.ldb_admin.newuser(self.simple_user, self.user_pass) + self.ldb_admin.newuser(self.admin_user, self.user_pass) + self.desc_sddl = self.sd_utils.get_sd_as_sddl(self.base_dn) + + user_sid = self.sd_utils.get_object_sid(self.get_user_dn(self.dirsync_user)) + mod = "(A;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;%s)" % str(user_sid) + self.sd_utils.dacl_add_ace(self.base_dn, mod) + + # add admins to the Domain Admins group + self.ldb_admin.add_remove_group_members("Domain Admins", self.admin_user, + add_members_operation=True) + + def tearDown(self): + super(SimpleDirsyncTests, self).tearDown() + delete_force(self.ldb_admin, self.get_user_dn(self.dirsync_user)) + delete_force(self.ldb_admin, self.get_user_dn(self.simple_user)) + delete_force(self.ldb_admin, self.get_user_dn(self.admin_user)) + if self.ouname: + delete_force(self.ldb_admin, self.ouname) + self.sd_utils.modify_sd_on_dn(self.base_dn, self.desc_sddl) + try: + self.ldb_admin.deletegroup("testgroup") + except: + pass + + #def test_dirsync_errors(self): + + + def test_dirsync_supported(self): + """Test the basic of the dirsync is supported""" + self.ldb_dirsync = self.get_ldb_connection(self.dirsync_user, self.user_pass) + self.ldb_simple = self.get_ldb_connection(self.simple_user, self.user_pass) + res = self.ldb_admin.search(self.base_dn, expression="samaccountname=*", controls=["dirsync:1:0:1"]) + res = self.ldb_dirsync.search(self.base_dn, expression="samaccountname=*", controls=["dirsync:1:0:1"]) + try: + self.ldb_simple.search(self.base_dn, + expression="samaccountname=*", + controls=["dirsync:1:0:1"]) + except LdbError,l: + self.assertTrue(str(l).find("LDAP_INSUFFICIENT_ACCESS_RIGHTS") != -1) + + def test_parentGUID_referrals(self): + res2 = self.ldb_admin.search(self.base_dn, scope=SCOPE_BASE, attrs=["objectGUID"]) + + res = self.ldb_admin.search(self.base_dn, + expression="name=Configuration", + controls=["dirsync:1:0:1"]) + self.assertEqual(res2[0].get("objectGUID"), res[0].get("parentGUID")) + + def test_ok_not_rootdc(self): + """Test if it's ok to do dirsync on another NC that is not the root DC""" + try: + res = self.ldb_admin.search("CN=Configuration, %s" % self.base_dn, + expression="samaccountname=*", + controls=["dirsync:1:0:1"]) + except: + self.assertTrue(False) + + def test_dirsync_errors(self): + """Test if dirsync returns the correct LDAP errors in case of pb""" + self.ldb_simple = self.get_ldb_connection(self.simple_user, self.user_pass) + self.ldb_dirsync = self.get_ldb_connection(self.dirsync_user, self.user_pass) + try: + self.ldb_simple.search(self.base_dn, + expression="samaccountname=*", + controls=["dirsync:1:0:1"]) + except LdbError,l: + print l + self.assertTrue(str(l).find("LDAP_INSUFFICIENT_ACCESS_RIGHTS") != -1) + + try: + self.ldb_simple.search("CN=Users,%s" % self.base_dn, + expression="samaccountname=*", + controls=["dirsync:1:0:1"]) + except LdbError,l: + print l + self.assertTrue(str(l).find("LDAP_INSUFFICIENT_ACCESS_RIGHTS") != -1) + + try: + self.ldb_simple.search("CN=Users,%s" % self.base_dn, + expression="samaccountname=*", + controls=["dirsync:1:1:1"]) + except LdbError,l: + print l + self.assertTrue(str(l).find("LDAP_UNWILLING_TO_PERFORM") != -1) + + try: + self.ldb_dirsync.search("CN=Users,%s" % self.base_dn, + expression="samaccountname=*", + controls=["dirsync:1:0:1"]) + except LdbError,l: + print l + self.assertTrue(str(l).find("LDAP_INSUFFICIENT_ACCESS_RIGHTS") != -1) + + try: + self.ldb_admin.search("CN=Users,%s" % self.base_dn, + expression="samaccountname=*", + controls=["dirsync:1:0:1"]) + except LdbError,l: + print l + self.assertTrue(str(l).find("LDAP_INSUFFICIENT_ACCESS_RIGHTS") != -1) + + try: + self.ldb_admin.search("CN=Users,%s" % self.base_dn, + expression="samaccountname=*", + controls=["dirsync:1:1:1"]) + except LdbError,l: + print l + self.assertTrue(str(l).find("LDAP_UNWILLING_TO_PERFORM") != -1) + + + + + def test_dirsync_attributes(self): + """Check behavior with some attributes """ + res = self.ldb_admin.search(self.base_dn, + expression="samaccountname=*", + controls=["dirsync:1:0:1"]) + # Check that nTSecurityDescriptor is returned as it's the case when doing dirsync + self.assertTrue(res.msgs[0].get("ntsecuritydescriptor") != None) + # Check that non replicated attributes are not returned + self.assertTrue(res.msgs[0].get("badPwdCount") == None) + # Check that non forward link are not returned + self.assertTrue(res.msgs[0].get("memberof") == None) + + # Asking for instanceType will return also objectGUID + res = self.ldb_admin.search(self.base_dn, + expression="samaccountname=Administrator", + attrs=["instanceType"], + controls=["dirsync:1:0:1"]) + self.assertTrue(res.msgs[0].get("objectGUID") != None) + self.assertTrue(res.msgs[0].get("instanceType") != None) + + # We don't return an entry if asked for objectGUID + res = self.ldb_admin.search(self.base_dn, + expression="dn=%s" % self.base_dn, + attrs=["objectGUID"], + controls=["dirsync:1:0:1"]) + self.assertEquals(len(res.msgs), 0) + + # a request on the root of a NC didn't return parentGUID + res = self.ldb_admin.search(self.base_dn, + expression="dn=%s" % self.base_dn, + attrs=["name"], + controls=["dirsync:1:0:1"]) + self.assertTrue(res.msgs[0].get("objectGUID") != None) + self.assertTrue(res.msgs[0].get("name") != None) + self.assertTrue(res.msgs[0].get("parentGUID") == None) + self.assertTrue(res.msgs[0].get("instanceType") != None) + + # Asking for name will return also objectGUID and parentGUID + # and instanceType and of course name + res = self.ldb_admin.search(self.base_dn, + expression="samaccountname=Administrator", + attrs=["name"], + controls=["dirsync:1:0:1"]) + self.assertTrue(res.msgs[0].get("objectGUID") != None) + self.assertTrue(res.msgs[0].get("name") != None) + self.assertTrue(res.msgs[0].get("parentGUID") != None) + self.assertTrue(res.msgs[0].get("instanceType") != None) + + # Asking for dn will not return not only DN but more like if attrs=* + # parentGUID should be returned + res = self.ldb_admin.search(self.base_dn, + expression="samaccountname=Administrator", + attrs=["dn"], + controls=["dirsync:1:0:1"]) + count = len(res.msgs[0]) + res2 = self.ldb_admin.search(self.base_dn, + expression="samaccountname=Administrator", + controls=["dirsync:1:0:1"]) + count2 = len(res2.msgs[0]) + self.assertEqual(count, count2) + + # Asking for cn will return nothing on objects that have CN as RDN + res = self.ldb_admin.search(self.base_dn, + expression="samaccountname=Administrator", + attrs=["cn"], + controls=["dirsync:1:0:1"]) + self.assertEqual(len(res.msgs), 0) + # Asking for parentGUID will return nothing too + res = self.ldb_admin.search(self.base_dn, + expression="samaccountname=Administrator", + attrs=["parentGUID"], + controls=["dirsync:1:0:1"]) + self.assertEqual(len(res.msgs), 0) + ouname="OU=testou,%s" % self.base_dn + self.ouname = ouname + self.ldb_admin.create_ou(ouname) + delta = Message() + delta.dn = Dn(self.ldb_admin, str(ouname)) + delta["cn"] = MessageElement("test ou", + FLAG_MOD_ADD, + "cn" ) + self.ldb_admin.modify(delta) + res = self.ldb_admin.search(self.base_dn, + expression="name=testou", + attrs=["cn"], + controls=["dirsync:1:0:1"]) + + self.assertEqual(len(res.msgs), 1) + self.assertEqual(len(res.msgs[0]), 3) + delete_force(self.ldb_admin, ouname) + + def test_dirsync_with_controls(self): + """Check that dirsync return correct informations when dealing with the NC""" + res = self.ldb_admin.search(self.base_dn, + expression="(dn=%s)" % str(self.base_dn), + attrs=["name"], + controls=["dirsync:1:0:10000", "extended_dn:1", "show_deleted:1"]) + + def test_dirsync_basenc(self): + """Check that dirsync return correct informations when dealing with the NC""" + res = self.ldb_admin.search(self.base_dn, + expression="(dn=%s)" % str(self.base_dn), + attrs=["name"], + controls=["dirsync:1:0:10000"]) + self.assertEqual(len(res.msgs), 1) + self.assertEqual(len(res.msgs[0]), 3) + + res = self.ldb_admin.search(self.base_dn, + expression="(dn=%s)" % str(self.base_dn), + attrs=["ntSecurityDescriptor"], + controls=["dirsync:1:0:10000"]) + self.assertEqual(len(res.msgs), 1) + self.assertEqual(len(res.msgs[0]), 3) + + def test_dirsync_othernc(self): + """Check that dirsync return information for entries that are normaly referrals (ie. other NCs)""" + res = self.ldb_admin.search(self.base_dn, + expression="(objectclass=configuration)", + attrs=["name"], + controls=["dirsync:1:0:10000"]) + self.assertEqual(len(res.msgs), 1) + self.assertEqual(len(res.msgs[0]), 4) + + res = self.ldb_admin.search(self.base_dn, + expression="(objectclass=configuration)", + attrs=["ntSecurityDescriptor"], + controls=["dirsync:1:0:10000"]) + self.assertEqual(len(res.msgs), 1) + self.assertEqual(len(res.msgs[0]), 3) + + res = self.ldb_admin.search(self.base_dn, + expression="(objectclass=domaindns)", + attrs=["ntSecurityDescriptor"], + controls=["dirsync:1:0:10000"]) + nb = len(res.msgs) + + # only sub nc returns a result when asked for objectGUID + res = self.ldb_admin.search(self.base_dn, + expression="(objectclass=domaindns)", + attrs=["objectGUID"], + controls=["dirsync:1:0:0"]) + self.assertEqual(len(res.msgs), nb - 1) + if nb > 1: + self.assertTrue(res.msgs[0].get("objectGUID") != None) + else: + res = self.ldb_admin.search(self.base_dn, + expression="(objectclass=configuration)", + attrs=["objectGUID"], + controls=["dirsync:1:0:0"]) + + + def test_dirsync_send_delta(self): + """Check that dirsync return correct delta when sending the last cookie""" + res = self.ldb_admin.search(self.base_dn, + expression="(&(samaccountname=test*)(!(isDeleted=*)))", + controls=["dirsync:1:0:10000"]) + ctl = str(res.controls[0]).split(":") + ctl[1] = "1" + ctl[2] = "0" + ctl[3] = "10000" + control = str(":".join(ctl)) + res = self.ldb_admin.search(self.base_dn, + expression="(&(samaccountname=test*)(!(isDeleted=*)))", + controls=[control]) + self.assertEqual(len(res), 0) + + res = self.ldb_admin.search(self.base_dn, + expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))", + controls=["dirsync:1:0:100000"]) + + ctl = str(res.controls[0]).split(":") + ctl[1] = "1" + ctl[2] = "0" + ctl[3] = "10000" + control2 = str(":".join(ctl)) + + # Let's create an OU + ouname="OU=testou2,%s" % self.base_dn + self.ouname = ouname + self.ldb_admin.create_ou(ouname) + res = self.ldb_admin.search(self.base_dn, + expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))", + controls=[control2]) + self.assertEqual(len(res), 1) + ctl = str(res.controls[0]).split(":") + ctl[1] = "1" + ctl[2] = "0" + ctl[3] = "10000" + control3 = str(":".join(ctl)) + + delta = Message() + delta.dn = Dn(self.ldb_admin, str(ouname)) + + delta["cn"] = MessageElement("test ou", + FLAG_MOD_ADD, + "cn" ) + self.ldb_admin.modify(delta) + res = self.ldb_admin.search(self.base_dn, + expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))", + controls=[control3]) + + self.assertEqual(len(res.msgs), 1) + # 3 attributes: instanceType, cn and objectGUID + self.assertEqual(len(res.msgs[0]), 3) + + delta = Message() + delta.dn = Dn(self.ldb_admin, str(ouname)) + delta["cn"] = MessageElement([], + FLAG_MOD_DELETE, + "cn" ) + self.ldb_admin.modify(delta) + res = self.ldb_admin.search(self.base_dn, + expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))", + controls=[control3]) + + self.assertEqual(len(res.msgs), 1) + # So we won't have much attribute returned but instanceType and GUID + # are. + # 3 attributes: instanceType and objectGUID and cn but empty + self.assertEqual(len(res.msgs[0]), 3) + ouname = "OU=newouname,%s" % self.base_dn + self.ldb_admin.rename(str(res[0].dn), str(Dn(self.ldb_admin, ouname))) + self.ouname = ouname + ctl = str(res.controls[0]).split(":") + ctl[1] = "1" + ctl[2] = "0" + ctl[3] = "10000" + control4 = str(":".join(ctl)) + res = self.ldb_admin.search(self.base_dn, + expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))", + controls=[control3]) + + self.assertTrue(res[0].get("parentGUID") != None) + self.assertTrue(res[0].get("name") != None) + delete_force(self.ldb_admin, ouname) + + def test_dirsync_linkedattributes(self): + """Check that dirsync returnd deleted objects too""" + # Let's search for members + self.ldb_simple = self.get_ldb_connection(self.simple_user, self.user_pass) + res = self.ldb_simple.search(self.base_dn, + expression="(name=Administrators)", + controls=["dirsync:1:1:1"]) + + self.assertTrue(len(res[0].get("member")) > 0) + size = len(res[0].get("member")) + + ctl = str(res.controls[0]).split(":") + ctl[1] = "1" + ctl[2] = "1" + ctl[3] = "10000" + control1 = str(":".join(ctl)) + self.ldb_admin.add_remove_group_members("Administrators", self.simple_user, + add_members_operation=True) + + res = self.ldb_simple.search(self.base_dn, + expression="(name=Administrators)", + controls=[control1]) + + self.assertEqual(len(res[0].get("member")), size + 1) + ctl = str(res.controls[0]).split(":") + ctl[1] = "1" + ctl[2] = "1" + ctl[3] = "10000" + control1 = str(":".join(ctl)) + + # remove the user from the group + self.ldb_admin.add_remove_group_members("Administrators", self.simple_user, + add_members_operation=False) + + res = self.ldb_simple.search(self.base_dn, + expression="(name=Administrators)", + controls=[control1]) + + self.assertEqual(len(res[0].get("member")), size ) + + self.ldb_admin.newgroup("testgroup") + self.ldb_admin.add_remove_group_members("testgroup", self.simple_user, + add_members_operation=True) + + res = self.ldb_admin.search(self.base_dn, + expression="(name=testgroup)", + controls=["dirsync:1:0:1"]) + + self.assertEqual(len(res[0].get("member")), 1) + self.assertTrue(res[0].get("member") != "" ) + + ctl = str(res.controls[0]).split(":") + ctl[1] = "1" + ctl[2] = "0" + ctl[3] = "1" + control1 = str(":".join(ctl)) + + # Check that reasking the same question but with an updated cookie + # didn't return any results. + print control1 + res = self.ldb_admin.search(self.base_dn, + expression="(name=testgroup)", + controls=[control1]) + self.assertEqual(len(res), 0) + + ctl = str(res.controls[0]).split(":") + ctl[1] = "1" + ctl[2] = "1" + ctl[3] = "10000" + control1 = str(":".join(ctl)) + + self.ldb_admin.add_remove_group_members("testgroup", self.simple_user, + add_members_operation=False) + + res = self.ldb_admin.search(self.base_dn, + expression="(name=testgroup)", + attrs=["member"], + controls=[control1]) + + self.ldb_admin.deletegroup("testgroup") + self.assertEqual(len(res[0].get("member")), 0) + + + + def test_dirsync_deleted_items(self): + """Check that dirsync returnd deleted objects too""" + # Let's create an OU + ouname="OU=testou3,%s" % self.base_dn + self.ouname = ouname + self.ldb_admin.create_ou(ouname) + res = self.ldb_admin.search(self.base_dn, + expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))", + controls=["dirsync:1:0:1"]) + guid = None + for e in res: + if str(e["name"]) == "testou3": + guid = str(ndr_unpack(misc.GUID,e.get("objectGUID")[0])) + + ctl = str(res.controls[0]).split(":") + ctl[1] = "1" + ctl[2] = "0" + ctl[3] = "10000" + control1 = str(":".join(ctl)) + + # So now delete the object and check that + # we can see the object but deleted when admin + delete_force(self.ldb_admin, ouname) + + res = self.ldb_admin.search(self.base_dn, + expression="(objectClass=organizationalUnit)", + controls=[control1]) + self.assertEqual(len(res), 1) + guid2 = str(ndr_unpack(misc.GUID,res[0].get("objectGUID")[0])) + self.assertEqual(guid2, guid) + self.assertTrue(res[0].get("isDeleted")) + self.assertTrue(res[0].get("name") != None) + + def test_cookie_from_others(self): + res = self.ldb_admin.search(self.base_dn, + expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))", + controls=["dirsync:1:0:1"]) + ctl = str(res.controls[0]).split(":") + cookie = ndr_unpack(drsblobs.ldapControlDirSyncCookie, base64.b64decode(str(ctl[4]))) + cookie.blob.guid1 = misc.GUID("128a99bf-abcd-1234-abcd-1fb625e530db") + controls=["dirsync:1:0:0:%s" % base64.b64encode(ndr_pack(cookie))] + res = self.ldb_admin.search(self.base_dn, + expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))", + controls=controls) + +class ExtendedDirsyncTests(SimpleDirsyncTests): + def test_dirsync_linkedattributes(self): + flag_incr_linked = 2147483648 + self.ldb_simple = self.get_ldb_connection(self.simple_user, self.user_pass) + res = self.ldb_admin.search(self.base_dn, + attrs=["member"], + expression="(name=Administrators)", + controls=["dirsync:1:%d:1" % flag_incr_linked]) + + self.assertTrue(res[0].get("member;range=1-1") != None ) + self.assertTrue(len(res[0].get("member;range=1-1")) > 0) + size = len(res[0].get("member;range=1-1")) + + ctl = str(res.controls[0]).split(":") + ctl[1] = "1" + ctl[2] = "%d" % flag_incr_linked + ctl[3] = "10000" + control1 = str(":".join(ctl)) + self.ldb_admin.add_remove_group_members("Administrators", self.simple_user, + add_members_operation=True) + self.ldb_admin.add_remove_group_members("Administrators", self.dirsync_user, + add_members_operation=True) + + + res = self.ldb_admin.search(self.base_dn, + expression="(name=Administrators)", + controls=[control1]) + + self.assertEqual(len(res[0].get("member;range=1-1")), 2) + ctl = str(res.controls[0]).split(":") + ctl[1] = "1" + ctl[2] = "%d" % flag_incr_linked + ctl[3] = "10000" + control1 = str(":".join(ctl)) + + # remove the user from the group + self.ldb_admin.add_remove_group_members("Administrators", self.simple_user, + add_members_operation=False) + + res = self.ldb_admin.search(self.base_dn, + expression="(name=Administrators)", + controls=[control1]) + + self.assertEqual(res[0].get("member;range=1-1"), None ) + self.assertEqual(len(res[0].get("member;range=0-0")), 1) + + ctl = str(res.controls[0]).split(":") + ctl[1] = "1" + ctl[2] = "%d" % flag_incr_linked + ctl[3] = "10000" + control2 = str(":".join(ctl)) + + self.ldb_admin.add_remove_group_members("Administrators", self.dirsync_user, + add_members_operation=False) + + res = self.ldb_admin.search(self.base_dn, + expression="(name=Administrators)", + controls=[control2]) + + self.assertEqual(res[0].get("member;range=1-1"), None ) + self.assertEqual(len(res[0].get("member;range=0-0")), 1) + + res = self.ldb_admin.search(self.base_dn, + expression="(name=Administrators)", + controls=[control1]) + + self.assertEqual(res[0].get("member;range=1-1"), None ) + self.assertEqual(len(res[0].get("member;range=0-0")), 2) + + def test_dirsync_deleted_items(self): + """Check that dirsync returnd deleted objects too""" + # Let's create an OU + self.ldb_simple = self.get_ldb_connection(self.simple_user, self.user_pass) + ouname="OU=testou3,%s" % self.base_dn + self.ouname = ouname + self.ldb_admin.create_ou(ouname) + + # Specify LDAP_DIRSYNC_OBJECT_SECURITY + res = self.ldb_simple.search(self.base_dn, + expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))", + controls=["dirsync:1:1:1"]) + + guid = None + for e in res: + if str(e["name"]) == "testou3": + guid = str(ndr_unpack(misc.GUID,e.get("objectGUID")[0])) + + self.assertTrue(guid != None) + ctl = str(res.controls[0]).split(":") + ctl[1] = "1" + ctl[2] = "1" + ctl[3] = "10000" + control1 = str(":".join(ctl)) + + # So now delete the object and check that + # we can see the object but deleted when admin + # we just see the objectGUID when simple user + delete_force(self.ldb_admin, ouname) + + res = self.ldb_simple.search(self.base_dn, + expression="(objectClass=organizationalUnit)", + controls=[control1]) + self.assertEqual(len(res), 1) + guid2 = str(ndr_unpack(misc.GUID,res[0].get("objectGUID")[0])) + self.assertEqual(guid2, guid) + self.assertEqual(str(res[0].dn), "") + + +ldb = SamDB(ldapshost, credentials=creds, session_info=system_session(lp), lp=lp) + +runner = SubunitTestRunner() +rc = 0 +# +if not runner.run(unittest.makeSuite(SimpleDirsyncTests)).wasSuccessful(): + rc = 1 +if not runner.run(unittest.makeSuite(ExtendedDirsyncTests)).wasSuccessful(): + rc = 1 + +sys.exit(rc) diff --git a/source4/dsdb/tests/python/sam.py b/source4/dsdb/tests/python/sam.py index 5f7c90db23..b08fba5a7d 100755 --- a/source4/dsdb/tests/python/sam.py +++ b/source4/dsdb/tests/python/sam.py @@ -36,8 +36,8 @@ from samba.dsdb import (UF_NORMAL_ACCOUNT, UF_ACCOUNTDISABLE, ATYPE_SECURITY_LOCAL_GROUP, ATYPE_DISTRIBUTION_GLOBAL_GROUP, ATYPE_DISTRIBUTION_UNIVERSAL_GROUP, ATYPE_DISTRIBUTION_LOCAL_GROUP, ATYPE_WORKSTATION_TRUST) -from samba.dcerpc.security import (DOMAIN_RID_USERS, DOMAIN_RID_DOMAIN_MEMBERS, - DOMAIN_RID_DCS, DOMAIN_RID_READONLY_DCS) +from samba.dcerpc.security import (DOMAIN_RID_USERS, DOMAIN_RID_ADMINS, + DOMAIN_RID_DOMAIN_MEMBERS, DOMAIN_RID_DCS, DOMAIN_RID_READONLY_DCS) from subunit.run import SubunitTestRunner import unittest @@ -1471,25 +1471,33 @@ class SamTests(unittest.TestCase): self.assertEquals(num, ERR_OTHER) delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) -# This isn't supported yet in s4 -# try: -# ldb.add({ -# "dn": "cn=ldaptestuser,cn=users," + self.base_dn, -# "objectclass": "user", -# "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT)}) -# self.fail() -# except LdbError, (num, _): -# self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) -# delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) -# -# try: -# ldb.add({ -# "dn": "cn=ldaptestuser,cn=users," + self.base_dn, -# "objectclass": "user", -# "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)}) -# except LdbError, (num, _): -# self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) -# delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) + try: + ldb.add({ + "dn": "cn=ldaptestuser,cn=users," + self.base_dn, + "objectclass": "user", + "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT)}) + self.fail() + except LdbError, (num, _): + self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) + delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) + + try: + ldb.add({ + "dn": "cn=ldaptestuser,cn=users," + self.base_dn, + "objectclass": "user", + "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)}) + except LdbError, (num, _): + self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) + delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) + + try: + ldb.add({ + "dn": "cn=ldaptestuser,cn=users," + self.base_dn, + "objectclass": "user", + "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)}) + except LdbError, (num, _): + self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION) + delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) # This isn't supported yet in s4 - needs ACL module adaption # try: @@ -1570,17 +1578,16 @@ class SamTests(unittest.TestCase): except LdbError, (num, _): self.assertEquals(num, ERR_OTHER) -# This isn't supported yet in s4 -# try: -# m = Message() -# m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) -# m["userAccountControl"] = MessageElement( -# str(UF_SERVER_TRUST_ACCOUNT), -# FLAG_MOD_REPLACE, "userAccountControl") -# ldb.modify(m) -# self.fail() -# except LdbError, (num, _): -# self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) + try: + m = Message() + m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) + m["userAccountControl"] = MessageElement( + str(UF_SERVER_TRUST_ACCOUNT), + FLAG_MOD_REPLACE, "userAccountControl") + ldb.modify(m) + self.fail() + except LdbError, (num, _): + self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) m = Message() m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) @@ -1589,6 +1596,17 @@ class SamTests(unittest.TestCase): FLAG_MOD_REPLACE, "userAccountControl") ldb.modify(m) + try: + m = Message() + m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) + m["userAccountControl"] = MessageElement( + str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT), + FLAG_MOD_REPLACE, "userAccountControl") + ldb.modify(m) + self.fail() + except LdbError, (num, _): + self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) + res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn, scope=SCOPE_BASE, attrs=["sAMAccountType"]) self.assertTrue(len(res1) == 1) @@ -1866,7 +1884,215 @@ class SamTests(unittest.TestCase): # except LdbError, (num, _): # self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS) + # "primaryGroupID" does not change if account type remains the same + + # For a user account + + ldb.add({ + "dn": "cn=ldaptestuser2,cn=users," + self.base_dn, + "objectclass": "user", + "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)}) + + res1 = ldb.search("cn=ldaptestuser2,cn=users," + self.base_dn, + scope=SCOPE_BASE, + attrs=["userAccountControl"]) + self.assertTrue(len(res1) == 1) + self.assertEquals(int(res1[0]["userAccountControl"][0]), + UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE) + + m = Message() + m.dn = Dn(ldb, "<SID=" + ldb.get_domain_sid() + "-" + str(DOMAIN_RID_ADMINS) + ">") + m["member"] = MessageElement( + "cn=ldaptestuser2,cn=users," + self.base_dn, FLAG_MOD_ADD, "member") + ldb.modify(m) + + m = Message() + m.dn = Dn(ldb, "cn=ldaptestuser2,cn=users," + self.base_dn) + m["primaryGroupID"] = MessageElement(str(DOMAIN_RID_ADMINS), + FLAG_MOD_REPLACE, "primaryGroupID") + ldb.modify(m) + + m = Message() + m.dn = Dn(ldb, "cn=ldaptestuser2,cn=users," + self.base_dn) + m["userAccountControl"] = MessageElement( + str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD), + FLAG_MOD_REPLACE, "userAccountControl") + ldb.modify(m) + + res1 = ldb.search("cn=ldaptestuser2,cn=users," + self.base_dn, + scope=SCOPE_BASE, + attrs=["userAccountControl", "primaryGroupID"]) + self.assertTrue(len(res1) == 1) + self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0) + self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_ADMINS) + + # For a workstation account + + res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, + scope=SCOPE_BASE, + attrs=["primaryGroupID"]) + self.assertTrue(len(res1) == 1) + self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_DOMAIN_MEMBERS) + + m = Message() + m.dn = Dn(ldb, "<SID=" + ldb.get_domain_sid() + "-" + str(DOMAIN_RID_USERS) + ">") + m["member"] = MessageElement( + "cn=ldaptestcomputer,cn=computers," + self.base_dn, FLAG_MOD_ADD, "member") + ldb.modify(m) + + m = Message() + m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) + m["primaryGroupID"] = MessageElement(str(DOMAIN_RID_USERS), + FLAG_MOD_REPLACE, "primaryGroupID") + ldb.modify(m) + + m = Message() + m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) + m["userAccountControl"] = MessageElement( + str(UF_WORKSTATION_TRUST_ACCOUNT), + FLAG_MOD_REPLACE, "userAccountControl") + ldb.modify(m) + + res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, + scope=SCOPE_BASE, + attrs=["primaryGroupID"]) + self.assertTrue(len(res1) == 1) + self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_USERS) + delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) + delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn) + delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) + + def test_isCriticalSystemObject(self): + """Test the isCriticalSystemObject behaviour""" + print "Testing isCriticalSystemObject behaviour\n" + + # Add tests + + ldb.add({ + "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn, + "objectclass": "computer"}) + + res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, + scope=SCOPE_BASE, + attrs=["isCriticalSystemObject"]) + self.assertTrue(len(res1) == 1) + self.assertTrue("isCriticalSystemObject" not in res1[0]) + + delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) + + ldb.add({ + "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn, + "objectclass": "computer", + "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)}) + + res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, + scope=SCOPE_BASE, + attrs=["isCriticalSystemObject"]) + self.assertTrue(len(res1) == 1) + self.assertEquals(res1[0]["isCriticalSystemObject"][0], "FALSE") + + delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) + + ldb.add({ + "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn, + "objectclass": "computer", + "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)}) + + res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, + scope=SCOPE_BASE, + attrs=["isCriticalSystemObject"]) + self.assertTrue(len(res1) == 1) + self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE") + + delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) + + ldb.add({ + "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn, + "objectclass": "computer", + "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT)}) + + res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, + scope=SCOPE_BASE, + attrs=["isCriticalSystemObject"]) + self.assertTrue(len(res1) == 1) + self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE") + + # Modification tests + + m = Message() + m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) + m["userAccountControl"] = MessageElement(str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD), + FLAG_MOD_REPLACE, "userAccountControl") + ldb.modify(m) + + res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, + scope=SCOPE_BASE, + attrs=["isCriticalSystemObject"]) + self.assertTrue(len(res1) == 1) + self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE") + + m = Message() + m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) + m["userAccountControl"] = MessageElement(str(UF_WORKSTATION_TRUST_ACCOUNT), + FLAG_MOD_REPLACE, "userAccountControl") + ldb.modify(m) + + res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, + scope=SCOPE_BASE, + attrs=["isCriticalSystemObject"]) + self.assertTrue(len(res1) == 1) + self.assertEquals(res1[0]["isCriticalSystemObject"][0], "FALSE") + + m = Message() + m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) + m["userAccountControl"] = MessageElement( + str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT), + FLAG_MOD_REPLACE, "userAccountControl") + ldb.modify(m) + + res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, + scope=SCOPE_BASE, + attrs=["isCriticalSystemObject"]) + self.assertTrue(len(res1) == 1) + self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE") + + m = Message() + m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) + m["userAccountControl"] = MessageElement(str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD), + FLAG_MOD_REPLACE, "userAccountControl") + ldb.modify(m) + + res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, + scope=SCOPE_BASE, + attrs=["isCriticalSystemObject"]) + self.assertTrue(len(res1) == 1) + self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE") + + m = Message() + m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) + m["userAccountControl"] = MessageElement(str(UF_SERVER_TRUST_ACCOUNT), + FLAG_MOD_REPLACE, "userAccountControl") + ldb.modify(m) + + res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, + scope=SCOPE_BASE, + attrs=["isCriticalSystemObject"]) + self.assertTrue(len(res1) == 1) + self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE") + + m = Message() + m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) + m["userAccountControl"] = MessageElement(str(UF_WORKSTATION_TRUST_ACCOUNT), + FLAG_MOD_REPLACE, "userAccountControl") + ldb.modify(m) + + res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn, + scope=SCOPE_BASE, + attrs=["isCriticalSystemObject"]) + self.assertTrue(len(res1) == 1) + self.assertEquals(res1[0]["isCriticalSystemObject"][0], "FALSE") + delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn) def test_service_principal_name_updates(self): diff --git a/source4/dsdb/tests/python/token_group.py b/source4/dsdb/tests/python/token_group.py index 62bdbd5ee0..fb7654e7e0 100755 --- a/source4/dsdb/tests/python/token_group.py +++ b/source4/dsdb/tests/python/token_group.py @@ -78,7 +78,7 @@ class TokenTest(samba.tests.TestCase): res = self.ldb.search("", scope=ldb.SCOPE_BASE, attrs=["tokenGroups"]) self.assertEquals(len(res), 1) - print("Geting tokenGroups from rootDSE") + print("Getting tokenGroups from rootDSE") tokengroups = [] for sid in res[0]['tokenGroups']: tokengroups.append(str(ndr_unpack(samba.dcerpc.security.dom_sid, sid))) @@ -93,7 +93,7 @@ class TokenTest(samba.tests.TestCase): self.fail(msg="calculated groups don't match against rootDSE tokenGroups") def test_dn_tokenGroups(self): - print("Geting tokenGroups from user DN") + print("Getting tokenGroups from user DN") res = self.ldb.search(self.user_sid_dn, scope=ldb.SCOPE_BASE, attrs=["tokenGroups"]) self.assertEquals(len(res), 1) diff --git a/source4/dsdb/wscript_build b/source4/dsdb/wscript_build index 9d56e4f150..fe00059c4b 100644 --- a/source4/dsdb/wscript_build +++ b/source4/dsdb/wscript_build @@ -8,7 +8,7 @@ bld.SAMBA_LIBRARY('samdb', autoproto='samdb/samdb_proto.h', public_deps='krb5', vnum='0.0.1', - deps='ndr NDR_DRSUAPI NDR_DRSBLOBS auth_system_session LIBCLI_AUTH ndr SAMDB_SCHEMA ldbsamba samdb-common LIBCLI_DRSUAPI cli-ldap-common samba-util com_err authkrb5 credentials ldbwrap', + deps='ndr NDR_DRSUAPI NDR_DRSBLOBS auth_system_session LIBCLI_AUTH ndr SAMDB_SCHEMA ldbsamba samdb-common LIBCLI_DRSUAPI cli-ldap-common samba-util com_err authkrb5 credentials ldbwrap errors', ) diff --git a/source4/dynconfig/dynconfig.c b/source4/dynconfig/dynconfig.c deleted file mode 100644 index 65e57e0fc1..0000000000 --- a/source4/dynconfig/dynconfig.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Copyright (C) 2001 by Martin Pool <mbp@samba.org> - Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003. - Copyright (C) Stefan Metzmacher 2003 - - 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 <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" - -/** - * @file dynconfig.c - * - * @brief Global configurations, initialized to configured defaults. - * - * This file should be the only file that depends on path - * configuration (--prefix, etc), so that if ./configure is re-run, - * all programs will be appropriately updated. Everything else in - * Samba should import extern variables from here, rather than relying - * on preprocessor macros. - * - * Eventually some of these may become even more variable, so that - * they can for example consistently be set across the whole of Samba - * by command-line parameters, config file entries, or environment - * variables. - * - * @todo Perhaps eventually these should be merged into the parameter - * table? There's kind of a chicken-and-egg situation there... - **/ - -#include "dynconfig.h" - -#define DEFINE_DYN_CONFIG_PARAM(name) \ -const char *dyn_##name = name; \ -\ -bool is_default_dyn_##name(void) \ -{\ - if (strcmp(name, dyn_##name) == 0) { \ - return true; \ - } \ - return false; \ -}\ -\ -const char *get_dyn_##name(void) \ -{\ - return dyn_##name;\ -}\ -\ -const char *set_dyn_##name(const char *newpath) \ -{\ - if (newpath == NULL) { \ - return NULL; \ - } \ - if (strcmp(name, newpath) == 0) { \ - return dyn_##name; \ - } \ - newpath = strdup(newpath);\ - if (newpath == NULL) { \ - return NULL; \ - } \ - if (is_default_dyn_##name()) { \ - /* do not free a static string */ \ - } else if (dyn_##name) {\ - free(discard_const(dyn_##name)); \ - }\ - dyn_##name = newpath; \ - return dyn_##name;\ -} - -/* these are in common with s3 */ -DEFINE_DYN_CONFIG_PARAM(SBINDIR) -DEFINE_DYN_CONFIG_PARAM(BINDIR) -DEFINE_DYN_CONFIG_PARAM(SWATDIR) -DEFINE_DYN_CONFIG_PARAM(CONFIGFILE) /**< Location of smb.conf file. **/ -DEFINE_DYN_CONFIG_PARAM(LOGFILEBASE) /** Log file directory. **/ -DEFINE_DYN_CONFIG_PARAM(LMHOSTSFILE) /** Statically configured LanMan hosts. **/ -DEFINE_DYN_CONFIG_PARAM(CODEPAGEDIR) -DEFINE_DYN_CONFIG_PARAM(LIBDIR) -DEFINE_DYN_CONFIG_PARAM(MODULESDIR) -DEFINE_DYN_CONFIG_PARAM(SHLIBEXT) -DEFINE_DYN_CONFIG_PARAM(LOCKDIR) -DEFINE_DYN_CONFIG_PARAM(STATEDIR) /** Persistent state files. Default LOCKDIR */ -DEFINE_DYN_CONFIG_PARAM(CACHEDIR) /** Temporary cache files. Default LOCKDIR */ -DEFINE_DYN_CONFIG_PARAM(PIDDIR) -DEFINE_DYN_CONFIG_PARAM(NCALRPCDIR) -DEFINE_DYN_CONFIG_PARAM(SMB_PASSWD_FILE) -DEFINE_DYN_CONFIG_PARAM(PRIVATE_DIR) -DEFINE_DYN_CONFIG_PARAM(LOCALEDIR) -DEFINE_DYN_CONFIG_PARAM(NMBDSOCKETDIR) - -/* these are not in s3 */ -DEFINE_DYN_CONFIG_PARAM(DATADIR) -DEFINE_DYN_CONFIG_PARAM(SETUPDIR) -DEFINE_DYN_CONFIG_PARAM(WINBINDD_SOCKET_DIR) -DEFINE_DYN_CONFIG_PARAM(WINBINDD_PRIVILEGED_SOCKET_DIR) -DEFINE_DYN_CONFIG_PARAM(NTP_SIGND_SOCKET_DIR) -DEFINE_DYN_CONFIG_PARAM(PYTHONDIR) -DEFINE_DYN_CONFIG_PARAM(PYTHONARCHDIR) -DEFINE_DYN_CONFIG_PARAM(SCRIPTSBINDIR) diff --git a/source4/dynconfig/dynconfig.h b/source4/dynconfig/dynconfig.h deleted file mode 100644 index ee710f3de9..0000000000 --- a/source4/dynconfig/dynconfig.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Copyright (C) 2001 by Martin Pool <mbp@samba.org> - Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003. - - - 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 <http://www.gnu.org/licenses/>. -*/ - -/** - * @file dynconfig.h - * - * @brief Exported global configurations. - **/ - -#define DEFINE_DYN_CONFIG_PROTO(name) \ -extern const char *dyn_##name; \ -const char *get_dyn_##name(void); \ -const char *set_dyn_##name(const char *newpath); \ -bool is_default_dyn_##name(void); - -/* these are in common with s3 */ -DEFINE_DYN_CONFIG_PROTO(SBINDIR) -DEFINE_DYN_CONFIG_PROTO(BINDIR) -DEFINE_DYN_CONFIG_PROTO(SWATDIR) -DEFINE_DYN_CONFIG_PROTO(CONFIGFILE) /**< Location of smb.conf file. **/ -DEFINE_DYN_CONFIG_PROTO(LOGFILEBASE) /** Log file directory. **/ -DEFINE_DYN_CONFIG_PROTO(LMHOSTSFILE) /** Statically configured LanMan hosts. **/ -DEFINE_DYN_CONFIG_PROTO(CODEPAGEDIR) -DEFINE_DYN_CONFIG_PROTO(LIBDIR) -DEFINE_DYN_CONFIG_PROTO(MODULESDIR) -DEFINE_DYN_CONFIG_PROTO(SHLIBEXT) -DEFINE_DYN_CONFIG_PROTO(LOCKDIR) -DEFINE_DYN_CONFIG_PROTO(STATEDIR) /** Persistent state files. Default LOCKDIR */ -DEFINE_DYN_CONFIG_PROTO(CACHEDIR) /** Temporary cache files. Default LOCKDIR */ -DEFINE_DYN_CONFIG_PROTO(PIDDIR) -DEFINE_DYN_CONFIG_PROTO(NCALRPCDIR) -DEFINE_DYN_CONFIG_PROTO(SMB_PASSWD_FILE) -DEFINE_DYN_CONFIG_PROTO(PRIVATE_DIR) -DEFINE_DYN_CONFIG_PROTO(LOCALEDIR) -DEFINE_DYN_CONFIG_PROTO(NMBDSOCKETDIR) - -/* these are not in s3 */ -DEFINE_DYN_CONFIG_PROTO(DATADIR) -DEFINE_DYN_CONFIG_PROTO(SETUPDIR) -DEFINE_DYN_CONFIG_PROTO(WINBINDD_SOCKET_DIR) -DEFINE_DYN_CONFIG_PROTO(WINBINDD_PRIVILEGED_SOCKET_DIR) -DEFINE_DYN_CONFIG_PROTO(NTP_SIGND_SOCKET_DIR) -DEFINE_DYN_CONFIG_PROTO(PYTHONDIR) -DEFINE_DYN_CONFIG_PROTO(PYTHONARCHDIR) -DEFINE_DYN_CONFIG_PROTO(SCRIPTSBINDIR) diff --git a/source4/dynconfig/wscript b/source4/dynconfig/wscript deleted file mode 100755 index f815e81a2d..0000000000 --- a/source4/dynconfig/wscript +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/env python - -import string, Utils, Options, sys, Build, os, intltool -from samba_utils import EXPAND_VARIABLES, os_path_relpath - -# list of directory options to offer in configure -dir_options = { - 'with-piddir' : [ '${PREFIX}/var/run', 'where to put pid files' ], - 'with-privatedir' : [ '${PREFIX}/private', 'Where to put sam.ldb and other private files' ], - 'with-winbindd-socket-dir' : [ '${PREFIX}/var/lib/winbindd', 'winbind socket directory' ], - 'with-winbindd-privileged-socket-dir' : [ '${PREFIX}/var/lib/winbindd_privileged', 'winbind privileged socket directory'], - 'with-ntp-signd-socket-dir' : [ '${PREFIX}/var/run/ntp_signd', 'NTP signed directory'], - 'with-lockdir' : [ '${PREFIX}/var/locks', 'where to put lock files' ] - } - -# list of cflags to use for dynconfig.c -dyn_cflags = { - 'BINDIR' : '${BINDIR}', - 'SBINDIR' : '${SBINDIR}', - 'SCRIPTSBINDIR' : '${SBINDIR}', - 'CONFIGDIR' : '${SYSCONFDIR}', - 'CONFIGFILE' : '${SYSCONFDIR}/smb.conf', - 'LMHOSTSFILE' : '${SYSCONFDIR}/lmhosts', - 'PRIVATE_DIR' : '${PRIVATEDIR}', - 'LOGFILEBASE' : '${LOCALSTATEDIR}', - 'LOCKDIR' : '${LOCALSTATEDIR}/locks', - 'PIDDIR' : '${LOCALSTATEDIR}/run', - 'DATADIR' : '${DATADIR}', - 'LOCALEDIR' : '${LOCALEDIR}', - 'SETUPDIR' : '${DATADIR}/setup', - 'WINBINDD_SOCKET_DIR' : '${WINBINDD_SOCKET_DIR}', - 'WINBINDD_PRIVILEGED_SOCKET_DIR' : '${WINBINDD_PRIVILEGED_SOCKET_DIR}', - 'NTP_SIGND_SOCKET_DIR' : '${NTP_SIGND_SOCKET_DIR}', - 'NCALRPCDIR' : '${LOCALSTATEDIR}/ncalrpc', - 'PYTHONDIR' : '${PYTHONDIR}', - 'PYTHONARCHDIR' : '${PYTHONARCHDIR}', - 'MODULESDIR' : '${PREFIX}/modules', - 'INCLUDEDIR' : '${PREFIX}/include', - 'PKGCONFIGDIR' : '${LIBDIR}/pkgconfig', - 'SWATDIR' : '${DATADIR}/swat', - 'CODEPAGEDIR' : '${LIBDIR}/samba', - 'LIBDIR' : '${LIBDIR}', - 'LIBEXECDIR' : '${MODULESDIR}', - 'STATEDIR' : '${LOCALSTATEDIR}', - 'CACHEDIR' : '${LOCKDIR}', - 'SMB_PASSWD_FILE' : '${PRIVATEDIR}/smbpasswd', - 'NMBDSOCKETDIR' : '${LOCALSTATEDIR}/nmbd', - } - -# changes for when FHS is enabled -dyn_cflags_fhs = { - 'BINDIR' : '${BINDIR}', - 'SBINDIR' : '${SBINDIR}', - 'SCRIPTSBINDIR' : '${SBINDIR}', - 'CONFIGDIR' : '${SYSCONFDIR}/samba', - 'CONFIGFILE' : '${SYSCONFDIR}/samba/smb.conf', - 'LMHOSTSFILE' : '${SYSCONFDIR}/samba/lmhosts', - 'PRIVATE_DIR' : '${LOCALSTATEDIR}/lib/samba/private', - 'LOGFILEBASE' : '${LOCALSTATEDIR}/log/samba', - 'LOCKDIR' : '${LOCALSTATEDIR}/lib/samba', - 'PIDDIR' : '${LOCALSTATEDIR}/run/samba', - 'SETUPDIR' : '${DATADIR}/samba/setup', - 'WINBINDD_SOCKET_DIR' : '${LOCALSTATEDIR}/run/samba/winbindd', - 'WINBINDD_PRIVILEGED_SOCKET_DIR' : '${LOCALSTATEDIR}/run/samba/winbindd_privileged', - 'NTP_SIGND_SOCKET_DIR' : '${LOCALSTATEDIR}/run/samba/ntp_signd', - 'NCALRPCDIR' : '${LOCALSTATEDIR}/run/samba/ncalrpc', - 'PYTHONARCHDIR' : '${PYTHONARCHDIR}', - 'MODULESDIR' : '${LIBDIR}/samba', - 'LIBEXECDIR' : '${MODULESDIR}', - 'INCLUDEDIR' : '${INCLUDEDIR}/samba-4.0', - 'PKGCONFIGDIR' : '${LIBDIR}/pkgconfig', - 'SWATDIR' : '${DATADIR}/swat', - 'CODEPAGEDIR' : '${DATADIR}/samba', - 'NMBDSOCKETDIR' : '${LOCALSTATEDIR}/run/samba/nmbd', - } - -def get_varname(v): - '''work out a variable name from a configure option name''' - if v.startswith('with-'): - v = v[5:] - v = v.upper() - v = v.replace('-', '_') - return v - - -def set_options(opt): - # get all the basic GNU options from the gnu_dirs tool - opt.add_option('--enable-fhs', - help=("Use FHS-compliant paths (default no)"), - action="store_true", dest='ENABLE_FHS', default=False) - for option in dir_options.keys(): - default = dir_options[option][0] - help = dir_options[option][1] - varname = get_varname(option) - opt.add_option('--%s' % option, - help=(help + ' [%s]' % default), - action="store", dest=varname, default=default) - -def configure(conf): - # get all the basic GNU options from the gnu_dirs tool - for option in dir_options.keys(): - varname = get_varname(option) - value = getattr(Options.options, varname, None) - conf.ASSERT(value is not None, "Missing configure option %s" % varname) - conf.ASSERT(varname not in conf.env, "Variable %s already defined" % varname) - conf.env[varname] = value - - for f in dyn_cflags.keys(): - v = EXPAND_VARIABLES(conf, dyn_cflags[f]) - conf.ASSERT(v != '', "Empty dynconfig value for %s" % f) - conf.env[f] = v - - if Options.options.ENABLE_FHS: - for f in dyn_cflags_fhs.keys(): - v = EXPAND_VARIABLES(conf, dyn_cflags_fhs[f]) - conf.ASSERT(v != '', "Empty dynconfig value for %s" % f) - conf.env[f] = v - - if (not Options.options.ENABLE_FHS and - (conf.env.PREFIX == '/usr' or conf.env.PREFIX == '/usr/local')): - print("ERROR: Don't install directly under /usr or /usr/local without using the FHS option (--enable-fhs)") - sys.exit(1) - - -def dynconfig_cflags(bld, list=None): - '''work out the extra CFLAGS for dynconfig.c''' - cflags = [] - # override some paths when running from the build directory - override = { 'MODULESDIR' : 'bin/modules', - 'PYTHONDIR' : 'bin/python', - 'PYTHONARCHDIR' : 'bin/python', - 'CODEPAGEDIR' : os.path.join(bld.env.srcdir, 'codepages'), - 'SCRIPTSBINDIR' : os.path.join(bld.env.srcdir, 'source4/scripting/bin'), - 'SETUPDIR' : os.path.join(bld.env.srcdir, 'source4/setup') } - for f in dyn_cflags.keys(): - if list and not f in list: - continue - value = bld.env[f] - if not Options.is_install: - if f in override: - value = os.path.join(os.getcwd(), override[f]) - cflags.append('-D%s="%s"' % (f, value)) - return cflags -Build.BuildContext.dynconfig_cflags = dynconfig_cflags - -def build(bld): - cflags = bld.dynconfig_cflags() - bld.SAMBA_SUBSYSTEM('DYNCONFIG', - 'dynconfig.c', - deps='replace talloc', - public_headers=os_path_relpath(os.path.join(Options.launch_dir, 'version.h'), bld.curdir), - header_path='samba', - cflags=cflags) diff --git a/source4/echo_server/echo_server.c b/source4/echo_server/echo_server.c index 4be6f21af8..60729d8535 100644 --- a/source4/echo_server/echo_server.c +++ b/source4/echo_server/echo_server.c @@ -25,7 +25,7 @@ #include "param/param.h" /* This defines task_server_terminate */ #include "smbd/process_model.h" -/* We get load_interfaces from here */ +/* We get load_interface_list from here */ #include "socket/netif.h" /* NTSTATUS-related stuff */ #include "libcli/util/ntstatus.h" @@ -197,7 +197,7 @@ static NTSTATUS echo_add_socket(struct echo_server *echo, address, port, &echo_socket->local_address); if (ret != 0) { - status = map_nt_error_from_unix(errno); + status = map_nt_error_from_unix_common(errno); return status; } @@ -212,7 +212,7 @@ static NTSTATUS echo_add_socket(struct echo_server *echo, echo_udp_socket, &echo_udp_socket->dgram); if (ret != 0) { - status = map_nt_error_from_unix(errno); + status = map_nt_error_from_unix_common(errno); DEBUG(0, ("Failed to bind to %s:%u UDP - %s\n", address, port, nt_errstr(status))); return status; @@ -269,10 +269,10 @@ static NTSTATUS echo_startup_interfaces(struct echo_server *echo, return NT_STATUS_INTERNAL_ERROR; } - num_interfaces = iface_count(ifaces); + num_interfaces = iface_list_count(ifaces); for(i=0; i<num_interfaces; i++) { - const char *address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i)); + const char *address = talloc_strdup(tmp_ctx, iface_list_n_ip(ifaces, i)); status = echo_add_socket(echo, model_ops, "echo", address, ECHO_SERVICE_PORT); NT_STATUS_NOT_OK_RETURN(status); @@ -308,9 +308,9 @@ static void echo_task_init(struct task_server *task) break; } - load_interfaces(task, lpcfg_interfaces(task->lp_ctx), &ifaces); + load_interface_list(task, task->lp_ctx, &ifaces); - if (iface_count(ifaces) == 0) { + if (iface_list_count(ifaces) == 0) { task_server_terminate(task, "echo: No network interfaces configured", false); diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c index 037934f2a6..66170cb29f 100644 --- a/source4/heimdal/kdc/krb5tgs.c +++ b/source4/heimdal/kdc/krb5tgs.c @@ -282,8 +282,9 @@ check_PAC(krb5_context context, hdb_entry_ex *client, hdb_entry_ex *server, hdb_entry_ex *krbtgt, - const EncryptionKey *server_key, + const EncryptionKey *server_check_key, const EncryptionKey *krbtgt_check_key, + const EncryptionKey *server_sign_key, const EncryptionKey *krbtgt_sign_key, EncTicketPart *tkt, krb5_data *rspac, @@ -328,7 +329,7 @@ check_PAC(krb5_context context, ret = krb5_pac_verify(context, pac, tkt->authtime, client_principal, - krbtgt_check_key, NULL); + server_check_key, krbtgt_check_key); if (ret) { krb5_pac_free(context, pac); return ret; @@ -351,7 +352,7 @@ check_PAC(krb5_context context, *signedpath = 1; ret = _krb5_pac_sign(context, pac, tkt->authtime, client_principal, - server_key, krbtgt_sign_key, rspac); + server_sign_key, krbtgt_sign_key, rspac); } krb5_pac_free(context, pac); @@ -1464,10 +1465,9 @@ tgs_build_reply(krb5_context context, const struct sockaddr *from_addr) { krb5_error_code ret; - krb5_principal cp = NULL, sp = NULL; - krb5_principal client_principal = NULL; + krb5_principal cp = NULL, sp = NULL, tp = NULL; krb5_principal krbtgt_principal = NULL; - char *spn = NULL, *cpn = NULL; + char *spn = NULL, *cpn = NULL, *tpn = NULL; hdb_entry_ex *server = NULL, *client = NULL, *s4u2self_impersonated_client = NULL; HDB *clientdb, *s4u2self_impersonated_clientdb; krb5_realm ref_realm = NULL; @@ -1719,16 +1719,16 @@ server_lookup: krb5_free_principal(context, krbtgt_principal); if (ret) { krb5_error_code ret2; - char *tpn, *tpn2; - ret = krb5_unparse_name(context, krbtgt->entry.principal, &tpn); - ret2 = krb5_unparse_name(context, krbtgt->entry.principal, &tpn2); + char *ktpn, *ktpn2; + ret = krb5_unparse_name(context, krbtgt->entry.principal, &ktpn); + ret2 = krb5_unparse_name(context, krbtgt_principal, &ktpn2); kdc_log(context, config, 0, "Request with wrong krbtgt: %s, %s not found in our database", - (ret == 0) ? tpn : "<unknown>", (ret2 == 0) ? tpn2 : "<unknown>"); + (ret == 0) ? ktpn : "<unknown>", (ret2 == 0) ? ktpn2 : "<unknown>"); if(ret == 0) - free(tpn); + free(ktpn); if(ret2 == 0) - free(tpn2); + free(ktpn2); ret = KRB5KRB_AP_ERR_NOT_US; goto out; } @@ -1740,13 +1740,13 @@ server_lookup: * this) before the strcmp() */ if (strcmp(krb5_principal_get_realm(context, server->entry.principal), krb5_principal_get_realm(context, krbtgt_out->entry.principal)) != 0) { - char *tpn; - ret = krb5_unparse_name(context, krbtgt_out->entry.principal, &tpn); + char *ktpn; + ret = krb5_unparse_name(context, krbtgt_out->entry.principal, &ktpn); kdc_log(context, config, 0, "Request with wrong krbtgt: %s", - (ret == 0) ? tpn : "<unknown>"); + (ret == 0) ? ktpn : "<unknown>"); if(ret == 0) - free(tpn); + free(ktpn); ret = KRB5KRB_AP_ERR_NOT_US; } @@ -1789,7 +1789,9 @@ server_lookup: } ret = check_PAC(context, config, cp, - client, server, krbtgt, ekey, &tkey_check->key, &tkey_sign->key, + client, server, krbtgt, + &tkey_check->key, &tkey_check->key, + ekey, &tkey_sign->key, tgt, &rspac, &signedpath); if (ret) { const char *msg = krb5_get_error_message(context, ret); @@ -1821,7 +1823,9 @@ server_lookup: * Process request */ - client_principal = cp; + /* by default the tgt principal matches the client principal */ + tp = cp; + tpn = cpn; if (client) { const PA_DATA *sdata; @@ -1832,7 +1836,6 @@ server_lookup: krb5_crypto crypto; krb5_data datack; PA_S4U2Self self; - char *selfcpn = NULL; const char *str; ret = decode_PA_S4U2Self(sdata->padata_value.data, @@ -1875,14 +1878,14 @@ server_lookup: } ret = _krb5_principalname2krb5_principal(context, - &client_principal, + &tp, self.name, self.realm); free_PA_S4U2Self(&self); if (ret) goto out; - ret = krb5_unparse_name(context, client_principal, &selfcpn); + ret = krb5_unparse_name(context, tp, &tpn); if (ret) goto out; @@ -1890,7 +1893,7 @@ server_lookup: if(rspac.data) { krb5_pac p = NULL; krb5_data_free(&rspac); - ret = _kdc_db_fetch(context, config, client_principal, HDB_F_GET_CLIENT | HDB_F_CANON, + ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | HDB_F_CANON, NULL, &s4u2self_impersonated_clientdb, &s4u2self_impersonated_client); if (ret) { const char *msg; @@ -1904,14 +1907,16 @@ server_lookup: if (ret == HDB_ERR_NOENTRY) ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; msg = krb5_get_error_message(context, ret); - kdc_log(context, config, 1, "S2U4Self principal to impersonate %s not found in database: %s", cpn, msg); + kdc_log(context, config, 1, + "S2U4Self principal to impersonate %s not found in database: %s", + tpn, msg); krb5_free_error_message(context, msg); goto out; } ret = _kdc_pac_generate(context, s4u2self_impersonated_client, &p); if (ret) { kdc_log(context, config, 0, "PAC generation failed for -- %s", - selfcpn); + tpn); goto out; } if (p != NULL) { @@ -1922,7 +1927,7 @@ server_lookup: krb5_pac_free(context, p); if (ret) { kdc_log(context, config, 0, "PAC signing failed for -- %s", - selfcpn); + tpn); goto out; } } @@ -1937,8 +1942,7 @@ server_lookup: kdc_log(context, config, 0, "S4U2Self: %s is not allowed " "to impersonate to service " "(tried for user %s to service %s)", - cpn, selfcpn, spn); - free(selfcpn); + cpn, tpn, spn); goto out; } @@ -1954,8 +1958,7 @@ server_lookup: str = ""; } kdc_log(context, config, 0, "s4u2self %s impersonating %s to " - "service %s %s", cpn, selfcpn, spn, str); - free(selfcpn); + "service %s %s", cpn, tpn, spn, str); } } @@ -1971,7 +1974,6 @@ server_lookup: int ad_signedpath = 0; Key *clientkey; Ticket *t; - char *str; /* * Require that the KDC have issued the service's krbtgt (not @@ -2002,11 +2004,23 @@ server_lookup: goto out; } + ret = _krb5_principalname2krb5_principal(context, + &tp, + adtkt.cname, + adtkt.crealm); + if (ret) + goto out; + + ret = krb5_unparse_name(context, tp, &tpn); + if (ret) + goto out; + /* check that ticket is valid */ if (adtkt.flags.forwardable == 0) { kdc_log(context, config, 0, "Missing forwardable flag on ticket for " - "constrained delegation from %s to %s ", cpn, spn); + "constrained delegation from %s as %s to %s ", + cpn, tpn, spn); ret = KRB5KDC_ERR_BADOPTION; goto out; } @@ -2015,25 +2029,37 @@ server_lookup: client, sp); if (ret) { kdc_log(context, config, 0, - "constrained delegation from %s to %s not allowed", - cpn, spn); + "constrained delegation from %s as %s to %s not allowed", + cpn, tpn, spn); goto out; } - ret = _krb5_principalname2krb5_principal(context, - &client_principal, - adtkt.cname, - adtkt.crealm); - if (ret) - goto out; - - ret = krb5_unparse_name(context, client_principal, &str); - if (ret) + ret = verify_flags(context, config, &adtkt, tpn); + if (ret) { goto out; + } - ret = verify_flags(context, config, &adtkt, str); + krb5_data_free(&rspac); + /* + * generate the PAC for the user. + * + * TODO: pass in t->sname and t->realm and build + * a S4U_DELEGATION_INFO blob to the PAC. + */ + ret = check_PAC(context, config, tp, + client, server, krbtgt, + &clientkey->key, &tkey_check->key, + ekey, &tkey_sign->key, + &adtkt, &rspac, &ad_signedpath); + if (ret == 0 && !ad_signedpath) + ret = KRB5KDC_ERR_BADOPTION; if (ret) { - free(str); + const char *msg = krb5_get_error_message(context, ret); + kdc_log(context, config, 0, + "Verify delegated PAC failed to %s for client" + "%s as %s from %s with %s", + spn, cpn, tpn, from, msg); + krb5_free_error_message(context, msg); goto out; } @@ -2043,7 +2069,7 @@ server_lookup: ret = check_KRB5SignedPath(context, config, krbtgt, - cp, + tp, &adtkt, NULL, &ad_signedpath); @@ -2055,15 +2081,13 @@ server_lookup: "KRB5SignedPath check from service %s failed " "for delegation to %s for client %s " "from %s failed with %s", - spn, str, cpn, from, msg); + spn, tpn, cpn, from, msg); krb5_free_error_message(context, msg); - free(str); goto out; } kdc_log(context, config, 0, "constrained delegation for %s " - "from %s to %s", str, cpn, spn); - free(str); + "from %s to %s", tpn, cpn, spn); } /* @@ -2134,7 +2158,7 @@ server_lookup: ret = tgs_make_reply(context, config, b, - client_principal, + tp, tgt, replykey, rk_is_subkey, @@ -2156,6 +2180,8 @@ server_lookup: reply); out: + if (tpn != cpn) + free(tpn); free(spn); free(cpn); @@ -2170,8 +2196,8 @@ out: if(s4u2self_impersonated_client) _kdc_free_ent(context, s4u2self_impersonated_client); - if (client_principal && client_principal != cp) - krb5_free_principal(context, client_principal); + if (tp && tp != cp) + krb5_free_principal(context, tp); if (cp) krb5_free_principal(context, cp); if (sp) diff --git a/source4/heimdal/lib/roken/getprogname.c b/source4/heimdal/lib/roken/getprogname.c deleted file mode 100644 index a310208a84..0000000000 --- a/source4/heimdal/lib/roken/getprogname.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 1995-2004 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <config.h> - -#include "roken.h" - -#ifndef HAVE___PROGNAME -const char *__progname; -#endif - -#ifndef HAVE_GETPROGNAME -ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL -getprogname(void) -{ - return __progname; -} -#endif /* HAVE_GETPROGNAME */ diff --git a/source4/heimdal/lib/roken/setprogname.c b/source4/heimdal/lib/roken/setprogname.c deleted file mode 100644 index 88a5f9bb44..0000000000 --- a/source4/heimdal/lib/roken/setprogname.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 1995-2004 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <config.h> - -#include "roken.h" - -#ifndef HAVE___PROGNAME -extern const char *__progname; -#endif - -#ifndef HAVE_SETPROGNAME - -ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL -setprogname(const char *argv0) -{ - -#ifndef HAVE___PROGNAME - - const char *p; - if(argv0 == NULL) - return; - p = strrchr(argv0, '/'); - -#ifdef BACKSLASH_PATH_DELIM - { - const char * pb; - - pb = strrchr((p != NULL)? p : argv0, '\\'); - if (pb != NULL) - p = pb; - } -#endif - - if(p == NULL) - p = argv0; - else - p++; - -#ifdef _WIN32 - { - char * fn = strdup(p); - char * ext; - - strlwr(fn); - ext = strrchr(fn, '.'); - if (ext != NULL && !strcmp(ext, ".exe")) - *ext = '\0'; - - __progname = fn; - } -#else - - __progname = p; - -#endif - -#endif /* HAVE___PROGNAME */ -} - -#endif /* HAVE_SETPROGNAME */ diff --git a/source4/heimdal_build/replace.c b/source4/heimdal_build/replace.c index 51393f6e68..e6a74f9ba8 100644 --- a/source4/heimdal_build/replace.c +++ b/source4/heimdal_build/replace.c @@ -83,3 +83,20 @@ return -1; } #endif + +#ifndef HAVE_SETPROGNAME + +/* We don't want to use a setprogname reimplementation */ +void setprogname(const char *argv0) +{ +} + +#endif /* HAVE_SETPROGNAME */ + +#ifndef HAVE_GETPROGNAME +/* We don't want to use a getprogname reimplementation */ +const char *getprogname(void) +{ + return ""; +} +#endif /* HAVE_GETPROGNAME */ diff --git a/source4/heimdal_build/wscript_build b/source4/heimdal_build/wscript_build index a1bd4783b0..705caa52e2 100644 --- a/source4/heimdal_build/wscript_build +++ b/source4/heimdal_build/wscript_build @@ -400,12 +400,6 @@ if not bld.CONFIG_SET('USING_SYSTEM_ROKEN'): ../heimdal_build/replace.c ''' - if not bld.CONFIG_SET('HAVE_GETPROGNAME'): - ROKEN_HOSTCC_SOURCE += ''' - lib/roken/getprogname.c - lib/roken/setprogname.c - ''' - if not bld.CONFIG_SET('HAVE_CLOSEFROM'): ROKEN_HOSTCC_SOURCE += ''' lib/roken/closefrom.c @@ -621,6 +615,13 @@ if not bld.CONFIG_SET("USING_SYSTEM_KRB5"): version.c warn.c krb5_err.c heim_err.c k524_err.c krb_err.c''')] + ["../heimdal_build/krb5-glue.c"] + # Alias subsystem to allow common kerberos code that will + # otherwise link against MIT's gssapi_krb5 + HEIMDAL_SUBSYSTEM('gssapi_krb5', + '', + deps='gssapi' + ) + HEIMDAL_LIBRARY('krb5', KRB5_SOURCE, version_script='lib/krb5/version-script.map', includes='../heimdal/lib/krb5 ../heimdal/lib/asn1 ../heimdal/include', @@ -633,6 +634,12 @@ if not bld.CONFIG_SET("USING_SYSTEM_KRB5"): HEIMDAL_AUTOPROTO('lib/krb5/krb5-protos.h', KRB5_PROTO_SOURCE, options='-E KRB5_LIB -q -P comment -o') + # Alias subsystem to allow common kerberos code that will + # otherwise link against MIT's k5crypto + HEIMDAL_SUBSYSTEM('k5crypto', + '', + deps='krb5') + if not bld.CONFIG_SET("USING_SYSTEM_ASN1"): HEIMDAL_HEIM_ASN1_DER_SOURCE = ''' lib/asn1/der_get.c diff --git a/source4/heimdal_build/wscript_configure b/source4/heimdal_build/wscript_configure index f711fe7f28..6552d3a925 100644 --- a/source4/heimdal_build/wscript_configure +++ b/source4/heimdal_build/wscript_configure @@ -73,6 +73,7 @@ conf.DEFINE('SAMBA4_INTERNAL_HEIMDAL', 1) # setup the right defines for a in-tree heimdal build Logs.info("Using in-tree heimdal kerberos defines") conf.define('HAVE_GSSAPI_GSSAPI_H', 1) +conf.define('HAVE_GSSAPI_GSSAPI_KRB5_H', 1) conf.define('HAVE_AP_OPTS_USE_SUBKEY', 1) conf.define('HAVE_KRB5_ADDRESSES', 1) conf.define('HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK', 1) @@ -82,6 +83,8 @@ conf.define('HAVE_ADDR_TYPE_IN_KRB5_ADDRESS', 1) conf.define('HAVE_GSS_DISPLAY_STATUS', 1) conf.define('HAVE_GSS_WRAP_IOV', 1) conf.define('HAVE_GSS_KRB5_IMPORT_CRED', 1) +conf.define('HAVE_GSS_OID_EQUAL', 1) +conf.define('HAVE_GSS_INQUIRE_SEC_CONTEXT_BY_OID', 1) conf.define('HAVE_GSSKRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT', 1) conf.define('HAVE_LIBGSSAPI', 1) conf.define('HAVE_ADDR_TYPE_IN_KRB5_ADDRESS', 1) diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c index 732e553ca3..72262ac18b 100644 --- a/source4/kdc/db-glue.c +++ b/source4/kdc/db-glue.c @@ -159,6 +159,20 @@ static HDBFlags uf2HDBFlags(krb5_context context, uint32_t userAccountControl, e if (userAccountControl & UF_TRUSTED_FOR_DELEGATION) { flags.ok_as_delegate = 1; } + if (userAccountControl & UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION) { + /* + * this is confusing... + * + * UF_TRUSTED_FOR_DELEGATION + * => ok_as_delegate + * + * and + * + * UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION + * => trusted_for_delegation + */ + flags.trusted_for_delegation = 1; + } if (!(userAccountControl & UF_NOT_DELEGATED)) { flags.forwardable = 1; flags.proxiable = 1; @@ -1521,14 +1535,12 @@ krb5_error_code samba_kdc_nextkey(krb5_context context, /* Check if a given entry may delegate or do s4u2self to this target principal * * This is currently a very nasty hack - allowing only delegation to itself. - * - * This is shared between the constrained delegation and S4U2Self code. */ krb5_error_code -samba_kdc_check_identical_client_and_server(krb5_context context, - struct samba_kdc_db_context *kdc_db_ctx, - hdb_entry_ex *entry, - krb5_const_principal target_principal) +samba_kdc_check_s4u2self(krb5_context context, + struct samba_kdc_db_context *kdc_db_ctx, + hdb_entry_ex *entry, + krb5_const_principal target_principal) { krb5_error_code ret; krb5_principal enterprise_prinicpal = NULL; @@ -1541,11 +1553,11 @@ samba_kdc_check_identical_client_and_server(krb5_context context, "objectSid", NULL }; - TALLOC_CTX *mem_ctx = talloc_named(kdc_db_ctx, 0, "samba_kdc_check_constrained_delegation"); + TALLOC_CTX *mem_ctx = talloc_named(kdc_db_ctx, 0, "samba_kdc_check_s4u2self"); if (!mem_ctx) { ret = ENOMEM; - krb5_set_error_message(context, ret, "samba_kdc_fetch: talloc_named() failed!"); + krb5_set_error_message(context, ret, "samba_kdc_check_s4u2self: talloc_named() failed!"); return ret; } @@ -1553,7 +1565,7 @@ samba_kdc_check_identical_client_and_server(krb5_context context, /* Need to reparse the enterprise principal to find the real target */ if (target_principal->name.name_string.len != 1) { ret = KRB5_PARSE_MALFORMED; - krb5_set_error_message(context, ret, "samba_kdc_check_constrained_delegation: request for delegation to enterprise principal with wrong (%d) number of components", + krb5_set_error_message(context, ret, "samba_kdc_check_s4u2self: request for delegation to enterprise principal with wrong (%d) number of components", target_principal->name.name_string.len); talloc_free(mem_ctx); return ret; @@ -1645,6 +1657,19 @@ samba_kdc_check_pkinit_ms_upn_match(krb5_context context, return ret; } +/* + * Check if a given entry may delegate to this target principal + * with S4U2Proxy. + */ +krb5_error_code +samba_kdc_check_s4u2proxy(krb5_context context, + struct samba_kdc_db_context *kdc_db_ctx, + hdb_entry_ex *entry, + krb5_const_principal target_principal) +{ + return KRB5KDC_ERR_BADOPTION; +} + NTSTATUS samba_kdc_setup_db_ctx(TALLOC_CTX *mem_ctx, struct samba_kdc_base_context *base_ctx, struct samba_kdc_db_context **kdc_db_ctx_out) { diff --git a/source4/kdc/db-glue.h b/source4/kdc/db-glue.h index 4f1e06fa7a..18d2c07de6 100644 --- a/source4/kdc/db-glue.h +++ b/source4/kdc/db-glue.h @@ -37,10 +37,10 @@ krb5_error_code samba_kdc_nextkey(krb5_context context, hdb_entry_ex *entry); krb5_error_code -samba_kdc_check_identical_client_and_server(krb5_context context, - struct samba_kdc_db_context *kdc_db_ctx, - hdb_entry_ex *entry, - krb5_const_principal target_principal); +samba_kdc_check_s4u2self(krb5_context context, + struct samba_kdc_db_context *kdc_db_ctx, + hdb_entry_ex *entry, + krb5_const_principal target_principal); krb5_error_code samba_kdc_check_pkinit_ms_upn_match(krb5_context context, @@ -48,5 +48,11 @@ samba_kdc_check_pkinit_ms_upn_match(krb5_context context, hdb_entry_ex *entry, krb5_const_principal certificate_principal); +krb5_error_code +samba_kdc_check_s4u2proxy(krb5_context context, + struct samba_kdc_db_context *kdc_db_ctx, + hdb_entry_ex *entry, + krb5_const_principal target_principal); + NTSTATUS samba_kdc_setup_db_ctx(TALLOC_CTX *mem_ctx, struct samba_kdc_base_context *base_ctx, struct samba_kdc_db_context **kdc_db_ctx_out); diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c index 8511b2f27b..f82712e2b2 100644 --- a/source4/kdc/hdb-samba4.c +++ b/source4/kdc/hdb-samba4.c @@ -121,7 +121,7 @@ static krb5_error_code hdb_samba4_destroy(krb5_context context, HDB *db) } static krb5_error_code -hdb_samba4_check_identical_client_and_server(krb5_context context, HDB *db, +hdb_samba4_check_constrained_delegation(krb5_context context, HDB *db, hdb_entry_ex *entry, krb5_const_principal target_principal) { @@ -130,9 +130,9 @@ hdb_samba4_check_identical_client_and_server(krb5_context context, HDB *db, kdc_db_ctx = talloc_get_type_abort(db->hdb_db, struct samba_kdc_db_context); - return samba_kdc_check_identical_client_and_server(context, kdc_db_ctx, - entry, - target_principal); + return samba_kdc_check_s4u2proxy(context, kdc_db_ctx, + entry, + target_principal); } static krb5_error_code @@ -150,6 +150,21 @@ hdb_samba4_check_pkinit_ms_upn_match(krb5_context context, HDB *db, certificate_principal); } +static krb5_error_code +hdb_samba4_check_s4u2self(krb5_context context, HDB *db, + hdb_entry_ex *entry, + krb5_const_principal target_principal) +{ + struct samba_kdc_db_context *kdc_db_ctx; + + kdc_db_ctx = talloc_get_type_abort(db->hdb_db, + struct samba_kdc_db_context); + + return samba_kdc_check_s4u2self(context, kdc_db_ctx, + entry, + target_principal); +} + /* This interface is to be called by the KDC and libnet_keytab_dump, * which is expecting Samba calling conventions. * It is also called by a wrapper (hdb_samba4_create) from the @@ -197,9 +212,9 @@ NTSTATUS hdb_samba4_create_kdc(struct samba_kdc_base_context *base_ctx, (*db)->hdb_destroy = hdb_samba4_destroy; (*db)->hdb_auth_status = NULL; - (*db)->hdb_check_constrained_delegation = hdb_samba4_check_identical_client_and_server; + (*db)->hdb_check_constrained_delegation = hdb_samba4_check_constrained_delegation; (*db)->hdb_check_pkinit_ms_upn_match = hdb_samba4_check_pkinit_ms_upn_match; - (*db)->hdb_check_s4u2self = hdb_samba4_check_identical_client_and_server; + (*db)->hdb_check_s4u2self = hdb_samba4_check_s4u2self; return NT_STATUS_OK; } diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c index 784b98b072..0723408043 100644 --- a/source4/kdc/kdc.c +++ b/source4/kdc/kdc.c @@ -654,7 +654,7 @@ static NTSTATUS kdc_add_socket(struct kdc_server *kdc, address, port, &kdc_socket->local_address); if (ret != 0) { - status = map_nt_error_from_unix(errno); + status = map_nt_error_from_unix_common(errno); return status; } @@ -685,7 +685,7 @@ static NTSTATUS kdc_add_socket(struct kdc_server *kdc, kdc_udp_socket, &kdc_udp_socket->dgram); if (ret != 0) { - status = map_nt_error_from_unix(errno); + status = map_nt_error_from_unix_common(errno); DEBUG(0,("Failed to bind to %s:%u UDP - %s\n", address, port, nt_errstr(status))); return status; @@ -729,29 +729,34 @@ static NTSTATUS kdc_startup_interfaces(struct kdc_server *kdc, struct loadparm_c return NT_STATUS_INTERNAL_ERROR; } - num_interfaces = iface_count(ifaces); + num_interfaces = iface_list_count(ifaces); /* if we are allowing incoming packets from any address, then we need to bind to the wildcard address */ if (!lpcfg_bind_interfaces_only(lp_ctx)) { - if (kdc_port) { - status = kdc_add_socket(kdc, model_ops, - "kdc", "0.0.0.0", kdc_port, - kdc_process, false); - NT_STATUS_NOT_OK_RETURN(status); - } - - if (kpasswd_port) { - status = kdc_add_socket(kdc, model_ops, - "kpasswd", "0.0.0.0", kpasswd_port, - kpasswdd_process, false); - NT_STATUS_NOT_OK_RETURN(status); + const char **wcard = iface_list_wildcard(kdc, lp_ctx); + NT_STATUS_HAVE_NO_MEMORY(wcard); + for (i=0; wcard[i]; i++) { + if (kdc_port) { + status = kdc_add_socket(kdc, model_ops, + "kdc", wcard[i], kdc_port, + kdc_process, false); + NT_STATUS_NOT_OK_RETURN(status); + } + + if (kpasswd_port) { + status = kdc_add_socket(kdc, model_ops, + "kpasswd", wcard[i], kpasswd_port, + kpasswdd_process, false); + NT_STATUS_NOT_OK_RETURN(status); + } } + talloc_free(wcard); done_wildcard = true; } for (i=0; i<num_interfaces; i++) { - const char *address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i)); + const char *address = talloc_strdup(tmp_ctx, iface_list_n_ip(ifaces, i)); if (kdc_port) { status = kdc_add_socket(kdc, model_ops, @@ -895,9 +900,9 @@ static void kdc_task_init(struct task_server *task) break; } - load_interfaces(task, lpcfg_interfaces(task->lp_ctx), &ifaces); + load_interface_list(task, task->lp_ctx, &ifaces); - if (iface_count(ifaces) == 0) { + if (iface_list_count(ifaces) == 0) { task_server_terminate(task, "kdc: no network interfaces configured", false); return; } diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c index dcabe39db6..50b5d1d292 100644 --- a/source4/kdc/mit_samba.c +++ b/source4/kdc/mit_samba.c @@ -330,10 +330,10 @@ static int mit_samba_check_s4u2proxy(struct mit_samba_context *ctx, return ret; } - ret = samba_kdc_check_identical_client_and_server(ctx->context, - ctx->db_ctx, - entry, - target_principal); + ret = samba_kdc_check_s4u2proxy(ctx->context, + ctx->db_ctx, + entry, + target_principal); krb5_free_principal(ctx->context, target_principal); diff --git a/source4/kdc/proxy.c b/source4/kdc/proxy.c index 98db956f65..324bfb8e2e 100644 --- a/source4/kdc/proxy.c +++ b/source4/kdc/proxy.c @@ -556,7 +556,7 @@ static void kdc_tcp_proxy_read_pdu_done(struct tevent_req *subreq) */ state->out = data_blob_talloc(state, raw.data + 4, raw.length - 4); if (state->out.length != raw.length - 4) { - tevent_req_nomem(NULL, req); + tevent_req_oom(req); return; } diff --git a/source4/ldap_server/ldap_extended.c b/source4/ldap_server/ldap_extended.c index f70b8084d7..5cfa2d3b16 100644 --- a/source4/ldap_server/ldap_extended.c +++ b/source4/ldap_server/ldap_extended.c @@ -82,7 +82,7 @@ static void ldapsrv_starttls_postprocess_done(struct tevent_req *subreq) conn, &conn->sockets.tls); TALLOC_FREE(subreq); if (ret == -1) { - NTSTATUS status = map_nt_error_from_unix(sys_errno); + NTSTATUS status = map_nt_error_from_unix_common(sys_errno); DEBUG(1,("ldapsrv_starttls_postprocess_done: accept_tls_loop: " "tstream_tls_accept_recv() - %d:%s => %s", diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index adcf7bc71d..411be29440 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -708,7 +708,7 @@ static struct tevent_req *ldapsrv_process_call_send(TALLOC_CTX *mem_ctx, ok = tevent_queue_add(call_queue, ev, req, ldapsrv_process_call_trigger, NULL); if (!ok) { - tevent_req_nomem(NULL, req); + tevent_req_oom(req); return tevent_req_post(req, ev); } @@ -815,7 +815,7 @@ static NTSTATUS add_socket(struct task_server *task, status = stream_setup_socket(task, task->event_ctx, lp_ctx, model_ops, &ldap_stream_nonpriv_ops, - "ipv4", address, &port, + "ip", address, &port, lpcfg_socket_options(lp_ctx), ldap_service); if (!NT_STATUS_IS_OK(status)) { @@ -830,7 +830,7 @@ static NTSTATUS add_socket(struct task_server *task, status = stream_setup_socket(task, task->event_ctx, lp_ctx, model_ops, &ldap_stream_nonpriv_ops, - "ipv4", address, &port, + "ip", address, &port, lpcfg_socket_options(lp_ctx), ldap_service); if (!NT_STATUS_IS_OK(status)) { @@ -852,7 +852,7 @@ static NTSTATUS add_socket(struct task_server *task, status = stream_setup_socket(task, task->event_ctx, lp_ctx, model_ops, &ldap_stream_nonpriv_ops, - "ipv4", address, &port, + "ip", address, &port, lpcfg_socket_options(lp_ctx), ldap_service); if (!NT_STATUS_IS_OK(status)) { @@ -866,7 +866,7 @@ static NTSTATUS add_socket(struct task_server *task, status = stream_setup_socket(task, task->event_ctx, lp_ctx, model_ops, &ldap_stream_nonpriv_ops, - "ipv4", address, &port, + "ip", address, &port, lpcfg_socket_options(lp_ctx), ldap_service); if (!NT_STATUS_IS_OK(status)) { @@ -951,25 +951,34 @@ static void ldapsrv_task_init(struct task_server *task) int num_interfaces; int i; - load_interfaces(task, lpcfg_interfaces(task->lp_ctx), &ifaces); - num_interfaces = iface_count(ifaces); + load_interface_list(task, task->lp_ctx, &ifaces); + num_interfaces = iface_list_count(ifaces); /* We have been given an interfaces line, and been told to only bind to those interfaces. Create a socket per interface and bind to only these. */ for(i = 0; i < num_interfaces; i++) { - const char *address = iface_n_ip(ifaces, i); + const char *address = iface_list_n_ip(ifaces, i); status = add_socket(task, task->lp_ctx, model_ops, address, ldap_service); if (!NT_STATUS_IS_OK(status)) goto failed; } } else { - status = add_socket(task, task->lp_ctx, model_ops, - lpcfg_socket_address(task->lp_ctx), ldap_service); - if (!NT_STATUS_IS_OK(status)) goto failed; + const char **wcard; + int i; + wcard = iface_list_wildcard(task, task->lp_ctx); + if (wcard == NULL) { + DEBUG(0,("No wildcard addresses available\n")); + goto failed; + } + for (i=0; wcard[i]; i++) { + status = add_socket(task, task->lp_ctx, model_ops, wcard[i], ldap_service); + if (!NT_STATUS_IS_OK(status)) goto failed; + } + talloc_free(wcard); } - ldapi_path = private_path(ldap_service, task->lp_ctx, "ldapi"); + ldapi_path = lpcfg_private_path(ldap_service, task->lp_ctx, "ldapi"); if (!ldapi_path) { goto failed; } @@ -986,7 +995,7 @@ static void ldapsrv_task_init(struct task_server *task) } #ifdef WITH_LDAPI_PRIV_SOCKET - priv_dir = private_path(ldap_service, task->lp_ctx, "ldap_priv"); + priv_dir = lpcfg_private_path(ldap_service, task->lp_ctx, "ldap_priv"); if (priv_dir == NULL) { goto failed; } diff --git a/source4/lib/cmdline/popt_common.c b/source4/lib/cmdline/popt_common.c index 16c6a1b81b..af1e900092 100644 --- a/source4/lib/cmdline/popt_common.c +++ b/source4/lib/cmdline/popt_common.c @@ -186,7 +186,7 @@ static void popt_common_callback(poptContext con, } } -struct poptOption popt_common_connection[] = { +struct poptOption popt_common_connection4[] = { { NULL, 0, POPT_ARG_CALLBACK, (void *)popt_common_callback }, { "name-resolve", 'R', POPT_ARG_STRING, NULL, 'R', "Use these name resolution services only", "NAME-RESOLVE-ORDER" }, { "socket-options", 'O', POPT_ARG_STRING, NULL, 'O', "socket options to use", "SOCKETOPTIONS" }, @@ -199,7 +199,7 @@ struct poptOption popt_common_connection[] = { { NULL } }; -struct poptOption popt_common_samba[] = { +struct poptOption popt_common_samba4[] = { { NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST, (void *)popt_samba_callback }, { "debuglevel", 'd', POPT_ARG_STRING, NULL, 'd', "Set debug level", "DEBUGLEVEL" }, { "debug-stderr", 0, POPT_ARG_NONE, NULL, OPT_DEBUG_STDERR, "Send debug output to STDERR", NULL }, @@ -211,7 +211,7 @@ struct poptOption popt_common_samba[] = { { NULL } }; -struct poptOption popt_common_version[] = { +struct poptOption popt_common_version4[] = { { NULL, 0, POPT_ARG_CALLBACK, (void *)popt_version_callback }, { "version", 'V', POPT_ARG_NONE, NULL, 'V', "Print version" }, { NULL } diff --git a/source4/lib/cmdline/popt_common.h b/source4/lib/cmdline/popt_common.h index 2f4ab2c178..8aed4d0496 100644 --- a/source4/lib/cmdline/popt_common.h +++ b/source4/lib/cmdline/popt_common.h @@ -23,19 +23,19 @@ #include <popt.h> /* Common popt structures */ -extern struct poptOption popt_common_samba[]; -extern struct poptOption popt_common_connection[]; -extern struct poptOption popt_common_version[]; -extern struct poptOption popt_common_credentials[]; +extern struct poptOption popt_common_samba4[]; +extern struct poptOption popt_common_connection4[]; +extern struct poptOption popt_common_version4[]; +extern struct poptOption popt_common_credentials4[]; #ifndef POPT_TABLEEND #define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL } #endif -#define POPT_COMMON_SAMBA { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_samba, 0, "Common samba options:", NULL }, -#define POPT_COMMON_CONNECTION { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_connection, 0, "Connection options:", NULL }, -#define POPT_COMMON_VERSION { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_version, 0, "Common samba options:", NULL }, -#define POPT_COMMON_CREDENTIALS { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_credentials, 0, "Authentication options:", NULL }, +#define POPT_COMMON_SAMBA { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_samba4, 0, "Common samba options:", NULL }, +#define POPT_COMMON_CONNECTION { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_connection4, 0, "Connection options:", NULL }, +#define POPT_COMMON_VERSION { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_version4, 0, "Common samba options:", NULL }, +#define POPT_COMMON_CREDENTIALS { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_credentials4, 0, "Authentication options:", NULL }, extern struct cli_credentials *cmdline_credentials; extern struct loadparm_context *cmdline_lp_ctx; diff --git a/source4/lib/cmdline/popt_credentials.c b/source4/lib/cmdline/popt_credentials.c index 6dcef3f22b..497d2a7228 100644 --- a/source4/lib/cmdline/popt_credentials.c +++ b/source4/lib/cmdline/popt_credentials.c @@ -168,7 +168,7 @@ static void popt_common_credentials_callback(poptContext con, -struct poptOption popt_common_credentials[] = { +struct poptOption popt_common_credentials4[] = { { NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST, (void *)popt_common_credentials_callback }, { "user", 'U', POPT_ARG_STRING, NULL, 'U', "Set the network username", "[DOMAIN/]USERNAME[%PASSWORD]" }, { "no-pass", 'N', POPT_ARG_NONE, &dont_ask, 'N', "Don't ask for a password" }, diff --git a/source4/lib/events/events.h b/source4/lib/events/events.h index f66698838d..546a5e5158 100644 --- a/source4/lib/events/events.h +++ b/source4/lib/events/events.h @@ -1,6 +1,8 @@ #ifndef __LIB_EVENTS_H__ #define __LIB_EVENTS_H__ +#ifndef TEVENT_COMPAT_DEFINES #define TEVENT_COMPAT_DEFINES 1 +#endif #include <tevent.h> struct tevent_context *s4_event_context_init(TALLOC_CTX *mem_ctx); struct tevent_context *event_context_find(TALLOC_CTX *mem_ctx) _DEPRECATED_; diff --git a/source4/lib/ldb-samba/ldb_wrap.c b/source4/lib/ldb-samba/ldb_wrap.c index 7dcf514e23..66213bf288 100644 --- a/source4/lib/ldb-samba/ldb_wrap.c +++ b/source4/lib/ldb-samba/ldb_wrap.c @@ -35,7 +35,7 @@ #include "dsdb/samdb/samdb.h" #include "param/param.h" #include "../lib/util/dlinklist.h" -#include <tdb.h> +#include "../lib/tdb_compat/tdb_compat.h" /* this is used to catch debug messages from ldb @@ -126,10 +126,7 @@ char *wrap_casefold(void *context, void *mem_ctx, const char *s, size_t n) return NULL; } - ldb_set_modules_dir(ldb, - talloc_asprintf(ldb, - "%s/ldb", - lpcfg_modulesdir(lp_ctx))); + ldb_set_modules_dir(ldb, modules_path(ldb, "ldb")); ldb_set_debug(ldb, ldb_wrap_debug, NULL); @@ -177,7 +174,7 @@ char *wrap_casefold(void *context, void *mem_ctx, const char *s, size_t n) struct loadparm_context *lp_ctx, struct auth_session_info *session_info, struct cli_credentials *credentials, - int flags) + unsigned int flags) { struct ldb_wrap *w; /* see if we can re-use an existing ldb */ @@ -195,7 +192,7 @@ char *wrap_casefold(void *context, void *mem_ctx, const char *s, size_t n) } int samba_ldb_connect(struct ldb_context *ldb, struct loadparm_context *lp_ctx, - const char *url, int flags) + const char *url, unsigned int flags) { int ret; char *real_url = NULL; @@ -209,7 +206,7 @@ int samba_ldb_connect(struct ldb_context *ldb, struct loadparm_context *lp_ctx, flags |= LDB_FLG_ENABLE_TRACING; } - real_url = private_path(ldb, lp_ctx, url); + real_url = lpcfg_private_path(ldb, lp_ctx, url); if (real_url == NULL) { return LDB_ERR_OPERATIONS_ERROR; } @@ -230,7 +227,7 @@ int samba_ldb_connect(struct ldb_context *ldb, struct loadparm_context *lp_ctx, struct loadparm_context *lp_ctx, struct auth_session_info *session_info, struct cli_credentials *credentials, - int flags, + unsigned int flags, struct ldb_context *ldb) { struct ldb_wrap *w; diff --git a/source4/lib/ldb-samba/ldb_wrap.h b/source4/lib/ldb-samba/ldb_wrap.h index 4d2539fff5..aa7ccb3a23 100644 --- a/source4/lib/ldb-samba/ldb_wrap.h +++ b/source4/lib/ldb-samba/ldb_wrap.h @@ -53,18 +53,18 @@ struct ldb_context *ldb_wrap_find(const char *url, struct loadparm_context *lp_ctx, struct auth_session_info *session_info, struct cli_credentials *credentials, - int flags); + unsigned int flags); bool ldb_wrap_add(const char *url, struct tevent_context *ev, struct loadparm_context *lp_ctx, struct auth_session_info *session_info, struct cli_credentials *credentials, - int flags, + unsigned int flags, struct ldb_context *ldb); char *ldb_relative_path(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *name); int samba_ldb_connect(struct ldb_context *ldb, struct loadparm_context *lp_ctx, - const char *url, int flags); + const char *url, unsigned int flags); #endif /* _LDB_WRAP_H_ */ diff --git a/source4/lib/ldb-samba/samba_extensions.c b/source4/lib/ldb-samba/samba_extensions.c index 63b0f3df91..be9f36a5a7 100644 --- a/source4/lib/ldb-samba/samba_extensions.c +++ b/source4/lib/ldb-samba/samba_extensions.c @@ -82,7 +82,7 @@ static int extensions_hook(struct ldb_context *ldb, enum ldb_module_hook_type t) if (r != LDB_SUCCESS) { return ldb_operr(ldb); } - gensec_init(cmdline_lp_ctx); + gensec_init(); if (ldb_set_opaque(ldb, "sessionInfo", system_session(cmdline_lp_ctx))) { return ldb_operr(ldb); diff --git a/source4/lib/ldb-samba/wscript_build b/source4/lib/ldb-samba/wscript_build index a8d4df2ce0..2e1cacba64 100644 --- a/source4/lib/ldb-samba/wscript_build +++ b/source4/lib/ldb-samba/wscript_build @@ -8,7 +8,7 @@ bld.SAMBA_LIBRARY('ldbsamba', source='ldif_handlers.c', autoproto='ldif_handlers_proto.h', public_deps='ldb', - deps='security ndr NDR_DRSBLOBS NDR_DNSP ldbwrap samdb-common SAMDB_SCHEMA tdb pyldb-util', + deps='security ndr NDR_DRSBLOBS NDR_DNSP ldbwrap samdb-common SAMDB_SCHEMA tdb_compat pyldb-util errors', private_library=True ) diff --git a/source4/lib/ldb/common/ldb_controls.c b/source4/lib/ldb/common/ldb_controls.c index 5048b6deac..b3ef243493 100644 --- a/source4/lib/ldb/common/ldb_controls.c +++ b/source4/lib/ldb/common/ldb_controls.c @@ -482,10 +482,10 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO } /* w2k3 seems to ignore the parameter, - * but w2k sends a wrong cookie when this value is to small - * this would cause looping forever, while getting - * the same data and same cookie forever - */ + * but w2k sends a wrong cookie when this value is to small + * this would cause looping forever, while getting + * the same data and same cookie forever + */ if (max_attrs == 0) max_attrs = 0x0FFFFFFF; ctrl->oid = LDB_CONTROL_DIRSYNC_OID; diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c index 9c5a279b8a..28c414e6b2 100644 --- a/source4/lib/ldb/common/ldb_msg.c +++ b/source4/lib/ldb/common/ldb_msg.c @@ -130,7 +130,6 @@ static int _ldb_msg_add_el(struct ldb_message *msg, els = talloc_realloc(msg, msg->elements, struct ldb_message_element, msg->num_elements + 1); if (!els) { - errno = ENOMEM; return LDB_ERR_OPERATIONS_ERROR; } @@ -164,7 +163,6 @@ int ldb_msg_add_empty(struct ldb_message *msg, el->flags = flags; el->name = talloc_strdup(msg->elements, attr_name); if (!el->name) { - errno = ENOMEM; return LDB_ERR_OPERATIONS_ERROR; } @@ -229,7 +227,6 @@ int ldb_msg_add_value(struct ldb_message *msg, vals = talloc_realloc(msg->elements, el->values, struct ldb_val, el->num_values+1); if (!vals) { - errno = ENOMEM; return LDB_ERR_OPERATIONS_ERROR; } el->values = vals; diff --git a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c b/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c index e5b43fd0c9..223868a6c0 100644 --- a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c +++ b/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c @@ -1136,7 +1136,7 @@ static int lsql_modify(struct lsql_context *ctx) for (i = 0; i < msg->num_elements; i++) { const struct ldb_message_element *el = &msg->elements[i]; const struct ldb_schema_attribute *a; - int flags = el->flags & LDB_FLAG_MOD_MASK; + unsigned int flags = el->flags & LDB_FLAG_MOD_MASK; char *attr; char *mod; unsigned int j; @@ -1596,7 +1596,8 @@ static const struct ldb_module_ops lsqlite3_ops = { */ static int initialize(struct lsqlite3_private *lsqlite3, - struct ldb_context *ldb, const char *url, int flags) + struct ldb_context *ldb, const char *url, + unsigned int flags) { TALLOC_CTX *local_ctx; long long queryInt; diff --git a/source4/lib/ldb/ldb_tdb/ldb_cache.c b/source4/lib/ldb/ldb_tdb/ldb_cache.c index 697f7427a4..e54ceaaa98 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_cache.c +++ b/source4/lib/ldb/ldb_tdb/ldb_cache.c @@ -345,9 +345,6 @@ int ltdb_cache_load(struct ldb_module *module) ltdb->check_base = false; } - talloc_free(ltdb->cache->last_attribute.name); - memset(<db->cache->last_attribute, 0, sizeof(ltdb->cache->last_attribute)); - talloc_free(ltdb->cache->indexlist); ltdb_attributes_unload(module); /* calls internally "talloc_free" */ diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index 02e4acbbde..24cc93feb9 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -155,7 +155,7 @@ static int ltdb_dn_list_load(struct ldb_module *module, key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn)); key.dsize = strlen((char *)key.dptr); - rec = tdb_fetch(ltdb->idxptr->itdb, key); + rec = tdb_fetch_compat(ltdb->idxptr->itdb, key); if (rec.dptr == NULL) { goto normal_index; } @@ -261,7 +261,7 @@ static int ltdb_dn_list_store(struct ldb_module *module, struct ldb_dn *dn, } if (ltdb->idxptr->itdb == NULL) { - ltdb->idxptr->itdb = tdb_open(NULL, 1000, TDB_INTERNAL, O_RDWR, 0); + ltdb->idxptr->itdb = tdb_open_compat(NULL, 1000, TDB_INTERNAL, O_RDWR, 0, NULL, NULL); if (ltdb->idxptr->itdb == NULL) { return LDB_ERR_OPERATIONS_ERROR; } @@ -270,7 +270,7 @@ static int ltdb_dn_list_store(struct ldb_module *module, struct ldb_dn *dn, key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn)); key.dsize = strlen((char *)key.dptr); - rec = tdb_fetch(ltdb->idxptr->itdb, key); + rec = tdb_fetch_compat(ltdb->idxptr->itdb, key); if (rec.dptr != NULL) { list2 = ltdb_index_idxptr(module, rec, false); if (list2 == NULL) { @@ -294,7 +294,7 @@ static int ltdb_dn_list_store(struct ldb_module *module, struct ldb_dn *dn, rec.dsize = sizeof(void *); ret = tdb_store(ltdb->idxptr->itdb, key, rec, TDB_INSERT); - if (ret == -1) { + if (ret != 0) { return ltdb_err_map(tdb_error(ltdb->idxptr->itdb)); } return LDB_SUCCESS; @@ -1569,7 +1569,7 @@ int ltdb_reindex(struct ldb_module *module) * putting NULL entries in the in-memory tdb */ ret = tdb_traverse(ltdb->tdb, delete_index, module); - if (ret == -1) { + if (ret < 0) { return LDB_ERR_OPERATIONS_ERROR; } @@ -1583,7 +1583,7 @@ int ltdb_reindex(struct ldb_module *module) /* now traverse adding any indexes for normal LDB records */ ret = tdb_traverse(ltdb->tdb, re_index, &ctx); - if (ret == -1) { + if (ret < 0) { struct ldb_context *ldb = ldb_module_get_ctx(module); ldb_asprintf_errstring(ldb, "reindexing traverse failed: %s", ldb_errstring(ldb)); return LDB_ERR_OPERATIONS_ERROR; diff --git a/source4/lib/ldb/ldb_tdb/ldb_pack.c b/source4/lib/ldb/ldb_tdb/ldb_pack.c index 8ab07cd347..7c13065aee 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_pack.c +++ b/source4/lib/ldb/ldb_tdb/ldb_pack.c @@ -74,7 +74,7 @@ static int attribute_storable_values(const struct ldb_message_element *el) */ int ltdb_pack_data(struct ldb_module *module, const struct ldb_message *message, - struct TDB_DATA *data) + TDB_DATA *data) { struct ldb_context *ldb; unsigned int i, j, real_elements=0; @@ -155,7 +155,7 @@ int ltdb_pack_data(struct ldb_module *module, Free with ltdb_unpack_data_free() */ int ltdb_unpack_data(struct ldb_module *module, - const struct TDB_DATA *data, + const TDB_DATA *data, struct ldb_message *message) { struct ldb_context *ldb; diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index a49751de15..46e2d74998 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -32,6 +32,7 @@ */ #include "ldb_tdb.h" +#include <lib/tdb_compat/tdb_compat.h> /* add one element to a message @@ -223,7 +224,7 @@ static int ltdb_search_base(struct ldb_module *module, struct ldb_dn *dn) return LDB_ERR_OPERATIONS_ERROR; } - tdb_data = tdb_fetch(ltdb->tdb, tdb_key); + tdb_data = tdb_fetch_compat(ltdb->tdb, tdb_key); talloc_free(tdb_key.dptr); if (!tdb_data.dptr) { return LDB_ERR_NO_SUCH_OBJECT; @@ -255,7 +256,7 @@ int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_mes return LDB_ERR_OPERATIONS_ERROR; } - tdb_data = tdb_fetch(ltdb->tdb, tdb_key); + tdb_data = tdb_fetch_compat(ltdb->tdb, tdb_key); talloc_free(tdb_key.dptr); if (!tdb_data.dptr) { return LDB_ERR_NO_SUCH_OBJECT; @@ -479,7 +480,7 @@ static int ltdb_search_full(struct ltdb_context *ctx) ret = tdb_traverse_read(ltdb->tdb, search_func, ctx); } - if (ret == -1) { + if (ret < 0) { return LDB_ERR_OPERATIONS_ERROR; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 2f7f222086..0d4be49123 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -50,6 +50,7 @@ */ #include "ldb_tdb.h" +#include <lib/tdb_compat/tdb_compat.h> /* @@ -67,9 +68,13 @@ int ltdb_err_map(enum TDB_ERROR tdb_code) case TDB_ERR_IO: return LDB_ERR_PROTOCOL_ERROR; case TDB_ERR_LOCK: +#ifndef BUILD_TDB2 case TDB_ERR_NOLOCK: +#endif return LDB_ERR_BUSY; +#ifndef BUILD_TDB2 case TDB_ERR_LOCK_TIMEOUT: +#endif return LDB_ERR_TIME_LIMIT_EXCEEDED; case TDB_ERR_EXISTS: return LDB_ERR_ENTRY_ALREADY_EXISTS; @@ -110,7 +115,8 @@ int ltdb_unlock_read(struct ldb_module *module) void *data = ldb_module_get_private(module); struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); if (ltdb->in_transaction == 0 && ltdb->read_lock_count == 1) { - return tdb_unlockall_read(ltdb->tdb); + tdb_unlockall_read(ltdb->tdb); + return 0; } ltdb->read_lock_count--; return 0; @@ -124,7 +130,7 @@ int ltdb_unlock_read(struct ldb_module *module) note that the key for a record can depend on whether the dn refers to a case sensitive index record or not */ -struct TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn) +TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn) { struct ldb_context *ldb = ldb_module_get_ctx(module); TDB_DATA key; @@ -263,7 +269,7 @@ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flg } ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs); - if (ret == -1) { + if (ret != 0) { ret = ltdb_err_map(tdb_error(ltdb->tdb)); goto done; } @@ -653,7 +659,7 @@ int ltdb_modify_internal(struct ldb_module *module, return LDB_ERR_OTHER; } - tdb_data = tdb_fetch(ltdb->tdb, tdb_key); + tdb_data = tdb_fetch_compat(ltdb->tdb, tdb_key); if (!tdb_data.dptr) { talloc_free(tdb_key.dptr); return ltdb_err_map(tdb_error(ltdb->tdb)); @@ -1072,10 +1078,7 @@ static int ltdb_del_trans(struct ldb_module *module) return ltdb_err_map(tdb_error(ltdb->tdb)); } - if (tdb_transaction_cancel(ltdb->tdb) != 0) { - return ltdb_err_map(tdb_error(ltdb->tdb)); - } - + tdb_transaction_cancel(ltdb->tdb); return LDB_SUCCESS; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index 33313b00da..96ad43fbd6 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -1,7 +1,7 @@ #include "replace.h" #include "system/filesys.h" #include "system/time.h" -#include "tdb.h" +#include "tdb_compat.h" #include "ldb_module.h" /* this private structure is used by the ltdb backend in the @@ -21,11 +21,6 @@ struct ltdb_private { struct ldb_message *attributes; bool one_level_indexes; bool attribute_indexes; - - struct { - char *name; - int flags; - } last_attribute; } *cache; int in_transaction; @@ -107,11 +102,11 @@ int ltdb_index_transaction_cancel(struct ldb_module *module); int ltdb_pack_data(struct ldb_module *module, const struct ldb_message *message, - struct TDB_DATA *data); + TDB_DATA *data); void ltdb_unpack_data_free(struct ldb_module *module, struct ldb_message *message); int ltdb_unpack_data(struct ldb_module *module, - const struct TDB_DATA *data, + const TDB_DATA *data, struct ldb_message *message); /* The following definitions come from lib/ldb/ldb_tdb/ldb_search.c */ @@ -132,7 +127,7 @@ int ltdb_search(struct ltdb_context *ctx); /* The following definitions come from lib/ldb/ldb_tdb/ldb_tdb.c */ int ltdb_lock_read(struct ldb_module *module); int ltdb_unlock_read(struct ldb_module *module); -struct TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn); +TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn); int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs); int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg, struct ldb_request *req); int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn); diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c b/source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c index b9f3e79f20..16a037a6c3 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c @@ -24,29 +24,30 @@ #include "ldb_tdb.h" #include "dlinklist.h" -/* - the purpose of this code is to work around the braindead posix locking - rules, to allow us to have a ldb open more than once while allowing - locking to work -*/ - -struct ltdb_wrap { - struct ltdb_wrap *next, *prev; - struct tdb_context *tdb; - dev_t device; - ino_t inode; -}; - -static struct ltdb_wrap *tdb_list; - -/* destroy the last connection to a tdb */ -static int ltdb_wrap_destructor(struct ltdb_wrap *w) +/* FIXME: TDB2 does this internally, so no need to wrap multiple opens! */ +#if BUILD_TDB2 +static void ltdb_log_fn(struct tdb_context *tdb, + enum tdb_log_level level, + const char *message, + struct ldb_context *ldb) { - tdb_close(w->tdb); - DLIST_REMOVE(tdb_list, w); - return 0; -} + enum ldb_debug_level ldb_level; + const char *name = tdb_name(tdb); + + switch (level) { + case TDB_LOG_WARNING: + ldb_level = LDB_DEBUG_WARNING; + case TDB_LOG_USE_ERROR: + case TDB_LOG_ERROR: + ldb_level = LDB_DEBUG_FATAL; + break; + default: + ldb_level = LDB_DEBUG_FATAL; + } + ldb_debug(ldb, ldb_level, "ltdb: tdb(%s): %s", name, message); +} +#else /* !TDB2 */ static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { @@ -83,6 +84,32 @@ static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, con ldb_debug(ldb, ldb_level, "ltdb: tdb(%s): %s", name, message); talloc_free(message); } +#endif + +/* + the purpose of this code is to work around the braindead posix locking + rules, to allow us to have a ldb open more than once while allowing + locking to work + + TDB2 handles multiple opens, so we don't have this problem there. +*/ + +struct ltdb_wrap { + struct ltdb_wrap *next, *prev; + struct tdb_context *tdb; + dev_t device; + ino_t inode; +}; + +static struct ltdb_wrap *tdb_list; + +/* destroy the last connection to a tdb */ +static int ltdb_wrap_destructor(struct ltdb_wrap *w) +{ + tdb_close(w->tdb); + DLIST_REMOVE(tdb_list, w); + return 0; +} /* wrapped connection to a tdb database. The caller should _not_ free @@ -98,10 +125,6 @@ struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, { struct ltdb_wrap *w; struct stat st; - struct tdb_logging_context log_ctx; - - log_ctx.log_fn = ltdb_log_fn; - log_ctx.log_private = ldb; if (stat(path, &st) == 0) { for (w=tdb_list;w;w=w->next) { @@ -119,7 +142,7 @@ struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, return NULL; } - w->tdb = tdb_open_ex(path, hash_size, tdb_flags, open_flags, mode, &log_ctx, NULL); + w->tdb = tdb_open_compat(path, hash_size, tdb_flags, open_flags, mode, ltdb_log_fn, ldb); if (w->tdb == NULL) { talloc_free(w); return NULL; @@ -140,4 +163,3 @@ struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, return w->tdb; } - diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c index 5fcc5a64b6..e2a2e7180e 100644 --- a/source4/lib/ldb/pyldb.c +++ b/source4/lib/ldb/pyldb.c @@ -7,6 +7,8 @@ Copyright (C) 2006 Simo Sorce <idra@samba.org> Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org> Copyright (C) 2009-2010 Matthias Dieter Wallnöfer + Copyright (C) 2009-2011 Andrew Tridgell + Copyright (C) 2009-2011 Andrew Bartlett ** NOTE! The following LGPL license applies to the ldb ** library. This does NOT imply that all of Samba is released @@ -48,7 +50,7 @@ static PyObject *PyLdbModule_FromModule(struct ldb_module *mod); static struct ldb_message_element *PyObject_AsMessageElement( TALLOC_CTX *mem_ctx, PyObject *set_obj, - int flags, + unsigned int flags, const char *attr_name); /* There's no Py_ssize_t in 2.4, apparently */ @@ -384,6 +386,62 @@ static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self) return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn)); } +static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs) +{ + const char * const kwnames[] = { "mode", NULL }; + int mode = 1; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", + discard_const_p(char *, kwnames), + &mode)) + return NULL; + return PyString_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode)); +} + +static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args) +{ + char *name; + const struct ldb_val *val; + + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + val = ldb_dn_get_extended_component(self->dn, name); + if (val == NULL) { + Py_RETURN_NONE; + } + + return PyString_FromStringAndSize((const char *)val->data, val->length); +} + +static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args) +{ + char *name; + PyObject *value; + int err; + + if (!PyArg_ParseTuple(args, "sO", &name, &value)) + return NULL; + + if (value == Py_None) { + err = ldb_dn_set_extended_component(self->dn, name, NULL); + } else { + struct ldb_val val; + if (!PyString_Check(value)) { + PyErr_SetString(PyExc_TypeError, "Expected a string argument"); + return NULL; + } + val.data = (uint8_t *)PyString_AsString(value); + val.length = PyString_Size(value); + err = ldb_dn_set_extended_component(self->dn, name, &val); + } + + if (err != LDB_SUCCESS) { + PyErr_SetString(PyExc_TypeError, "Failed to set extended component"); + return NULL; + } + + Py_RETURN_NONE; +} + static PyObject *py_ldb_dn_repr(PyLdbDnObject *self) { return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn)))); @@ -485,6 +543,9 @@ static PyMethodDef py_ldb_dn_methods[] = { { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS, "S.canonical_ex_str() -> string\n" "Canonical version of this DN (like a posix path, with terminating newline)." }, + { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS, + "S.extended_str(mode=1) -> string\n" + "Extended version of this DN" }, { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS, "S.parent() -> dn\n" "Get the parent for this DN." }, @@ -497,6 +558,12 @@ static PyMethodDef py_ldb_dn_methods[] = { { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS, "S.check_special(name) -> bool\n\n" "Check if name is a special DN name"}, + { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS, + "S.get_extended_component(name) -> string\n\n" + "returns a DN extended component as a binary string"}, + { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS, + "S.set_extended_component(name, value) -> string\n\n" + "set a DN extended component as a binary string"}, { NULL } }; @@ -737,11 +804,11 @@ static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs) char *url = NULL; PyObject *py_options = Py_None; const char **options; - int flags = 0; + unsigned int flags = 0; int ret; struct ldb_context *ldb; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ziO:Ldb.__init__", + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__", discard_const_p(char *, kwnames), &url, &flags, &py_options)) return -1; @@ -792,13 +859,13 @@ static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs) { char *url; - int flags = 0; + unsigned int flags = 0; PyObject *py_options = Py_None; int ret; const char **options; const char * const kwnames[] = { "url", "flags", "options", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ziO", + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO", discard_const_p(char *, kwnames), &url, &flags, &py_options)) return NULL; @@ -819,7 +886,7 @@ static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwa Py_RETURN_NONE; } -static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args) +static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs) { PyObject *py_msg; PyObject *py_controls = Py_None; @@ -829,8 +896,12 @@ static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args) struct ldb_message *msg; int ret; TALLOC_CTX *mem_ctx; + bool validate=true; + const char * const kwnames[] = { "message", "controls", "validate", NULL }; - if (!PyArg_ParseTuple(args, "O|O", &py_msg, &py_controls)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob", + discard_const_p(char *, kwnames), + &py_msg, &py_controls, &validate)) return NULL; mem_ctx = talloc_new(NULL); @@ -855,11 +926,13 @@ static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args) } msg = PyLdbMessage_AsMessage(py_msg); - ret = ldb_msg_sanity_check(ldb_ctx, msg); - if (ret != LDB_SUCCESS) { - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - talloc_free(mem_ctx); - return NULL; + if (validate) { + ret = ldb_msg_sanity_check(ldb_ctx, msg); + if (ret != LDB_SUCCESS) { + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + talloc_free(mem_ctx); + return NULL; + } } ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls, @@ -958,7 +1031,7 @@ static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx, return msg; } -static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args) +static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs) { PyObject *py_obj; int ret; @@ -968,8 +1041,11 @@ static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args) PyObject *py_controls = Py_None; TALLOC_CTX *mem_ctx; struct ldb_control **parsed_controls; + const char * const kwnames[] = { "message", "controls", NULL }; - if (!PyArg_ParseTuple(args, "O|O", &py_obj, &py_controls )) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", + discard_const_p(char *, kwnames), + &py_obj, &py_controls)) return NULL; mem_ctx = talloc_new(NULL); @@ -1047,7 +1123,7 @@ static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args) Py_RETURN_NONE; } -static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args) +static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs) { PyObject *py_dn; struct ldb_dn *dn; @@ -1057,8 +1133,11 @@ static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args) PyObject *py_controls = Py_None; TALLOC_CTX *mem_ctx; struct ldb_control **parsed_controls; + const char * const kwnames[] = { "dn", "controls", NULL }; - if (!PyArg_ParseTuple(args, "O|O", &py_dn, &py_controls)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", + discard_const_p(char *, kwnames), + &py_dn, &py_controls)) return NULL; mem_ctx = talloc_new(NULL); @@ -1119,7 +1198,7 @@ static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args) Py_RETURN_NONE; } -static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args) +static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs) { PyObject *py_dn1, *py_dn2; struct ldb_dn *dn1, *dn2; @@ -1130,10 +1209,13 @@ static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args) struct ldb_control **parsed_controls; struct ldb_context *ldb_ctx; struct ldb_request *req; + const char * const kwnames[] = { "dn1", "dn2", "controls", NULL }; ldb_ctx = PyLdb_AsLdbContext(self); - if (!PyArg_ParseTuple(args, "OO|O", &py_dn1, &py_dn2, &py_controls)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O", + discard_const_p(char *, kwnames), + &py_dn1, &py_dn2, &py_controls)) return NULL; @@ -1586,17 +1668,17 @@ static PyMethodDef py_ldb_methods[] = { { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS, "S.connect(url, flags=0, options=None) -> None\n" "Connect to a LDB URL." }, - { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS, - "S.modify(message) -> None\n" + { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS, + "S.modify(message, controls=None, validate=False) -> None\n" "Modify an entry." }, - { "add", (PyCFunction)py_ldb_add, METH_VARARGS, - "S.add(message) -> None\n" + { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS, + "S.add(message, controls=None) -> None\n" "Add an entry." }, - { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS, - "S.delete(dn) -> None\n" + { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS, + "S.delete(dn, controls=None) -> None\n" "Remove an entry." }, - { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS, - "S.rename(old_dn, new_dn) -> None\n" + { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS, + "S.rename(old_dn, new_dn, controls=None) -> None\n" "Rename an entry." }, { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS, "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n" @@ -2031,7 +2113,7 @@ static PyTypeObject PyLdbModule = { static struct ldb_message_element *PyObject_AsMessageElement( TALLOC_CTX *mem_ctx, PyObject *set_obj, - int flags, + unsigned int flags, const char *attr_name) { struct ldb_message_element *me; @@ -2122,9 +2204,9 @@ static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObj static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args) { - int flags; + unsigned int flags; struct ldb_message_element *el; - if (!PyArg_ParseTuple(args, "i", &flags)) + if (!PyArg_ParseTuple(args, "I", &flags)) return NULL; el = PyLdbMessageElement_AsMessageElement(self); @@ -2192,13 +2274,13 @@ static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyOb { PyObject *py_elements = NULL; struct ldb_message_element *el; - int flags = 0; + unsigned int flags = 0; char *name = NULL; const char * const kwnames[] = { "elements", "flags", "name", NULL }; PyLdbMessageElementObject *ret; TALLOC_CTX *mem_ctx; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Ois", + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs", discard_const_p(char *, kwnames), &py_elements, &flags, &name)) return NULL; @@ -2427,15 +2509,20 @@ static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name) static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args) { - PyObject *name, *ret; - if (!PyArg_ParseTuple(args, "O", &name)) + PyObject *name, *ret, *retobj; + retobj = NULL; + if (!PyArg_ParseTuple(args, "O|O", &name, &retobj)) return NULL; ret = py_ldb_msg_getitem_helper(self, name); if (ret == NULL) { if (PyErr_Occurred()) return NULL; - Py_RETURN_NONE; + if (retobj != NULL) { + return retobj; + } else { + Py_RETURN_NONE; + } } return ret; } @@ -3202,4 +3289,14 @@ void initldb(void) PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl); PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION)); + +#define ADD_LDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(val)) + + ADD_LDB_STRING(LDB_SYNTAX_DN); + ADD_LDB_STRING(LDB_SYNTAX_DN); + ADD_LDB_STRING(LDB_SYNTAX_DIRECTORY_STRING); + ADD_LDB_STRING(LDB_SYNTAX_INTEGER); + ADD_LDB_STRING(LDB_SYNTAX_BOOLEAN); + ADD_LDB_STRING(LDB_SYNTAX_OCTET_STRING); + ADD_LDB_STRING(LDB_SYNTAX_UTC_TIME); } diff --git a/source4/lib/ldb/tests/python/api.py b/source4/lib/ldb/tests/python/api.py index a9f68cbd71..e7658d51ab 100755 --- a/source4/lib/ldb/tests/python/api.py +++ b/source4/lib/ldb/tests/python/api.py @@ -516,6 +516,11 @@ class LdbMsgTests(unittest.TestCase): self.msg["foo"] = ["bar"] self.assertEquals("bar", self.msg.get("foo")[0]) + def test_get_default(self): + self.assertEquals(None, self.msg.get("tatayoyo")) + + self.assertEquals("anniecordie", self.msg.get("tatayoyo", "anniecordie")) + def test_get_unknown(self): self.assertEquals(None, self.msg.get("lalalala")) diff --git a/source4/lib/ldb/tools/cmdline.c b/source4/lib/ldb/tools/cmdline.c index b2be54ebf9..a06445fc0f 100644 --- a/source4/lib/ldb/tools/cmdline.c +++ b/source4/lib/ldb/tools/cmdline.c @@ -101,7 +101,7 @@ struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, poptContext pc; int num_options = 0; int opt; - int flags = 0; + unsigned int flags = 0; int rc; struct poptOption **popt_options; @@ -297,7 +297,7 @@ struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, } /* now connect to the ldb */ - if (ldb_connect(ldb, ret->url, flags, ret->options) != 0) { + if (ldb_connect(ldb, ret->url, flags, ret->options) != LDB_SUCCESS) { fprintf(stderr, "Failed to connect to %s - %s\n", ret->url, ldb_errstring(ldb)); goto failed; diff --git a/source4/lib/ldb/tools/ldbtest.c b/source4/lib/ldb/tools/ldbtest.c index a9d8fafe81..4e181af9d5 100644 --- a/source4/lib/ldb/tools/ldbtest.c +++ b/source4/lib/ldb/tools/ldbtest.c @@ -126,7 +126,7 @@ static void add_records(struct ldb_context *ldb, ldb_delete(ldb, msg.dn); - if (ldb_add(ldb, &msg) != 0) { + if (ldb_add(ldb, &msg) != LDB_SUCCESS) { printf("Add of %s failed - %s\n", name, ldb_errstring(ldb)); exit(LDB_ERR_OPERATIONS_ERROR); } @@ -183,7 +183,7 @@ static void modify_records(struct ldb_context *ldb, vals[2].data = (uint8_t *)talloc_asprintf(tmp_ctx, "%s@other2.example.com", name); vals[2].length = strlen((char *)vals[2].data); - if (ldb_modify(ldb, &msg) != 0) { + if (ldb_modify(ldb, &msg) != LDB_SUCCESS) { printf("Modify of %s failed - %s\n", name, ldb_errstring(ldb)); exit(LDB_ERR_OPERATIONS_ERROR); } @@ -213,7 +213,7 @@ static void delete_records(struct ldb_context *ldb, printf("Deleting uid Test%d\r", i); fflush(stdout); - if (ldb_delete(ldb, dn) != 0) { + if (ldb_delete(ldb, dn) != LDB_SUCCESS) { printf("Delete of %s failed - %s\n", ldb_dn_get_linearized(dn), ldb_errstring(ldb)); exit(LDB_ERR_OPERATIONS_ERROR); } @@ -304,7 +304,7 @@ static void start_test_index(struct ldb_context **ldb) struct ldb_dn *indexlist; struct ldb_dn *basedn; int ret; - int flags = 0; + unsigned int flags = 0; const char *specials; specials = getenv("LDB_SPECIALS"); @@ -343,7 +343,7 @@ static void start_test_index(struct ldb_context **ldb) ldb_msg_add_string(msg, "uid", strdup("test")); ldb_msg_add_string(msg, "objectClass", strdup("OpenLDAPperson")); - if (ldb_add(*ldb, msg) != 0) { + if (ldb_add(*ldb, msg) != LDB_SUCCESS) { printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb)); exit(LDB_ERR_OPERATIONS_ERROR); } @@ -356,7 +356,7 @@ static void start_test_index(struct ldb_context **ldb) (*ldb) = ldb_init(options, NULL); ret = ldb_connect(*ldb, options->url, flags, NULL); - if (ret != 0) { + if (ret != LDB_SUCCESS) { printf("failed to connect to %s\n", options->url); exit(LDB_ERR_OPERATIONS_ERROR); } diff --git a/source4/lib/ldb/wscript b/source4/lib/ldb/wscript index b59e782e45..7de95494c7 100755 --- a/source4/lib/ldb/wscript +++ b/source4/lib/ldb/wscript @@ -16,29 +16,33 @@ sys.path.insert(0, srcdir + '/buildtools/wafsamba') import wafsamba, samba_dist, Options samba_dist.DIST_DIRS('''source4/lib/ldb:. lib/replace:lib/replace lib/talloc:lib/talloc - lib/tdb:lib/tdb lib/tevent:lib/tevent lib/popt:lib/popt + lib/tdb:lib/tdb lib/tdb2:lib/tdb2 lib/tdb_compat:lib/tdb_compat lib/ccan:lib/ccan lib/tevent:lib/tevent lib/popt:lib/popt buildtools:buildtools''') def set_options(opt): opt.BUILTIN_DEFAULT('replace') opt.PRIVATE_EXTENSION_DEFAULT('ldb', noextension='ldb') - opt.RECURSE('lib/tdb') + opt.RECURSE('lib/tdb_compat') opt.RECURSE('lib/tevent') opt.RECURSE('lib/replace') opt.tool_options('python') # options for disabling pyc or pyo compilation def configure(conf): - conf.RECURSE('lib/tdb') + conf.RECURSE('lib/tdb_compat') conf.RECURSE('lib/tevent') conf.RECURSE('lib/popt') conf.RECURSE('lib/replace') + conf.RECURSE('lib/tdb_compat') conf.find_program('python', var='PYTHON') conf.find_program('xsltproc', var='XSLTPROC') conf.check_tool('python') conf.check_python_version((2,4,2)) conf.SAMBA_CHECK_PYTHON_HEADERS(mandatory=True) + # This make #include <ccan/...> work. + conf.ADD_EXTRA_INCLUDES('''#lib''') + # where does the default LIBDIR end up? in conf.env somewhere? # conf.CONFIG_PATH('LDB_MODULESDIR', conf.SUBST_ENV_VAR('MODULESDIR') + '/ldb') @@ -72,10 +76,11 @@ def configure(conf): conf.SAMBA_CONFIG_H() def build(bld): - bld.RECURSE('lib/tdb') + bld.RECURSE('lib/tdb_compat') bld.RECURSE('lib/tevent') bld.RECURSE('lib/popt') bld.RECURSE('lib/replace') + bld.RECURSE('lib/tdb_compat') if bld.env.standalone_ldb: private_library = False @@ -233,14 +238,14 @@ def build(bld): init_function='ldb_tdb_init', module_init_name='ldb_init_module', internal_module=False, - deps='tdb ldb', + deps='tdb_compat ldb', subsystem='ldb') # have a separate subsystem for common/ldb.c, so it can rebuild # for install with a different -DLDB_MODULESDIR= bld.SAMBA_SUBSYSTEM('LIBLDB_MAIN', 'common/ldb.c', - deps='tevent', + deps='tevent tdb_compat', includes='include', cflags=['-DLDB_MODULESDIR=\"%s\"' % modules_dir]) diff --git a/source4/lib/messaging/irpc.h b/source4/lib/messaging/irpc.h index bdb1b8fedb..15f8259e51 100644 --- a/source4/lib/messaging/irpc.h +++ b/source4/lib/messaging/irpc.h @@ -35,7 +35,7 @@ struct irpc_message { struct ndr_pull *ndr; bool defer_reply; bool no_reply; - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; struct irpc_list *irpc; void *data; struct tevent_context *ev; @@ -58,24 +58,24 @@ typedef NTSTATUS (*irpc_function_t)(struct irpc_message *, void *r); struct ndr_interface_table; -NTSTATUS irpc_register(struct messaging_context *msg_ctx, +NTSTATUS irpc_register(struct imessaging_context *msg_ctx, const struct ndr_interface_table *table, int call, irpc_function_t fn, void *private_data); struct dcerpc_binding_handle *irpc_binding_handle(TALLOC_CTX *mem_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, struct server_id server_id, const struct ndr_interface_table *table); struct dcerpc_binding_handle *irpc_binding_handle_by_name(TALLOC_CTX *mem_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, const char *dest_task, const struct ndr_interface_table *table); void irpc_binding_handle_add_security_token(struct dcerpc_binding_handle *h, struct security_token *token); -NTSTATUS irpc_add_name(struct messaging_context *msg_ctx, const char *name); -struct server_id *irpc_servers_byname(struct messaging_context *msg_ctx, TALLOC_CTX *mem_ctx, const char *name); -void irpc_remove_name(struct messaging_context *msg_ctx, const char *name); +NTSTATUS irpc_add_name(struct imessaging_context *msg_ctx, const char *name); +struct server_id *irpc_servers_byname(struct imessaging_context *msg_ctx, TALLOC_CTX *mem_ctx, const char *name); +void irpc_remove_name(struct imessaging_context *msg_ctx, const char *name); NTSTATUS irpc_send_reply(struct irpc_message *m, NTSTATUS status); #endif diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c index f9d63203f2..484f22b2ee 100644 --- a/source4/lib/messaging/messaging.c +++ b/source4/lib/messaging/messaging.c @@ -27,22 +27,22 @@ #include "lib/socket/socket.h" #include "librpc/gen_ndr/ndr_irpc.h" #include "lib/messaging/irpc.h" -#include "tdb_wrap.h" +#include "lib/util/tdb_wrap.h" #include "../lib/util/unix_privs.h" #include "librpc/rpc/dcerpc.h" -#include <tdb.h> +#include "../lib/tdb_compat/tdb_compat.h" #include "../lib/util/util_tdb.h" #include "cluster/cluster.h" #include "../lib/util/tevent_ntstatus.h" /* change the message version with any incompatible changes in the protocol */ -#define MESSAGING_VERSION 1 +#define IMESSAGING_VERSION 1 /* a pending irpc call */ struct irpc_request { - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; int callid; struct { void (*handler)(struct irpc_request *irpc, struct irpc_message *m); @@ -50,7 +50,7 @@ struct irpc_request { } incoming; }; -struct messaging_context { +struct imessaging_context { struct server_id server_id; struct socket_context *sock; const char *base_path; @@ -58,8 +58,8 @@ struct messaging_context { struct dispatch_fn **dispatch; uint32_t num_types; struct idr_context *dispatch_tree; - struct messaging_rec *pending; - struct messaging_rec *retry_queue; + struct imessaging_rec *pending; + struct imessaging_rec *retry_queue; struct irpc_list *irpc; struct idr_context *idr; const char **names; @@ -81,12 +81,12 @@ struct dispatch_fn { }; /* an individual message */ -struct messaging_rec { - struct messaging_rec *next, *prev; - struct messaging_context *msg; +struct imessaging_rec { + struct imessaging_rec *next, *prev; + struct imessaging_context *msg; const char *path; - struct messaging_header { + struct imessaging_header { uint32_t version; uint32_t msg_type; struct server_id from; @@ -99,20 +99,22 @@ struct messaging_rec { }; -static void irpc_handler(struct messaging_context *, void *, +static void irpc_handler(struct imessaging_context *, void *, uint32_t, struct server_id, DATA_BLOB *); /* A useful function for testing the message system. */ -static void ping_message(struct messaging_context *msg, void *private_data, +static void ping_message(struct imessaging_context *msg, void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *data) { - DEBUG(1,("INFO: Received PING message from server %u.%u [%.*s]\n", - (unsigned int)src.node, (unsigned int)src.id, (int)data->length, + char *task_id = server_id_str(NULL, &src); + DEBUG(1,("INFO: Received PING message from server %s [%.*s]\n", + task_id, (int)data->length, data->data?(const char *)data->data:"")); - messaging_send(msg, src, MSG_PONG, data); + talloc_free(task_id); + imessaging_send(msg, src, MSG_PONG, data); } /* @@ -121,7 +123,7 @@ static void ping_message(struct messaging_context *msg, void *private_data, static NTSTATUS irpc_uptime(struct irpc_message *msg, struct irpc_uptime *r) { - struct messaging_context *ctx = talloc_get_type(msg->private_data, struct messaging_context); + struct imessaging_context *ctx = talloc_get_type(msg->private_data, struct imessaging_context); *r->out.start_time = timeval_to_nttime(&ctx->start_time); return NT_STATUS_OK; } @@ -129,10 +131,10 @@ static NTSTATUS irpc_uptime(struct irpc_message *msg, /* return the path to a messaging socket */ -static char *messaging_path(struct messaging_context *msg, struct server_id server_id) +static char *imessaging_path(struct imessaging_context *msg, struct server_id server_id) { TALLOC_CTX *tmp_ctx = talloc_new(msg); - const char *id = cluster_id_string(tmp_ctx, server_id); + const char *id = server_id_str(tmp_ctx, &server_id); char *s; if (id == NULL) { return NULL; @@ -149,7 +151,7 @@ static char *messaging_path(struct messaging_context *msg, struct server_id serv per message. That allows a single messasging context to register (for example) a debug handler for more than one piece of code */ -static void messaging_dispatch(struct messaging_context *msg, struct messaging_rec *rec) +static void imessaging_dispatch(struct imessaging_context *msg, struct imessaging_rec *rec) { struct dispatch_fn *d, *next; @@ -176,18 +178,18 @@ static void messaging_dispatch(struct messaging_context *msg, struct messaging_r /* handler for messages that arrive from other nodes in the cluster */ -static void cluster_message_handler(struct messaging_context *msg, DATA_BLOB packet) +static void cluster_message_handler(struct imessaging_context *msg, DATA_BLOB packet) { - struct messaging_rec *rec; + struct imessaging_rec *rec; - rec = talloc(msg, struct messaging_rec); + rec = talloc(msg, struct imessaging_rec); if (rec == NULL) { - smb_panic("Unable to allocate messaging_rec"); + smb_panic("Unable to allocate imessaging_rec"); } rec->msg = msg; rec->path = msg->path; - rec->header = (struct messaging_header *)packet.data; + rec->header = (struct imessaging_header *)packet.data; rec->packet = packet; rec->retries = 0; @@ -198,7 +200,7 @@ static void cluster_message_handler(struct messaging_context *msg, DATA_BLOB pac return; } - messaging_dispatch(msg, rec); + imessaging_dispatch(msg, rec); talloc_free(rec); } @@ -207,9 +209,9 @@ static void cluster_message_handler(struct messaging_context *msg, DATA_BLOB pac /* try to send the message */ -static NTSTATUS try_send(struct messaging_rec *rec) +static NTSTATUS try_send(struct imessaging_rec *rec) { - struct messaging_context *msg = rec->msg; + struct imessaging_context *msg = rec->msg; size_t nsent; void *priv; NTSTATUS status; @@ -238,15 +240,15 @@ static NTSTATUS try_send(struct messaging_rec *rec) static void msg_retry_timer(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { - struct messaging_context *msg = talloc_get_type(private_data, - struct messaging_context); + struct imessaging_context *msg = talloc_get_type(private_data, + struct imessaging_context); msg->retry_te = NULL; /* put the messages back on the main queue */ while (msg->retry_queue) { - struct messaging_rec *rec = msg->retry_queue; + struct imessaging_rec *rec = msg->retry_queue; DLIST_REMOVE(msg->retry_queue, rec); - DLIST_ADD_END(msg->pending, rec, struct messaging_rec *); + DLIST_ADD_END(msg->pending, rec, struct imessaging_rec *); } EVENT_FD_WRITEABLE(msg->event.fde); @@ -255,10 +257,10 @@ static void msg_retry_timer(struct tevent_context *ev, struct tevent_timer *te, /* handle a socket write event */ -static void messaging_send_handler(struct messaging_context *msg) +static void imessaging_send_handler(struct imessaging_context *msg) { while (msg->pending) { - struct messaging_rec *rec = msg->pending; + struct imessaging_rec *rec = msg->pending; NTSTATUS status; status = try_send(rec); if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { @@ -268,7 +270,7 @@ static void messaging_send_handler(struct messaging_context *msg) backoff this record */ DLIST_REMOVE(msg->pending, rec); DLIST_ADD_END(msg->retry_queue, rec, - struct messaging_rec *); + struct imessaging_rec *); if (msg->retry_te == NULL) { msg->retry_te = event_add_timed(msg->event.ev, msg, @@ -282,8 +284,8 @@ static void messaging_send_handler(struct messaging_context *msg) if (!NT_STATUS_IS_OK(status)) { TALLOC_CTX *tmp_ctx = talloc_new(msg); DEBUG(1,("messaging: Lost message from %s to %s of type %u - %s\n", - cluster_id_string(tmp_ctx, rec->header->from), - cluster_id_string(tmp_ctx, rec->header->to), + server_id_str(tmp_ctx, &rec->header->from), + server_id_str(tmp_ctx, &rec->header->to), rec->header->msg_type, nt_errstr(status))); talloc_free(tmp_ctx); @@ -299,9 +301,9 @@ static void messaging_send_handler(struct messaging_context *msg) /* handle a new incoming packet */ -static void messaging_recv_handler(struct messaging_context *msg) +static void imessaging_recv_handler(struct imessaging_context *msg) { - struct messaging_rec *rec; + struct imessaging_rec *rec; NTSTATUS status; DATA_BLOB packet; size_t msize; @@ -332,15 +334,15 @@ static void messaging_recv_handler(struct messaging_context *msg) return; } - rec = talloc(msg, struct messaging_rec); + rec = talloc(msg, struct imessaging_rec); if (rec == NULL) { - smb_panic("Unable to allocate messaging_rec"); + smb_panic("Unable to allocate imessaging_rec"); } talloc_steal(rec, packet.data); rec->msg = msg; rec->path = msg->path; - rec->header = (struct messaging_header *)packet.data; + rec->header = (struct imessaging_header *)packet.data; rec->packet = packet; rec->retries = 0; @@ -351,7 +353,7 @@ static void messaging_recv_handler(struct messaging_context *msg) return; } - messaging_dispatch(msg, rec); + imessaging_dispatch(msg, rec); talloc_free(rec); } @@ -359,16 +361,16 @@ static void messaging_recv_handler(struct messaging_context *msg) /* handle a socket event */ -static void messaging_handler(struct tevent_context *ev, struct tevent_fd *fde, +static void imessaging_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *private_data) { - struct messaging_context *msg = talloc_get_type(private_data, - struct messaging_context); + struct imessaging_context *msg = talloc_get_type(private_data, + struct imessaging_context); if (flags & EVENT_FD_WRITE) { - messaging_send_handler(msg); + imessaging_send_handler(msg); } if (flags & EVENT_FD_READ) { - messaging_recv_handler(msg); + imessaging_recv_handler(msg); } } @@ -376,7 +378,7 @@ static void messaging_handler(struct tevent_context *ev, struct tevent_fd *fde, /* Register a dispatch function for a particular message type. */ -NTSTATUS messaging_register(struct messaging_context *msg, void *private_data, +NTSTATUS imessaging_register(struct imessaging_context *msg, void *private_data, uint32_t msg_type, msg_callback_t fn) { struct dispatch_fn *d; @@ -409,7 +411,7 @@ NTSTATUS messaging_register(struct messaging_context *msg, void *private_data, register a temporary message handler. The msg_type is allocated above MSG_TMP_BASE */ -NTSTATUS messaging_register_tmp(struct messaging_context *msg, void *private_data, +NTSTATUS imessaging_register_tmp(struct imessaging_context *msg, void *private_data, msg_callback_t fn, uint32_t *msg_type) { struct dispatch_fn *d; @@ -435,7 +437,7 @@ NTSTATUS messaging_register_tmp(struct messaging_context *msg, void *private_dat /* De-register the function for a particular message type. */ -void messaging_deregister(struct messaging_context *msg, uint32_t msg_type, void *private_data) +void imessaging_deregister(struct imessaging_context *msg, uint32_t msg_type, void *private_data) { struct dispatch_fn *d, *next; @@ -460,14 +462,14 @@ void messaging_deregister(struct messaging_context *msg, uint32_t msg_type, void /* Send a message to a particular server */ -NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server, +NTSTATUS imessaging_send(struct imessaging_context *msg, struct server_id server, uint32_t msg_type, const DATA_BLOB *data) { - struct messaging_rec *rec; + struct imessaging_rec *rec; NTSTATUS status; size_t dlength = data?data->length:0; - rec = talloc(msg, struct messaging_rec); + rec = talloc(msg, struct imessaging_rec); if (rec == NULL) { return NT_STATUS_NO_MEMORY; } @@ -480,10 +482,10 @@ NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server, rec->retries = 0; rec->msg = msg; - rec->header = (struct messaging_header *)rec->packet.data; + rec->header = (struct imessaging_header *)rec->packet.data; /* zero padding */ ZERO_STRUCTP(rec->header); - rec->header->version = MESSAGING_VERSION; + rec->header->version = IMESSAGING_VERSION; rec->header->msg_type = msg_type; rec->header->from = msg->server_id; rec->header->to = server; @@ -501,7 +503,7 @@ NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server, return status; } - rec->path = messaging_path(msg, server); + rec->path = imessaging_path(msg, server); talloc_steal(rec, rec->path); if (msg->pending != NULL) { @@ -514,7 +516,7 @@ NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server, if (msg->pending == NULL) { EVENT_FD_WRITEABLE(msg->event.fde); } - DLIST_ADD_END(msg->pending, rec, struct messaging_rec *); + DLIST_ADD_END(msg->pending, rec, struct imessaging_rec *); return NT_STATUS_OK; } @@ -526,7 +528,7 @@ NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server, /* Send a message to a particular server, with the message containing a single pointer */ -NTSTATUS messaging_send_ptr(struct messaging_context *msg, struct server_id server, +NTSTATUS imessaging_send_ptr(struct imessaging_context *msg, struct server_id server, uint32_t msg_type, void *ptr) { DATA_BLOB blob; @@ -534,14 +536,14 @@ NTSTATUS messaging_send_ptr(struct messaging_context *msg, struct server_id serv blob.data = (uint8_t *)&ptr; blob.length = sizeof(void *); - return messaging_send(msg, server, msg_type, &blob); + return imessaging_send(msg, server, msg_type, &blob); } /* destroy the messaging context */ -static int messaging_destructor(struct messaging_context *msg) +static int imessaging_destructor(struct imessaging_context *msg) { unlink(msg->path); while (msg->names && msg->names[0]) { @@ -553,12 +555,12 @@ static int messaging_destructor(struct messaging_context *msg) /* create the listening socket and setup the dispatcher */ -struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, +struct imessaging_context *imessaging_init(TALLOC_CTX *mem_ctx, const char *dir, struct server_id server_id, struct tevent_context *ev) { - struct messaging_context *msg; + struct imessaging_context *msg; NTSTATUS status; struct socket_address *path; @@ -566,7 +568,7 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, return NULL; } - msg = talloc_zero(mem_ctx, struct messaging_context); + msg = talloc_zero(mem_ctx, struct imessaging_context); if (msg == NULL) { return NULL; } @@ -582,7 +584,7 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, mkdir(dir, 0700); msg->base_path = talloc_reference(msg, dir); - msg->path = messaging_path(msg, server_id); + msg->path = imessaging_path(msg, server_id); msg->server_id = server_id; msg->idr = idr_init(msg); msg->dispatch_tree = idr_init(msg); @@ -617,13 +619,13 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, msg->event.ev = ev; msg->event.fde = event_add_fd(ev, msg, socket_get_fd(msg->sock), - EVENT_FD_READ, messaging_handler, msg); + EVENT_FD_READ, imessaging_handler, msg); tevent_fd_set_auto_close(msg->event.fde); - talloc_set_destructor(msg, messaging_destructor); + talloc_set_destructor(msg, imessaging_destructor); - messaging_register(msg, NULL, MSG_PING, ping_message); - messaging_register(msg, NULL, MSG_IRPC, irpc_handler); + imessaging_register(msg, NULL, MSG_PING, ping_message); + imessaging_register(msg, NULL, MSG_IRPC, irpc_handler); IRPC_REGISTER(msg, irpc, IRPC_UPTIME, irpc_uptime, msg); return msg; @@ -632,14 +634,14 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, /* A hack, for the short term until we get 'client only' messaging in place */ -struct messaging_context *messaging_client_init(TALLOC_CTX *mem_ctx, +struct imessaging_context *imessaging_client_init(TALLOC_CTX *mem_ctx, const char *dir, struct tevent_context *ev) { struct server_id id; ZERO_STRUCT(id); - id.id = random() % 0x10000000; - return messaging_init(mem_ctx, dir, id, ev); + id.pid = random() % 0x10000000; + return imessaging_init(mem_ctx, dir, id, ev); } /* a list of registered irpc server functions @@ -657,7 +659,7 @@ struct irpc_list { /* register a irpc server function */ -NTSTATUS irpc_register(struct messaging_context *msg_ctx, +NTSTATUS irpc_register(struct imessaging_context *msg_ctx, const struct ndr_interface_table *table, int callnum, irpc_function_t fn, void *private_data) { @@ -688,7 +690,7 @@ NTSTATUS irpc_register(struct messaging_context *msg_ctx, /* handle an incoming irpc reply message */ -static void irpc_handler_reply(struct messaging_context *msg_ctx, struct irpc_message *m) +static void irpc_handler_reply(struct imessaging_context *msg_ctx, struct irpc_message *m) { struct irpc_request *irpc; @@ -734,7 +736,7 @@ NTSTATUS irpc_send_reply(struct irpc_message *m, NTSTATUS status) /* send the reply message */ packet = ndr_push_blob(push); - status = messaging_send(m->msg_ctx, m->from, MSG_IRPC, &packet); + status = imessaging_send(m->msg_ctx, m->from, MSG_IRPC, &packet); if (!NT_STATUS_IS_OK(status)) goto failed; failed: @@ -745,7 +747,7 @@ failed: /* handle an incoming irpc request message */ -static void irpc_handler_request(struct messaging_context *msg_ctx, +static void irpc_handler_request(struct imessaging_context *msg_ctx, struct irpc_message *m) { struct irpc_list *i; @@ -809,7 +811,7 @@ failed: /* handle an incoming irpc message */ -static void irpc_handler(struct messaging_context *msg_ctx, void *private_data, +static void irpc_handler(struct imessaging_context *msg_ctx, void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *packet) { struct irpc_message *m; @@ -856,7 +858,7 @@ static int irpc_destructor(struct irpc_request *irpc) /* open the naming database */ -static struct tdb_wrap *irpc_namedb_open(struct messaging_context *msg_ctx) +static struct tdb_wrap *irpc_namedb_open(struct imessaging_context *msg_ctx) { struct tdb_wrap *t; char *path = talloc_asprintf(msg_ctx, "%s/names.tdb", msg_ctx->base_path); @@ -872,7 +874,7 @@ static struct tdb_wrap *irpc_namedb_open(struct messaging_context *msg_ctx) /* add a string name that this irpc server can be called on */ -NTSTATUS irpc_add_name(struct messaging_context *msg_ctx, const char *name) +NTSTATUS irpc_add_name(struct imessaging_context *msg_ctx, const char *name) { struct tdb_wrap *t; TDB_DATA rec; @@ -912,7 +914,7 @@ NTSTATUS irpc_add_name(struct messaging_context *msg_ctx, const char *name) /* return a list of server ids for a server name */ -struct server_id *irpc_servers_byname(struct messaging_context *msg_ctx, +struct server_id *irpc_servers_byname(struct imessaging_context *msg_ctx, TALLOC_CTX *mem_ctx, const char *name) { @@ -957,7 +959,7 @@ struct server_id *irpc_servers_byname(struct messaging_context *msg_ctx, /* remove a name from a messaging context */ -void irpc_remove_name(struct messaging_context *msg_ctx, const char *name) +void irpc_remove_name(struct imessaging_context *msg_ctx, const char *name) { struct tdb_wrap *t; TDB_DATA rec; @@ -1005,13 +1007,13 @@ void irpc_remove_name(struct messaging_context *msg_ctx, const char *name) talloc_free(t); } -struct server_id messaging_get_server_id(struct messaging_context *msg_ctx) +struct server_id imessaging_get_server_id(struct imessaging_context *msg_ctx) { return msg_ctx->server_id; } struct irpc_bh_state { - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; struct server_id server_id; const struct ndr_interface_table *table; uint32_t timeout; @@ -1137,7 +1139,7 @@ static struct tevent_req *irpc_bh_raw_call_send(TALLOC_CTX *mem_ctx, /* and send it */ state->in_packet = ndr_push_blob(ndr); - status = messaging_send(hs->msg_ctx, hs->server_id, + status = imessaging_send(hs->msg_ctx, hs->server_id, MSG_IRPC, &state->in_packet); if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); @@ -1176,7 +1178,7 @@ static void irpc_bh_raw_call_incoming_handler(struct irpc_request *irpc, m->ndr->data + m->ndr->offset, m->ndr->data_size - m->ndr->offset); if ((m->ndr->data_size - m->ndr->offset) > 0 && !state->out_data.data) { - tevent_req_nomem(NULL, req); + tevent_req_oom(req); return; } @@ -1270,7 +1272,7 @@ static const struct dcerpc_binding_handle_ops irpc_bh_ops = { /* initialise a irpc binding handle */ struct dcerpc_binding_handle *irpc_binding_handle(TALLOC_CTX *mem_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, struct server_id server_id, const struct ndr_interface_table *table) { @@ -1298,7 +1300,7 @@ struct dcerpc_binding_handle *irpc_binding_handle(TALLOC_CTX *mem_ctx, } struct dcerpc_binding_handle *irpc_binding_handle_by_name(TALLOC_CTX *mem_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, const char *dest_task, const struct ndr_interface_table *table) { @@ -1312,7 +1314,7 @@ struct dcerpc_binding_handle *irpc_binding_handle_by_name(TALLOC_CTX *mem_ctx, errno = EADDRNOTAVAIL; return NULL; } - if (sids[0].id == 0) { + if (sids[0].pid == 0) { talloc_free(sids); errno = EADDRNOTAVAIL; return NULL; diff --git a/source4/lib/messaging/messaging.h b/source4/lib/messaging/messaging.h index 4bc6d8c509..eb8a8abc79 100644 --- a/source4/lib/messaging/messaging.h +++ b/source4/lib/messaging/messaging.h @@ -21,9 +21,9 @@ #ifndef _MESSAGES_H_ #define _MESSAGES_H_ -#include "librpc/gen_ndr/server_id4.h" +#include "librpc/gen_ndr/server_id.h" -struct messaging_context; +struct imessaging_context; /* general messages */ #define MSG_DEBUG 1 @@ -42,27 +42,27 @@ struct messaging_context; /* taskid for messaging of parent process */ #define SAMBA_PARENT_TASKID 0 -typedef void (*msg_callback_t)(struct messaging_context *msg, void *private_data, +typedef void (*msg_callback_t)(struct imessaging_context *msg, void *private_data, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data); -NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server, +NTSTATUS imessaging_send(struct imessaging_context *msg, struct server_id server, uint32_t msg_type, const DATA_BLOB *data); -NTSTATUS messaging_register(struct messaging_context *msg, void *private_data, +NTSTATUS imessaging_register(struct imessaging_context *msg, void *private_data, uint32_t msg_type, msg_callback_t fn); -NTSTATUS messaging_register_tmp(struct messaging_context *msg, void *private_data, +NTSTATUS imessaging_register_tmp(struct imessaging_context *msg, void *private_data, msg_callback_t fn, uint32_t *msg_type); -struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, +struct imessaging_context *imessaging_init(TALLOC_CTX *mem_ctx, const char *dir, struct server_id server_id, struct tevent_context *ev); -struct messaging_context *messaging_client_init(TALLOC_CTX *mem_ctx, +struct imessaging_context *imessaging_client_init(TALLOC_CTX *mem_ctx, const char *dir, struct tevent_context *ev); -NTSTATUS messaging_send_ptr(struct messaging_context *msg, struct server_id server, +NTSTATUS imessaging_send_ptr(struct imessaging_context *msg, struct server_id server, uint32_t msg_type, void *ptr); -void messaging_deregister(struct messaging_context *msg, uint32_t msg_type, void *private_data); -struct server_id messaging_get_server_id(struct messaging_context *msg_ctx); +void imessaging_deregister(struct imessaging_context *msg, uint32_t msg_type, void *private_data); +struct server_id imessaging_get_server_id(struct imessaging_context *msg_ctx); #endif diff --git a/source4/lib/messaging/pymessaging.c b/source4/lib/messaging/pymessaging.c index 358d205b53..cafd45beae 100644 --- a/source4/lib/messaging/pymessaging.c +++ b/source4/lib/messaging/pymessaging.c @@ -31,11 +31,11 @@ #include "param/param.h" #include "param/pyparam.h" #include "librpc/rpc/dcerpc.h" -#include "librpc/gen_ndr/server_id4.h" +#include "librpc/gen_ndr/server_id.h" void initmessaging(void); -extern PyTypeObject messaging_Type; +extern PyTypeObject imessaging_Type; static bool server_id_from_py(PyObject *object, struct server_id *server_id) { @@ -45,12 +45,12 @@ static bool server_id_from_py(PyObject *object, struct server_id *server_id) } if (PyTuple_Size(object) == 3) { - return PyArg_ParseTuple(object, "iii", &server_id->id, &server_id->id2, &server_id->node); + return PyArg_ParseTuple(object, "iii", &server_id->pid, &server_id->task_id, &server_id->vnn); } else { - int id, id2; - if (!PyArg_ParseTuple(object, "ii", &id, &id2)) + int pid, task_id; + if (!PyArg_ParseTuple(object, "ii", &pid, &task_id)) return false; - *server_id = cluster_id(id, id2); + *server_id = cluster_id(pid, task_id); return true; } } @@ -58,23 +58,23 @@ static bool server_id_from_py(PyObject *object, struct server_id *server_id) typedef struct { PyObject_HEAD TALLOC_CTX *mem_ctx; - struct messaging_context *msg_ctx; -} messaging_Object; + struct imessaging_context *msg_ctx; +} imessaging_Object; -static PyObject *py_messaging_connect(PyTypeObject *self, PyObject *args, PyObject *kwargs) +static PyObject *py_imessaging_connect(PyTypeObject *self, PyObject *args, PyObject *kwargs) { struct tevent_context *ev; const char *kwnames[] = { "own_id", "messaging_path", NULL }; PyObject *own_id = Py_None; - const char *messaging_path = NULL; - messaging_Object *ret; + const char *imessaging_path = NULL; + imessaging_Object *ret; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oz:connect", - discard_const_p(char *, kwnames), &own_id, &messaging_path)) { + discard_const_p(char *, kwnames), &own_id, &imessaging_path)) { return NULL; } - ret = PyObject_New(messaging_Object, &messaging_Type); + ret = PyObject_New(imessaging_Object, &imessaging_Type); if (ret == NULL) return NULL; @@ -82,11 +82,11 @@ static PyObject *py_messaging_connect(PyTypeObject *self, PyObject *args, PyObje ev = s4_event_context_init(ret->mem_ctx); - if (messaging_path == NULL) { - messaging_path = lpcfg_messaging_path(ret->mem_ctx, + if (imessaging_path == NULL) { + imessaging_path = lpcfg_imessaging_path(ret->mem_ctx, py_default_loadparm_context(ret->mem_ctx)); } else { - messaging_path = talloc_strdup(ret->mem_ctx, messaging_path); + imessaging_path = talloc_strdup(ret->mem_ctx, imessaging_path); } if (own_id != Py_None) { @@ -95,18 +95,18 @@ static PyObject *py_messaging_connect(PyTypeObject *self, PyObject *args, PyObje if (!server_id_from_py(own_id, &server_id)) return NULL; - ret->msg_ctx = messaging_init(ret->mem_ctx, - messaging_path, + ret->msg_ctx = imessaging_init(ret->mem_ctx, + imessaging_path, server_id, ev); } else { - ret->msg_ctx = messaging_client_init(ret->mem_ctx, - messaging_path, + ret->msg_ctx = imessaging_client_init(ret->mem_ctx, + imessaging_path, ev); } if (ret->msg_ctx == NULL) { - PyErr_SetString(PyExc_RuntimeError, "messaging_connect unable to create a messaging context"); + PyErr_SetString(PyExc_RuntimeError, "imessaging_connect unable to create a messaging context"); talloc_free(ret->mem_ctx); return NULL; } @@ -114,16 +114,16 @@ static PyObject *py_messaging_connect(PyTypeObject *self, PyObject *args, PyObje return (PyObject *)ret; } -static void py_messaging_dealloc(PyObject *self) +static void py_imessaging_dealloc(PyObject *self) { - messaging_Object *iface = (messaging_Object *)self; + imessaging_Object *iface = (imessaging_Object *)self; talloc_free(iface->msg_ctx); self->ob_type->tp_free(self); } -static PyObject *py_messaging_send(PyObject *self, PyObject *args, PyObject *kwargs) +static PyObject *py_imessaging_send(PyObject *self, PyObject *args, PyObject *kwargs) { - messaging_Object *iface = (messaging_Object *)self; + imessaging_Object *iface = (imessaging_Object *)self; uint32_t msg_type; DATA_BLOB data; PyObject *target; @@ -143,7 +143,7 @@ static PyObject *py_messaging_send(PyObject *self, PyObject *args, PyObject *kwa if (!server_id_from_py(target, &server)) return NULL; - status = messaging_send(iface->msg_ctx, server, msg_type, &data); + status = imessaging_send(iface->msg_ctx, server, msg_type, &data); if (NT_STATUS_IS_ERR(status)) { PyErr_SetNTSTATUS(status); return NULL; @@ -152,20 +152,20 @@ static PyObject *py_messaging_send(PyObject *self, PyObject *args, PyObject *kwa Py_RETURN_NONE; } -static void py_msg_callback_wrapper(struct messaging_context *msg, void *private_data, +static void py_msg_callback_wrapper(struct imessaging_context *msg, void *private_data, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data) { PyObject *callback = (PyObject *)private_data; - PyObject_CallFunction(callback, discard_const_p(char, "i(iii)s#"), msg_type, - server_id.id, server_id.id2, server_id.node, + PyObject_CallFunction(callback, discard_const_p(char, "i(iii)s#"), msg_type, + server_id.pid, server_id.task_id, server_id.vnn, data->data, data->length); } -static PyObject *py_messaging_register(PyObject *self, PyObject *args, PyObject *kwargs) +static PyObject *py_imessaging_register(PyObject *self, PyObject *args, PyObject *kwargs) { - messaging_Object *iface = (messaging_Object *)self; + imessaging_Object *iface = (imessaging_Object *)self; int msg_type = -1; PyObject *callback; NTSTATUS status; @@ -180,11 +180,11 @@ static PyObject *py_messaging_register(PyObject *self, PyObject *args, PyObject if (msg_type == -1) { uint32_t msg_type32 = msg_type; - status = messaging_register_tmp(iface->msg_ctx, callback, + status = imessaging_register_tmp(iface->msg_ctx, callback, py_msg_callback_wrapper, &msg_type32); msg_type = msg_type32; } else { - status = messaging_register(iface->msg_ctx, callback, + status = imessaging_register(iface->msg_ctx, callback, msg_type, py_msg_callback_wrapper); } if (NT_STATUS_IS_ERR(status)) { @@ -195,9 +195,9 @@ static PyObject *py_messaging_register(PyObject *self, PyObject *args, PyObject return PyLong_FromLong(msg_type); } -static PyObject *py_messaging_deregister(PyObject *self, PyObject *args, PyObject *kwargs) +static PyObject *py_imessaging_deregister(PyObject *self, PyObject *args, PyObject *kwargs) { - messaging_Object *iface = (messaging_Object *)self; + imessaging_Object *iface = (imessaging_Object *)self; int msg_type = -1; PyObject *callback; const char *kwnames[] = { "callback", "msg_type", NULL }; @@ -207,49 +207,49 @@ static PyObject *py_messaging_deregister(PyObject *self, PyObject *args, PyObjec return NULL; } - messaging_deregister(iface->msg_ctx, msg_type, callback); + imessaging_deregister(iface->msg_ctx, msg_type, callback); Py_DECREF(callback); Py_RETURN_NONE; } -static PyMethodDef py_messaging_methods[] = { - { "send", (PyCFunction)py_messaging_send, METH_VARARGS|METH_KEYWORDS, +static PyMethodDef py_imessaging_methods[] = { + { "send", (PyCFunction)py_imessaging_send, METH_VARARGS|METH_KEYWORDS, "S.send(target, msg_type, data) -> None\nSend a message" }, - { "register", (PyCFunction)py_messaging_register, METH_VARARGS|METH_KEYWORDS, + { "register", (PyCFunction)py_imessaging_register, METH_VARARGS|METH_KEYWORDS, "S.register(callback, msg_type=None) -> msg_type\nRegister a message handler" }, - { "deregister", (PyCFunction)py_messaging_deregister, METH_VARARGS|METH_KEYWORDS, + { "deregister", (PyCFunction)py_imessaging_deregister, METH_VARARGS|METH_KEYWORDS, "S.deregister(callback, msg_type) -> None\nDeregister a message handler" }, { NULL, NULL, 0, NULL } }; -static PyObject *py_messaging_server_id(PyObject *obj, void *closure) +static PyObject *py_imessaging_server_id(PyObject *obj, void *closure) { - messaging_Object *iface = (messaging_Object *)obj; - struct server_id server_id = messaging_get_server_id(iface->msg_ctx); + imessaging_Object *iface = (imessaging_Object *)obj; + struct server_id server_id = imessaging_get_server_id(iface->msg_ctx); - return Py_BuildValue("(iii)", server_id.id, server_id.id2, - server_id.node); + return Py_BuildValue("(iii)", server_id.pid, server_id.task_id, + server_id.vnn); } -static PyGetSetDef py_messaging_getset[] = { - { discard_const_p(char, "server_id"), py_messaging_server_id, NULL, +static PyGetSetDef py_imessaging_getset[] = { + { discard_const_p(char, "server_id"), py_imessaging_server_id, NULL, discard_const_p(char, "local server id") }, { NULL }, }; -PyTypeObject messaging_Type = { +PyTypeObject imessaging_Type = { PyObject_HEAD_INIT(NULL) 0, .tp_name = "messaging.Messaging", - .tp_basicsize = sizeof(messaging_Object), + .tp_basicsize = sizeof(imessaging_Object), .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, - .tp_new = py_messaging_connect, - .tp_dealloc = py_messaging_dealloc, - .tp_methods = py_messaging_methods, - .tp_getset = py_messaging_getset, - .tp_doc = "Messaging(own_id=None, messaging_path=None)\n" \ + .tp_new = py_imessaging_connect, + .tp_dealloc = py_imessaging_dealloc, + .tp_methods = py_imessaging_methods, + .tp_getset = py_imessaging_getset, + .tp_doc = "Messaging(own_id=None, imessaging_path=None)\n" \ "Create a new object that can be used to communicate with the peers in the specified messaging path.\n" \ "If no path is specified, the default path from smb.conf will be used." }; @@ -258,13 +258,13 @@ void initmessaging(void) { PyObject *mod; - if (PyType_Ready(&messaging_Type) < 0) + if (PyType_Ready(&imessaging_Type) < 0) return; mod = Py_InitModule3("messaging", NULL, "Internal RPC"); if (mod == NULL) return; - Py_INCREF((PyObject *)&messaging_Type); - PyModule_AddObject(mod, "Messaging", (PyObject *)&messaging_Type); + Py_INCREF((PyObject *)&imessaging_Type); + PyModule_AddObject(mod, "Messaging", (PyObject *)&imessaging_Type); } diff --git a/source4/lib/messaging/tests/irpc.c b/source4/lib/messaging/tests/irpc.c index 4d0b6b4378..cfa2bcb91e 100644 --- a/source4/lib/messaging/tests/irpc.c +++ b/source4/lib/messaging/tests/irpc.c @@ -34,7 +34,7 @@ static bool test_debug; struct irpc_test_data { - struct messaging_context *msg_ctx1, *msg_ctx2; + struct imessaging_context *msg_ctx1, *msg_ctx2; struct tevent_context *ev; }; @@ -246,15 +246,15 @@ static bool irpc_setup(struct torture_context *tctx, void **_data) data->ev = tctx->ev; torture_assert(tctx, data->msg_ctx1 = - messaging_init(tctx, - lpcfg_messaging_path(tctx, tctx->lp_ctx), + imessaging_init(tctx, + lpcfg_imessaging_path(tctx, tctx->lp_ctx), cluster_id(0, MSG_ID1), data->ev), "Failed to init first messaging context"); torture_assert(tctx, data->msg_ctx2 = - messaging_init(tctx, - lpcfg_messaging_path(tctx, tctx->lp_ctx), + imessaging_init(tctx, + lpcfg_imessaging_path(tctx, tctx->lp_ctx), cluster_id(0, MSG_ID2), data->ev), "Failed to init second messaging context"); diff --git a/source4/lib/messaging/tests/messaging.c b/source4/lib/messaging/tests/messaging.c index 82fdf2f73e..38c34fc52e 100644 --- a/source4/lib/messaging/tests/messaging.c +++ b/source4/lib/messaging/tests/messaging.c @@ -29,24 +29,24 @@ static uint32_t msg_pong; -static void ping_message(struct messaging_context *msg, void *private_data, +static void ping_message(struct imessaging_context *msg, void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *data) { NTSTATUS status; - status = messaging_send(msg, src, msg_pong, data); + status = imessaging_send(msg, src, msg_pong, data); if (!NT_STATUS_IS_OK(status)) { printf("pong failed - %s\n", nt_errstr(status)); } } -static void pong_message(struct messaging_context *msg, void *private_data, +static void pong_message(struct imessaging_context *msg, void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *data) { int *count = (int *)private_data; (*count)++; } -static void exit_message(struct messaging_context *msg, void *private_data, +static void exit_message(struct imessaging_context *msg, void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *data) { talloc_free(private_data); @@ -59,8 +59,8 @@ static void exit_message(struct messaging_context *msg, void *private_data, static bool test_ping_speed(struct torture_context *tctx) { struct tevent_context *ev; - struct messaging_context *msg_client_ctx; - struct messaging_context *msg_server_ctx; + struct imessaging_context *msg_client_ctx; + struct imessaging_context *msg_server_ctx; int ping_count = 0; int pong_count = 0; struct timeval tv; @@ -71,24 +71,24 @@ static bool test_ping_speed(struct torture_context *tctx) ev = tctx->ev; - msg_server_ctx = messaging_init(tctx, - lpcfg_messaging_path(tctx, tctx->lp_ctx), cluster_id(0, 1), + msg_server_ctx = imessaging_init(tctx, + lpcfg_imessaging_path(tctx, tctx->lp_ctx), cluster_id(0, 1), ev); torture_assert(tctx, msg_server_ctx != NULL, "Failed to init ping messaging context"); - messaging_register_tmp(msg_server_ctx, NULL, ping_message, &msg_ping); - messaging_register_tmp(msg_server_ctx, tctx, exit_message, &msg_exit); + imessaging_register_tmp(msg_server_ctx, NULL, ping_message, &msg_ping); + imessaging_register_tmp(msg_server_ctx, tctx, exit_message, &msg_exit); - msg_client_ctx = messaging_init(tctx, - lpcfg_messaging_path(tctx, tctx->lp_ctx), + msg_client_ctx = imessaging_init(tctx, + lpcfg_imessaging_path(tctx, tctx->lp_ctx), cluster_id(0, 2), ev); torture_assert(tctx, msg_client_ctx != NULL, - "msg_client_ctx messaging_init() failed"); + "msg_client_ctx imessaging_init() failed"); - messaging_register_tmp(msg_client_ctx, &pong_count, pong_message, &msg_pong); + imessaging_register_tmp(msg_client_ctx, &pong_count, pong_message, &msg_pong); tv = timeval_current(); @@ -100,8 +100,8 @@ static bool test_ping_speed(struct torture_context *tctx) data.data = discard_const_p(uint8_t, "testing"); data.length = strlen((const char *)data.data); - status1 = messaging_send(msg_client_ctx, cluster_id(0, 1), msg_ping, &data); - status2 = messaging_send(msg_client_ctx, cluster_id(0, 1), msg_ping, NULL); + status1 = imessaging_send(msg_client_ctx, cluster_id(0, 1), msg_ping, &data); + status2 = imessaging_send(msg_client_ctx, cluster_id(0, 1), msg_ping, NULL); torture_assert_ntstatus_ok(tctx, status1, "msg1 failed"); ping_count++; @@ -121,7 +121,7 @@ static bool test_ping_speed(struct torture_context *tctx) } torture_comment(tctx, "sending exit\n"); - messaging_send(msg_client_ctx, cluster_id(0, 1), msg_exit, NULL); + imessaging_send(msg_client_ctx, cluster_id(0, 1), msg_exit, NULL); torture_assert_int_equal(tctx, ping_count, pong_count, "ping test failed"); diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c index f1e14c1b86..42b7374f7a 100644 --- a/source4/lib/registry/rpc.c +++ b/source4/lib/registry/rpc.c @@ -485,7 +485,7 @@ _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, struct dcerpc_pipe *p; struct rpc_registry_context *rctx; - dcerpc_init(lp_ctx); + dcerpc_init(); rctx = talloc(NULL, struct rpc_registry_context); W_ERROR_HAVE_NO_MEMORY(rctx); diff --git a/source4/lib/registry/wscript_build b/source4/lib/registry/wscript_build index 2f0372a933..5adc941718 100644 --- a/source4/lib/registry/wscript_build +++ b/source4/lib/registry/wscript_build @@ -13,7 +13,7 @@ bld.SAMBA_SUBSYSTEM('TDR_REGF', bld.SAMBA_LIBRARY('registry', source='interface.c util.c samba.c patchfile_dotreg.c patchfile_preg.c patchfile.c regf.c hive.c local.c ldb.c dir.c rpc.c', pc_files='registry.pc', - public_deps='samba-util TDR_REGF ldb RPC_NDR_WINREG ldbsamba util_reg', + public_deps='dcerpc samba-util TDR_REGF ldb RPC_NDR_WINREG ldbsamba util_reg', public_headers='registry.h', vnum='0.0.1' ) diff --git a/source4/lib/socket/access.c b/source4/lib/socket/access.c index ab39d63ef5..589797763f 100644 --- a/source4/lib/socket/access.c +++ b/source4/lib/socket/access.c @@ -249,9 +249,9 @@ static bool allow_access_internal(TALLOC_CTX *mem_ctx, } /* return true if access should be allowed */ -bool allow_access(TALLOC_CTX *mem_ctx, - const char **deny_list, const char **allow_list, - const char *cname, const char *caddr) +bool socket_allow_access(TALLOC_CTX *mem_ctx, + const char **deny_list, const char **allow_list, + const char *cname, const char *caddr) { bool ret; char *nc_cname = talloc_strdup(mem_ctx, cname); @@ -346,7 +346,7 @@ bool socket_check_access(struct socket_context *sock, return false; } - ret = allow_access(mem_ctx, deny_list, allow_list, name, addr->addr); + ret = socket_allow_access(mem_ctx, deny_list, allow_list, name, addr->addr); if (ret) { DEBUG(2,("socket_check_access: Allowed connection to '%s' from %s (%s)\n", diff --git a/source4/lib/socket/connect_multi.c b/source4/lib/socket/connect_multi.c index 300e5fb1e5..4ce5115e97 100644 --- a/source4/lib/socket/connect_multi.c +++ b/source4/lib/socket/connect_multi.c @@ -136,7 +136,7 @@ static void connect_multi_next_socket(struct composite_context *result) if (composite_nomem(state, result)) return; state->result = result; - result->status = socket_create("ipv4", SOCKET_TYPE_STREAM, &state->sock, 0); + result->status = socket_create(multi->server_address->family, SOCKET_TYPE_STREAM, &state->sock, 0); if (!composite_is_ok(result)) return; state->addr = socket_address_copy(state, multi->server_address); @@ -162,7 +162,7 @@ static void connect_multi_next_socket(struct composite_context *result) connect attempt state, so it will go away when this request completes */ event_add_timed(result->event_ctx, state, - timeval_current_ofs(0, MULTI_PORT_DELAY), + timeval_current_ofs_usec(MULTI_PORT_DELAY), connect_multi_timer, result); } } diff --git a/source4/lib/socket/interface.c b/source4/lib/socket/interface.c index c4411b623c..d5b610fea7 100644 --- a/source4/lib/socket/interface.c +++ b/source4/lib/socket/interface.c @@ -21,15 +21,19 @@ #include "includes.h" #include "system/network.h" +#include "param/param.h" #include "lib/socket/netif.h" #include "../lib/util/util_net.h" #include "../lib/util/dlinklist.h" -/** used for network interfaces */ +/* used for network interfaces */ struct interface { struct interface *next, *prev; - struct in_addr ip; - struct in_addr nmask; + char *name; + int flags; + struct sockaddr_storage ip; + struct sockaddr_storage netmask; + struct sockaddr_storage bcast; const char *ip_s; const char *bcast_s; const char *nmask_s; @@ -45,31 +49,51 @@ struct interface { /**************************************************************************** Try and find an interface that matches an ip. If we cannot, return NULL **************************************************************************/ -static struct interface *iface_find(struct interface *interfaces, - struct in_addr ip, bool CheckMask) +static struct interface *iface_list_find(struct interface *interfaces, + const struct sockaddr *ip, + bool check_mask) { struct interface *i; - if (is_zero_ip_v4(ip)) return interfaces; - for (i=interfaces;i;i=i->next) - if (CheckMask) { - if (same_net_v4(i->ip,ip,i->nmask)) return i; - } else if (i->ip.s_addr == ip.s_addr) return i; + if (is_address_any(ip)) { + return interfaces; + } + + for (i=interfaces;i;i=i->next) { + if (check_mask) { + if (same_net(ip, (struct sockaddr *)&i->ip, (struct sockaddr *)&i->netmask)) { + return i; + } + } else if (sockaddr_equal((struct sockaddr *)&i->ip, ip)) { + return i; + } + } return NULL; } - /**************************************************************************** add an interface to the linked list of interfaces ****************************************************************************/ -static void add_interface(TALLOC_CTX *mem_ctx, struct in_addr ip, struct in_addr nmask, struct interface **interfaces) +static void add_interface(TALLOC_CTX *mem_ctx, const struct iface_struct *ifs, struct interface **interfaces, + bool enable_ipv6) { + char addr[INET6_ADDRSTRLEN]; struct interface *iface; - struct in_addr bcast; - if (iface_find(*interfaces, ip, false)) { - DEBUG(3,("not adding duplicate interface %s\n",inet_ntoa(ip))); + if (iface_list_find(*interfaces, (const struct sockaddr *)&ifs->ip, false)) { + DEBUG(3,("add_interface: not adding duplicate interface %s\n", + print_sockaddr(addr, sizeof(addr), &ifs->ip) )); + return; + } + + if (!(ifs->flags & (IFF_BROADCAST|IFF_LOOPBACK))) { + DEBUG(3,("not adding non-broadcast interface %s\n", + ifs->name )); + return; + } + + if (!enable_ipv6 && ifs->ip.ss_family != AF_INET) { return; } @@ -79,26 +103,40 @@ static void add_interface(TALLOC_CTX *mem_ctx, struct in_addr ip, struct in_addr ZERO_STRUCTPN(iface); - iface->ip = ip; - iface->nmask = nmask; - bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr); + iface->name = talloc_strdup(iface, ifs->name); + if (!iface->name) { + SAFE_FREE(iface); + return; + } + iface->flags = ifs->flags; + iface->ip = ifs->ip; + iface->netmask = ifs->netmask; + iface->bcast = ifs->bcast; /* keep string versions too, to avoid people tripping over the implied static in inet_ntoa() */ - iface->ip_s = talloc_strdup(iface, inet_ntoa(iface->ip)); - iface->nmask_s = talloc_strdup(iface, inet_ntoa(iface->nmask)); - - if (nmask.s_addr != ~0) { - iface->bcast_s = talloc_strdup(iface, inet_ntoa(bcast)); - } - - DLIST_ADD_END(*interfaces, iface, struct interface *); - - DEBUG(3,("added interface ip=%s nmask=%s\n", iface->ip_s, iface->nmask_s)); + print_sockaddr(addr, sizeof(addr), &iface->ip); + DEBUG(4,("added interface %s ip=%s ", + iface->name, addr)); + iface->ip_s = talloc_strdup(iface, addr); + + print_sockaddr(addr, sizeof(addr), + &iface->bcast); + DEBUG(4,("bcast=%s ", addr)); + iface->bcast_s = talloc_strdup(iface, addr); + + print_sockaddr(addr, sizeof(addr), + &iface->netmask); + DEBUG(4,("netmask=%s\n", addr)); + iface->nmask_s = talloc_strdup(iface, addr); + + /* + this needs to be a ADD_END, as some tests (such as the + spoolss notify test) depend on the interfaces ordering + */ + DLIST_ADD_END(*interfaces, iface, NULL); } - - /** interpret a single element from a interfaces= config line @@ -114,99 +152,155 @@ static void interpret_interface(TALLOC_CTX *mem_ctx, const char *token, struct iface_struct *probed_ifaces, int total_probed, - struct interface **local_interfaces) + struct interface **local_interfaces, + bool enable_ipv6) { - struct in_addr ip, nmask; + struct sockaddr_storage ss; + struct sockaddr_storage ss_mask; + struct sockaddr_storage ss_net; + struct sockaddr_storage ss_bcast; + struct iface_struct ifs; char *p; - char *address; - int i, added=0; + int i; + bool added=false; + bool goodaddr = false; - ip.s_addr = 0; - nmask.s_addr = 0; - /* first check if it is an interface name */ for (i=0;i<total_probed;i++) { if (gen_fnmatch(token, probed_ifaces[i].name) == 0) { - add_interface(mem_ctx, probed_ifaces[i].ip, - probed_ifaces[i].netmask, - local_interfaces); - added = 1; + add_interface(mem_ctx, &probed_ifaces[i], + local_interfaces, enable_ipv6); + added = true; } } - if (added) return; + if (added) { + return; + } /* maybe it is a DNS name */ p = strchr_m(token,'/'); - if (!p) { - /* don't try to do dns lookups on wildcard names */ - if (strpbrk(token, "*?") != NULL) { + if (p == NULL) { + if (!interpret_string_addr(&ss, token, 0)) { + DEBUG(2, ("interpret_interface: Can't find address " + "for %s\n", token)); return; } - ip.s_addr = interpret_addr2(token).s_addr; + for (i=0;i<total_probed;i++) { - if (ip.s_addr == probed_ifaces[i].ip.s_addr) { - add_interface(mem_ctx, probed_ifaces[i].ip, - probed_ifaces[i].netmask, - local_interfaces); + if (sockaddr_equal((struct sockaddr *)&ss, (struct sockaddr *)&probed_ifaces[i].ip)) { + add_interface(mem_ctx, &probed_ifaces[i], + local_interfaces, enable_ipv6); return; } } - DEBUG(2,("can't determine netmask for %s\n", token)); + DEBUG(2,("interpret_interface: " + "can't determine interface for %s\n", + token)); return; } - address = talloc_strdup(mem_ctx, token); - p = strchr_m(address,'/'); - /* parse it into an IP address/netmasklength pair */ - *p++ = 0; - - ip.s_addr = interpret_addr2(address).s_addr; + *p = 0; + goodaddr = interpret_string_addr(&ss, token, 0); + *p++ = '/'; + + if (!goodaddr) { + DEBUG(2,("interpret_interface: " + "can't determine interface for %s\n", + token)); + return; + } if (strlen(p) > 2) { - nmask.s_addr = interpret_addr2(p).s_addr; + goodaddr = interpret_string_addr(&ss_mask, p, 0); + if (!goodaddr) { + DEBUG(2,("interpret_interface: " + "can't determine netmask from %s\n", + p)); + return; + } } else { - nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES)); + char *endp = NULL; + unsigned long val = strtoul(p, &endp, 0); + if (p == endp || (endp && *endp != '\0')) { + DEBUG(2,("interpret_interface: " + "can't determine netmask value from %s\n", + p)); + return; + } + if (!make_netmask(&ss_mask, &ss, val)) { + DEBUG(2,("interpret_interface: " + "can't apply netmask value %lu from %s\n", + val, + p)); + return; + } } - /* maybe the first component was a broadcast address */ - if (ip.s_addr == MKBCADDR(ip.s_addr, nmask.s_addr) || - ip.s_addr == MKNETADDR(ip.s_addr, nmask.s_addr)) { + make_bcast(&ss_bcast, &ss, &ss_mask); + make_net(&ss_net, &ss, &ss_mask); + + /* Maybe the first component was a broadcast address. */ + if (sockaddr_equal((struct sockaddr *)&ss_bcast, (struct sockaddr *)&ss) || + sockaddr_equal((struct sockaddr *)&ss_net, (struct sockaddr *)&ss)) { for (i=0;i<total_probed;i++) { - if (same_net_v4(ip, probed_ifaces[i].ip, nmask)) { - add_interface(mem_ctx, probed_ifaces[i].ip, nmask, - local_interfaces); - talloc_free(address); + if (same_net((struct sockaddr *)&ss, + (struct sockaddr *)&probed_ifaces[i].ip, + (struct sockaddr *)&ss_mask)) { + /* Temporarily replace netmask on + * the detected interface - user knows + * best.... */ + struct sockaddr_storage saved_mask = + probed_ifaces[i].netmask; + probed_ifaces[i].netmask = ss_mask; + DEBUG(2,("interpret_interface: " + "using netmask value %s from " + "config file on interface %s\n", + p, + probed_ifaces[i].name)); + add_interface(mem_ctx, &probed_ifaces[i], + local_interfaces, enable_ipv6); + probed_ifaces[i].netmask = saved_mask; return; } } - DEBUG(2,("Can't determine ip for broadcast address %s\n", address)); - talloc_free(address); + DEBUG(2,("interpret_interface: Can't determine ip for " + "broadcast address %s\n", + token)); return; } - add_interface(mem_ctx, ip, nmask, local_interfaces); - talloc_free(address); + /* Just fake up the interface definition. User knows best. */ + + DEBUG(2,("interpret_interface: Adding interface %s\n", + token)); + + ZERO_STRUCT(ifs); + (void)strlcpy(ifs.name, token, sizeof(ifs.name)); + ifs.flags = IFF_BROADCAST; + ifs.ip = ss; + ifs.netmask = ss_mask; + ifs.bcast = ss_bcast; + add_interface(mem_ctx, &ifs, + local_interfaces, enable_ipv6); } /** load the list of network interfaces **/ -void load_interfaces(TALLOC_CTX *mem_ctx, const char **interfaces, struct interface **local_interfaces) +void load_interface_list(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct interface **local_interfaces) { - const char **ptr = interfaces; + const char **ptr = lpcfg_interfaces(lp_ctx); int i; - struct iface_struct ifaces[MAX_INTERFACES]; - struct in_addr loopback_ip; + struct iface_struct *ifaces; int total_probed; + bool enable_ipv6 = lpcfg_parm_bool(lp_ctx, NULL, "ipv6", "enable", true); *local_interfaces = NULL; - loopback_ip = interpret_addr2("127.0.0.1"); - /* probe the kernel for interfaces */ - total_probed = get_interfaces(ifaces, MAX_INTERFACES); + total_probed = get_interfaces(mem_ctx, &ifaces); /* if we don't have a interfaces line then use all interfaces except loopback */ @@ -215,27 +309,27 @@ void load_interfaces(TALLOC_CTX *mem_ctx, const char **interfaces, struct interf DEBUG(0,("ERROR: Could not determine network interfaces, you must use a interfaces config line\n")); } for (i=0;i<total_probed;i++) { - if (ifaces[i].ip.s_addr != loopback_ip.s_addr) { - add_interface(mem_ctx, ifaces[i].ip, - ifaces[i].netmask, local_interfaces); + if (!is_loopback_addr((struct sockaddr *)&ifaces[i].ip)) { + add_interface(mem_ctx, &ifaces[i], local_interfaces, enable_ipv6); } } } while (ptr && *ptr) { - interpret_interface(mem_ctx, *ptr, ifaces, total_probed, local_interfaces); + interpret_interface(mem_ctx, *ptr, ifaces, total_probed, local_interfaces, enable_ipv6); ptr++; } if (!*local_interfaces) { DEBUG(0,("WARNING: no network interfaces found\n")); } + talloc_free(ifaces); } /** how many interfaces do we have **/ -int iface_count(struct interface *ifaces) +int iface_list_count(struct interface *ifaces) { int ret = 0; struct interface *i; @@ -248,7 +342,7 @@ int iface_count(struct interface *ifaces) /** return IP of the Nth interface **/ -const char *iface_n_ip(struct interface *ifaces, int n) +const char *iface_list_n_ip(struct interface *ifaces, int n) { struct interface *i; @@ -261,10 +355,59 @@ const char *iface_n_ip(struct interface *ifaces, int n) return NULL; } + +/** + return the first IPv4 interface address we have registered + **/ +const char *iface_list_first_v4(struct interface *ifaces) +{ + struct interface *i; + + for (i=ifaces; i; i=i->next) { + if (i->ip.ss_family == AF_INET) { + return i->ip_s; + } + } + return NULL; +} + +/** + return the first IPv6 interface address we have registered + **/ +static const char *iface_list_first_v6(struct interface *ifaces) +{ + struct interface *i; + +#ifdef HAVE_IPV6 + for (i=ifaces; i; i=i->next) { + if (i->ip.ss_family == AF_INET6) { + return i->ip_s; + } + } +#endif + return NULL; +} + +/** + check if an interface is IPv4 + **/ +bool iface_list_n_is_v4(struct interface *ifaces, int n) +{ + struct interface *i; + + for (i=ifaces;i && n;i=i->next) + n--; + + if (i) { + return i->ip.ss_family == AF_INET; + } + return false; +} + /** return bcast of the Nth interface **/ -const char *iface_n_bcast(struct interface *ifaces, int n) +const char *iface_list_n_bcast(struct interface *ifaces, int n) { struct interface *i; @@ -280,7 +423,7 @@ const char *iface_n_bcast(struct interface *ifaces, int n) /** return netmask of the Nth interface **/ -const char *iface_n_netmask(struct interface *ifaces, int n) +const char *iface_list_n_netmask(struct interface *ifaces, int n) { struct interface *i; @@ -297,28 +440,37 @@ const char *iface_n_netmask(struct interface *ifaces, int n) return the local IP address that best matches a destination IP, or our first interface if none match */ -const char *iface_best_ip(struct interface *ifaces, const char *dest) +const char *iface_list_best_ip(struct interface *ifaces, const char *dest) { struct interface *iface; - struct in_addr ip; + struct sockaddr_storage ss; - ip.s_addr = interpret_addr(dest); - iface = iface_find(ifaces, ip, true); + if (!interpret_string_addr(&ss, dest, AI_NUMERICHOST)) { + return iface_list_n_ip(ifaces, 0); + } + iface = iface_list_find(ifaces, (const struct sockaddr *)&ss, true); if (iface) { return iface->ip_s; } - return iface_n_ip(ifaces, 0); +#ifdef HAVE_IPV6 + if (ss.ss_family == AF_INET6) { + return iface_list_first_v6(ifaces); + } +#endif + return iface_list_first_v4(ifaces); } /** return true if an IP is one one of our local networks */ -bool iface_is_local(struct interface *ifaces, const char *dest) +bool iface_list_is_local(struct interface *ifaces, const char *dest) { - struct in_addr ip; + struct sockaddr_storage ss; - ip.s_addr = interpret_addr(dest); - if (iface_find(ifaces, ip, true)) { + if (!interpret_string_addr(&ss, dest, AI_NUMERICHOST)) { + return false; + } + if (iface_list_find(ifaces, (const struct sockaddr *)&ss, true)) { return true; } return false; @@ -327,9 +479,50 @@ bool iface_is_local(struct interface *ifaces, const char *dest) /** return true if a IP matches a IP/netmask pair */ -bool iface_same_net(const char *ip1, const char *ip2, const char *netmask) +bool iface_list_same_net(const char *ip1, const char *ip2, const char *netmask) { - return same_net_v4(interpret_addr2(ip1), - interpret_addr2(ip2), - interpret_addr2(netmask)); + struct sockaddr_storage ip1_ss, ip2_ss, nm_ss; + + if (!interpret_string_addr(&ip1_ss, ip1, AI_NUMERICHOST)) { + return false; + } + if (!interpret_string_addr(&ip2_ss, ip2, AI_NUMERICHOST)) { + return false; + } + if (!interpret_string_addr(&nm_ss, netmask, AI_NUMERICHOST)) { + return false; + } + + return same_net((struct sockaddr *)&ip1_ss, + (struct sockaddr *)&ip2_ss, + (struct sockaddr *)&nm_ss); +} + +/** + return the list of wildcard interfaces + this will include the IPv4 0.0.0.0, and may include IPv6 :: + it is overridden by the 'socket address' option in smb.conf +*/ +const char **iface_list_wildcard(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) +{ + const char **ret; + const char *socket_address; + + /* the user may have configured a specific address */ + socket_address = lpcfg_socket_address(lp_ctx); + if (strcmp(socket_address, "") != 0) { + ret = (const char **)str_list_make(mem_ctx, socket_address, NULL); + return ret; + } + + ret = (const char **)str_list_make(mem_ctx, "0.0.0.0", NULL); + if (ret == NULL) return NULL; + +#ifdef HAVE_IPV6 + if (lpcfg_parm_bool(lp_ctx, NULL, "ipv6", "enable", true)) { + return str_list_add(ret, "::"); + } +#endif + + return ret; } diff --git a/source4/lib/socket/netif.c b/source4/lib/socket/netif.c deleted file mode 100644 index e36f268bde..0000000000 --- a/source4/lib/socket/netif.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - Unix SMB/CIFS implementation. - return a list of network interfaces - Copyright (C) Andrew Tridgell 1998 - Copyright (C) Jeremy Allison 2007 - Copyright (C) Jelmer Vernooij 2007 - - 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 <http://www.gnu.org/licenses/>. -*/ - - -/* working out the interfaces for a OS is an incredibly non-portable - thing. We have several possible implementations below, and autoconf - tries each of them to see what works - - Note that this file does _not_ include includes.h. That is so this code - can be called directly from the autoconf tests. That also means - this code cannot use any of the normal Samba debug stuff or defines. - This is standalone code. - -*/ - -#include "includes.h" -#include "system/network.h" -#include "netif.h" -#include "lib/util/tsort.h" - -/**************************************************************************** - Try the "standard" getifaddrs/freeifaddrs interfaces. - Also gets IPv6 interfaces. -****************************************************************************/ - -/**************************************************************************** - Get the netmask address for a local interface. -****************************************************************************/ - -static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) -{ - struct ifaddrs *iflist = NULL; - struct ifaddrs *ifptr = NULL; - int total = 0; - - if (getifaddrs(&iflist) < 0) { - return -1; - } - - /* Loop through interfaces, looking for given IP address */ - for (ifptr = iflist, total = 0; - ifptr != NULL && total < max_interfaces; - ifptr = ifptr->ifa_next) { - - memset(&ifaces[total], '\0', sizeof(ifaces[total])); - - if (!ifptr->ifa_addr || !ifptr->ifa_netmask) { - continue; - } - - /* Check the interface is up. */ - if (!(ifptr->ifa_flags & IFF_UP)) { - continue; - } - - /* We don't support IPv6 *yet* */ - if (ifptr->ifa_addr->sa_family != AF_INET) { - continue; - } - - ifaces[total].ip = ((struct sockaddr_in *)ifptr->ifa_addr)->sin_addr; - ifaces[total].netmask = ((struct sockaddr_in *)ifptr->ifa_netmask)->sin_addr; - - strlcpy(ifaces[total].name, ifptr->ifa_name, - sizeof(ifaces[total].name)); - total++; - } - - freeifaddrs(iflist); - - return total; -} - -static int iface_comp(struct iface_struct *i1, struct iface_struct *i2) -{ - int r; - r = strcmp(i1->name, i2->name); - if (r) return r; - r = ntohl(i1->ip.s_addr) - ntohl(i2->ip.s_addr); - if (r) return r; - r = ntohl(i1->netmask.s_addr) - ntohl(i2->netmask.s_addr); - return r; -} - -/* this wrapper is used to remove duplicates from the interface list generated - above */ -int get_interfaces(struct iface_struct *ifaces, int max_interfaces) -{ - int total, i, j; - - total = _get_interfaces(ifaces, max_interfaces); - if (total <= 0) return total; - - /* now we need to remove duplicates */ - TYPESAFE_QSORT(ifaces, total, iface_comp); - - for (i=1;i<total;) { - if (iface_comp(&ifaces[i-1], &ifaces[i]) == 0) { - for (j=i-1;j<total-1;j++) { - ifaces[j] = ifaces[j+1]; - } - total--; - } else { - i++; - } - } - - return total; -} diff --git a/source4/lib/socket/netif.h b/source4/lib/socket/netif.h index 417c6e074f..1d90a4fd13 100644 --- a/source4/lib/socket/netif.h +++ b/source4/lib/socket/netif.h @@ -20,17 +20,5 @@ */ #include "system/network.h" - -struct iface_struct { - char name[16]; - struct in_addr ip; - struct in_addr netmask; -}; - -struct interface; - -#define MAX_INTERFACES 128 - -#ifndef AUTOCONF_TEST +#include "lib/socket/interfaces.h" #include "lib/socket/netif_proto.h" -#endif diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 4b5cecab34..2dbdaad11d 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -451,7 +451,7 @@ _PUBLIC_ NTSTATUS socket_dup(struct socket_context *sock) } fd = dup(sock->fd); if (fd == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } close(sock->fd); sock->fd = fd; @@ -473,6 +473,11 @@ _PUBLIC_ struct socket_address *socket_address_from_strings(TALLOC_CTX *mem_ctx, return NULL; } + if (strcmp(family, "ip") == 0 && is_ipaddress_v6(host)) { + /* leaving as "ip" would force IPv4 */ + family = "ipv6"; + } + addr->family = family; addr->addr = talloc_strdup(addr, host); if (!addr->addr) { @@ -498,7 +503,19 @@ _PUBLIC_ struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx if (!addr) { return NULL; } - addr->family = NULL; + switch (sockaddr->sa_family) { + case AF_INET: + addr->family = "ipv4"; + break; +#ifdef HAVE_IPV6 + case AF_INET6: + addr->family = "ipv6"; + break; +#endif + case AF_UNIX: + addr->family = "unix"; + break; + } addr->addr = NULL; addr->port = 0; addr->sockaddr = (struct sockaddr *)talloc_memdup(addr, sockaddr, sockaddrlen); @@ -510,6 +527,50 @@ _PUBLIC_ struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx return addr; } + +/* + Create a new socket_address from sockaddr_storage + */ +_PUBLIC_ struct socket_address *socket_address_from_sockaddr_storage(TALLOC_CTX *mem_ctx, + const struct sockaddr_storage *sockaddr, + uint16_t port) +{ + struct socket_address *addr = talloc_zero(mem_ctx, struct socket_address); + char addr_str[INET6_ADDRSTRLEN+1]; + const char *str; + + if (!addr) { + return NULL; + } + addr->port = port; + switch (sockaddr->ss_family) { + case AF_INET: + addr->family = "ipv4"; + break; +#ifdef HAVE_IPV6 + case AF_INET6: + addr->family = "ipv6"; + break; +#endif + default: + talloc_free(addr); + return NULL; + } + + str = print_sockaddr(addr_str, sizeof(addr_str), sockaddr); + if (str == NULL) { + talloc_free(addr); + return NULL; + } + addr->addr = talloc_strdup(addr, str); + if (addr->addr == NULL) { + talloc_free(addr); + return NULL; + } + + return addr; +} + /* Copy a socket_address structure */ struct socket_address *socket_address_copy(TALLOC_CTX *mem_ctx, const struct socket_address *oaddr) @@ -567,110 +628,6 @@ _PUBLIC_ const struct socket_ops *socket_getops_byname(const char *family, enum return NULL; } -enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON}; - -static const struct { - const char *name; - int level; - int option; - int value; - int opttype; -} socket_options[] = { - {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL}, - {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL}, - {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL}, -#ifdef TCP_NODELAY - {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL}, -#endif -#ifdef IPTOS_LOWDELAY - {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON}, -#endif -#ifdef IPTOS_THROUGHPUT - {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON}, -#endif -#ifdef SO_REUSEPORT - {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL}, -#endif -#ifdef SO_SNDBUF - {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT}, -#endif -#ifdef SO_RCVBUF - {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT}, -#endif -#ifdef SO_SNDLOWAT - {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT}, -#endif -#ifdef SO_RCVLOWAT - {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT}, -#endif -#ifdef SO_SNDTIMEO - {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT}, -#endif -#ifdef SO_RCVTIMEO - {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT}, -#endif - {NULL,0,0,0,0}}; - - -/** - Set user socket options. -**/ -_PUBLIC_ void set_socket_options(int fd, const char *options) -{ - const char **options_list = (const char **)str_list_make(NULL, options, " \t,"); - int j; - - if (!options_list) - return; - - for (j = 0; options_list[j]; j++) { - const char *tok = options_list[j]; - int ret=0,i; - int value = 1; - char *p; - bool got_value = false; - - if ((p = strchr(tok,'='))) { - *p = 0; - value = atoi(p+1); - got_value = true; - } - - for (i=0;socket_options[i].name;i++) - if (strequal(socket_options[i].name,tok)) - break; - - if (!socket_options[i].name) { - DEBUG(0,("Unknown socket option %s\n",tok)); - continue; - } - - switch (socket_options[i].opttype) { - case OPT_BOOL: - case OPT_INT: - ret = setsockopt(fd,socket_options[i].level, - socket_options[i].option,(char *)&value,sizeof(int)); - break; - - case OPT_ON: - if (got_value) - DEBUG(0,("syntax error - %s does not take a value\n",tok)); - - { - int on = socket_options[i].value; - ret = setsockopt(fd,socket_options[i].level, - socket_options[i].option,(char *)&on,sizeof(int)); - } - break; - } - - if (ret != 0) - DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) )); - } - - talloc_free(options_list); -} - /* set some flags on a socket */ diff --git a/source4/lib/socket/socket.h b/source4/lib/socket/socket.h index 4a744797b3..e00b61ba6c 100644 --- a/source4/lib/socket/socket.h +++ b/source4/lib/socket/socket.h @@ -174,14 +174,18 @@ struct socket_address *socket_address_from_strings(TALLOC_CTX *mem_ctx, struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx, struct sockaddr *sockaddr, size_t addrlen); +struct sockaddr_storage; +struct socket_address *socket_address_from_sockaddr_storage(TALLOC_CTX *mem_ctx, + const struct sockaddr_storage *sockaddr, + uint16_t port); _PUBLIC_ void socket_address_set_port(struct socket_address *a, uint16_t port); struct socket_address *socket_address_copy(TALLOC_CTX *mem_ctx, const struct socket_address *oaddr); const struct socket_ops *socket_getops_byname(const char *name, enum socket_type type); -bool allow_access(TALLOC_CTX *mem_ctx, - const char **deny_list, const char **allow_list, - const char *cname, const char *caddr); +bool socket_allow_access(TALLOC_CTX *mem_ctx, + const char **deny_list, const char **allow_list, + const char *cname, const char *caddr); bool socket_check_access(struct socket_context *sock, const char *service_name, const char **allow_list, const char **deny_list); diff --git a/source4/lib/socket/socket_ip.c b/source4/lib/socket/socket_ip.c index 4e66653252..80f7d333f3 100644 --- a/source4/lib/socket/socket_ip.c +++ b/source4/lib/socket/socket_ip.c @@ -47,7 +47,7 @@ static NTSTATUS ipv4_init(struct socket_context *sock) sock->fd = socket(PF_INET, type, 0); if (sock->fd == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } sock->backend_name = "ipv4"; @@ -70,16 +70,16 @@ static NTSTATUS ip_connect_complete(struct socket_context *sock, uint32_t flags) for non-blocking connect */ ret = getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, &error, &len); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } if (error != 0) { - return map_nt_error_from_unix(error); + return map_nt_error_from_unix_common(error); } if (!(flags & SOCKET_FLAG_BLOCK)) { ret = set_blocking(sock->fd, false); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } } @@ -102,7 +102,7 @@ static NTSTATUS ipv4_connect(struct socket_context *sock, if (my_address && my_address->sockaddr) { ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } } else if (my_address) { my_ip = interpret_addr2(my_address->addr); @@ -119,7 +119,7 @@ static NTSTATUS ipv4_connect(struct socket_context *sock, ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } } } @@ -127,7 +127,7 @@ static NTSTATUS ipv4_connect(struct socket_context *sock, if (srv_address->sockaddr) { ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } } else { srv_ip = interpret_addr2(srv_address->addr); @@ -147,7 +147,7 @@ static NTSTATUS ipv4_connect(struct socket_context *sock, ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr)); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } } @@ -186,20 +186,20 @@ static NTSTATUS ipv4_listen(struct socket_context *sock, } if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } if (sock->type == SOCKET_TYPE_STREAM) { ret = listen(sock->fd, queue_size); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } } if (!(flags & SOCKET_FLAG_BLOCK)) { ret = set_blocking(sock->fd, false); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } } @@ -220,14 +220,14 @@ static NTSTATUS ipv4_accept(struct socket_context *sock, struct socket_context * new_fd = accept(sock->fd, (struct sockaddr *)&cli_addr, &cli_addr_len); if (new_fd == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } if (!(sock->flags & SOCKET_FLAG_BLOCK)) { int ret = set_blocking(new_fd, false); if (ret == -1) { close(new_fd); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } } @@ -268,7 +268,7 @@ static NTSTATUS ip_recv(struct socket_context *sock, void *buf, if (gotlen == 0) { return NT_STATUS_END_OF_FILE; } else if (gotlen == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } *nread = gotlen; @@ -311,7 +311,7 @@ static NTSTATUS ipv4_recvfrom(struct socket_context *sock, void *buf, return NT_STATUS_END_OF_FILE; } else if (gotlen == -1) { talloc_free(src); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } src->sockaddrlen = from_len; @@ -342,7 +342,7 @@ static NTSTATUS ip_send(struct socket_context *sock, len = send(sock->fd, blob->data, blob->length, 0); if (len == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } *sendlen = len; @@ -383,7 +383,7 @@ static NTSTATUS ipv4_sendto(struct socket_context *sock, (struct sockaddr *)&srv_addr, sizeof(srv_addr)); } if (len == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } *sendlen = len; @@ -518,7 +518,7 @@ static NTSTATUS ip_pending(struct socket_context *sock, size_t *npending) *npending = value; return NT_STATUS_OK; } - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } static const struct socket_ops ipv4_ops = { @@ -604,7 +604,7 @@ static NTSTATUS ipv6_init(struct socket_context *sock) sock->fd = socket(PF_INET6, type, 0); if (sock->fd == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } sock->backend_name = "ipv6"; @@ -623,7 +623,7 @@ static NTSTATUS ipv6_tcp_connect(struct socket_context *sock, if (my_address && my_address->sockaddr) { ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } } else if (my_address) { struct in6_addr my_ip; @@ -638,7 +638,7 @@ static NTSTATUS ipv6_tcp_connect(struct socket_context *sock, ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } } } @@ -661,15 +661,28 @@ static NTSTATUS ipv6_tcp_connect(struct socket_context *sock, ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr)); } if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } return ip_connect_complete(sock, flags); } +/* + fix the sin6_scope_id based on the address interface + */ +static void fix_scope_id(struct sockaddr_in6 *in6, + const char *address) +{ + const char *p = strchr(address, '%'); + if (p != NULL) { + in6->sin6_scope_id = if_nametoindex(p+1); + } +} + + static NTSTATUS ipv6_listen(struct socket_context *sock, - const struct socket_address *my_address, - int queue_size, uint32_t flags) + const struct socket_address *my_address, + int queue_size, uint32_t flags) { struct sockaddr_in6 my_addr; struct in6_addr ip_addr; @@ -680,31 +693,38 @@ static NTSTATUS ipv6_listen(struct socket_context *sock, if (my_address->sockaddr) { ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); } else { + int one = 1; ip_addr = interpret_addr6(my_address->addr); ZERO_STRUCT(my_addr); my_addr.sin6_addr = ip_addr; my_addr.sin6_port = htons(my_address->port); my_addr.sin6_family = PF_INET6; - - ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); + fix_scope_id(&my_addr, my_address->addr); + + /* when binding on ipv6 we always want to only bind on v6 */ + ret = setsockopt(sock->fd, IPPROTO_IPV6, IPV6_V6ONLY, + (const void *)&one, sizeof(one)); + if (ret != -1) { + ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); + } } if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } if (sock->type == SOCKET_TYPE_STREAM) { ret = listen(sock->fd, queue_size); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } } if (!(flags & SOCKET_FLAG_BLOCK)) { ret = set_blocking(sock->fd, false); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } } @@ -725,14 +745,14 @@ static NTSTATUS ipv6_tcp_accept(struct socket_context *sock, struct socket_conte new_fd = accept(sock->fd, (struct sockaddr *)&cli_addr, &cli_addr_len); if (new_fd == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } if (!(sock->flags & SOCKET_FLAG_BLOCK)) { int ret = set_blocking(new_fd, false); if (ret == -1) { close(new_fd); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } } @@ -796,7 +816,7 @@ static NTSTATUS ipv6_recvfrom(struct socket_context *sock, void *buf, return NT_STATUS_END_OF_FILE; } else if (gotlen == -1) { talloc_free(src); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } src->sockaddrlen = from_len; @@ -847,7 +867,7 @@ static NTSTATUS ipv6_sendto(struct socket_context *sock, (struct sockaddr *)&srv_addr, sizeof(srv_addr)); } if (len == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } *sendlen = len; diff --git a/source4/lib/socket/socket_unix.c b/source4/lib/socket/socket_unix.c index f1fa0a3a30..d492f01268 100644 --- a/source4/lib/socket/socket_unix.c +++ b/source4/lib/socket/socket_unix.c @@ -33,7 +33,7 @@ _PUBLIC_ const struct socket_ops *socket_unixdom_ops(enum socket_type type); */ static NTSTATUS unixdom_error(int ernum) { - return map_nt_error_from_unix(ernum); + return map_nt_error_from_unix_common(ernum); } static NTSTATUS unixdom_init(struct socket_context *sock) @@ -53,7 +53,7 @@ static NTSTATUS unixdom_init(struct socket_context *sock) sock->fd = socket(PF_UNIX, type, 0); if (sock->fd == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } sock->private_data = NULL; @@ -76,16 +76,16 @@ static NTSTATUS unixdom_connect_complete(struct socket_context *sock, uint32_t f for non-blocking connect */ ret = getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, &error, &len); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } if (error != 0) { - return map_nt_error_from_unix(error); + return map_nt_error_from_unix_common(error); } if (!(flags & SOCKET_FLAG_BLOCK)) { ret = set_blocking(sock->fd, false); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } } @@ -194,7 +194,7 @@ static NTSTATUS unixdom_accept(struct socket_context *sock, int ret = set_blocking(new_fd, false); if (ret == -1) { close(new_fd); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } } @@ -280,7 +280,7 @@ static NTSTATUS unixdom_sendto(struct socket_context *sock, (struct sockaddr *)&srv_addr, sizeof(srv_addr)); } if (len == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } *sendlen = len; @@ -390,7 +390,7 @@ static NTSTATUS unixdom_pending(struct socket_context *sock, size_t *npending) *npending = value; return NT_STATUS_OK; } - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } static const struct socket_ops unixdom_ops = { diff --git a/source4/lib/socket/testsuite.c b/source4/lib/socket/testsuite.c index 2489277433..357e4ae5df 100644 --- a/source4/lib/socket/testsuite.c +++ b/source4/lib/socket/testsuite.c @@ -42,7 +42,7 @@ static bool test_udp(struct torture_context *tctx) TALLOC_CTX *mem_ctx = tctx; struct interface *ifaces; - load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces); + load_interface_list(tctx, tctx->lp_ctx, &ifaces); status = socket_create("ip", SOCKET_TYPE_DGRAM, &sock1, 0); torture_assert_ntstatus_ok(tctx, status, "creating DGRAM IP socket 1"); @@ -53,7 +53,7 @@ static bool test_udp(struct torture_context *tctx) talloc_steal(mem_ctx, sock2); localhost = socket_address_from_strings(sock1, sock1->backend_name, - iface_best_ip(ifaces, "127.0.0.1"), 0); + iface_list_best_ip(ifaces, "127.0.0.1"), 0); torture_assert(tctx, localhost, "Localhost not found"); @@ -62,10 +62,10 @@ static bool test_udp(struct torture_context *tctx) srv_addr = socket_get_my_addr(sock1, mem_ctx); torture_assert(tctx, srv_addr != NULL && - strcmp(srv_addr->addr, iface_best_ip(ifaces, "127.0.0.1")) == 0, + strcmp(srv_addr->addr, iface_list_best_ip(ifaces, "127.0.0.1")) == 0, talloc_asprintf(tctx, "Expected server address of %s but got %s", - iface_best_ip(ifaces, "127.0.0.1"), srv_addr ? srv_addr->addr : NULL)); + iface_list_best_ip(ifaces, "127.0.0.1"), srv_addr ? srv_addr->addr : NULL)); torture_comment(tctx, "server port is %d\n", srv_addr->port); @@ -135,9 +135,9 @@ static bool test_tcp(struct torture_context *tctx) torture_assert_ntstatus_ok(tctx, status, "creating IP stream socket 1"); talloc_steal(mem_ctx, sock2); - load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces); + load_interface_list(tctx, tctx->lp_ctx, &ifaces); localhost = socket_address_from_strings(sock1, sock1->backend_name, - iface_best_ip(ifaces, "127.0.0.1"), 0); + iface_list_best_ip(ifaces, "127.0.0.1"), 0); torture_assert(tctx, localhost, "Localhost not found"); status = socket_listen(sock1, localhost, 0, 0); @@ -147,7 +147,7 @@ static bool test_tcp(struct torture_context *tctx) torture_assert(tctx, srv_addr && srv_addr->addr, "Unexpected socket_get_my_addr NULL\n"); - torture_assert_str_equal(tctx, srv_addr->addr, iface_best_ip(ifaces, "127.0.0.1"), + torture_assert_str_equal(tctx, srv_addr->addr, iface_list_best_ip(ifaces, "127.0.0.1"), "Unexpected server address"); torture_comment(tctx, "server port is %d\n", srv_addr->port); diff --git a/source4/lib/socket/wscript_build b/source4/lib/socket/wscript_build index e2ff9b078a..c10970d17a 100644 --- a/source4/lib/socket/wscript_build +++ b/source4/lib/socket/wscript_build @@ -1,11 +1,11 @@ #!/usr/bin/env python bld.SAMBA_LIBRARY('netif', - source='interface.c netif.c', - autoproto='netif_proto.h', - deps='samba-util', - private_library=True - ) + source='interface.c', + deps='samba-util interfaces samba-hostconfig', + private_library=True, + autoproto='netif_proto.h' + ) bld.SAMBA_MODULE('socket_ip', source='socket_ip.c', diff --git a/source4/lib/tdb_wrap.c b/source4/lib/tdb_wrap.c deleted file mode 100644 index 97294e13d3..0000000000 --- a/source4/lib/tdb_wrap.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - Unix SMB/CIFS implementation. - TDB wrap functions - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007 - - 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 <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include <tdb.h> -#include "../lib/util/dlinklist.h" -#include "tdb_wrap.h" -#include <tdb.h> - -static struct tdb_wrap *tdb_list; - -/* destroy the last connection to a tdb */ -static int tdb_wrap_destructor(struct tdb_wrap *w) -{ - tdb_close(w->tdb); - DLIST_REMOVE(tdb_list, w); - return 0; -} - -/* - Log tdb messages via DEBUG(). -*/ -static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, - const char *format, ...) PRINTF_ATTRIBUTE(3,4); - -static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, - const char *format, ...) -{ - va_list ap; - char *ptr = NULL; - int dl; - - va_start(ap, format); - vasprintf(&ptr, format, ap); - va_end(ap); - - switch (level) { - case TDB_DEBUG_FATAL: - dl = 0; - break; - case TDB_DEBUG_ERROR: - dl = 1; - break; - case TDB_DEBUG_WARNING: - dl = 2; - break; - case TDB_DEBUG_TRACE: - dl = 5; - break; - default: - dl = 0; - } - - if (ptr != NULL) { - const char *name = tdb_name(tdb); - DEBUG(dl, ("tdb(%s): %s", name ? name : "unnamed", ptr)); - free(ptr); - } -} - - -/* - wrapped connection to a tdb database - to close just talloc_free() the tdb_wrap pointer - */ -struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx, - const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode) -{ - struct tdb_wrap *w; - struct tdb_logging_context log_ctx; - log_ctx.log_fn = tdb_wrap_log; - - for (w=tdb_list;w;w=w->next) { - if (strcmp(name, w->name) == 0) { - return talloc_reference(mem_ctx, w); - } - } - - w = talloc(mem_ctx, struct tdb_wrap); - if (w == NULL) { - return NULL; - } - - w->name = talloc_strdup(w, name); - - w->tdb = tdb_open_ex(name, hash_size, tdb_flags, - open_flags, mode, &log_ctx, NULL); - if (w->tdb == NULL) { - talloc_free(w); - return NULL; - } - - talloc_set_destructor(w, tdb_wrap_destructor); - - DLIST_ADD(tdb_list, w); - - return w; -} diff --git a/source4/lib/tdb_wrap.h b/source4/lib/tdb_wrap.h deleted file mode 100644 index 94035c1bea..0000000000 --- a/source4/lib/tdb_wrap.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - database wrap headers - - Copyright (C) Andrew Tridgell 2004 - - 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 <http://www.gnu.org/licenses/>. -*/ - -/* IMPORTANT: tdb_wrap should be always preferred over tdb_context for end consumer functions - it's because if the code will be running inside smbd, then we must use the linked list - of open tdb files, to determine if the tdb we desire is already open - as otherwise, when you close the tdb (even on a different file descriptor), - ALL LOCKS are lost (due to a real screwup in the POSIX specification that nobody has been able to get fixed) -*/ - -#ifndef _TDB_WRAP_H_ -#define _TDB_WRAP_H_ - -#include <tdb.h> - -struct tdb_wrap { - struct tdb_context *tdb; - - const char *name; - struct tdb_wrap *next, *prev; -}; - -struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx, - const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode); - -#endif /* _TDB_WRAP_H_ */ diff --git a/source4/lib/wscript_build b/source4/lib/wscript_build index 872259d670..cf60820da7 100644 --- a/source4/lib/wscript_build +++ b/source4/lib/wscript_build @@ -5,12 +5,3 @@ bld.SAMBA_SUBSYSTEM('GENCACHE', enabled=False, deps='tdb-wrap' ) - - -bld.SAMBA_LIBRARY('tdb-wrap', - source='tdb_wrap.c', - deps='tdb talloc samba-util', - public_headers='tdb_wrap.h', - private_library=True - ) - diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index f521b5f420..f5e02dd458 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -51,34 +51,6 @@ static NTSTATUS smbcli_link_internal(struct smbcli_tree *tree, } /**************************************************************************** - Map standard UNIX permissions onto wire representations. -****************************************************************************/ -uint32_t unix_perms_to_wire(mode_t perms) -{ - unsigned int ret = 0; - - ret |= ((perms & S_IXOTH) ? UNIX_X_OTH : 0); - ret |= ((perms & S_IWOTH) ? UNIX_W_OTH : 0); - ret |= ((perms & S_IROTH) ? UNIX_R_OTH : 0); - ret |= ((perms & S_IXGRP) ? UNIX_X_GRP : 0); - ret |= ((perms & S_IWGRP) ? UNIX_W_GRP : 0); - ret |= ((perms & S_IRGRP) ? UNIX_R_GRP : 0); - ret |= ((perms & S_IXUSR) ? UNIX_X_USR : 0); - ret |= ((perms & S_IWUSR) ? UNIX_W_USR : 0); - ret |= ((perms & S_IRUSR) ? UNIX_R_USR : 0); -#ifdef S_ISVTX - ret |= ((perms & S_ISVTX) ? UNIX_STICKY : 0); -#endif -#ifdef S_ISGID - ret |= ((perms & S_ISGID) ? UNIX_SET_GID : 0); -#endif -#ifdef S_ISUID - ret |= ((perms & S_ISUID) ? UNIX_SET_UID : 0); -#endif - return ret; -} - -/**************************************************************************** Symlink a file (UNIX extensions). ****************************************************************************/ NTSTATUS smbcli_unix_symlink(struct smbcli_tree *tree, const char *fname_src, diff --git a/source4/libcli/finddcs_nbt.c b/source4/libcli/finddcs_nbt.c index 12b94f7bab..9579a9e449 100644 --- a/source4/libcli/finddcs_nbt.c +++ b/source4/libcli/finddcs_nbt.c @@ -33,7 +33,7 @@ struct finddcs_nbt_state { struct tevent_context *ev; struct tevent_req *req; - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; const char *my_netbios_name; const char *domain_name; @@ -70,7 +70,7 @@ struct tevent_req *finddcs_nbt_send(TALLOC_CTX *mem_ctx, struct dom_sid *domain_sid, struct resolve_context *resolve_ctx, struct tevent_context *event_ctx, - struct messaging_context *msg_ctx) + struct imessaging_context *msg_ctx) { struct finddcs_nbt_state *state; struct nbt_name name; @@ -295,7 +295,7 @@ NTSTATUS finddcs_nbt(TALLOC_CTX *mem_ctx, struct dom_sid *domain_sid, struct resolve_context *resolve_ctx, struct tevent_context *event_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, int *num_dcs, struct nbt_dc_name **dcs) { struct tevent_req *req = finddcs_nbt_send(mem_ctx, diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 65659794c5..f5cf25ec3f 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -221,7 +221,7 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, NULL }; - gensec_init(lp_ctx); + gensec_init(); status = gensec_client_start(conn, &conn->gensec, conn->event.event_ctx, diff --git a/source4/libcli/rap/rap.c b/source4/libcli/rap/rap.c index 5ea9e816e8..7743f64c4c 100644 --- a/source4/libcli/rap/rap.c +++ b/source4/libcli/rap/rap.c @@ -1633,3 +1633,50 @@ NTSTATUS smbcli_rap_netuserdelete(struct smbcli_tree *tree, talloc_free(call); return result; } + +NTSTATUS smbcli_rap_netremotetod(struct smbcli_tree *tree, + TALLOC_CTX *mem_ctx, + struct rap_NetRemoteTOD *r) +{ + struct rap_call *call; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + if (!(call = new_rap_cli_call(mem_ctx, RAP_NetRemoteTOD))) { + return NT_STATUS_NO_MEMORY; + } + + rap_cli_push_rcvbuf(call, r->in.bufsize); + + rap_cli_expect_format(call, "DDBBBBWWBBWB"); + rap_cli_expect_extra_format(call, ""); + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(rap_NetRemoteTOD, r); + } + + result = rap_cli_do_call(tree, call); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + result = NT_STATUS_INVALID_PARAMETER; + + NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status)); + NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert)); + + NDR_GOTO(ndr_pull_rap_TimeOfDayInfo(call->ndr_pull_data, NDR_SCALARS|NDR_BUFFERS, &r->out.tod)); + + result = NT_STATUS_OK; + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(rap_NetRemoteTOD, r); + } + + done: + talloc_free(call); + return result; +} diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 84bf250f6a..bf608f1ec1 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -229,7 +229,7 @@ _PUBLIC_ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, cons make_nbt_name(&nbt_name, host, name_type); - status = resolve_name(resolve_ctx, &nbt_name, tmp_ctx, &address, event_ctx); + status = resolve_name_ex(resolve_ctx, 0, 0, &nbt_name, tmp_ctx, &address, event_ctx); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return NULL; diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 7a3993c79b..43316692a4 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -338,7 +338,7 @@ _PUBLIC_ void smbcli_transport_idle_handler(struct smbcli_transport *transport, transport->socket->event.te = event_add_timed(transport->socket->event.ctx, transport, - timeval_current_ofs(0, period), + timeval_current_ofs_usec(period), idle_handler, transport); } diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index f3ce4e9c5f..d20367474a 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -924,8 +924,8 @@ enum smb_setfileinfo_level { RAW_SFILEINFO_END_OF_FILE_INFO = SMB_SFILEINFO_END_OF_FILE_INFO, RAW_SFILEINFO_UNIX_BASIC = SMB_SFILEINFO_UNIX_BASIC, RAW_SFILEINFO_UNIX_INFO2 = SMB_SFILEINFO_UNIX_INFO2, - RAW_SFILEINFO_UNIX_LINK = SMB_SFILEINFO_UNIX_LINK, - RAW_SFILEINFO_UNIX_HLINK = SMB_SFILEINFO_UNIX_HLINK, + RAW_SFILEINFO_UNIX_LINK = SMB_SET_FILE_UNIX_LINK, + RAW_SFILEINFO_UNIX_HLINK = SMB_SET_FILE_UNIX_HLINK, RAW_SFILEINFO_BASIC_INFORMATION = SMB_SFILEINFO_BASIC_INFORMATION, RAW_SFILEINFO_RENAME_INFORMATION = SMB_SFILEINFO_RENAME_INFORMATION, RAW_SFILEINFO_LINK_INFORMATION = SMB_SFILEINFO_LINK_INFORMATION, diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 5797540edd..1cacaab5cf 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -29,52 +29,6 @@ if (!req) return NULL; \ } while (0) -/** - Return a string representing a CIFS attribute for a file. -**/ -char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib) -{ - int i, len; - const struct { - char c; - uint16_t attr; - } attr_strs[] = { - {'V', FILE_ATTRIBUTE_VOLUME}, - {'D', FILE_ATTRIBUTE_DIRECTORY}, - {'A', FILE_ATTRIBUTE_ARCHIVE}, - {'H', FILE_ATTRIBUTE_HIDDEN}, - {'S', FILE_ATTRIBUTE_SYSTEM}, - {'N', FILE_ATTRIBUTE_NORMAL}, - {'R', FILE_ATTRIBUTE_READONLY}, - {'d', FILE_ATTRIBUTE_DEVICE}, - {'t', FILE_ATTRIBUTE_TEMPORARY}, - {'s', FILE_ATTRIBUTE_SPARSE}, - {'r', FILE_ATTRIBUTE_REPARSE_POINT}, - {'c', FILE_ATTRIBUTE_COMPRESSED}, - {'o', FILE_ATTRIBUTE_OFFLINE}, - {'n', FILE_ATTRIBUTE_NONINDEXED}, - {'e', FILE_ATTRIBUTE_ENCRYPTED} - }; - char *ret; - - ret = talloc_array(mem_ctx, char, ARRAY_SIZE(attr_strs)+1); - if (!ret) { - return NULL; - } - - for (len=i=0; i<ARRAY_SIZE(attr_strs); i++) { - if (attrib & attr_strs[i].attr) { - ret[len++] = attr_strs[i].c; - } - } - - ret[len] = 0; - - talloc_set_name_const(ret, ret); - - return ret; -} - /**************************************************************************** Rename a file - async interface ****************************************************************************/ @@ -950,6 +904,7 @@ struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_loc break; } case RAW_LOCK_SMB2: + case RAW_LOCK_SMB2_BREAK: return NULL; } diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 6ad3e9ee8d..ff36d50e94 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -262,11 +262,11 @@ static bool smb_raw_setinfo_backend(struct smbcli_tree *tree, return smb_raw_setfileinfo_passthru(mem_ctx, parms->generic.level, parms, blob); - /* Unhandled levels */ - + /* Unhandled levels */ case RAW_SFILEINFO_UNIX_LINK: case RAW_SFILEINFO_UNIX_HLINK: case RAW_SFILEINFO_RENAME_INFORMATION_SMB2: + case RAW_SFILEINFO_LINK_INFORMATION: break; } diff --git a/source4/libcli/raw/smb.h b/source4/libcli/raw/smb.h index 05bf91fe3b..008ab57c0d 100644 --- a/source4/libcli/raw/smb.h +++ b/source4/libcli/raw/smb.h @@ -23,8 +23,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef _SMB_H -#define _SMB_H +#ifndef _RAW_SMB_H +#define _RAW_SMB_H /* deny modes */ #define DENY_DOS 0 @@ -366,24 +366,6 @@ #define DESIRED_ACCESS_PIPE 0x2019f -/* FileAttributes (search attributes) field */ -#define FILE_ATTRIBUTE_READONLY 0x0001 -#define FILE_ATTRIBUTE_HIDDEN 0x0002 -#define FILE_ATTRIBUTE_SYSTEM 0x0004 -#define FILE_ATTRIBUTE_VOLUME 0x0008 -#define FILE_ATTRIBUTE_DIRECTORY 0x0010 -#define FILE_ATTRIBUTE_ARCHIVE 0x0020 -#define FILE_ATTRIBUTE_DEVICE 0x0040 -#define FILE_ATTRIBUTE_NORMAL 0x0080 -#define FILE_ATTRIBUTE_TEMPORARY 0x0100 -#define FILE_ATTRIBUTE_SPARSE 0x0200 -#define FILE_ATTRIBUTE_REPARSE_POINT 0x0400 -#define FILE_ATTRIBUTE_COMPRESSED 0x0800 -#define FILE_ATTRIBUTE_OFFLINE 0x1000 -#define FILE_ATTRIBUTE_NONINDEXED 0x2000 -#define FILE_ATTRIBUTE_ENCRYPTED 0x4000 -#define FILE_ATTRIBUTE_ALL_MASK 0x7FFF - /* Flags - combined with attributes. */ #define FILE_FLAG_WRITE_THROUGH 0x80000000L #define FILE_FLAG_NO_BUFFERING 0x20000000L @@ -472,7 +454,7 @@ /* where to find the base of the SMB packet proper */ /* REWRITE TODO: smb_base needs to be removed */ -#define smb_base(buf) (((char *)(buf))+4) +#define smb_base(buf) (((const char *)(buf))+4) /* we don't allow server strings to be longer than 48 characters as otherwise NT will not honour the announce packets */ @@ -600,4 +582,4 @@ #include "libcli/raw/interfaces.h" #include "libcli/smb/smb_common.h" -#endif /* _SMB_H */ +#endif /* _RAW_SMB_H */ diff --git a/source4/libcli/raw/trans2.h b/source4/libcli/raw/trans2.h index 63632eb5ed..d9a3f5f7d2 100644 --- a/source4/libcli/raw/trans2.h +++ b/source4/libcli/raw/trans2.h @@ -316,161 +316,4 @@ Found 0 aliased levels #define MAX_MAC_INFO_LEVEL 0x3FF #define SMB_QFS_MAC_FS_INFO 0x301 - - -/* UNIX CIFS Extensions - created by HP */ -/* - * UNIX CIFS Extensions have the range 0x200 - 0x2FF reserved. - * Supposedly Microsoft have agreed to this. - */ - -#define MIN_UNIX_INFO_LEVEL 0x200 -#define MAX_UNIX_INFO_LEVEL 0x2FF - -#define INFO_LEVEL_IS_UNIX(level) (((level) >= MIN_UNIX_INFO_LEVEL) && ((level) <= MAX_UNIX_INFO_LEVEL)) - -#define SMB_MODE_NO_CHANGE 0xFFFFFFFF /* file mode value which */ - /* means "don't change it" */ -#define SMB_UID_NO_CHANGE 0xFFFFFFFF -#define SMB_GID_NO_CHANGE 0xFFFFFFFF - -#define SMB_SIZE_NO_CHANGE_LO 0xFFFFFFFF -#define SMB_SIZE_NO_CHANGE_HI 0xFFFFFFFF - -#define SMB_TIME_NO_CHANGE_LO 0xFFFFFFFF -#define SMB_TIME_NO_CHANGE_HI 0xFFFFFFFF - -/* -UNIX_BASIC info level: - -Offset Size Name -0 LARGE_INTEGER EndOfFile File size -8 LARGE_INTEGER Blocks Number of bytes used on disk (st_blocks). -16 LARGE_INTEGER CreationTime Creation time -24 LARGE_INTEGER LastAccessTime Last access time -32 LARGE_INTEGER LastModificationTime Last modification time -40 LARGE_INTEGER Uid Numeric user id for the owner -48 LARGE_INTEGER Gid Numeric group id of owner -56 ULONG Type Enumeration specifying the pathname type: - 0 -- File - 1 -- Directory - 2 -- Symbolic link - 3 -- Character device - 4 -- Block device - 5 -- FIFO (named pipe) - 6 -- Unix domain socket - -60 LARGE_INTEGER devmajor Major device number if type is device -68 LARGE_INTEGER devminor Minor device number if type is device -76 LARGE_INTEGER uniqueid This is a server-assigned unique id for the file. The client - will typically map this onto an inode number. The scope of - uniqueness is the share. -84 LARGE_INTEGER permissions Standard UNIX file permissions - see below. -92 LARGE_INTEGER nlinks The number of directory entries that map to this entry - (number of hard links) - -100 - end. -*/ - -/* -SMB_QUERY_FILE_UNIX_INFO2 is SMB_QUERY_FILE_UNIX_BASIC with create -time and file flags appended. The corresponding info level for -findfirst/findnext is SMB_FIND_FILE_UNIX_UNIX2. - -Size Offset Value ---------------------- -0 LARGE_INTEGER EndOfFile File size -8 LARGE_INTEGER Blocks Number of blocks used on disk -16 LARGE_INTEGER ChangeTime Attribute change time -24 LARGE_INTEGER LastAccessTime Last access time -32 LARGE_INTEGER LastModificationTime Last modification time -40 LARGE_INTEGER Uid Numeric user id for the owner -48 LARGE_INTEGER Gid Numeric group id of owner -56 ULONG Type Enumeration specifying the file type -60 LARGE_INTEGER devmajor Major device number if type is device -68 LARGE_INTEGER devminor Minor device number if type is device -76 LARGE_INTEGER uniqueid This is a server-assigned unique id -84 LARGE_INTEGER permissions Standard UNIX permissions -92 LARGE_INTEGER nlinks Number of hard link) -100 LARGE_INTEGER CreationTime Create/birth time -108 ULONG FileFlags File flags enumeration -112 ULONG FileFlagsMask Mask of valid flags -*/ - -/* UNIX filetype mappings. */ - -#define UNIX_TYPE_FILE 0 -#define UNIX_TYPE_DIR 1 -#define UNIX_TYPE_SYMLINK 2 -#define UNIX_TYPE_CHARDEV 3 -#define UNIX_TYPE_BLKDEV 4 -#define UNIX_TYPE_FIFO 5 -#define UNIX_TYPE_SOCKET 6 -#define UNIX_TYPE_UNKNOWN 0xFFFFFFFF - -/* - * Oh this is fun. "Standard UNIX permissions" has no - * meaning in POSIX. We need to define the mapping onto - * and off the wire as this was not done in the original HP - * spec. JRA. - */ - -#define UNIX_X_OTH 0000001 -#define UNIX_W_OTH 0000002 -#define UNIX_R_OTH 0000004 -#define UNIX_X_GRP 0000010 -#define UNIX_W_GRP 0000020 -#define UNIX_R_GRP 0000040 -#define UNIX_X_USR 0000100 -#define UNIX_W_USR 0000200 -#define UNIX_R_USR 0000400 -#define UNIX_STICKY 0001000 -#define UNIX_SET_GID 0002000 -#define UNIX_SET_UID 0004000 - -/* Masks for the above */ -#define UNIX_OTH_MASK 0000007 -#define UNIX_GRP_MASK 0000070 -#define UNIX_USR_MASK 0000700 -#define UNIX_PERM_MASK 0000777 -#define UNIX_EXTRA_MASK 0007000 -#define UNIX_ALL_MASK 0007777 - -/* Flags for the file_flags field in UNIX_INFO2: */ -#define EXT_SECURE_DELETE 0x00000001 -#define EXT_ENABLE_UNDELETE 0x00000002 -#define EXT_SYNCHRONOUS 0x00000004 -#define EXT_IMMUTABLE 0x00000008 -#define EXT_OPEN_APPEND_ONLY 0x00000010 -#define EXT_DO_NOT_BACKUP 0x00000020 -#define EXT_NO_UPDATE_ATIME 0x00000040 -#define EXT_HIDDEN 0x00000080 - -#define SMB_QFILEINFO_UNIX_LINK 0x201 -#define SMB_SFILEINFO_UNIX_LINK 0x201 -#define SMB_SFILEINFO_UNIX_HLINK 0x203 - -/* - Info level for QVOLINFO - returns version of CIFS UNIX extensions, plus - 64-bits worth of capability fun :-). -*/ - -#define SMB_QUERY_CIFS_UNIX_INFO 0x200 - -/* Returns the following. - - UINT16 major version number - UINT16 minor version number - LARGE_INTEGER capability bitfield - -*/ - -#define CIFS_UNIX_MAJOR_VERSION 1 -#define CIFS_UNIX_MINOR_VERSION 0 - -#define CIFS_UNIX_FCNTL_LOCKS_CAP 0x1 -#define CIFS_UNIX_POSIX_ACLS_CAP 0x2 - -/* ... more as we think of them :-). */ - #endif diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index 0ad3e1230b..150705f8d8 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -47,13 +47,13 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx, int i, count=0; struct resolve_bcast_data *data = talloc_get_type(userdata, struct resolve_bcast_data); - num_interfaces = iface_count(data->ifaces); + num_interfaces = iface_list_count(data->ifaces); address_list = talloc_array(mem_ctx, const char *, num_interfaces+1); if (address_list == NULL) return NULL; for (i=0;i<num_interfaces;i++) { - const char *bcast = iface_n_bcast(data->ifaces, i); + const char *bcast = iface_list_n_bcast(data->ifaces, i); if (bcast == NULL) continue; address_list[count] = talloc_strdup(address_list, bcast); if (address_list[count] == NULL) { @@ -101,6 +101,6 @@ bool resolve_context_add_bcast_method(struct resolve_context *ctx, struct interf bool resolve_context_add_bcast_method_lp(struct resolve_context *ctx, struct loadparm_context *lp_ctx) { struct interface *ifaces; - load_interfaces(ctx, lpcfg_interfaces(lp_ctx), &ifaces); + load_interface_list(ctx, lp_ctx, &ifaces); return resolve_context_add_bcast_method(ctx, ifaces, lpcfg_nbt_port(lp_ctx), lpcfg_parm_int(lp_ctx, NULL, "nbt", "timeout", 1)); } diff --git a/source4/libcli/resolve/dns_ex.c b/source4/libcli/resolve/dns_ex.c index 35e2ad74c3..5921212579 100644 --- a/source4/libcli/resolve/dns_ex.c +++ b/source4/libcli/resolve/dns_ex.c @@ -37,6 +37,7 @@ #include "libcli/composite/composite.h" #include "librpc/gen_ndr/ndr_nbt.h" #include "libcli/resolve/resolve.h" +#include "lib/util/util_net.h" #ifdef class #undef class @@ -87,6 +88,7 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd) struct rk_resource_record **srv_rr; uint32_t addrs_valid = 0; struct rk_resource_record **addrs_rr; + struct rk_dns_reply **srv_replies = NULL; char *addrs; bool first; uint32_t i; @@ -135,14 +137,13 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd) continue; } } else { - /* we are only interested in A records */ - /* TODO: add AAAA support */ - if (rr->type != rk_ns_t_a) { + /* we are only interested in A or AAAA records */ + if (rr->type != rk_ns_t_a && rr->type != rk_ns_t_aaaa) { continue; } - /* verify we actually have a A record here */ - if (!rr->u.a) { + /* verify we actually have a record here */ + if (!rr->u.data) { continue; } } @@ -167,6 +168,13 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd) goto done; } + srv_replies = talloc_zero_array(state, + struct rk_dns_reply *, + count); + if (!srv_replies) { + goto done; + } + /* Loop over all returned records and pick the records */ for (rr=reply->head;rr;rr=rr->next) { /* we are only interested in the IN class */ @@ -193,14 +201,13 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd) srv_rr[srv_valid] = rr; srv_valid++; } else { - /* we are only interested in A records */ - /* TODO: add AAAA support */ - if (rr->type != rk_ns_t_a) { + /* we are only interested in A or AAAA records */ + if (rr->type != rk_ns_t_a && rr->type != rk_ns_t_aaaa) { continue; } - /* verify we actually have a A record here */ - if (!rr->u.a) { + /* verify we actually have a record record here */ + if (!rr->u.data) { continue; } @@ -210,19 +217,23 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd) } for (i=0; i < srv_valid; i++) { - for (rr=reply->head;rr;rr=rr->next) { + srv_replies[i] = rk_dns_lookup(srv_rr[i]->u.srv->target, "A"); + if (srv_replies[i] == NULL) + continue; + /* Add first A record to addrs_rr */ + for (rr=srv_replies[i]->head;rr;rr=rr->next) { if (rr->class != rk_ns_c_in) { continue; } - /* we are only interested in A records */ - if (rr->type != rk_ns_t_a) { + /* we are only interested in A or AAAA records */ + if (rr->type != rk_ns_t_a && rr->type != rk_ns_t_aaaa) { continue; } - /* verify we actually have a srv record here */ - if (strcmp(&srv_rr[i]->u.srv->target[0], rr->domain) != 0) { + /* verify we actually have a record here */ + if (!rr->u.data) { continue; } @@ -241,8 +252,10 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd) goto done; } first = true; - for (i=0; i < count; i++) { + for (i=0; i < addrs_valid; i++) { uint16_t port; + char addrstr[INET6_ADDRSTRLEN]; + if (!addrs_rr[i]) { continue; } @@ -254,9 +267,28 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd) port = state->port; } - addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s", + switch (addrs_rr[i]->type) { + case rk_ns_t_a: + if (inet_ntop(AF_INET, addrs_rr[i]->u.a, + addrstr, sizeof(addrstr)) == NULL) { + continue; + } + break; +#ifdef HAVE_IPV6 + case rk_ns_t_aaaa: + if (inet_ntop(AF_INET6, (struct in6_addr *)addrs_rr[i]->u.data, + addrstr, sizeof(addrstr)) == NULL) { + continue; + } + break; +#endif + default: + continue; + } + + addrs = talloc_asprintf_append_buffer(addrs, "%s%s@%u/%s", first?"":",", - inet_ntoa(*addrs_rr[i]->u.a), + addrstr, port, addrs_rr[i]->domain); if (!addrs) { @@ -270,6 +302,12 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd) } done: + if (reply != NULL) + rk_dns_free_data(reply); + for (i=0; i < srv_valid; i++) { + if (srv_replies[i] != NULL) + rk_dns_free_data(srv_replies[i]); + } close(fd); } @@ -287,7 +325,6 @@ static void run_child_getaddrinfo(struct dns_ex_state *state, int fd) ZERO_STRUCT(hints); hints.ai_socktype = SOCK_STREAM; - hints.ai_family = AF_INET;/* TODO: add AF_INET6 support */ hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV; ret = getaddrinfo(state->name.name, "0", &hints, &res_list); @@ -315,16 +352,13 @@ static void run_child_getaddrinfo(struct dns_ex_state *state, int fd) } first = true; for (res = res_list; res; res = res->ai_next) { - struct sockaddr_in *in; - - if (res->ai_family != AF_INET) { + char addrstr[INET6_ADDRSTRLEN]; + if (!print_sockaddr_len(addrstr, sizeof(addrstr), (struct sockaddr *)res->ai_addr, res->ai_addrlen)) { continue; } - in = (struct sockaddr_in *)res->ai_addr; - - addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s", + addrs = talloc_asprintf_append_buffer(addrs, "%s%s@%u/%s", first?"":",", - inet_ntoa(in->sin_addr), + addrstr, state->port, state->name.name); if (!addrs) { @@ -406,7 +440,7 @@ static void pipe_handler(struct tevent_context *ev, struct tevent_fd *fde, for (i=0; i < num_addrs; i++) { uint32_t port = 0; - char *p = strrchr(addrs[i], ':'); + char *p = strrchr(addrs[i], '@'); char *n; if (!p) { @@ -426,8 +460,7 @@ static void pipe_handler(struct tevent_context *ev, struct tevent_fd *fde, *n = '\0'; n++; - if (strcmp(addrs[i], "0.0.0.0") == 0 || - inet_addr(addrs[i]) == INADDR_NONE) { + if (strcmp(addrs[i], "0.0.0.0") == 0) { composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND); return; } @@ -437,7 +470,7 @@ static void pipe_handler(struct tevent_context *ev, struct tevent_fd *fde, return; } state->addrs[i] = socket_address_from_strings(state->addrs, - "ipv4", + "ip", addrs[i], port); if (composite_nomem(state->addrs[i], c)) return; @@ -485,7 +518,7 @@ struct composite_context *resolve_name_dns_ex_send(TALLOC_CTX *mem_ctx, /* setup a pipe to chat to our child */ ret = pipe(fd); if (ret == -1) { - composite_error(c, map_nt_error_from_unix(errno)); + composite_error(c, map_nt_error_from_unix_common(errno)); return c; } @@ -509,7 +542,7 @@ struct composite_context *resolve_name_dns_ex_send(TALLOC_CTX *mem_ctx, state->child = fork(); if (state->child == (pid_t)-1) { - composite_error(c, map_nt_error_from_unix(errno)); + composite_error(c, map_nt_error_from_unix_common(errno)); return c; } diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index c17e93a1f6..b5930aade1 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -171,12 +171,10 @@ struct composite_context *resolve_name_all_send(struct resolve_context *ctx, if (is_ipaddress(state->name.name) || strcasecmp(state->name.name, "localhost") == 0) { - struct in_addr ip = interpret_addr2(state->name.name); - state->addrs = talloc_array(state, struct socket_address *, 2); if (composite_nomem(state->addrs, c)) return c; - state->addrs[0] = socket_address_from_strings(state->addrs, "ipv4", - inet_ntoa(ip), 0); + state->addrs[0] = socket_address_from_strings(state->addrs, "ip", + state->name.name, 0); if (composite_nomem(state->addrs[0], c)) return c; state->addrs[1] = NULL; state->names = talloc_array(state, char *, 2); @@ -316,18 +314,6 @@ NTSTATUS resolve_name_ex(struct resolve_context *ctx, } -/* - general name resolution - sync call - */ -NTSTATUS resolve_name(struct resolve_context *ctx, - struct nbt_name *name, - TALLOC_CTX *mem_ctx, - const char **reply_addr, - struct tevent_context *ev) -{ - return resolve_name_ex(ctx, 0, 0, name, mem_ctx, reply_addr, ev); -} - /* Initialise a struct nbt_name with a NULL scope */ void make_nbt_name(struct nbt_name *nbt, const char *name, int type) diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index 989f40e6cd..a52b99a23e 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -77,6 +77,6 @@ bool resolve_context_add_wins_method(struct resolve_context *ctx, const char **a bool resolve_context_add_wins_method_lp(struct resolve_context *ctx, struct loadparm_context *lp_ctx) { struct interface *ifaces; - load_interfaces(ctx, lpcfg_interfaces(lp_ctx), &ifaces); + load_interface_list(ctx, lp_ctx, &ifaces); return resolve_context_add_wins_method(ctx, lpcfg_wins_server_list(lp_ctx), ifaces, lpcfg_nbt_port(lp_ctx), lpcfg_parm_int(lp_ctx, NULL, "nbt", "timeout", 1)); } diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 64ed6c3acc..0e3bf1512b 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -20,6 +20,8 @@ */ #include "includes.h" +#include <tevent.h> +#include "lib/util/tevent_ntstatus.h" #include "libcli/raw/libcliraw.h" #include "libcli/raw/raw_proto.h" #include "libcli/smb2/smb2.h" @@ -29,6 +31,7 @@ #include "param/param.h" struct smb2_connect_state { + struct tevent_context *ev; struct cli_credentials *credentials; struct resolve_context *resolve_ctx; const char *host; @@ -43,67 +46,167 @@ struct smb2_connect_state { struct smb2_tree *tree; }; +static void smb2_connect_resolve_done(struct composite_context *creq); + /* - continue after tcon reply -*/ -static void continue_tcon(struct smb2_request *req) + a composite function that does a full negprot/sesssetup/tcon, returning + a connected smb2_tree + */ +struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + const char *host, + const char **ports, + const char *share, + struct resolve_context *resolve_ctx, + struct cli_credentials *credentials, + struct smbcli_options *options, + const char *socket_options, + struct gensec_settings *gensec_settings) { - struct composite_context *c = talloc_get_type(req->async.private_data, - struct composite_context); - struct smb2_connect_state *state = talloc_get_type(c->private_data, - struct smb2_connect_state); - - c->status = smb2_tree_connect_recv(req, &state->tcon); - if (!composite_is_ok(c)) return; - - state->tree->tid = state->tcon.out.tid; + struct tevent_req *req; + struct smb2_connect_state *state; + struct nbt_name name; + struct composite_context *creq; + + req = tevent_req_create(mem_ctx, &state, + struct smb2_connect_state); + if (req == NULL) { + return NULL; + } + + state->ev = ev; + state->credentials = credentials; + state->options = *options; + state->host = host; + state->ports = ports; + state->share = share; + state->resolve_ctx = resolve_ctx; + state->socket_options = socket_options; + state->gensec_settings = gensec_settings; + + ZERO_STRUCT(name); + name.name = host; - composite_done(c); + creq = resolve_name_send(resolve_ctx, state, &name, ev); + if (tevent_req_nomem(creq, req)) { + return tevent_req_post(req, ev); + } + creq->async.fn = smb2_connect_resolve_done; + creq->async.private_data = req; + return req; } -/* - continue after a session setup -*/ -static void continue_session(struct composite_context *creq) +static void smb2_connect_socket_done(struct composite_context *creq); + +static void smb2_connect_resolve_done(struct composite_context *creq) { - struct composite_context *c = talloc_get_type(creq->async.private_data, - struct composite_context); - struct smb2_connect_state *state = talloc_get_type(c->private_data, - struct smb2_connect_state); - struct smb2_request *req; + struct tevent_req *req = + talloc_get_type_abort(creq->async.private_data, + struct tevent_req); + struct smb2_connect_state *state = + tevent_req_data(req, + struct smb2_connect_state); + NTSTATUS status; + const char *addr; + const char **ports; + const char *default_ports[] = { "445", NULL }; - c->status = smb2_session_setup_spnego_recv(creq); - if (!composite_is_ok(c)) return; + status = resolve_name_recv(creq, state, &addr); + if (tevent_req_nterror(req, status)) { + return; + } - state->tree = smb2_tree_init(state->session, state, true); - if (composite_nomem(state->tree, c)) return; + if (state->ports == NULL) { + ports = default_ports; + } else { + ports = state->ports; + } - state->tcon.in.reserved = 0; - state->tcon.in.path = talloc_asprintf(state, "\\\\%s\\%s", - state->host, state->share); - if (composite_nomem(state->tcon.in.path, c)) return; - - req = smb2_tree_connect_send(state->tree, &state->tcon); - if (composite_nomem(req, c)) return; + creq = smbcli_sock_connect_send(state, addr, ports, + state->host, state->resolve_ctx, + state->ev, state->socket_options); + if (tevent_req_nomem(creq, req)) { + return; + } + creq->async.fn = smb2_connect_socket_done; + creq->async.private_data = req; +} + +static void smb2_connect_negprot_done(struct smb2_request *smb2req); - req->async.fn = continue_tcon; - req->async.private_data = c; +static void smb2_connect_socket_done(struct composite_context *creq) +{ + struct tevent_req *req = + talloc_get_type_abort(creq->async.private_data, + struct tevent_req); + struct smb2_connect_state *state = + tevent_req_data(req, + struct smb2_connect_state); + struct smbcli_socket *sock; + struct smb2_transport *transport; + struct smb2_request *smb2req; + NTSTATUS status; + uint16_t dialects[3] = { + SMB2_DIALECT_REVISION_000, + SMB2_DIALECT_REVISION_202, + SMB2_DIALECT_REVISION_210 + }; + + status = smbcli_sock_connect_recv(creq, state, &sock); + if (tevent_req_nterror(req, status)) { + return; + } + + transport = smb2_transport_init(sock, state, &state->options); + if (tevent_req_nomem(transport, req)) { + return; + } + + ZERO_STRUCT(state->negprot); + state->negprot.in.dialect_count = ARRAY_SIZE(dialects); + switch (transport->options.signing) { + case SMB_SIGNING_OFF: + state->negprot.in.security_mode = 0; + break; + case SMB_SIGNING_SUPPORTED: + case SMB_SIGNING_AUTO: + state->negprot.in.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED; + break; + case SMB_SIGNING_REQUIRED: + state->negprot.in.security_mode = + SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED; + break; + } + state->negprot.in.capabilities = 0; + unix_to_nt_time(&state->negprot.in.start_time, time(NULL)); + state->negprot.in.dialects = dialects; + + smb2req = smb2_negprot_send(transport, &state->negprot); + if (tevent_req_nomem(smb2req, req)) { + return; + } + smb2req->async.fn = smb2_connect_negprot_done; + smb2req->async.private_data = req; } -/* - continue after negprot reply -*/ -static void continue_negprot(struct smb2_request *req) +static void smb2_connect_session_done(struct tevent_req *subreq); + +static void smb2_connect_negprot_done(struct smb2_request *smb2req) { - struct composite_context *c = talloc_get_type(req->async.private_data, - struct composite_context); - struct smb2_connect_state *state = talloc_get_type(c->private_data, - struct smb2_connect_state); - struct smb2_transport *transport = req->transport; - struct composite_context *creq; + struct tevent_req *req = + talloc_get_type_abort(smb2req->async.private_data, + struct tevent_req); + struct smb2_connect_state *state = + tevent_req_data(req, + struct smb2_connect_state); + struct smb2_transport *transport = smb2req->transport; + struct tevent_req *subreq; + NTSTATUS status; - c->status = smb2_negprot_recv(req, c, &state->negprot); - if (!composite_is_ok(c)) return; + status = smb2_negprot_recv(smb2req, state, &state->negprot); + if (tevent_req_nterror(req, status)) { + return; + } transport->negotiate.secblob = state->negprot.out.secblob; talloc_steal(transport, transport->negotiate.secblob.data); @@ -115,7 +218,7 @@ static void continue_negprot(struct smb2_request *req) switch (transport->options.signing) { case SMB_SIGNING_OFF: if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) { - composite_error(c, NT_STATUS_ACCESS_DENIED); + tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); return; } transport->signing_required = false; @@ -138,179 +241,158 @@ static void continue_negprot(struct smb2_request *req) if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_ENABLED) { transport->signing_required = true; } else { - composite_error(c, NT_STATUS_ACCESS_DENIED); + tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); return; } break; } state->session = smb2_session_init(transport, state->gensec_settings, state, true); - if (composite_nomem(state->session, c)) return; - - creq = smb2_session_setup_spnego_send(state->session, state->credentials); - - composite_continue(c, creq, continue_session, c); -} - -/* - continue after a socket connect completes -*/ -static void continue_socket(struct composite_context *creq) -{ - struct composite_context *c = talloc_get_type(creq->async.private_data, - struct composite_context); - struct smb2_connect_state *state = talloc_get_type(c->private_data, - struct smb2_connect_state); - struct smbcli_socket *sock; - struct smb2_transport *transport; - struct smb2_request *req; - uint16_t dialects[3] = { - SMB2_DIALECT_REVISION_000, - SMB2_DIALECT_REVISION_202, - SMB2_DIALECT_REVISION_210 - }; - - c->status = smbcli_sock_connect_recv(creq, state, &sock); - if (!composite_is_ok(c)) return; - - transport = smb2_transport_init(sock, state, &state->options); - if (composite_nomem(transport, c)) return; - - ZERO_STRUCT(state->negprot); - state->negprot.in.dialect_count = sizeof(dialects) / sizeof(dialects[0]); - switch (transport->options.signing) { - case SMB_SIGNING_OFF: - state->negprot.in.security_mode = 0; - break; - case SMB_SIGNING_SUPPORTED: - case SMB_SIGNING_AUTO: - state->negprot.in.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED; - break; - case SMB_SIGNING_REQUIRED: - state->negprot.in.security_mode = - SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED; - break; + if (tevent_req_nomem(state->session, req)) { + return; } - state->negprot.in.capabilities = 0; - unix_to_nt_time(&state->negprot.in.start_time, time(NULL)); - state->negprot.in.dialects = dialects; - req = smb2_negprot_send(transport, &state->negprot); - if (composite_nomem(req, c)) return; - - req->async.fn = continue_negprot; - req->async.private_data = c; + subreq = smb2_session_setup_spnego_send(state, state->ev, + state->session, + state->credentials); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, smb2_connect_session_done, req); } +static void smb2_connect_tcon_done(struct smb2_request *smb2req); -/* - continue after a resolve finishes -*/ -static void continue_resolve(struct composite_context *creq) +static void smb2_connect_session_done(struct tevent_req *subreq) { - struct composite_context *c = talloc_get_type(creq->async.private_data, - struct composite_context); - struct smb2_connect_state *state = talloc_get_type(c->private_data, - struct smb2_connect_state); - const char *addr; - const char **ports; - const char *default_ports[] = { "445", NULL }; + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + struct smb2_connect_state *state = + tevent_req_data(req, + struct smb2_connect_state); + struct smb2_request *smb2req; + NTSTATUS status; - c->status = resolve_name_recv(creq, state, &addr); - if (!composite_is_ok(c)) return; + status = smb2_session_setup_spnego_recv(subreq); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } - if (state->ports == NULL) { - ports = default_ports; - } else { - ports = state->ports; + state->tree = smb2_tree_init(state->session, state, true); + if (tevent_req_nomem(state->tree, req)) { + return; } - creq = smbcli_sock_connect_send(state, addr, ports, state->host, state->resolve_ctx, c->event_ctx, state->socket_options); + state->tcon.in.reserved = 0; + state->tcon.in.path = talloc_asprintf(state, "\\\\%s\\%s", + state->host, state->share); + if (tevent_req_nomem(state->tcon.in.path, req)) { + return; + } - composite_continue(c, creq, continue_socket, c); + smb2req = smb2_tree_connect_send(state->tree, &state->tcon); + if (tevent_req_nomem(smb2req, req)) { + return; + } + smb2req->async.fn = smb2_connect_tcon_done; + smb2req->async.private_data = req; } -/* - a composite function that does a full negprot/sesssetup/tcon, returning - a connected smb2_tree - */ -struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, - const char *host, - const char **ports, - const char *share, - struct resolve_context *resolve_ctx, - struct cli_credentials *credentials, - struct tevent_context *ev, - struct smbcli_options *options, - const char *socket_options, - struct gensec_settings *gensec_settings) +static void smb2_connect_tcon_done(struct smb2_request *smb2req) { - struct composite_context *c; - struct smb2_connect_state *state; - struct nbt_name name; - struct composite_context *creq; - - c = composite_create(mem_ctx, ev); - if (c == NULL) return NULL; - - state = talloc(c, struct smb2_connect_state); - if (composite_nomem(state, c)) return c; - c->private_data = state; + struct tevent_req *req = + talloc_get_type_abort(smb2req->async.private_data, + struct tevent_req); + struct smb2_connect_state *state = + tevent_req_data(req, + struct smb2_connect_state); + NTSTATUS status; - state->credentials = credentials; - state->options = *options; - state->host = talloc_strdup(c, host); - if (composite_nomem(state->host, c)) return c; - state->ports = talloc_reference(state, ports); - state->share = talloc_strdup(c, share); - if (composite_nomem(state->share, c)) return c; - state->resolve_ctx = talloc_reference(state, resolve_ctx); - state->socket_options = talloc_reference(state, socket_options); - state->gensec_settings = talloc_reference(state, gensec_settings); + status = smb2_tree_connect_recv(smb2req, &state->tcon); + if (tevent_req_nterror(req, status)) { + return; + } - ZERO_STRUCT(name); - name.name = host; + state->tree->tid = state->tcon.out.tid; - creq = resolve_name_send(resolve_ctx, state, &name, c->event_ctx); - composite_continue(c, creq, continue_resolve, c); - return c; + tevent_req_done(req); } -/* - receive a connect reply -*/ -NTSTATUS smb2_connect_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, +NTSTATUS smb2_connect_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, struct smb2_tree **tree) { + struct smb2_connect_state *state = + tevent_req_data(req, + struct smb2_connect_state); NTSTATUS status; - struct smb2_connect_state *state = talloc_get_type(c->private_data, - struct smb2_connect_state); - status = composite_wait(c); - if (NT_STATUS_IS_OK(status)) { - *tree = talloc_steal(mem_ctx, state->tree); + + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; } - talloc_free(c); - return status; + + *tree = talloc_move(mem_ctx, &state->tree); + + tevent_req_received(req); + return NT_STATUS_OK; } /* sync version of smb2_connect */ -NTSTATUS smb2_connect(TALLOC_CTX *mem_ctx, - const char *host, const char **ports, - const char *share, +NTSTATUS smb2_connect(TALLOC_CTX *mem_ctx, + const char *host, + const char **ports, + const char *share, struct resolve_context *resolve_ctx, struct cli_credentials *credentials, struct smb2_tree **tree, struct tevent_context *ev, struct smbcli_options *options, - const char *socket_options, - struct gensec_settings *gensec_settings) + const char *socket_options, + struct gensec_settings *gensec_settings) { - struct composite_context *c = smb2_connect_send(mem_ctx, host, ports, - share, resolve_ctx, - credentials, ev, options, - socket_options, - gensec_settings); - return smb2_connect_recv(c, mem_ctx, tree); + struct tevent_req *subreq; + NTSTATUS status; + bool ok; + TALLOC_CTX *frame = talloc_stackframe(); + + if (frame == NULL) { + return NT_STATUS_NO_MEMORY; + } + + subreq = smb2_connect_send(frame, + ev, + host, + ports, + share, + resolve_ctx, + credentials, + options, + socket_options, + gensec_settings); + if (subreq == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + + ok = tevent_req_poll(subreq, ev); + if (!ok) { + status = map_nt_error_from_unix_common(errno); + TALLOC_FREE(frame); + return status; + } + + status = smb2_connect_recv(subreq, mem_ctx, tree); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + + TALLOC_FREE(frame); + return NT_STATUS_OK; } diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 12479623e7..d46cdefc69 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -20,10 +20,11 @@ */ #include "includes.h" +#include <tevent.h> +#include "lib/util/tevent_ntstatus.h" #include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" -#include "libcli/composite/composite.h" #include "auth/gensec/gensec.h" #include <unistd.h> @@ -136,56 +137,133 @@ NTSTATUS smb2_session_setup(struct smb2_session *session, return smb2_session_setup_recv(req, mem_ctx, io); } - -struct smb2_session_state { +struct smb2_session_setup_spnego_state { struct smb2_session_setup io; struct smb2_request *req; NTSTATUS gensec_status; }; +static void smb2_session_setup_spnego_handler(struct smb2_request *req); + +/* + a composite function that does a full SPNEGO session setup + */ +struct tevent_req *smb2_session_setup_spnego_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct smb2_session *session, + struct cli_credentials *credentials) +{ + struct tevent_req *req; + struct smb2_session_setup_spnego_state *state; + const char *chosen_oid; + struct smb2_request *subreq; + NTSTATUS status; + + req = tevent_req_create(mem_ctx, &state, + struct smb2_session_setup_spnego_state); + if (req == NULL) { + return NULL; + } + + ZERO_STRUCT(state->io); + state->io.in.vc_number = 0; + if (session->transport->signing_required) { + state->io.in.security_mode = + SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED; + } + state->io.in.capabilities = 0; + state->io.in.channel = 0; + state->io.in.previous_sessionid = 0; + + status = gensec_set_credentials(session->gensec, credentials); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + + status = gensec_set_target_hostname(session->gensec, + session->transport->socket->hostname); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + + status = gensec_set_target_service(session->gensec, "cifs"); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + + if (session->transport->negotiate.secblob.length > 0) { + chosen_oid = GENSEC_OID_SPNEGO; + } else { + chosen_oid = GENSEC_OID_NTLMSSP; + } + + status = gensec_start_mech_by_oid(session->gensec, chosen_oid); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + + status = gensec_update(session->gensec, state, + session->transport->negotiate.secblob, + &state->io.in.secblob); + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + state->gensec_status = status; + + subreq = smb2_session_setup_send(session, &state->io); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + subreq->async.fn = smb2_session_setup_spnego_handler; + subreq->async.private_data = req; + + return req; +} + /* handle continuations of the spnego session setup */ -static void session_request_handler(struct smb2_request *req) +static void smb2_session_setup_spnego_handler(struct smb2_request *subreq) { - struct composite_context *c = talloc_get_type(req->async.private_data, - struct composite_context); - struct smb2_session_state *state = talloc_get_type(c->private_data, - struct smb2_session_state); - struct smb2_session *session = req->session; + struct tevent_req *req = + talloc_get_type_abort(subreq->async.private_data, + struct tevent_req); + struct smb2_session_setup_spnego_state *state = + tevent_req_data(req, + struct smb2_session_setup_spnego_state); + struct smb2_session *session = subreq->session; NTSTATUS session_key_err; DATA_BLOB session_key; NTSTATUS peer_status; + NTSTATUS status; - c->status = smb2_session_setup_recv(req, c, &state->io); - peer_status = c->status; - + status = smb2_session_setup_recv(subreq, state, &state->io); + peer_status = status; if (NT_STATUS_EQUAL(peer_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || (NT_STATUS_IS_OK(peer_status) && NT_STATUS_EQUAL(state->gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED))) { - c->status = gensec_update(session->gensec, c, - state->io.out.secblob, - &state->io.in.secblob); - state->gensec_status = c->status; - + status = gensec_update(session->gensec, state, + state->io.out.secblob, + &state->io.in.secblob); + state->gensec_status = status; session->uid = state->io.out.uid; } - if (!NT_STATUS_IS_OK(c->status) && - !NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - composite_error(c, c->status); + if (!NT_STATUS_IS_OK(status) && + !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + tevent_req_nterror(req, status); return; } if (NT_STATUS_EQUAL(peer_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - state->req = smb2_session_setup_send(session, &state->io); - if (state->req == NULL) { - composite_error(c, NT_STATUS_NO_MEMORY); + subreq = smb2_session_setup_send(session, &state->io); + if (tevent_req_nomem(subreq, req)) { return; } - state->req->async.fn = session_request_handler; - state->req->async.private_data = c; + subreq->async.fn = smb2_session_setup_spnego_handler; + subreq->async.private_data = req; return; } @@ -198,84 +276,21 @@ static void session_request_handler(struct smb2_request *req) if (session->session_key.length == 0) { DEBUG(0,("Wrong session key length %u for SMB2 signing\n", (unsigned)session->session_key.length)); - composite_error(c, NT_STATUS_ACCESS_DENIED); + tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); return; } session->signing_active = true; } - composite_done(c); -} - -/* - a composite function that does a full SPNEGO session setup - */ -struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *session, - struct cli_credentials *credentials) -{ - struct composite_context *c; - struct smb2_session_state *state; - const char *chosen_oid; - - c = composite_create(session, session->transport->socket->event.ctx); - if (c == NULL) return NULL; - - state = talloc(c, struct smb2_session_state); - if (composite_nomem(state, c)) return c; - c->private_data = state; - - ZERO_STRUCT(state->io); - state->io.in.vc_number = 0; - if (session->transport->signing_required) { - state->io.in.security_mode = - SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED; - } - state->io.in.capabilities = 0; - state->io.in.channel = 0; - state->io.in.previous_sessionid = 0; - - c->status = gensec_set_credentials(session->gensec, credentials); - if (!composite_is_ok(c)) return c; - - c->status = gensec_set_target_hostname(session->gensec, - session->transport->socket->hostname); - if (!composite_is_ok(c)) return c; - - c->status = gensec_set_target_service(session->gensec, "cifs"); - if (!composite_is_ok(c)) return c; - - if (session->transport->negotiate.secblob.length > 0) { - chosen_oid = GENSEC_OID_SPNEGO; - } else { - chosen_oid = GENSEC_OID_NTLMSSP; - } - - c->status = gensec_start_mech_by_oid(session->gensec, chosen_oid); - if (!composite_is_ok(c)) return c; - - c->status = gensec_update(session->gensec, c, - session->transport->negotiate.secblob, - &state->io.in.secblob); - if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - composite_error(c, c->status); - return c; - } - state->gensec_status = c->status; - - state->req = smb2_session_setup_send(session, &state->io); - composite_continue_smb2(c, state->req, session_request_handler, c); - return c; + tevent_req_done(req); } /* receive a composite session setup reply */ -NTSTATUS smb2_session_setup_spnego_recv(struct composite_context *c) +NTSTATUS smb2_session_setup_spnego_recv(struct tevent_req *req) { - NTSTATUS status; - status = composite_wait(c); - talloc_free(c); - return status; + return tevent_req_simple_recv_ntstatus(req); } /* @@ -284,6 +299,37 @@ NTSTATUS smb2_session_setup_spnego_recv(struct composite_context *c) NTSTATUS smb2_session_setup_spnego(struct smb2_session *session, struct cli_credentials *credentials) { - struct composite_context *c = smb2_session_setup_spnego_send(session, credentials); - return smb2_session_setup_spnego_recv(c); + struct tevent_req *subreq; + NTSTATUS status; + bool ok; + TALLOC_CTX *frame = talloc_stackframe(); + struct tevent_context *ev = session->transport->socket->event.ctx; + + if (frame == NULL) { + return NT_STATUS_NO_MEMORY; + } + + subreq = smb2_session_setup_spnego_send(frame, ev, + session, credentials); + if (subreq == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + + ok = tevent_req_poll(subreq, ev); + if (!ok) { + status = map_nt_error_from_unix_common(errno); + TALLOC_FREE(frame); + return status; + } + + status = smb2_session_setup_spnego_recv(subreq); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + + TALLOC_FREE(frame); + return NT_STATUS_OK; } diff --git a/source4/libcli/smb2/wscript_build b/source4/libcli/smb2/wscript_build index c39cf5fd39..5b5ac7d4e6 100644 --- a/source4/libcli/smb2/wscript_build +++ b/source4/libcli/smb2/wscript_build @@ -3,6 +3,7 @@ bld.SAMBA_SUBSYSTEM('LIBCLI_SMB2', source='transport.c request.c negprot.c session.c tcon.c create.c close.c connect.c getinfo.c write.c read.c setinfo.c find.c ioctl.c logoff.c tdis.c flush.c lock.c notify.c cancel.c keepalive.c break.c util.c signing.c lease_break.c', autoproto='smb2_proto.h', - public_deps='LIBCLI_RAW LIBPACKET gensec' + deps='UTIL_TEVENT', + public_deps='LIBCLI_RAW LIBPACKET gensec tevent' ) diff --git a/source4/libcli/smb_composite/smb2.c b/source4/libcli/smb_composite/smb2.c index d71708a974..5c93869b5c 100644 --- a/source4/libcli/smb_composite/smb2.c +++ b/source4/libcli/smb_composite/smb2.c @@ -25,6 +25,8 @@ #include "includes.h" +#include <tevent.h> +#include "lib/util/tevent_ntstatus.h" #include "libcli/raw/libcliraw.h" #include "libcli/raw/raw_proto.h" #include "libcli/composite/composite.h" @@ -264,107 +266,182 @@ NTSTATUS smb2_composite_rmdir(struct smb2_tree *tree, struct smb_rmdir *io) return composite_wait_free(c); } +struct smb2_composite_setpathinfo_state { + struct smb2_tree *tree; + union smb_setfileinfo io; + NTSTATUS set_status; + struct smb2_create cr; + struct smb2_close cl; +}; + +static void smb2_composite_setpathinfo_create_done(struct smb2_request *smb2req); /* - continue after the setfileinfo in a composite setpathinfo - */ -static void continue_setpathinfo_close(struct smb2_request *req) + composite SMB2 setpathinfo call +*/ +struct tevent_req *smb2_composite_setpathinfo_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct smb2_tree *tree, + const union smb_setfileinfo *io) { - struct composite_context *ctx = talloc_get_type(req->async.private_data, - struct composite_context); - struct smb2_tree *tree = req->tree; - struct smb2_close close_parm; - NTSTATUS status; - union smb_setfileinfo *io2 = talloc_get_type(ctx->private_data, - union smb_setfileinfo); + struct tevent_req *req; + struct smb2_composite_setpathinfo_state *state; + struct smb2_request *smb2req; + + req = tevent_req_create(mem_ctx, &state, + struct smb2_composite_setpathinfo_state); + if (req == NULL) { + return NULL; + } - status = smb2_setinfo_recv(req); - if (!NT_STATUS_IS_OK(status)) { - composite_error(ctx, status); - return; + state->tree = tree; + state->io = *io; + + state->cr.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; + state->cr.in.create_disposition = NTCREATEX_DISP_OPEN; + state->cr.in.share_access = + NTCREATEX_SHARE_ACCESS_DELETE| + NTCREATEX_SHARE_ACCESS_READ| + NTCREATEX_SHARE_ACCESS_WRITE; + state->cr.in.create_options = 0; + state->cr.in.fname = state->io.generic.in.file.path; + if (state->cr.in.fname[0] == '\\') { + state->cr.in.fname++; } - ZERO_STRUCT(close_parm); - close_parm.in.file.handle = io2->generic.in.file.handle; - - req = smb2_close_send(tree, &close_parm); - composite_continue_smb2(ctx, req, continue_close, ctx); + smb2req = smb2_create_send(tree, &state->cr); + if (tevent_req_nomem(smb2req, req)) { + return tevent_req_post(req, ev); + } + smb2req->async.fn = smb2_composite_setpathinfo_create_done; + smb2req->async.private_data = req; + + return req; } +static void smb2_composite_setpathinfo_setinfo_done(struct smb2_request *smb2req); -/* - continue after the create in a composite setpathinfo - */ -static void continue_setpathinfo(struct smb2_request *req) +static void smb2_composite_setpathinfo_create_done(struct smb2_request *smb2req) { - struct composite_context *ctx = talloc_get_type(req->async.private_data, - struct composite_context); - struct smb2_tree *tree = req->tree; - struct smb2_create create_parm; + struct tevent_req *req = + talloc_get_type_abort(smb2req->async.private_data, + struct tevent_req); + struct smb2_composite_setpathinfo_state *state = + tevent_req_data(req, + struct smb2_composite_setpathinfo_state); NTSTATUS status; - union smb_setfileinfo *io2 = talloc_get_type(ctx->private_data, - union smb_setfileinfo); - status = smb2_create_recv(req, ctx, &create_parm); - if (!NT_STATUS_IS_OK(status)) { - composite_error(ctx, status); + status = smb2_create_recv(smb2req, state, &state->cr); + if (tevent_req_nterror(req, status)) { return; } - io2->generic.in.file.handle = create_parm.out.file.handle; + state->io.generic.in.file.handle = state->cr.out.file.handle; - req = smb2_setinfo_file_send(tree, io2); - composite_continue_smb2(ctx, req, continue_setpathinfo_close, ctx); + smb2req = smb2_setinfo_file_send(state->tree, &state->io); + if (tevent_req_nomem(smb2req, req)) { + return; + } + smb2req->async.fn = smb2_composite_setpathinfo_setinfo_done; + smb2req->async.private_data = req; } +static void smb2_composite_setpathinfo_close_done(struct smb2_request *smb2req); -/* - composite SMB2 setpathinfo call -*/ -struct composite_context *smb2_composite_setpathinfo_send(struct smb2_tree *tree, - union smb_setfileinfo *io) +static void smb2_composite_setpathinfo_setinfo_done(struct smb2_request *smb2req) { - struct composite_context *ctx; - struct smb2_create create_parm; - struct smb2_request *req; - union smb_setfileinfo *io2; + struct tevent_req *req = + talloc_get_type_abort(smb2req->async.private_data, + struct tevent_req); + struct smb2_composite_setpathinfo_state *state = + tevent_req_data(req, + struct smb2_composite_setpathinfo_state); + NTSTATUS status; - ctx = composite_create(tree, tree->session->transport->socket->event.ctx); - if (ctx == NULL) return NULL; + status = smb2_setinfo_recv(smb2req); + state->set_status = status; - ZERO_STRUCT(create_parm); - create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; - create_parm.in.create_disposition = NTCREATEX_DISP_OPEN; - create_parm.in.share_access = - NTCREATEX_SHARE_ACCESS_DELETE| - NTCREATEX_SHARE_ACCESS_READ| - NTCREATEX_SHARE_ACCESS_WRITE; - create_parm.in.create_options = 0; - create_parm.in.fname = io->generic.in.file.path; - if (create_parm.in.fname[0] == '\\') { - create_parm.in.fname++; + state->cl.in.file.handle = state->io.generic.in.file.handle; + + smb2req = smb2_close_send(state->tree, &state->cl); + if (tevent_req_nomem(smb2req, req)) { + return; } + smb2req->async.fn = smb2_composite_setpathinfo_close_done; + smb2req->async.private_data = req; +} - req = smb2_create_send(tree, &create_parm); +static void smb2_composite_setpathinfo_close_done(struct smb2_request *smb2req) +{ + struct tevent_req *req = + talloc_get_type_abort(smb2req->async.private_data, + struct tevent_req); + struct smb2_composite_setpathinfo_state *state = + tevent_req_data(req, + struct smb2_composite_setpathinfo_state); + NTSTATUS status; - io2 = talloc(ctx, union smb_setfileinfo); - if (composite_nomem(io2, ctx)) { - return ctx; + status = smb2_close_recv(smb2req, &state->cl); + + if (tevent_req_nterror(req, state->set_status)) { + return; } - *io2 = *io; - ctx->private_data = io2; + if (tevent_req_nterror(req, status)) { + return; + } - composite_continue_smb2(ctx, req, continue_setpathinfo, ctx); - return ctx; + tevent_req_done(req); } +NTSTATUS smb2_composite_setpathinfo_recv(struct tevent_req *req) +{ + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; + } + + tevent_req_received(req); + return NT_STATUS_OK; +} /* composite setpathinfo call */ NTSTATUS smb2_composite_setpathinfo(struct smb2_tree *tree, union smb_setfileinfo *io) { - struct composite_context *c = smb2_composite_setpathinfo_send(tree, io); - return composite_wait_free(c); + struct tevent_req *subreq; + NTSTATUS status; + bool ok; + TALLOC_CTX *frame = talloc_stackframe(); + struct tevent_context *ev = tree->session->transport->socket->event.ctx; + + if (frame == NULL) { + return NT_STATUS_NO_MEMORY; + } + + subreq = smb2_composite_setpathinfo_send(frame, ev, tree, io); + if (subreq == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + + ok = tevent_req_poll(subreq, ev); + if (!ok) { + status = map_nt_error_from_unix_common(errno); + TALLOC_FREE(frame); + return status; + } + + status = smb2_composite_setpathinfo_recv(subreq); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + + TALLOC_FREE(frame); + return NT_STATUS_OK; } diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c deleted file mode 100644 index a0154e370b..0000000000 --- a/source4/libcli/util/errormap.c +++ /dev/null @@ -1,1389 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * error mapping functions - * Copyright (C) Andrew Tridgell 2001 - * Copyright (C) Andrew Bartlett 2001 - * Copyright (C) Tim Potter 2000 - * - * 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 <http://www.gnu.org/licenses/>. - */ - -#include "includes.h" - -/* This map was extracted by the ERRMAPEXTRACT smbtorture command. - The setup was a Samba HEAD (2002-01-03) PDC and an Win2k member - workstation. The PDC was modified (by using the 'name_to_nt_status' - authentication module) to convert the username (in hex) into the - corresponding NTSTATUS error return. - - By opening two nbt sessions to the Win2k workstation, one negotiating - DOS and one negotiating NT errors it was possible to extract the - error mapping. (Because the server only supplies NT errors, the - NT4 workstation had to use its own error tables to convert these - to dos errors). - - Some errors show up as 'squashed' because the NT error connection - got back a different error to the one it sent, so a mapping could - not be determined (a guess has been made in this case, to map the - error as squashed). This is done mainly to prevent users from getting - NT_STATUS_WRONG_PASSWORD and NT_STATUS_NO_SUCH_USER errors (they get - NT_STATUS_LOGON_FAILURE instead. - - -- abartlet (2002-01-03) -*/ - -/* NT status -> dos error map */ -static const struct { - uint8_t dos_class; - uint32_t dos_code; - NTSTATUS ntstatus; -} ntstatus_to_dos_map[] = { - {ERRDOS, ERRnofiles, STATUS_NO_MORE_FILES}, - {ERRDOS, ERRnofiles, NT_STATUS_NO_MORE_ENTRIES}, - {ERRDOS, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, - {ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, - {ERRDOS, 87, NT_STATUS_INVALID_INFO_CLASS}, - {ERRDOS, 24, NT_STATUS_INFO_LENGTH_MISMATCH}, - {ERRHRD, ERRgeneral, NT_STATUS_ACCESS_VIOLATION}, - {ERRHRD, ERRgeneral, NT_STATUS_IN_PAGE_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_QUOTA}, - {ERRDOS, ERRbadfid, NT_STATUS_INVALID_HANDLE}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_INITIAL_STACK}, - {ERRDOS, 193, NT_STATUS_BAD_INITIAL_PC}, - {ERRDOS, 87, NT_STATUS_INVALID_CID}, - {ERRHRD, ERRgeneral, NT_STATUS_TIMER_NOT_CANCELED}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER}, - {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_DEVICE}, - {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE}, - {ERRDOS, ERRbadfunc, NT_STATUS_INVALID_DEVICE_REQUEST}, - {ERRDOS, 38, NT_STATUS_END_OF_FILE}, - {ERRDOS, 34, NT_STATUS_WRONG_VOLUME}, - {ERRDOS, 21, NT_STATUS_NO_MEDIA_IN_DEVICE}, - {ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_MEDIA}, - {ERRDOS, 27, NT_STATUS_NONEXISTENT_SECTOR}, -/** Session setup succeeded. This shouldn't happen...*/ -/** Session setup succeeded. This shouldn't happen...*/ -/** NT error on DOS connection! (NT_STATUS_OK) */ -/* { This NT error code was 'sqashed' - from NT_STATUS_MORE_PROCESSING_REQUIRED to NT_STATUS_OK - during the session setup } -*/ -#if 0 - {SUCCESS, 0, NT_STATUS_OK}, -#endif - {ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY}, - {ERRDOS, 487, NT_STATUS_CONFLICTING_ADDRESSES}, - {ERRDOS, 487, NT_STATUS_NOT_MAPPED_VIEW}, - {ERRDOS, 87, NT_STATUS_UNABLE_TO_FREE_VM}, - {ERRDOS, 87, NT_STATUS_UNABLE_TO_DELETE_SECTION}, - {ERRDOS, 2142, NT_STATUS_INVALID_SYSTEM_SERVICE}, - {ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_INSTRUCTION}, - {ERRDOS, ERRnoaccess, NT_STATUS_INVALID_LOCK_SEQUENCE}, - {ERRDOS, ERRnoaccess, NT_STATUS_INVALID_VIEW_SIZE}, - {ERRDOS, 193, NT_STATUS_INVALID_FILE_FOR_SECTION}, - {ERRDOS, ERRnoaccess, NT_STATUS_ALREADY_COMMITTED}, -/* { This NT error code was 'sqashed' - from NT_STATUS_ACCESS_DENIED to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE - during the session setup } -*/ - {ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, - {ERRDOS, 111, NT_STATUS_BUFFER_TOO_SMALL}, - {ERRDOS, ERRbadfid, NT_STATUS_OBJECT_TYPE_MISMATCH}, - {ERRHRD, ERRgeneral, NT_STATUS_NONCONTINUABLE_EXCEPTION}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DISPOSITION}, - {ERRHRD, ERRgeneral, NT_STATUS_UNWIND}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_STACK}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_UNWIND_TARGET}, - {ERRDOS, 158, NT_STATUS_NOT_LOCKED}, - {ERRHRD, ERRgeneral, NT_STATUS_PARITY_ERROR}, - {ERRDOS, 487, NT_STATUS_UNABLE_TO_DECOMMIT_VM}, - {ERRDOS, 487, NT_STATUS_NOT_COMMITTED}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_PORT_ATTRIBUTES}, - {ERRHRD, ERRgeneral, NT_STATUS_PORT_MESSAGE_TOO_LONG}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_MIX}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_QUOTA_LOWER}, - {ERRHRD, ERRgeneral, NT_STATUS_DISK_CORRUPT_ERROR}, - {ERRDOS, ERRinvalidname, NT_STATUS_OBJECT_NAME_INVALID}, - {ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND}, - {ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION}, - {ERRHRD, ERRgeneral, NT_STATUS_HANDLE_NOT_WAITABLE}, - {ERRDOS, ERRbadfid, NT_STATUS_PORT_DISCONNECTED}, - {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_ALREADY_ATTACHED}, - {ERRDOS, 161, NT_STATUS_OBJECT_PATH_INVALID}, - {ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND}, - {ERRDOS, 161, NT_STATUS_OBJECT_PATH_SYNTAX_BAD}, - {ERRHRD, ERRgeneral, NT_STATUS_DATA_OVERRUN}, - {ERRHRD, ERRgeneral, NT_STATUS_DATA_LATE_ERROR}, - {ERRDOS, 23, NT_STATUS_DATA_ERROR}, - {ERRDOS, 23, NT_STATUS_CRC_ERROR}, - {ERRDOS, ERRnomem, NT_STATUS_SECTION_TOO_BIG}, - {ERRDOS, ERRnoaccess, NT_STATUS_PORT_CONNECTION_REFUSED}, - {ERRDOS, ERRbadfid, NT_STATUS_INVALID_PORT_HANDLE}, - {ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION}, - {ERRHRD, ERRgeneral, NT_STATUS_QUOTA_EXCEEDED}, - {ERRDOS, 87, NT_STATUS_INVALID_PAGE_PROTECTION}, - {ERRDOS, 288, NT_STATUS_MUTANT_NOT_OWNED}, - {ERRDOS, 298, NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, - {ERRDOS, 87, NT_STATUS_PORT_ALREADY_SET}, - {ERRDOS, 87, NT_STATUS_SECTION_NOT_IMAGE}, - {ERRDOS, 156, NT_STATUS_SUSPEND_COUNT_EXCEEDED}, - {ERRDOS, ERRnoaccess, NT_STATUS_THREAD_IS_TERMINATING}, - {ERRDOS, 87, NT_STATUS_BAD_WORKING_SET_LIMIT}, - {ERRDOS, 87, NT_STATUS_INCOMPATIBLE_FILE_MAP}, - {ERRDOS, 87, NT_STATUS_SECTION_PROTECTION}, - {ERRDOS, 282, NT_STATUS_EAS_NOT_SUPPORTED}, - {ERRDOS, 255, NT_STATUS_EA_TOO_LARGE}, - {ERRHRD, ERRgeneral, NT_STATUS_NONEXISTENT_EA_ENTRY}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_EAS_ON_FILE}, - {ERRHRD, ERRgeneral, NT_STATUS_EA_CORRUPT_ERROR}, - {ERRDOS, ERRlock, NT_STATUS_FILE_LOCK_CONFLICT}, - {ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED}, - {ERRDOS, ERRnoaccess, NT_STATUS_DELETE_PENDING}, - {ERRDOS, ERRunsup, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, - {ERRHRD, ERRgeneral, NT_STATUS_UNKNOWN_REVISION}, - {ERRHRD, ERRgeneral, NT_STATUS_REVISION_MISMATCH}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_OWNER}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_PRIMARY_GROUP}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_IMPERSONATION_TOKEN}, - {ERRHRD, ERRgeneral, NT_STATUS_CANT_DISABLE_MANDATORY}, - {ERRDOS, 2215, NT_STATUS_NO_LOGON_SERVERS}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_LOGON_SESSION}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_PRIVILEGE}, - {ERRDOS, ERRnoaccess, NT_STATUS_PRIVILEGE_NOT_HELD}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACCOUNT_NAME}, - {ERRHRD, ERRgeneral, NT_STATUS_USER_EXISTS}, -/* { This NT error code was 'sqashed' - from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE - during the session setup } -*/ - {ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, - {ERRHRD, ERRgeneral, NT_STATUS_GROUP_EXISTS}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_GROUP}, - {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_GROUP}, - {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_GROUP}, - {ERRHRD, ERRgeneral, NT_STATUS_LAST_ADMIN}, -/* { This NT error code was 'sqashed' - from NT_STATUS_WRONG_PASSWORD to NT_STATUS_LOGON_FAILURE - during the session setup } -*/ - {ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, - {ERRSRV, ERRbaduid, NT_STATUS_USER_SESSION_DELETED}, - {ERRHRD, ERRgeneral, NT_STATUS_ILL_FORMED_PASSWORD}, - {ERRHRD, ERRgeneral, NT_STATUS_PASSWORD_RESTRICTION}, - {ERRDOS, ERRnoaccess, NT_STATUS_LOGON_FAILURE}, - {ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, - {ERRSRV, 2241, NT_STATUS_INVALID_LOGON_HOURS}, - {ERRSRV, 2240, NT_STATUS_INVALID_WORKSTATION}, - {ERRSRV, 2242, NT_STATUS_PASSWORD_EXPIRED}, - {ERRSRV, 2239, NT_STATUS_ACCOUNT_DISABLED}, - {ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, - {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, - {ERRHRD, ERRgeneral, NT_STATUS_LUIDS_EXHAUSTED}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SUB_AUTHORITY}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACL}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SID}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SECURITY_DESCR}, - {ERRDOS, 127, NT_STATUS_PROCEDURE_NOT_FOUND}, - {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_FORMAT}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_TOKEN}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_INHERITANCE_ACL}, - {ERRDOS, 158, NT_STATUS_RANGE_NOT_LOCKED}, - {ERRDOS, 112, NT_STATUS_DISK_FULL}, - {ERRHRD, ERRgeneral, NT_STATUS_SERVER_DISABLED}, - {ERRHRD, ERRgeneral, NT_STATUS_SERVER_NOT_DISABLED}, - {ERRDOS, 68, NT_STATUS_TOO_MANY_GUIDS_REQUESTED}, - {ERRDOS, 259, NT_STATUS_GUIDS_EXHAUSTED}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ID_AUTHORITY}, - {ERRDOS, 259, NT_STATUS_AGENTS_EXHAUSTED}, - {ERRDOS, 154, NT_STATUS_INVALID_VOLUME_LABEL}, - {ERRDOS, ERRres, NT_STATUS_SECTION_NOT_EXTENDED}, - {ERRDOS, 487, NT_STATUS_NOT_MAPPED_DATA}, - {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_DATA_NOT_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_TYPE_NOT_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_NAME_NOT_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_ARRAY_BOUNDS_EXCEEDED}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_DENORMAL_OPERAND}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_DIVIDE_BY_ZERO}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_INEXACT_RESULT}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_INVALID_OPERATION}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_OVERFLOW}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_STACK_CHECK}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_UNDERFLOW}, - {ERRHRD, ERRgeneral, NT_STATUS_INTEGER_DIVIDE_BY_ZERO}, - {ERRDOS, 534, NT_STATUS_INTEGER_OVERFLOW}, - {ERRHRD, ERRgeneral, NT_STATUS_PRIVILEGED_INSTRUCTION}, - {ERRDOS, ERRnomem, NT_STATUS_TOO_MANY_PAGING_FILES}, - {ERRHRD, ERRgeneral, NT_STATUS_FILE_INVALID}, - {ERRHRD, ERRgeneral, NT_STATUS_ALLOTTED_SPACE_EXCEEDED}, -/* { This NT error code was 'sqashed' - from NT_STATUS_INSUFFICIENT_RESOURCES to NT_STATUS_INSUFF_SERVER_RESOURCES - during the session setup } -*/ - {ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, - {ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, - {ERRDOS, 23, NT_STATUS_DEVICE_DATA_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_CONNECTED}, - {ERRDOS, 21, NT_STATUS_DEVICE_POWER_FAILURE}, - {ERRDOS, 487, NT_STATUS_FREE_VM_NOT_AT_BASE}, - {ERRDOS, 487, NT_STATUS_MEMORY_NOT_ALLOCATED}, - {ERRHRD, ERRgeneral, NT_STATUS_WORKING_SET_QUOTA}, - {ERRDOS, 19, NT_STATUS_MEDIA_WRITE_PROTECTED}, - {ERRDOS, 21, NT_STATUS_DEVICE_NOT_READY}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_GROUP_ATTRIBUTES}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_IMPERSONATION_LEVEL}, - {ERRHRD, ERRgeneral, NT_STATUS_CANT_OPEN_ANONYMOUS}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_VALIDATION_CLASS}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_TOKEN_TYPE}, - {ERRDOS, 87, NT_STATUS_BAD_MASTER_BOOT_RECORD}, - {ERRHRD, ERRgeneral, NT_STATUS_INSTRUCTION_MISALIGNMENT}, - {ERRDOS, ERRpipebusy, NT_STATUS_INSTANCE_NOT_AVAILABLE}, - {ERRDOS, ERRpipebusy, NT_STATUS_PIPE_NOT_AVAILABLE}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PIPE_STATE}, - {ERRDOS, ERRpipebusy, NT_STATUS_PIPE_BUSY}, - {ERRDOS, ERRbadfunc, NT_STATUS_ILLEGAL_FUNCTION}, - {ERRDOS, ERRnotconnected, NT_STATUS_PIPE_DISCONNECTED}, - {ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_CLOSING}, - {ERRHRD, ERRgeneral, NT_STATUS_PIPE_CONNECTED}, - {ERRHRD, ERRgeneral, NT_STATUS_PIPE_LISTENING}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_READ_MODE}, - {ERRDOS, 121, NT_STATUS_IO_TIMEOUT}, - {ERRDOS, 38, NT_STATUS_FILE_FORCED_CLOSED}, - {ERRHRD, ERRgeneral, NT_STATUS_PROFILING_NOT_STARTED}, - {ERRHRD, ERRgeneral, NT_STATUS_PROFILING_NOT_STOPPED}, - {ERRHRD, ERRgeneral, NT_STATUS_COULD_NOT_INTERPRET}, - {ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, - {ERRDOS, ERRunsup, NT_STATUS_NOT_SUPPORTED}, - {ERRDOS, 51, NT_STATUS_REMOTE_NOT_LISTENING}, - {ERRDOS, 52, NT_STATUS_DUPLICATE_NAME}, - {ERRDOS, 53, NT_STATUS_BAD_NETWORK_PATH}, - {ERRDOS, 54, NT_STATUS_NETWORK_BUSY}, - {ERRDOS, 55, NT_STATUS_DEVICE_DOES_NOT_EXIST}, - {ERRDOS, 56, NT_STATUS_TOO_MANY_COMMANDS}, - {ERRDOS, 57, NT_STATUS_ADAPTER_HARDWARE_ERROR}, - {ERRDOS, 58, NT_STATUS_INVALID_NETWORK_RESPONSE}, - {ERRDOS, 59, NT_STATUS_UNEXPECTED_NETWORK_ERROR}, - {ERRDOS, 60, NT_STATUS_BAD_REMOTE_ADAPTER}, - {ERRDOS, 61, NT_STATUS_PRINT_QUEUE_FULL}, - {ERRDOS, 62, NT_STATUS_NO_SPOOL_SPACE}, - {ERRDOS, 63, NT_STATUS_PRINT_CANCELLED}, - {ERRDOS, 64, NT_STATUS_NETWORK_NAME_DELETED}, - {ERRDOS, 65, NT_STATUS_NETWORK_ACCESS_DENIED}, - {ERRDOS, 66, NT_STATUS_BAD_DEVICE_TYPE}, - {ERRDOS, ERRnosuchshare, NT_STATUS_BAD_NETWORK_NAME}, - {ERRDOS, 68, NT_STATUS_TOO_MANY_NAMES}, - {ERRDOS, 69, NT_STATUS_TOO_MANY_SESSIONS}, - {ERRDOS, 70, NT_STATUS_SHARING_PAUSED}, - {ERRDOS, 71, NT_STATUS_REQUEST_NOT_ACCEPTED}, - {ERRDOS, 72, NT_STATUS_REDIRECTOR_PAUSED}, - {ERRDOS, 88, NT_STATUS_NET_WRITE_FAULT}, - {ERRHRD, ERRgeneral, NT_STATUS_PROFILING_AT_LIMIT}, - {ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE}, - {ERRDOS, ERRnoaccess, NT_STATUS_FILE_RENAMED}, - {ERRDOS, 240, NT_STATUS_VIRTUAL_CIRCUIT_CLOSED}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_SECURITY_ON_OBJECT}, - {ERRHRD, ERRgeneral, NT_STATUS_CANT_WAIT}, - {ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_EMPTY}, - {ERRHRD, ERRgeneral, NT_STATUS_CANT_ACCESS_DOMAIN_INFO}, - {ERRHRD, ERRgeneral, NT_STATUS_CANT_TERMINATE_SELF}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SERVER_STATE}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DOMAIN_STATE}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DOMAIN_ROLE}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_DOMAIN}, - {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_EXISTS}, - {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_LIMIT_EXCEEDED}, - {ERRDOS, 300, NT_STATUS_OPLOCK_NOT_GRANTED}, - {ERRDOS, 301, NT_STATUS_INVALID_OPLOCK_PROTOCOL}, - {ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_DB_CORRUPTION}, - {ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_GENERIC_NOT_MAPPED}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_DESCRIPTOR_FORMAT}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_USER_BUFFER}, - {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_IO_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_CREATE_ERR}, - {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_MAP_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_EXTEND_ERR}, - {ERRHRD, ERRgeneral, NT_STATUS_NOT_LOGON_PROCESS}, - {ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_EXISTS}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_1}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_2}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_3}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_4}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_5}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_6}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_7}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_8}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_9}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_10}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_11}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_12}, - {ERRDOS, ERRbadpath, NT_STATUS_REDIRECTOR_NOT_STARTED}, - {ERRHRD, ERRgeneral, NT_STATUS_REDIRECTOR_STARTED}, - {ERRHRD, ERRgeneral, NT_STATUS_STACK_OVERFLOW}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_PACKAGE}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_FUNCTION_TABLE}, - {ERRDOS, 203, NT_STATUS(0xc0000100)}, - {ERRDOS, 145, NT_STATUS_DIRECTORY_NOT_EMPTY}, - {ERRHRD, ERRgeneral, NT_STATUS_FILE_CORRUPT_ERROR}, - {ERRDOS, 267, NT_STATUS_NOT_A_DIRECTORY}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_LOGON_SESSION_STATE}, - {ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_COLLISION}, - {ERRDOS, 206, NT_STATUS_NAME_TOO_LONG}, - {ERRDOS, 2401, NT_STATUS_FILES_OPEN}, - {ERRDOS, 2404, NT_STATUS_CONNECTION_IN_USE}, - {ERRHRD, ERRgeneral, NT_STATUS_MESSAGE_NOT_FOUND}, - {ERRDOS, ERRnoaccess, NT_STATUS_PROCESS_IS_TERMINATING}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LOGON_TYPE}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_GUID_TRANSLATION}, - {ERRHRD, ERRgeneral, NT_STATUS_CANNOT_IMPERSONATE}, - {ERRHRD, ERRgeneral, NT_STATUS_IMAGE_ALREADY_LOADED}, - {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_NOT_PRESENT}, - {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_LID_NOT_EXIST}, - {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_LID_ALREADY_OWNED}, - {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_NOT_LID_OWNER}, - {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_COMMAND}, - {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_LID}, - {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE}, - {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_SELECTOR}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_LDT}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_SIZE}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_OFFSET}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_DESCRIPTOR}, - {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_NE_FORMAT}, - {ERRHRD, ERRgeneral, NT_STATUS_RXACT_INVALID_STATE}, - {ERRHRD, ERRgeneral, NT_STATUS_RXACT_COMMIT_FAILURE}, - {ERRHRD, ERRgeneral, NT_STATUS_MAPPED_FILE_SIZE_ZERO}, - {ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES}, - {ERRHRD, ERRgeneral, NT_STATUS_CANCELLED}, - {ERRDOS, ERRnoaccess, NT_STATUS_CANNOT_DELETE}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_COMPUTER_NAME}, - {ERRDOS, ERRnoaccess, NT_STATUS_FILE_DELETED}, - {ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_ACCOUNT}, - {ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_GROUP}, - {ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_USER}, - {ERRHRD, ERRgeneral, NT_STATUS_MEMBERS_PRIMARY_GROUP}, - {ERRDOS, ERRbadfid, NT_STATUS_FILE_CLOSED}, - {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_THREADS}, - {ERRHRD, ERRgeneral, NT_STATUS_THREAD_NOT_IN_PROCESS}, - {ERRHRD, ERRgeneral, NT_STATUS_TOKEN_ALREADY_IN_USE}, - {ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_QUOTA_EXCEEDED}, - {ERRHRD, ERRgeneral, NT_STATUS_COMMITMENT_LIMIT}, - {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_LE_FORMAT}, - {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_NOT_MZ}, - {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_PROTECT}, - {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_WIN_16}, - {ERRHRD, ERRgeneral, NT_STATUS_LOGON_SERVER_CONFLICT}, - {ERRHRD, ERRgeneral, NT_STATUS_TIME_DIFFERENCE_AT_DC}, - {ERRHRD, ERRgeneral, NT_STATUS_SYNCHRONIZATION_REQUIRED}, - {ERRDOS, 126, NT_STATUS_DLL_NOT_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_OPEN_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_IO_PRIVILEGE_FAILED}, - {ERRDOS, 182, NT_STATUS_ORDINAL_NOT_FOUND}, - {ERRDOS, 127, NT_STATUS_ENTRYPOINT_NOT_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_CONTROL_C_EXIT}, - {ERRDOS, 64, NT_STATUS_LOCAL_DISCONNECT}, - {ERRDOS, 64, NT_STATUS_REMOTE_DISCONNECT}, - {ERRDOS, 51, NT_STATUS_REMOTE_RESOURCES}, - {ERRDOS, 59, NT_STATUS_LINK_FAILED}, - {ERRDOS, 59, NT_STATUS_LINK_TIMEOUT}, - {ERRDOS, 59, NT_STATUS_INVALID_CONNECTION}, - {ERRDOS, 59, NT_STATUS_INVALID_ADDRESS}, - {ERRHRD, ERRgeneral, NT_STATUS_DLL_INIT_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_MISSING_SYSTEMFILE}, - {ERRHRD, ERRgeneral, NT_STATUS_UNHANDLED_EXCEPTION}, - {ERRHRD, ERRgeneral, NT_STATUS_APP_INIT_FAILURE}, - {ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_CREATE_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_PAGEFILE}, - {ERRDOS, 124, NT_STATUS_INVALID_LEVEL}, - {ERRDOS, 86, NT_STATUS_WRONG_PASSWORD_CORE}, - {ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_FLOAT_CONTEXT}, - {ERRDOS, 109, NT_STATUS_PIPE_BROKEN}, - {ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_CORRUPT}, - {ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_IO_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_EVENT_PAIR}, - {ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_VOLUME}, - {ERRHRD, ERRgeneral, NT_STATUS_SERIAL_NO_DEVICE_INITED}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_ALIAS}, - {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_ALIAS}, - {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_ALIAS}, - {ERRHRD, ERRgeneral, NT_STATUS_ALIAS_EXISTS}, - {ERRHRD, ERRgeneral, NT_STATUS_LOGON_NOT_GRANTED}, - {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_SECRETS}, - {ERRHRD, ERRgeneral, NT_STATUS_SECRET_TOO_LONG}, - {ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_DB_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_FULLSCREEN_MODE}, - {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_CONTEXT_IDS}, - {ERRDOS, ERRnoaccess, NT_STATUS_LOGON_TYPE_NOT_GRANTED}, - {ERRHRD, ERRgeneral, NT_STATUS_NOT_REGISTRY_FILE}, - {ERRHRD, ERRgeneral, NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED}, - {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_FT_MISSING_MEMBER}, - {ERRHRD, ERRgeneral, NT_STATUS_ILL_FORMED_SERVICE_ENTRY}, - {ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_CHARACTER}, - {ERRHRD, ERRgeneral, NT_STATUS_UNMAPPABLE_CHARACTER}, - {ERRHRD, ERRgeneral, NT_STATUS_UNDEFINED_CHARACTER}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_VOLUME}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_WRONG_CYLINDER}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_UNKNOWN_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_BAD_REGISTERS}, - {ERRHRD, ERRgeneral, NT_STATUS_DISK_RECALIBRATE_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_DISK_OPERATION_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_DISK_RESET_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_SHARED_IRQ_BUSY}, - {ERRHRD, ERRgeneral, NT_STATUS_FT_ORPHANING}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000016e)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000016f)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc0000170)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc0000171)}, - {ERRHRD, ERRgeneral, NT_STATUS_PARTITION_FAILURE}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_BLOCK_LENGTH}, - {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_PARTITIONED}, - {ERRHRD, ERRgeneral, NT_STATUS_UNABLE_TO_LOCK_MEDIA}, - {ERRHRD, ERRgeneral, NT_STATUS_UNABLE_TO_UNLOAD_MEDIA}, - {ERRHRD, ERRgeneral, NT_STATUS_EOM_OVERFLOW}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_MEDIA}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc0000179)}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_MEMBER}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_MEMBER}, - {ERRHRD, ERRgeneral, NT_STATUS_KEY_DELETED}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_LOG_SPACE}, - {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_SIDS}, - {ERRHRD, ERRgeneral, NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED}, - {ERRHRD, ERRgeneral, NT_STATUS_KEY_HAS_CHILDREN}, - {ERRHRD, ERRgeneral, NT_STATUS_CHILD_MUST_BE_VOLATILE}, - {ERRDOS, 87, NT_STATUS_DEVICE_CONFIGURATION_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_DRIVER_INTERNAL_ERROR}, - {ERRDOS, 22, NT_STATUS_INVALID_DEVICE_STATE}, - {ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_PROTOCOL_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_BACKUP_CONTROLLER}, - {ERRHRD, ERRgeneral, NT_STATUS_LOG_FILE_FULL}, - {ERRDOS, 19, NT_STATUS_TOO_LATE}, - {ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_LSA_SECRET}, -/* { This NT error code was 'sqashed' - from NT_STATUS_NO_TRUST_SAM_ACCOUNT to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE - during the session setup } -*/ - {ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_SAM_ACCOUNT}, - {ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_DOMAIN_FAILURE}, - {ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE}, - {ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_FILE_CORRUPT}, - {ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_CANT_START}, - {ERRDOS, ERRnoaccess, NT_STATUS_TRUST_FAILURE}, - {ERRHRD, ERRgeneral, NT_STATUS_MUTANT_LIMIT_EXCEEDED}, - {ERRDOS, ERRinvgroup, NT_STATUS_NETLOGON_NOT_STARTED}, - {ERRSRV, 2239, NT_STATUS_ACCOUNT_EXPIRED}, - {ERRHRD, ERRgeneral, NT_STATUS_POSSIBLE_DEADLOCK}, - {ERRHRD, ERRgeneral, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, - {ERRHRD, ERRgeneral, NT_STATUS_REMOTE_SESSION_LIMIT}, - {ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_FILE_CHANGED}, - {ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT}, - {ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT}, - {ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT}, -/* { This NT error code was 'sqashed' - from NT_STATUS_DOMAIN_TRUST_INCONSISTENT to NT_STATUS_LOGON_FAILURE - during the session setup } -*/ - {ERRDOS, ERRnoaccess, NT_STATUS_DOMAIN_TRUST_INCONSISTENT}, - {ERRHRD, ERRgeneral, NT_STATUS_FS_DRIVER_REQUIRED}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_USER_SESSION_KEY}, - {ERRDOS, 59, NT_STATUS_USER_SESSION_DELETED}, - {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_LANG_NOT_FOUND}, - {ERRDOS, ERRnomem, NT_STATUS_INSUFF_SERVER_RESOURCES}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_BUFFER_SIZE}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_COMPONENT}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_WILDCARD}, - {ERRDOS, 68, NT_STATUS_TOO_MANY_ADDRESSES}, - {ERRDOS, 52, NT_STATUS_ADDRESS_ALREADY_EXISTS}, - {ERRDOS, 64, NT_STATUS_ADDRESS_CLOSED}, - {ERRDOS, 64, NT_STATUS_CONNECTION_DISCONNECTED}, - {ERRDOS, 64, NT_STATUS_CONNECTION_RESET}, - {ERRDOS, 68, NT_STATUS_TOO_MANY_NODES}, - {ERRDOS, 59, NT_STATUS_TRANSACTION_ABORTED}, - {ERRDOS, 59, NT_STATUS_TRANSACTION_TIMED_OUT}, - {ERRDOS, 59, NT_STATUS_TRANSACTION_NO_RELEASE}, - {ERRDOS, 59, NT_STATUS_TRANSACTION_NO_MATCH}, - {ERRDOS, 59, NT_STATUS_TRANSACTION_RESPONDED}, - {ERRDOS, 59, NT_STATUS_TRANSACTION_INVALID_ID}, - {ERRDOS, 59, NT_STATUS_TRANSACTION_INVALID_TYPE}, - {ERRDOS, ERRunsup, NT_STATUS_NOT_SERVER_SESSION}, - {ERRDOS, ERRunsup, NT_STATUS_NOT_CLIENT_SESSION}, - {ERRHRD, ERRgeneral, NT_STATUS_CANNOT_LOAD_REGISTRY_FILE}, - {ERRHRD, ERRgeneral, NT_STATUS_DEBUG_ATTACH_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_SYSTEM_PROCESS_TERMINATED}, - {ERRHRD, ERRgeneral, NT_STATUS_DATA_NOT_ACCEPTED}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_BROWSER_SERVERS_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_VDM_HARD_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_DRIVER_CANCEL_TIMEOUT}, - {ERRHRD, ERRgeneral, NT_STATUS_REPLY_MESSAGE_MISMATCH}, - {ERRHRD, ERRgeneral, NT_STATUS_MAPPED_ALIGNMENT}, - {ERRDOS, 193, NT_STATUS_IMAGE_CHECKSUM_MISMATCH}, - {ERRHRD, ERRgeneral, NT_STATUS_LOST_WRITEBEHIND_DATA}, - {ERRHRD, ERRgeneral, NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID}, - {ERRSRV, 2242, NT_STATUS_PASSWORD_MUST_CHANGE}, - {ERRHRD, ERRgeneral, NT_STATUS_NOT_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_NOT_TINY_STREAM}, - {ERRHRD, ERRgeneral, NT_STATUS_RECOVERY_FAILURE}, - {ERRHRD, ERRgeneral, NT_STATUS_STACK_OVERFLOW_READ}, - {ERRHRD, ERRgeneral, NT_STATUS_FAIL_CHECK}, - {ERRHRD, ERRgeneral, NT_STATUS_DUPLICATE_OBJECTID}, - {ERRHRD, ERRgeneral, NT_STATUS_OBJECTID_EXISTS}, - {ERRHRD, ERRgeneral, NT_STATUS_CONVERT_TO_LARGE}, - {ERRHRD, ERRgeneral, NT_STATUS_RETRY}, - {ERRHRD, ERRgeneral, NT_STATUS_FOUND_OUT_OF_SCOPE}, - {ERRHRD, ERRgeneral, NT_STATUS_ALLOCATE_BUCKET}, - {ERRHRD, ERRgeneral, NT_STATUS_PROPSET_NOT_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_MARSHALL_OVERFLOW}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_VARIANT}, - {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND}, - {ERRDOS, ERRnoaccess, NT_STATUS_ACCOUNT_LOCKED_OUT}, - {ERRDOS, ERRbadfid, NT_STATUS_HANDLE_NOT_CLOSABLE}, - {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_REFUSED}, - {ERRHRD, ERRgeneral, NT_STATUS_GRACEFUL_DISCONNECT}, - {ERRHRD, ERRgeneral, NT_STATUS_ADDRESS_ALREADY_ASSOCIATED}, - {ERRHRD, ERRgeneral, NT_STATUS_ADDRESS_NOT_ASSOCIATED}, - {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_INVALID}, - {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ACTIVE}, - {ERRHRD, ERRgeneral, NT_STATUS_NETWORK_UNREACHABLE}, - {ERRHRD, ERRgeneral, NT_STATUS_HOST_UNREACHABLE}, - {ERRHRD, ERRgeneral, NT_STATUS_PROTOCOL_UNREACHABLE}, - {ERRHRD, ERRgeneral, NT_STATUS_PORT_UNREACHABLE}, - {ERRHRD, ERRgeneral, NT_STATUS_REQUEST_ABORTED}, - {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ABORTED}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_COMPRESSION_BUFFER}, - {ERRHRD, ERRgeneral, NT_STATUS_USER_MAPPED_FILE}, - {ERRHRD, ERRgeneral, NT_STATUS_AUDIT_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_TIMER_RESOLUTION_NOT_SET}, - {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_COUNT_LIMIT}, - {ERRHRD, ERRgeneral, NT_STATUS_LOGIN_TIME_RESTRICTION}, - {ERRHRD, ERRgeneral, NT_STATUS_LOGIN_WKSTA_RESTRICTION}, - {ERRDOS, 193, NT_STATUS_IMAGE_MP_UP_MISMATCH}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000024a)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000024b)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000024c)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000024d)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000024e)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000024f)}, - {ERRHRD, ERRgeneral, NT_STATUS_INSUFFICIENT_LOGON_INFO}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_DLL_ENTRYPOINT}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_SERVICE_ENTRYPOINT}, - {ERRHRD, ERRgeneral, NT_STATUS_LPC_REPLY_LOST}, - {ERRHRD, ERRgeneral, NT_STATUS_IP_ADDRESS_CONFLICT1}, - {ERRHRD, ERRgeneral, NT_STATUS_IP_ADDRESS_CONFLICT2}, - {ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_QUOTA_LIMIT}, - {ERRSRV, ERRbadtype, NT_STATUS_PATH_NOT_COVERED}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_CALLBACK_ACTIVE}, - {ERRHRD, ERRgeneral, NT_STATUS_LICENSE_QUOTA_EXCEEDED}, - {ERRHRD, ERRgeneral, NT_STATUS_PWD_TOO_SHORT}, - {ERRHRD, ERRgeneral, NT_STATUS_PWD_TOO_RECENT}, - {ERRHRD, ERRgeneral, NT_STATUS_PWD_HISTORY_CONFLICT}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000025d)}, - {ERRHRD, ERRgeneral, NT_STATUS_PLUGPLAY_NO_DEVICE}, - {ERRHRD, ERRgeneral, NT_STATUS_UNSUPPORTED_COMPRESSION}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_HW_PROFILE}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH}, - {ERRDOS, 182, NT_STATUS_DRIVER_ORDINAL_NOT_FOUND}, - {ERRDOS, 127, NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND}, - {ERRDOS, 288, NT_STATUS_RESOURCE_NOT_OWNED}, - {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LINKS}, - {ERRHRD, ERRgeneral, NT_STATUS_QUOTA_LIST_INCONSISTENT}, - {ERRHRD, ERRgeneral, NT_STATUS_FILE_IS_OFFLINE}, - {ERRDOS, 21, NT_STATUS(0xc000026e)}, - {ERRDOS, 161, NT_STATUS(0xc0000281)}, - {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028a)}, - {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028b)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000028c)}, - {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028d)}, - {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028e)}, - {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028f)}, - {ERRDOS, ERRnoaccess, NT_STATUS(0xc0000290)}, - {ERRDOS, ERRbadfunc, NT_STATUS(0xc000029c)}, -}; - - -/* errmap NTSTATUS->Win32 */ -static const struct { - NTSTATUS ntstatus; - WERROR werror; -} ntstatus_to_werror_map[] = { - /* - * we add this manualy here, so that W_ERROR(0x5) - * gets mapped to NTSTATUS_ACCESS_DENIED - */ - {NT_STATUS_ACCESS_DENIED, WERR_ACCESS_DENIED}, - {NT_STATUS(0x103), W_ERROR(0x3e5)}, - {NT_STATUS(0x105), W_ERROR(0xea)}, - {NT_STATUS(0x106), W_ERROR(0x514)}, - {NT_STATUS(0x107), W_ERROR(0x515)}, - {NT_STATUS(0x10c), W_ERROR(0x3fe)}, - {NT_STATUS(0x10d), W_ERROR(0x516)}, - {NT_STATUS(0x121), W_ERROR(0x2009)}, - {NT_STATUS(0xc0000001), W_ERROR(0x1f)}, - {NT_STATUS(0xc0000002), W_ERROR(0x1)}, - {NT_STATUS(0xc0000003), W_ERROR(0x57)}, - {NT_STATUS(0xc0000004), W_ERROR(0x18)}, - {NT_STATUS(0xc0000005), W_ERROR(0x3e6)}, - {NT_STATUS(0xc0000006), W_ERROR(0x3e7)}, - {NT_STATUS(0xc0000007), W_ERROR(0x5ae)}, - {NT_STATUS(0xc0000008), W_ERROR(0x6)}, - {NT_STATUS(0xc0000009), W_ERROR(0x3e9)}, - {NT_STATUS(0xc000000a), W_ERROR(0xc1)}, - {NT_STATUS(0xc000000b), W_ERROR(0x57)}, - {NT_STATUS(0xc000000d), W_ERROR(0x57)}, - {NT_STATUS(0xc000000e), W_ERROR(0x2)}, - {NT_STATUS(0xc000000f), W_ERROR(0x2)}, - {NT_STATUS(0xc0000010), W_ERROR(0x1)}, - {NT_STATUS(0xc0000011), W_ERROR(0x26)}, - {NT_STATUS(0xc0000012), W_ERROR(0x22)}, - {NT_STATUS(0xc0000013), W_ERROR(0x15)}, - {NT_STATUS(0xc0000014), W_ERROR(0x6f9)}, - {NT_STATUS(0xc0000015), W_ERROR(0x1b)}, - {NT_STATUS(0xc0000016), W_ERROR(0xea)}, - {NT_STATUS(0xc0000017), W_ERROR(0x8)}, - {NT_STATUS(0xc0000018), W_ERROR(0x1e7)}, - {NT_STATUS(0xc0000019), W_ERROR(0x1e7)}, - {NT_STATUS(0xc000001a), W_ERROR(0x57)}, - {NT_STATUS(0xc000001b), W_ERROR(0x57)}, - {NT_STATUS(0xc000001c), W_ERROR(0x1)}, - {NT_STATUS(0xc000001d), W_ERROR(0xc000001d)}, - {NT_STATUS(0xc000001e), W_ERROR(0x5)}, - {NT_STATUS(0xc000001f), W_ERROR(0x5)}, - {NT_STATUS(0xc0000020), W_ERROR(0xc1)}, - {NT_STATUS(0xc0000021), W_ERROR(0x5)}, - {NT_STATUS(0xc0000022), W_ERROR(0x5)}, - {NT_STATUS(0xc0000023), W_ERROR(0x7a)}, - {NT_STATUS(0xc0000024), W_ERROR(0x6)}, - {NT_STATUS(0xc0000025), W_ERROR(0xc0000025)}, - {NT_STATUS(0xc0000026), W_ERROR(0xc0000026)}, - {NT_STATUS(0xc000002a), W_ERROR(0x9e)}, - {NT_STATUS(0xc000002b), W_ERROR(0xc000002b)}, - {NT_STATUS(0xc000002c), W_ERROR(0x1e7)}, - {NT_STATUS(0xc000002d), W_ERROR(0x1e7)}, - {NT_STATUS(0xc0000030), W_ERROR(0x57)}, - {NT_STATUS(0xc0000032), W_ERROR(0x571)}, - {NT_STATUS(0xc0000033), W_ERROR(0x7b)}, - {NT_STATUS(0xc0000034), W_ERROR(0x2)}, - {NT_STATUS(0xc0000035), W_ERROR(0xb7)}, - {NT_STATUS(0xc0000037), W_ERROR(0x6)}, - {NT_STATUS(0xc0000039), W_ERROR(0xa1)}, - {NT_STATUS(0xc000003a), W_ERROR(0x3)}, - {NT_STATUS(0xc000003b), W_ERROR(0xa1)}, - {NT_STATUS(0xc000003c), W_ERROR(0x45d)}, - {NT_STATUS(0xc000003d), W_ERROR(0x45d)}, - {NT_STATUS(0xc000003e), W_ERROR(0x17)}, - {NT_STATUS(0xc000003f), W_ERROR(0x17)}, - {NT_STATUS(0xc0000040), W_ERROR(0x8)}, - {NT_STATUS(0xc0000041), W_ERROR(0x5)}, - {NT_STATUS(0xc0000042), W_ERROR(0x6)}, - {NT_STATUS(0xc0000043), W_ERROR(0x20)}, - {NT_STATUS(0xc0000044), W_ERROR(0x718)}, - {NT_STATUS(0xc0000045), W_ERROR(0x57)}, - {NT_STATUS(0xc0000046), W_ERROR(0x120)}, - {NT_STATUS(0xc0000047), W_ERROR(0x12a)}, - {NT_STATUS(0xc0000048), W_ERROR(0x57)}, - {NT_STATUS(0xc0000049), W_ERROR(0x57)}, - {NT_STATUS(0xc000004a), W_ERROR(0x9c)}, - {NT_STATUS(0xc000004b), W_ERROR(0x5)}, - {NT_STATUS(0xc000004c), W_ERROR(0x57)}, - {NT_STATUS(0xc000004d), W_ERROR(0x57)}, - {NT_STATUS(0xc000004e), W_ERROR(0x57)}, - {NT_STATUS(0xc000004f), W_ERROR(0x11a)}, - {NT_STATUS(0xc0000050), W_ERROR(0xff)}, - {NT_STATUS(0xc0000051), W_ERROR(0x570)}, - {NT_STATUS(0xc0000052), W_ERROR(0x570)}, - {NT_STATUS(0xc0000053), W_ERROR(0x570)}, - {NT_STATUS(0xc0000054), W_ERROR(0x21)}, - {NT_STATUS(0xc0000055), W_ERROR(0x21)}, - {NT_STATUS(0xc0000056), W_ERROR(0x5)}, - {NT_STATUS(0xc0000057), W_ERROR(0x32)}, - {NT_STATUS(0xc0000058), W_ERROR(0x519)}, - {NT_STATUS(0xc0000059), W_ERROR(0x51a)}, - {NT_STATUS(0xc000005a), W_ERROR(0x51b)}, - {NT_STATUS(0xc000005b), W_ERROR(0x51c)}, - {NT_STATUS(0xc000005c), W_ERROR(0x51d)}, - {NT_STATUS(0xc000005d), W_ERROR(0x51e)}, - {NT_STATUS(0xc000005e), W_ERROR(0x51f)}, - {NT_STATUS(0xc000005f), W_ERROR(0x520)}, - {NT_STATUS(0xc0000060), W_ERROR(0x521)}, - {NT_STATUS(0xc0000061), W_ERROR(0x522)}, - {NT_STATUS(0xc0000062), W_ERROR(0x523)}, - {NT_STATUS(0xc0000063), W_ERROR(0x524)}, - {NT_STATUS(0xc0000064), W_ERROR(0x525)}, - {NT_STATUS(0xc0000065), W_ERROR(0x526)}, - {NT_STATUS(0xc0000066), W_ERROR(0x527)}, - {NT_STATUS(0xc0000067), W_ERROR(0x528)}, - {NT_STATUS(0xc0000068), W_ERROR(0x529)}, - {NT_STATUS(0xc0000069), W_ERROR(0x52a)}, - {NT_STATUS(0xc000006a), W_ERROR(0x56)}, - {NT_STATUS(0xc000006b), W_ERROR(0x52c)}, - {NT_STATUS(0xc000006c), W_ERROR(0x52d)}, - {NT_STATUS(0xc000006d), W_ERROR(0x52e)}, - {NT_STATUS(0xc000006e), W_ERROR(0x52f)}, - {NT_STATUS(0xc000006f), W_ERROR(0x530)}, - {NT_STATUS(0xc0000070), W_ERROR(0x531)}, - {NT_STATUS(0xc0000071), W_ERROR(0x532)}, - {NT_STATUS(0xc0000072), W_ERROR(0x533)}, - {NT_STATUS(0xc0000073), W_ERROR(0x534)}, - {NT_STATUS(0xc0000074), W_ERROR(0x535)}, - {NT_STATUS(0xc0000075), W_ERROR(0x536)}, - {NT_STATUS(0xc0000076), W_ERROR(0x537)}, - {NT_STATUS(0xc0000077), W_ERROR(0x538)}, - {NT_STATUS(0xc0000078), W_ERROR(0x539)}, - {NT_STATUS(0xc0000079), W_ERROR(0x53a)}, - {NT_STATUS(0xc000007a), W_ERROR(0x7f)}, - {NT_STATUS(0xc000007b), W_ERROR(0xc1)}, - {NT_STATUS(0xc000007c), W_ERROR(0x3f0)}, - {NT_STATUS(0xc000007d), W_ERROR(0x53c)}, - {NT_STATUS(0xc000007e), W_ERROR(0x9e)}, - {NT_STATUS(0xc000007f), W_ERROR(0x70)}, - {NT_STATUS(0xc0000080), W_ERROR(0x53d)}, - {NT_STATUS(0xc0000081), W_ERROR(0x53e)}, - {NT_STATUS(0xc0000082), W_ERROR(0x44)}, - {NT_STATUS(0xc0000083), W_ERROR(0x103)}, - {NT_STATUS(0xc0000084), W_ERROR(0x53f)}, - {NT_STATUS(0xc0000085), W_ERROR(0x103)}, - {NT_STATUS(0xc0000086), W_ERROR(0x9a)}, - {NT_STATUS(0xc0000087), W_ERROR(0xe)}, - {NT_STATUS(0xc0000088), W_ERROR(0x1e7)}, - {NT_STATUS(0xc0000089), W_ERROR(0x714)}, - {NT_STATUS(0xc000008a), W_ERROR(0x715)}, - {NT_STATUS(0xc000008b), W_ERROR(0x716)}, - {NT_STATUS(0xc000008c), W_ERROR(0xc000008c)}, - {NT_STATUS(0xc000008d), W_ERROR(0xc000008d)}, - {NT_STATUS(0xc000008e), W_ERROR(0xc000008e)}, - {NT_STATUS(0xc000008f), W_ERROR(0xc000008f)}, - {NT_STATUS(0xc0000090), W_ERROR(0xc0000090)}, - {NT_STATUS(0xc0000091), W_ERROR(0xc0000091)}, - {NT_STATUS(0xc0000092), W_ERROR(0xc0000092)}, - {NT_STATUS(0xc0000093), W_ERROR(0xc0000093)}, - {NT_STATUS(0xc0000094), W_ERROR(0xc0000094)}, - {NT_STATUS(0xc0000095), W_ERROR(0x216)}, - {NT_STATUS(0xc0000096), W_ERROR(0xc0000096)}, - {NT_STATUS(0xc0000097), W_ERROR(0x8)}, - {NT_STATUS(0xc0000098), W_ERROR(0x3ee)}, - {NT_STATUS(0xc0000099), W_ERROR(0x540)}, - {NT_STATUS(0xc000009a), W_ERROR(0x5aa)}, - {NT_STATUS(0xc000009b), W_ERROR(0x3)}, - {NT_STATUS(0xc000009c), W_ERROR(0x17)}, - {NT_STATUS(0xc000009d), W_ERROR(0x48f)}, - {NT_STATUS(0xc000009e), W_ERROR(0x15)}, - {NT_STATUS(0xc000009f), W_ERROR(0x1e7)}, - {NT_STATUS(0xc00000a0), W_ERROR(0x1e7)}, - {NT_STATUS(0xc00000a1), W_ERROR(0x5ad)}, - {NT_STATUS(0xc00000a2), W_ERROR(0x13)}, - {NT_STATUS(0xc00000a3), W_ERROR(0x15)}, - {NT_STATUS(0xc00000a4), W_ERROR(0x541)}, - {NT_STATUS(0xc00000a5), W_ERROR(0x542)}, - {NT_STATUS(0xc00000a6), W_ERROR(0x543)}, - {NT_STATUS(0xc00000a7), W_ERROR(0x544)}, - {NT_STATUS(0xc00000a8), W_ERROR(0x545)}, - {NT_STATUS(0xc00000a9), W_ERROR(0x57)}, - {NT_STATUS(0xc00000ab), W_ERROR(0xe7)}, - {NT_STATUS(0xc00000ac), W_ERROR(0xe7)}, - {NT_STATUS(0xc00000ad), W_ERROR(0xe6)}, - {NT_STATUS(0xc00000ae), W_ERROR(0xe7)}, - {NT_STATUS(0xc00000af), W_ERROR(0x1)}, - {NT_STATUS(0xc00000b0), W_ERROR(0xe9)}, - {NT_STATUS(0xc00000b1), W_ERROR(0xe8)}, - {NT_STATUS(0xc00000b2), W_ERROR(0x217)}, - {NT_STATUS(0xc00000b3), W_ERROR(0x218)}, - {NT_STATUS(0xc00000b4), W_ERROR(0xe6)}, - {NT_STATUS(0xc00000b5), W_ERROR(0x79)}, - {NT_STATUS(0xc00000b6), W_ERROR(0x26)}, - {NT_STATUS(0xc00000ba), W_ERROR(0x5)}, - {NT_STATUS(0xc00000bb), W_ERROR(0x32)}, - {NT_STATUS(0xc00000bc), W_ERROR(0x33)}, - {NT_STATUS(0xc00000bd), W_ERROR(0x34)}, - {NT_STATUS(0xc00000be), W_ERROR(0x35)}, - {NT_STATUS(0xc00000bf), W_ERROR(0x36)}, - {NT_STATUS(0xc00000c0), W_ERROR(0x37)}, - {NT_STATUS(0xc00000c1), W_ERROR(0x38)}, - {NT_STATUS(0xc00000c2), W_ERROR(0x39)}, - {NT_STATUS(0xc00000c3), W_ERROR(0x3a)}, - {NT_STATUS(0xc00000c4), W_ERROR(0x3b)}, - {NT_STATUS(0xc00000c5), W_ERROR(0x3c)}, - {NT_STATUS(0xc00000c6), W_ERROR(0x3d)}, - {NT_STATUS(0xc00000c7), W_ERROR(0x3e)}, - {NT_STATUS(0xc00000c8), W_ERROR(0x3f)}, - {NT_STATUS(0xc00000c9), W_ERROR(0x40)}, - {NT_STATUS(0xc00000ca), W_ERROR(0x41)}, - {NT_STATUS(0xc00000cb), W_ERROR(0x42)}, - {NT_STATUS(0xc00000cc), W_ERROR(0x43)}, - {NT_STATUS(0xc00000cd), W_ERROR(0x44)}, - {NT_STATUS(0xc00000ce), W_ERROR(0x45)}, - {NT_STATUS(0xc00000cf), W_ERROR(0x46)}, - {NT_STATUS(0xc00000d0), W_ERROR(0x47)}, - {NT_STATUS(0xc00000d1), W_ERROR(0x48)}, - {NT_STATUS(0xc00000d2), W_ERROR(0x58)}, - {NT_STATUS(0xc00000d4), W_ERROR(0x11)}, - {NT_STATUS(0xc00000d5), W_ERROR(0x5)}, - {NT_STATUS(0xc00000d6), W_ERROR(0xf0)}, - {NT_STATUS(0xc00000d7), W_ERROR(0x546)}, - {NT_STATUS(0xc00000d9), W_ERROR(0xe8)}, - {NT_STATUS(0xc00000da), W_ERROR(0x547)}, - {NT_STATUS(0xc00000dc), W_ERROR(0x548)}, - {NT_STATUS(0xc00000dd), W_ERROR(0x549)}, - {NT_STATUS(0xc00000de), W_ERROR(0x54a)}, - {NT_STATUS(0xc00000df), W_ERROR(0x54b)}, - {NT_STATUS(0xc00000e0), W_ERROR(0x54c)}, - {NT_STATUS(0xc00000e1), W_ERROR(0x54d)}, - {NT_STATUS(0xc00000e2), W_ERROR(0x12c)}, - {NT_STATUS(0xc00000e3), W_ERROR(0x12d)}, - {NT_STATUS(0xc00000e4), W_ERROR(0x54e)}, - {NT_STATUS(0xc00000e5), W_ERROR(0x54f)}, - {NT_STATUS(0xc00000e6), W_ERROR(0x550)}, - {NT_STATUS(0xc00000e7), W_ERROR(0x551)}, - {NT_STATUS(0xc00000e8), W_ERROR(0x6f8)}, - {NT_STATUS(0xc00000ed), W_ERROR(0x552)}, - {NT_STATUS(0xc00000ee), W_ERROR(0x553)}, - {NT_STATUS(0xc00000ef), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f0), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f1), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f2), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f3), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f4), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f5), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f6), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f7), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f8), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f9), W_ERROR(0x57)}, - {NT_STATUS(0xc00000fa), W_ERROR(0x57)}, - {NT_STATUS(0xc00000fb), W_ERROR(0x3)}, - {NT_STATUS(0xc00000fd), W_ERROR(0x3e9)}, - {NT_STATUS(0xc00000fe), W_ERROR(0x554)}, - {NT_STATUS(0xc0000100), W_ERROR(0xcb)}, - {NT_STATUS(0xc0000101), W_ERROR(0x91)}, - {NT_STATUS(0xc0000102), W_ERROR(0x570)}, - {NT_STATUS(0xc0000103), W_ERROR(0x10b)}, - {NT_STATUS(0xc0000104), W_ERROR(0x555)}, - {NT_STATUS(0xc0000105), W_ERROR(0x556)}, - {NT_STATUS(0xc0000106), W_ERROR(0xce)}, - {NT_STATUS(0xc0000107), W_ERROR(0x961)}, - {NT_STATUS(0xc0000108), W_ERROR(0x964)}, - {NT_STATUS(0xc000010a), W_ERROR(0x5)}, - {NT_STATUS(0xc000010b), W_ERROR(0x557)}, - {NT_STATUS(0xc000010d), W_ERROR(0x558)}, - {NT_STATUS(0xc000010e), W_ERROR(0x420)}, - {NT_STATUS(0xc0000117), W_ERROR(0x5a4)}, - {NT_STATUS(0xc000011b), W_ERROR(0xc1)}, - {NT_STATUS(0xc000011c), W_ERROR(0x559)}, - {NT_STATUS(0xc000011d), W_ERROR(0x55a)}, - {NT_STATUS(0xc000011e), W_ERROR(0x3ee)}, - {NT_STATUS(0xc000011f), W_ERROR(0x4)}, - {NT_STATUS(0xc0000120), W_ERROR(0x3e3)}, - {NT_STATUS(0xc0000121), W_ERROR(0x5)}, - {NT_STATUS(0xc0000122), W_ERROR(0x4ba)}, - {NT_STATUS(0xc0000123), W_ERROR(0x5)}, - {NT_STATUS(0xc0000124), W_ERROR(0x55b)}, - {NT_STATUS(0xc0000125), W_ERROR(0x55c)}, - {NT_STATUS(0xc0000126), W_ERROR(0x55d)}, - {NT_STATUS(0xc0000127), W_ERROR(0x55e)}, - {NT_STATUS(0xc0000128), W_ERROR(0x6)}, - {NT_STATUS(0xc000012b), W_ERROR(0x55f)}, - {NT_STATUS(0xc000012d), W_ERROR(0x5af)}, - {NT_STATUS(0xc000012e), W_ERROR(0xc1)}, - {NT_STATUS(0xc000012f), W_ERROR(0xc1)}, - {NT_STATUS(0xc0000130), W_ERROR(0xc1)}, - {NT_STATUS(0xc0000131), W_ERROR(0xc1)}, - {NT_STATUS(0xc0000133), W_ERROR(0x576)}, - {NT_STATUS(0xc0000135), W_ERROR(0x7e)}, - {NT_STATUS(0xc0000138), W_ERROR(0xb6)}, - {NT_STATUS(0xc0000139), W_ERROR(0x7f)}, - {NT_STATUS(0xc000013b), W_ERROR(0x40)}, - {NT_STATUS(0xc000013c), W_ERROR(0x40)}, - {NT_STATUS(0xc000013d), W_ERROR(0x33)}, - {NT_STATUS(0xc000013e), W_ERROR(0x3b)}, - {NT_STATUS(0xc000013f), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000140), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000141), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000142), W_ERROR(0x45a)}, - {NT_STATUS(0xc0000148), W_ERROR(0x7c)}, - {NT_STATUS(0xc0000149), W_ERROR(0x56)}, - {NT_STATUS(0xc000014b), W_ERROR(0x6d)}, - {NT_STATUS(0xc000014c), W_ERROR(0x3f1)}, - {NT_STATUS(0xc000014d), W_ERROR(0x3f8)}, - {NT_STATUS(0xc000014f), W_ERROR(0x3ed)}, - {NT_STATUS(0xc0000150), W_ERROR(0x45e)}, - {NT_STATUS(0xc0000151), W_ERROR(0x560)}, - {NT_STATUS(0xc0000152), W_ERROR(0x561)}, - {NT_STATUS(0xc0000153), W_ERROR(0x562)}, - {NT_STATUS(0xc0000154), W_ERROR(0x563)}, - {NT_STATUS(0xc0000155), W_ERROR(0x564)}, - {NT_STATUS(0xc0000156), W_ERROR(0x565)}, - {NT_STATUS(0xc0000157), W_ERROR(0x566)}, - {NT_STATUS(0xc0000158), W_ERROR(0x567)}, - {NT_STATUS(0xc0000159), W_ERROR(0x3ef)}, - {NT_STATUS(0xc000015a), W_ERROR(0x568)}, - {NT_STATUS(0xc000015b), W_ERROR(0x569)}, - {NT_STATUS(0xc000015c), W_ERROR(0x3f9)}, - {NT_STATUS(0xc000015d), W_ERROR(0x56a)}, - {NT_STATUS(0xc000015f), W_ERROR(0x45d)}, - {NT_STATUS(0xc0000162), W_ERROR(0x459)}, - {NT_STATUS(0xc0000165), W_ERROR(0x462)}, - {NT_STATUS(0xc0000166), W_ERROR(0x463)}, - {NT_STATUS(0xc0000167), W_ERROR(0x464)}, - {NT_STATUS(0xc0000168), W_ERROR(0x465)}, - {NT_STATUS(0xc0000169), W_ERROR(0x466)}, - {NT_STATUS(0xc000016a), W_ERROR(0x467)}, - {NT_STATUS(0xc000016b), W_ERROR(0x468)}, - {NT_STATUS(0xc000016c), W_ERROR(0x45f)}, - {NT_STATUS(0xc000016d), W_ERROR(0x45d)}, - {NT_STATUS(0xc0000172), W_ERROR(0x451)}, - {NT_STATUS(0xc0000173), W_ERROR(0x452)}, - {NT_STATUS(0xc0000174), W_ERROR(0x453)}, - {NT_STATUS(0xc0000175), W_ERROR(0x454)}, - {NT_STATUS(0xc0000176), W_ERROR(0x455)}, - {NT_STATUS(0xc0000177), W_ERROR(0x469)}, - {NT_STATUS(0xc0000178), W_ERROR(0x458)}, - {NT_STATUS(0xc000017a), W_ERROR(0x56b)}, - {NT_STATUS(0xc000017b), W_ERROR(0x56c)}, - {NT_STATUS(0xc000017c), W_ERROR(0x3fa)}, - {NT_STATUS(0xc000017d), W_ERROR(0x3fb)}, - {NT_STATUS(0xc000017e), W_ERROR(0x56d)}, - {NT_STATUS(0xc000017f), W_ERROR(0x56e)}, - {NT_STATUS(0xc0000180), W_ERROR(0x3fc)}, - {NT_STATUS(0xc0000181), W_ERROR(0x3fd)}, - {NT_STATUS(0xc0000182), W_ERROR(0x57)}, - {NT_STATUS(0xc0000183), W_ERROR(0x45d)}, - {NT_STATUS(0xc0000184), W_ERROR(0x16)}, - {NT_STATUS(0xc0000185), W_ERROR(0x45d)}, - {NT_STATUS(0xc0000186), W_ERROR(0x45d)}, - {NT_STATUS(0xc0000188), W_ERROR(0x5de)}, - {NT_STATUS(0xc0000189), W_ERROR(0x13)}, - {NT_STATUS(0xc000018a), W_ERROR(0x6fa)}, - {NT_STATUS(0xc000018b), W_ERROR(0x6fb)}, - {NT_STATUS(0xc000018c), W_ERROR(0x6fc)}, - {NT_STATUS(0xc000018d), W_ERROR(0x6fd)}, - {NT_STATUS(0xc000018e), W_ERROR(0x5dc)}, - {NT_STATUS(0xc000018f), W_ERROR(0x5dd)}, - {NT_STATUS(0xc0000190), W_ERROR(0x6fe)}, - {NT_STATUS(0xc0000192), W_ERROR(0x700)}, - {NT_STATUS(0xc0000193), W_ERROR(0x701)}, - {NT_STATUS(0xc0000194), W_ERROR(0x46b)}, - {NT_STATUS(0xc0000195), W_ERROR(0x4c3)}, - {NT_STATUS(0xc0000196), W_ERROR(0x4c4)}, - {NT_STATUS(0xc0000197), W_ERROR(0x5df)}, - {NT_STATUS(0xc0000198), W_ERROR(0x70f)}, - {NT_STATUS(0xc0000199), W_ERROR(0x710)}, - {NT_STATUS(0xc000019a), W_ERROR(0x711)}, - {NT_STATUS(0xc000019b), W_ERROR(0x712)}, - {NT_STATUS(0xc0000202), W_ERROR(0x572)}, - {NT_STATUS(0xc0000203), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000204), W_ERROR(0x717)}, - {NT_STATUS(0xc0000205), W_ERROR(0x46a)}, - {NT_STATUS(0xc0000206), W_ERROR(0x6f8)}, - {NT_STATUS(0xc0000207), W_ERROR(0x4be)}, - {NT_STATUS(0xc0000208), W_ERROR(0x4be)}, - {NT_STATUS(0xc0000209), W_ERROR(0x44)}, - {NT_STATUS(0xc000020a), W_ERROR(0x34)}, - {NT_STATUS(0xc000020b), W_ERROR(0x40)}, - {NT_STATUS(0xc000020c), W_ERROR(0x40)}, - {NT_STATUS(0xc000020d), W_ERROR(0x40)}, - {NT_STATUS(0xc000020e), W_ERROR(0x44)}, - {NT_STATUS(0xc000020f), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000210), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000211), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000212), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000213), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000214), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000215), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000216), W_ERROR(0x32)}, - {NT_STATUS(0xc0000217), W_ERROR(0x32)}, - {NT_STATUS(0xc000021c), W_ERROR(0x17e6)}, - {NT_STATUS(0xc0000220), W_ERROR(0x46c)}, - {NT_STATUS(0xc0000221), W_ERROR(0xc1)}, - {NT_STATUS(0xc0000224), W_ERROR(0x773)}, - {NT_STATUS(0xc0000225), W_ERROR(0x490)}, - {NT_STATUS(0xc000022a), W_ERROR(0xc000022a)}, - {NT_STATUS(0xc000022b), W_ERROR(0xc000022b)}, - {NT_STATUS(0xc000022d), W_ERROR(0x4d5)}, - {NT_STATUS(0xc0000230), W_ERROR(0x492)}, - {NT_STATUS(0xc0000233), W_ERROR(0x774)}, - {NT_STATUS(0xc0000234), W_ERROR(0x775)}, - {NT_STATUS(0xc0000235), W_ERROR(0x6)}, - {NT_STATUS(0xc0000236), W_ERROR(0x4c9)}, - {NT_STATUS(0xc0000237), W_ERROR(0x4ca)}, - {NT_STATUS(0xc0000238), W_ERROR(0x4cb)}, - {NT_STATUS(0xc0000239), W_ERROR(0x4cc)}, - {NT_STATUS(0xc000023a), W_ERROR(0x4cd)}, - {NT_STATUS(0xc000023b), W_ERROR(0x4ce)}, - {NT_STATUS(0xc000023c), W_ERROR(0x4cf)}, - {NT_STATUS(0xc000023d), W_ERROR(0x4d0)}, - {NT_STATUS(0xc000023e), W_ERROR(0x4d1)}, - {NT_STATUS(0xc000023f), W_ERROR(0x4d2)}, - {NT_STATUS(0xc0000240), W_ERROR(0x4d3)}, - {NT_STATUS(0xc0000241), W_ERROR(0x4d4)}, - {NT_STATUS(0xc0000243), W_ERROR(0x4c8)}, - {NT_STATUS(0xc0000246), W_ERROR(0x4d6)}, - {NT_STATUS(0xc0000247), W_ERROR(0x4d7)}, - {NT_STATUS(0xc0000248), W_ERROR(0x4d8)}, - {NT_STATUS(0xc0000249), W_ERROR(0xc1)}, - {NT_STATUS(0xc0000253), W_ERROR(0x54f)}, - {NT_STATUS(0xc0000257), W_ERROR(0x4d0)}, - {NT_STATUS(0xc0000259), W_ERROR(0x573)}, - {NT_STATUS(0xc000025e), W_ERROR(0x422)}, - {NT_STATUS(0xc0000262), W_ERROR(0xb6)}, - {NT_STATUS(0xc0000263), W_ERROR(0x7f)}, - {NT_STATUS(0xc0000264), W_ERROR(0x120)}, - {NT_STATUS(0xc0000265), W_ERROR(0x476)}, - {NT_STATUS(0xc0000267), W_ERROR(0x10fe)}, - {NT_STATUS(0xc000026c), W_ERROR(0x7d1)}, - {NT_STATUS(0xc000026d), W_ERROR(0x4b1)}, - {NT_STATUS(0xc000026e), W_ERROR(0x15)}, - {NT_STATUS(0xc0000272), W_ERROR(0x491)}, - {NT_STATUS(0xc0000275), W_ERROR(0x1126)}, - {NT_STATUS(0xc0000276), W_ERROR(0x1129)}, - {NT_STATUS(0xc0000277), W_ERROR(0x112a)}, - {NT_STATUS(0xc0000278), W_ERROR(0x1128)}, - {NT_STATUS(0xc0000279), W_ERROR(0x780)}, - {NT_STATUS(0xc0000280), W_ERROR(0x781)}, - {NT_STATUS(0xc0000281), W_ERROR(0xa1)}, - {NT_STATUS(0xc0000283), W_ERROR(0x488)}, - {NT_STATUS(0xc0000284), W_ERROR(0x489)}, - {NT_STATUS(0xc0000285), W_ERROR(0x48a)}, - {NT_STATUS(0xc0000286), W_ERROR(0x48b)}, - {NT_STATUS(0xc0000287), W_ERROR(0x48c)}, - {NT_STATUS(0xc000028a), W_ERROR(0x5)}, - {NT_STATUS(0xc000028b), W_ERROR(0x5)}, - {NT_STATUS(0xc000028d), W_ERROR(0x5)}, - {NT_STATUS(0xc000028e), W_ERROR(0x5)}, - {NT_STATUS(0xc000028f), W_ERROR(0x5)}, - {NT_STATUS(0xc0000290), W_ERROR(0x5)}, - {NT_STATUS(0xc0000291), W_ERROR(0x1777)}, - {NT_STATUS(0xc0000292), W_ERROR(0x1778)}, - {NT_STATUS(0xc0000293), W_ERROR(0x1772)}, - {NT_STATUS(0xc0000295), W_ERROR(0x1068)}, - {NT_STATUS(0xc0000296), W_ERROR(0x1069)}, - {NT_STATUS(0xc0000297), W_ERROR(0x106a)}, - {NT_STATUS(0xc0000298), W_ERROR(0x106b)}, - {NT_STATUS(0xc0000299), W_ERROR(0x201a)}, - {NT_STATUS(0xc000029a), W_ERROR(0x201b)}, - {NT_STATUS(0xc000029b), W_ERROR(0x201c)}, - {NT_STATUS(0xc000029c), W_ERROR(0x1)}, - {NT_STATUS(0xc000029d), W_ERROR(0x10ff)}, - {NT_STATUS(0xc000029e), W_ERROR(0x1100)}, - {NT_STATUS(0xc000029f), W_ERROR(0x494)}, - {NT_STATUS(0xc00002a1), W_ERROR(0x200a)}, - {NT_STATUS(0xc00002a2), W_ERROR(0x200b)}, - {NT_STATUS(0xc00002a3), W_ERROR(0x200c)}, - {NT_STATUS(0xc00002a4), W_ERROR(0x200d)}, - {NT_STATUS(0xc00002a5), W_ERROR(0x200e)}, - {NT_STATUS(0xc00002a6), W_ERROR(0x200f)}, - {NT_STATUS(0xc00002a7), W_ERROR(0x2010)}, - {NT_STATUS(0xc00002a8), W_ERROR(0x2011)}, - {NT_STATUS(0xc00002a9), W_ERROR(0x2012)}, - {NT_STATUS(0xc00002aa), W_ERROR(0x2013)}, - {NT_STATUS(0xc00002ab), W_ERROR(0x2014)}, - {NT_STATUS(0xc00002ac), W_ERROR(0x2015)}, - {NT_STATUS(0xc00002ad), W_ERROR(0x2016)}, - {NT_STATUS(0xc00002ae), W_ERROR(0x2017)}, - {NT_STATUS(0xc00002af), W_ERROR(0x2018)}, - {NT_STATUS(0xc00002b0), W_ERROR(0x2019)}, - {NT_STATUS(0xc00002b1), W_ERROR(0x211e)}, - {NT_STATUS(0xc00002b2), W_ERROR(0x1127)}, - {NT_STATUS(0xc00002b6), W_ERROR(0x651)}, - {NT_STATUS(0xc00002b7), W_ERROR(0x49a)}, - {NT_STATUS(0xc00002b8), W_ERROR(0x49b)}, - {NT_STATUS(0xc00002c1), W_ERROR(0x2024)}, - {NT_STATUS(0xc00002c3), W_ERROR(0x575)}, - {NT_STATUS(0xc00002c5), W_ERROR(0x3e6)}, - {NT_STATUS(0xc00002c6), W_ERROR(0x1075)}, - {NT_STATUS(0xc00002c7), W_ERROR(0x1076)}, - {NT_STATUS(0xc00002ca), W_ERROR(0x10e8)}, - {NT_STATUS(0xc00002cb), W_ERROR(0x2138)}, - {NT_STATUS(0xc00002cc), W_ERROR(0x4e3)}, - {NT_STATUS(0xc00002cd), W_ERROR(0x2139)}, - {NT_STATUS(0xc00002cf), W_ERROR(0x49d)}, - {NT_STATUS(0xc00002d0), W_ERROR(0x213a)}, - {NT_STATUS(0xc00002d4), W_ERROR(0x2141)}, - {NT_STATUS(0xc00002d5), W_ERROR(0x2142)}, - {NT_STATUS(0xc00002d6), W_ERROR(0x2143)}, - {NT_STATUS(0xc00002d7), W_ERROR(0x2144)}, - {NT_STATUS(0xc00002d8), W_ERROR(0x2145)}, - {NT_STATUS(0xc00002d9), W_ERROR(0x2146)}, - {NT_STATUS(0xc00002da), W_ERROR(0x2147)}, - {NT_STATUS(0xc00002db), W_ERROR(0x2148)}, - {NT_STATUS(0xc00002dc), W_ERROR(0x2149)}, - {NT_STATUS(0xc00002dd), W_ERROR(0x32)}, - {NT_STATUS(0xc00002df), W_ERROR(0x2151)}, - {NT_STATUS(0xc00002e0), W_ERROR(0x2152)}, - {NT_STATUS(0xc00002e1), W_ERROR(0x2153)}, - {NT_STATUS(0xc00002e2), W_ERROR(0x2154)}, - {NT_STATUS(0xc00002e3), W_ERROR(0x215d)}, - {NT_STATUS(0xc00002e4), W_ERROR(0x2163)}, - {NT_STATUS(0xc00002e5), W_ERROR(0x2164)}, - {NT_STATUS(0xc00002e6), W_ERROR(0x2165)}, - {NT_STATUS(0xc00002e7), W_ERROR(0x216d)}, - {NT_STATUS(0xc00002fe), W_ERROR(0x45b)}, - {NT_STATUS(0xc00002ff), W_ERROR(0x4e7)}, - {NT_STATUS(0xc0000300), W_ERROR(0x4e6)}, - {NT_STATUS(0x80000001), W_ERROR(0x80000001)}, - {NT_STATUS(0x80000002), W_ERROR(0x3e6)}, - {NT_STATUS(0x80000003), W_ERROR(0x80000003)}, - {NT_STATUS(0x80000004), W_ERROR(0x80000004)}, - {NT_STATUS(0x80000005), W_ERROR(0xea)}, - {NT_STATUS(0x80000006), W_ERROR(0x12)}, - {NT_STATUS(0x8000000b), W_ERROR(0x56f)}, - {NT_STATUS(0x8000000d), W_ERROR(0x12b)}, - {NT_STATUS(0x8000000e), W_ERROR(0x1c)}, - {NT_STATUS(0x8000000f), W_ERROR(0x15)}, - {NT_STATUS(0x80000010), W_ERROR(0x15)}, - {NT_STATUS(0x80000011), W_ERROR(0xaa)}, - {NT_STATUS(0x80000012), W_ERROR(0x103)}, - {NT_STATUS(0x80000013), W_ERROR(0xfe)}, - {NT_STATUS(0x80000014), W_ERROR(0xff)}, - {NT_STATUS(0x80000015), W_ERROR(0xff)}, - {NT_STATUS(0x80000016), W_ERROR(0x456)}, - {NT_STATUS(0x8000001a), W_ERROR(0x103)}, - {NT_STATUS(0x8000001b), W_ERROR(0x44d)}, - {NT_STATUS(0x8000001c), W_ERROR(0x456)}, - {NT_STATUS(0x8000001d), W_ERROR(0x457)}, - {NT_STATUS(0x8000001e), W_ERROR(0x44c)}, - {NT_STATUS(0x8000001f), W_ERROR(0x44e)}, - {NT_STATUS(0x80000021), W_ERROR(0x44f)}, - {NT_STATUS(0x80000022), W_ERROR(0x450)}, - {NT_STATUS(0x80000025), W_ERROR(0x962)}, - {NT_STATUS(0x80000288), W_ERROR(0x48d)}, - {NT_STATUS(0x80000289), W_ERROR(0x48e)}, - {NT_STATUS_OK, WERR_OK} -}; - -bool ntstatus_check_dos_mapping = true; - -/* - check if a DOS encoded NTSTATUS code maps to the given NTSTATUS code -*/ -bool ntstatus_dos_equal(NTSTATUS status1, NTSTATUS status2) -{ - /* when we negotiate nt status support, we don't want to consider - the mapping of dos codes, as we want to catch the cases where - a forced dos code is needed - */ - if (ntstatus_check_dos_mapping) { - return NT_STATUS_V(status1) == NT_STATUS_V(status2); - } - - /* otherwise check if the mapping comes out right. Note that it is important - that we do the mapping only from ntstatus -> dos and not from dos -> ntstatus, - as that is the mapping that servers must do */ - if (!NT_STATUS_IS_DOS(status1) && NT_STATUS_IS_DOS(status2)) { - uint8_t eclass; - uint32_t ecode; - ntstatus_to_dos(status1, &eclass, &ecode); - return eclass == NT_STATUS_DOS_CLASS(status2) && - ecode == NT_STATUS_DOS_CODE(status2); - } - if (NT_STATUS_IS_DOS(status1) && !NT_STATUS_IS_DOS(status2)) { - uint8_t eclass; - uint32_t ecode; - ntstatus_to_dos(status2, &eclass, &ecode); - return eclass == NT_STATUS_DOS_CLASS(status1) && - ecode == NT_STATUS_DOS_CODE(status1); - } - return NT_STATUS_V(status1) == NT_STATUS_V(status2); -} - -/***************************************************************************** -convert a NT status code to a dos class/code - *****************************************************************************/ -void ntstatus_to_dos(NTSTATUS ntstatus, uint8_t *eclass, uint32_t *ecode) -{ - int i; - if (NT_STATUS_IS_OK(ntstatus)) { - *eclass = 0; - *ecode = 0; - return; - } - if (NT_STATUS_IS_DOS(ntstatus)) { - *eclass = NT_STATUS_DOS_CLASS(ntstatus); - *ecode = NT_STATUS_DOS_CODE(ntstatus); - return; - } - for (i=0; NT_STATUS_V(ntstatus_to_dos_map[i].ntstatus); i++) { - if (NT_STATUS_V(ntstatus) == - NT_STATUS_V(ntstatus_to_dos_map[i].ntstatus)) { - *eclass = ntstatus_to_dos_map[i].dos_class; - *ecode = ntstatus_to_dos_map[i].dos_code; - return; - } - } - *eclass = ERRHRD; - *ecode = ERRgeneral; -} - - -/***************************************************************************** -convert a WERROR to a NT status32 code - *****************************************************************************/ -NTSTATUS werror_to_ntstatus(WERROR error) -{ - int i; - if (W_ERROR_IS_OK(error)) return NT_STATUS_OK; - for (i=0; NT_STATUS_V(ntstatus_to_werror_map[i].ntstatus); i++) { - if (W_ERROR_V(error) == - W_ERROR_V(ntstatus_to_werror_map[i].werror)) { - return ntstatus_to_werror_map[i].ntstatus; - } - } - - /* just guess ... */ - return NT_STATUS(W_ERROR_V(error) | 0xc0000000); -} - -/***************************************************************************** -convert a NTSTATUS to a WERROR - *****************************************************************************/ -WERROR ntstatus_to_werror(NTSTATUS error) -{ - int i; - if (NT_STATUS_IS_OK(error)) return WERR_OK; - for (i=0; NT_STATUS_V(ntstatus_to_werror_map[i].ntstatus); i++) { - if (NT_STATUS_V(error) == - NT_STATUS_V(ntstatus_to_werror_map[i].ntstatus)) { - return ntstatus_to_werror_map[i].werror; - } - } - - /* a lame guess */ - return W_ERROR(NT_STATUS_V(error) & 0xffff); -} - -/* Mapping between Unix, DOS and NT error numbers */ - -struct unix_error_map { - int unix_error; - NTSTATUS nt_error; -}; - -const struct unix_error_map unix_nt_errmap[] = { - { EAGAIN, STATUS_MORE_ENTRIES }, - { EINTR, STATUS_MORE_ENTRIES }, - { ENOBUFS, STATUS_MORE_ENTRIES }, -#ifdef EWOULDBLOCK - { EWOULDBLOCK, STATUS_MORE_ENTRIES }, -#endif - { EINPROGRESS, NT_STATUS_MORE_PROCESSING_REQUIRED }, - { EPERM, NT_STATUS_ACCESS_DENIED }, - { EACCES, NT_STATUS_ACCESS_DENIED }, - { ENOENT, NT_STATUS_OBJECT_NAME_NOT_FOUND }, - { ENOTDIR, NT_STATUS_NOT_A_DIRECTORY }, - { EIO, NT_STATUS_IO_DEVICE_ERROR }, - { EBADF, NT_STATUS_INVALID_HANDLE }, - { EINVAL, NT_STATUS_INVALID_PARAMETER }, - { EEXIST, NT_STATUS_OBJECT_NAME_COLLISION}, - { ENFILE, NT_STATUS_TOO_MANY_OPENED_FILES }, - { EMFILE, NT_STATUS_TOO_MANY_OPENED_FILES }, - { ENOSPC, NT_STATUS_DISK_FULL }, - { EISDIR, NT_STATUS_FILE_IS_A_DIRECTORY }, - { ENOTSOCK, NT_STATUS_INVALID_HANDLE }, - { EFAULT, NT_STATUS_INVALID_PARAMETER }, - { EMSGSIZE, NT_STATUS_INVALID_BUFFER_SIZE }, - { ENOMEM, NT_STATUS_NO_MEMORY }, - { EPIPE, NT_STATUS_CONNECTION_DISCONNECTED }, - { ECONNREFUSED, NT_STATUS_CONNECTION_REFUSED }, -#ifdef ECONNRESET - { ECONNRESET, NT_STATUS_CONNECTION_RESET }, -#endif - { EBUSY, NT_STATUS_SHARING_VIOLATION }, -#ifdef ENOTSUP - { ENOTSUP, NT_STATUS_NOT_SUPPORTED}, -#endif -#ifdef EOPNOTSUPP - { EOPNOTSUPP, NT_STATUS_NOT_SUPPORTED}, -#endif -#ifdef EHOSTUNREACH - { EHOSTUNREACH, NT_STATUS_HOST_UNREACHABLE }, -#endif -#ifdef ENETUNREACH - { ENETUNREACH, NT_STATUS_NETWORK_UNREACHABLE }, -#endif -#ifdef ETIMEDOUT - { ETIMEDOUT, NT_STATUS_IO_TIMEOUT }, -#endif -#ifdef EADDRINUSE - { EADDRINUSE, NT_STATUS_ADDRESS_ALREADY_ASSOCIATED }, -#endif -#ifdef ENOATTR - { ENOATTR, NT_STATUS_NOT_FOUND }, -#endif -#ifdef ENODATA - { ENODATA, NT_STATUS_NOT_FOUND }, -#endif -#ifdef EDQUOT - { EDQUOT, NT_STATUS_DISK_FULL }, /* Windows does NOT return NT_STATUS_QUOTA_EXCEEDED */ -#endif -#ifdef ENOTEMPTY - { ENOTEMPTY, NT_STATUS_DIRECTORY_NOT_EMPTY }, -#endif -#ifdef EXDEV - { EXDEV, NT_STATUS_NOT_SAME_DEVICE }, -#endif -#ifdef EROFS - { EROFS, NT_STATUS_MEDIA_WRITE_PROTECTED }, -#endif -#ifdef ENAMETOOLONG - { ENAMETOOLONG, NT_STATUS_NAME_TOO_LONG }, -#endif -#ifdef EFBIG - { EFBIG, NT_STATUS_DISK_FULL }, -#endif -#ifdef EADDRNOTAVAIL - { EADDRNOTAVAIL,NT_STATUS_ADDRESS_NOT_ASSOCIATED }, -#endif -#ifdef ESOCKTNOSUPPORT - { ESOCKTNOSUPPORT,NT_STATUS_INVALID_PARAMETER_MIX }, -#endif -#ifdef EAFNOSUPPORT - { EAFNOSUPPORT, NT_STATUS_INVALID_PARAMETER_MIX }, -#endif -#ifdef ENOPROTOOPT - { ENOPROTOOPT, NT_STATUS_INVALID_PARAMETER_MIX }, -#endif -#ifdef ENODEV - { ENODEV, NT_STATUS_NO_SUCH_DEVICE }, -#endif -#ifdef ENOSYS - { ENOSYS, NT_STATUS_INVALID_SYSTEM_SERVICE }, -#endif -#ifdef ECANCELED - { ECANCELED, NT_STATUS_CANCELLED }, -#endif - - { 0, NT_STATUS_UNSUCCESSFUL } -}; - - -/********************************************************************* - Map an NT error code from a Unix error code. -*********************************************************************/ -NTSTATUS map_nt_error_from_unix(int unix_error) -{ - int i; - - /* Look through list */ - for (i=0;i<ARRAY_SIZE(unix_nt_errmap);i++) { - if (unix_nt_errmap[i].unix_error == unix_error) { - return unix_nt_errmap[i].nt_error; - } - } - - /* Default return */ - return NT_STATUS_UNSUCCESSFUL; -} - -/* Convert a Unix error code to WERROR */ -WERROR unix_to_werror(int unix_error) -{ - return ntstatus_to_werror(map_nt_error_from_unix(unix_error)); -} diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c deleted file mode 100644 index ca998bbf6f..0000000000 --- a/source4/libcli/util/nterr.c +++ /dev/null @@ -1,958 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines - * Copyright (C) Luke Kenneth Casson Leighton 1997-2001. - * - * 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 <http://www.gnu.org/licenses/>. - */ - -/* NT error codes. please read nterr.h */ - -#include "includes.h" -#include "../libcli/ldap/ldap_errors.h" -#undef strcasecmp - -#if !defined(N_) -#define N_(string) string -#endif - -typedef struct -{ - const char *nt_errstr; - NTSTATUS nt_errcode; -} nt_err_code_struct; - -#define DOS_CODE(class, code) { #class ":" #code, NT_STATUS_DOS(class, code) } -#define LDAP_CODE(code) { #code, NT_STATUS_LDAP(code) } - -static const nt_err_code_struct nt_errs[] = -{ - { "NT_STATUS_OK", NT_STATUS_OK }, - { "STATUS_NO_MORE_FILES", STATUS_NO_MORE_FILES }, - { "STATUS_NO_MORE_EAS", STATUS_NO_MORE_EAS }, - { "STATUS_INVALID_EA_NAME", STATUS_INVALID_EA_NAME }, - { "STATUS_EA_LIST_INCONSISTENT", STATUS_EA_LIST_INCONSISTENT }, - { "STATUS_INVALID_EA_FLAG", STATUS_INVALID_EA_FLAG }, - { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, - { "NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED }, - { "NT_STATUS_INVALID_INFO_CLASS", NT_STATUS_INVALID_INFO_CLASS }, - { "NT_STATUS_INFO_LENGTH_MISMATCH", NT_STATUS_INFO_LENGTH_MISMATCH }, - { "NT_STATUS_ACCESS_VIOLATION", NT_STATUS_ACCESS_VIOLATION }, - { "STATUS_BUFFER_OVERFLOW", STATUS_BUFFER_OVERFLOW }, - { "NT_STATUS_IN_PAGE_ERROR", NT_STATUS_IN_PAGE_ERROR }, - { "NT_STATUS_PAGEFILE_QUOTA", NT_STATUS_PAGEFILE_QUOTA }, - { "NT_STATUS_INVALID_HANDLE", NT_STATUS_INVALID_HANDLE }, - { "NT_STATUS_BAD_INITIAL_STACK", NT_STATUS_BAD_INITIAL_STACK }, - { "NT_STATUS_BAD_INITIAL_PC", NT_STATUS_BAD_INITIAL_PC }, - { "NT_STATUS_INVALID_CID", NT_STATUS_INVALID_CID }, - { "NT_STATUS_TIMER_NOT_CANCELED", NT_STATUS_TIMER_NOT_CANCELED }, - { "NT_STATUS_INVALID_PARAMETER", NT_STATUS_INVALID_PARAMETER }, - { "NT_STATUS_NO_SUCH_DEVICE", NT_STATUS_NO_SUCH_DEVICE }, - { "NT_STATUS_NO_SUCH_FILE", NT_STATUS_NO_SUCH_FILE }, - { "NT_STATUS_INVALID_DEVICE_REQUEST", NT_STATUS_INVALID_DEVICE_REQUEST }, - { "NT_STATUS_END_OF_FILE", NT_STATUS_END_OF_FILE }, - { "NT_STATUS_WRONG_VOLUME", NT_STATUS_WRONG_VOLUME }, - { "NT_STATUS_NO_MEDIA_IN_DEVICE", NT_STATUS_NO_MEDIA_IN_DEVICE }, - { "NT_STATUS_UNRECOGNIZED_MEDIA", NT_STATUS_UNRECOGNIZED_MEDIA }, - { "NT_STATUS_NONEXISTENT_SECTOR", NT_STATUS_NONEXISTENT_SECTOR }, - { "NT_STATUS_MORE_PROCESSING_REQUIRED", NT_STATUS_MORE_PROCESSING_REQUIRED }, - { "NT_STATUS_NO_MEMORY", NT_STATUS_NO_MEMORY }, - { "NT_STATUS_CONFLICTING_ADDRESSES", NT_STATUS_CONFLICTING_ADDRESSES }, - { "NT_STATUS_NOT_MAPPED_VIEW", NT_STATUS_NOT_MAPPED_VIEW }, - { "NT_STATUS_UNABLE_TO_FREE_VM", NT_STATUS_UNABLE_TO_FREE_VM }, - { "NT_STATUS_UNABLE_TO_DELETE_SECTION", NT_STATUS_UNABLE_TO_DELETE_SECTION }, - { "NT_STATUS_INVALID_SYSTEM_SERVICE", NT_STATUS_INVALID_SYSTEM_SERVICE }, - { "NT_STATUS_ILLEGAL_INSTRUCTION", NT_STATUS_ILLEGAL_INSTRUCTION }, - { "NT_STATUS_INVALID_LOCK_SEQUENCE", NT_STATUS_INVALID_LOCK_SEQUENCE }, - { "NT_STATUS_INVALID_VIEW_SIZE", NT_STATUS_INVALID_VIEW_SIZE }, - { "NT_STATUS_INVALID_FILE_FOR_SECTION", NT_STATUS_INVALID_FILE_FOR_SECTION }, - { "NT_STATUS_ALREADY_COMMITTED", NT_STATUS_ALREADY_COMMITTED }, - { "NT_STATUS_ACCESS_DENIED", NT_STATUS_ACCESS_DENIED }, - { "NT_STATUS_BUFFER_TOO_SMALL", NT_STATUS_BUFFER_TOO_SMALL }, - { "NT_STATUS_OBJECT_TYPE_MISMATCH", NT_STATUS_OBJECT_TYPE_MISMATCH }, - { "NT_STATUS_NONCONTINUABLE_EXCEPTION", NT_STATUS_NONCONTINUABLE_EXCEPTION }, - { "NT_STATUS_INVALID_DISPOSITION", NT_STATUS_INVALID_DISPOSITION }, - { "NT_STATUS_UNWIND", NT_STATUS_UNWIND }, - { "NT_STATUS_BAD_STACK", NT_STATUS_BAD_STACK }, - { "NT_STATUS_INVALID_UNWIND_TARGET", NT_STATUS_INVALID_UNWIND_TARGET }, - { "NT_STATUS_NOT_LOCKED", NT_STATUS_NOT_LOCKED }, - { "NT_STATUS_PARITY_ERROR", NT_STATUS_PARITY_ERROR }, - { "NT_STATUS_UNABLE_TO_DECOMMIT_VM", NT_STATUS_UNABLE_TO_DECOMMIT_VM }, - { "NT_STATUS_NOT_COMMITTED", NT_STATUS_NOT_COMMITTED }, - { "NT_STATUS_INVALID_PORT_ATTRIBUTES", NT_STATUS_INVALID_PORT_ATTRIBUTES }, - { "NT_STATUS_PORT_MESSAGE_TOO_LONG", NT_STATUS_PORT_MESSAGE_TOO_LONG }, - { "NT_STATUS_INVALID_PARAMETER_MIX", NT_STATUS_INVALID_PARAMETER_MIX }, - { "NT_STATUS_INVALID_QUOTA_LOWER", NT_STATUS_INVALID_QUOTA_LOWER }, - { "NT_STATUS_DISK_CORRUPT_ERROR", NT_STATUS_DISK_CORRUPT_ERROR }, - { "NT_STATUS_OBJECT_NAME_INVALID", NT_STATUS_OBJECT_NAME_INVALID }, - { "NT_STATUS_OBJECT_NAME_NOT_FOUND", NT_STATUS_OBJECT_NAME_NOT_FOUND }, - { "NT_STATUS_OBJECT_NAME_COLLISION", NT_STATUS_OBJECT_NAME_COLLISION }, - { "NT_STATUS_HANDLE_NOT_WAITABLE", NT_STATUS_HANDLE_NOT_WAITABLE }, - { "NT_STATUS_PORT_DISCONNECTED", NT_STATUS_PORT_DISCONNECTED }, - { "NT_STATUS_DEVICE_ALREADY_ATTACHED", NT_STATUS_DEVICE_ALREADY_ATTACHED }, - { "NT_STATUS_OBJECT_PATH_INVALID", NT_STATUS_OBJECT_PATH_INVALID }, - { "NT_STATUS_OBJECT_PATH_NOT_FOUND", NT_STATUS_OBJECT_PATH_NOT_FOUND }, - { "NT_STATUS_OBJECT_PATH_SYNTAX_BAD", NT_STATUS_OBJECT_PATH_SYNTAX_BAD }, - { "NT_STATUS_DATA_OVERRUN", NT_STATUS_DATA_OVERRUN }, - { "NT_STATUS_DATA_LATE_ERROR", NT_STATUS_DATA_LATE_ERROR }, - { "NT_STATUS_DATA_ERROR", NT_STATUS_DATA_ERROR }, - { "NT_STATUS_CRC_ERROR", NT_STATUS_CRC_ERROR }, - { "NT_STATUS_SECTION_TOO_BIG", NT_STATUS_SECTION_TOO_BIG }, - { "NT_STATUS_PORT_CONNECTION_REFUSED", NT_STATUS_PORT_CONNECTION_REFUSED }, - { "NT_STATUS_INVALID_PORT_HANDLE", NT_STATUS_INVALID_PORT_HANDLE }, - { "NT_STATUS_SHARING_VIOLATION", NT_STATUS_SHARING_VIOLATION }, - { "NT_STATUS_QUOTA_EXCEEDED", NT_STATUS_QUOTA_EXCEEDED }, - { "NT_STATUS_INVALID_PAGE_PROTECTION", NT_STATUS_INVALID_PAGE_PROTECTION }, - { "NT_STATUS_MUTANT_NOT_OWNED", NT_STATUS_MUTANT_NOT_OWNED }, - { "NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED", NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED }, - { "NT_STATUS_PORT_ALREADY_SET", NT_STATUS_PORT_ALREADY_SET }, - { "NT_STATUS_SECTION_NOT_IMAGE", NT_STATUS_SECTION_NOT_IMAGE }, - { "NT_STATUS_SUSPEND_COUNT_EXCEEDED", NT_STATUS_SUSPEND_COUNT_EXCEEDED }, - { "NT_STATUS_THREAD_IS_TERMINATING", NT_STATUS_THREAD_IS_TERMINATING }, - { "NT_STATUS_BAD_WORKING_SET_LIMIT", NT_STATUS_BAD_WORKING_SET_LIMIT }, - { "NT_STATUS_INCOMPATIBLE_FILE_MAP", NT_STATUS_INCOMPATIBLE_FILE_MAP }, - { "NT_STATUS_SECTION_PROTECTION", NT_STATUS_SECTION_PROTECTION }, - { "NT_STATUS_EAS_NOT_SUPPORTED", NT_STATUS_EAS_NOT_SUPPORTED }, - { "NT_STATUS_EA_TOO_LARGE", NT_STATUS_EA_TOO_LARGE }, - { "NT_STATUS_NONEXISTENT_EA_ENTRY", NT_STATUS_NONEXISTENT_EA_ENTRY }, - { "NT_STATUS_NO_EAS_ON_FILE", NT_STATUS_NO_EAS_ON_FILE }, - { "NT_STATUS_EA_CORRUPT_ERROR", NT_STATUS_EA_CORRUPT_ERROR }, - { "NT_STATUS_FILE_LOCK_CONFLICT", NT_STATUS_FILE_LOCK_CONFLICT }, - { "NT_STATUS_LOCK_NOT_GRANTED", NT_STATUS_LOCK_NOT_GRANTED }, - { "NT_STATUS_DELETE_PENDING", NT_STATUS_DELETE_PENDING }, - { "NT_STATUS_CTL_FILE_NOT_SUPPORTED", NT_STATUS_CTL_FILE_NOT_SUPPORTED }, - { "NT_STATUS_UNKNOWN_REVISION", NT_STATUS_UNKNOWN_REVISION }, - { "NT_STATUS_REVISION_MISMATCH", NT_STATUS_REVISION_MISMATCH }, - { "NT_STATUS_INVALID_OWNER", NT_STATUS_INVALID_OWNER }, - { "NT_STATUS_INVALID_PRIMARY_GROUP", NT_STATUS_INVALID_PRIMARY_GROUP }, - { "NT_STATUS_NO_IMPERSONATION_TOKEN", NT_STATUS_NO_IMPERSONATION_TOKEN }, - { "NT_STATUS_CANT_DISABLE_MANDATORY", NT_STATUS_CANT_DISABLE_MANDATORY }, - { "NT_STATUS_NO_LOGON_SERVERS", NT_STATUS_NO_LOGON_SERVERS }, - { "NT_STATUS_NO_SUCH_LOGON_SESSION", NT_STATUS_NO_SUCH_LOGON_SESSION }, - { "NT_STATUS_NO_SUCH_PRIVILEGE", NT_STATUS_NO_SUCH_PRIVILEGE }, - { "NT_STATUS_PRIVILEGE_NOT_HELD", NT_STATUS_PRIVILEGE_NOT_HELD }, - { "NT_STATUS_INVALID_ACCOUNT_NAME", NT_STATUS_INVALID_ACCOUNT_NAME }, - { "NT_STATUS_USER_EXISTS", NT_STATUS_USER_EXISTS }, - { "NT_STATUS_NO_SUCH_USER", NT_STATUS_NO_SUCH_USER }, - { "NT_STATUS_GROUP_EXISTS", NT_STATUS_GROUP_EXISTS }, - { "NT_STATUS_NO_SUCH_GROUP", NT_STATUS_NO_SUCH_GROUP }, - { "NT_STATUS_MEMBER_IN_GROUP", NT_STATUS_MEMBER_IN_GROUP }, - { "NT_STATUS_MEMBER_NOT_IN_GROUP", NT_STATUS_MEMBER_NOT_IN_GROUP }, - { "NT_STATUS_LAST_ADMIN", NT_STATUS_LAST_ADMIN }, - { "NT_STATUS_WRONG_PASSWORD", NT_STATUS_WRONG_PASSWORD }, - { "NT_STATUS_ILL_FORMED_PASSWORD", NT_STATUS_ILL_FORMED_PASSWORD }, - { "NT_STATUS_PASSWORD_RESTRICTION", NT_STATUS_PASSWORD_RESTRICTION }, - { "NT_STATUS_LOGON_FAILURE", NT_STATUS_LOGON_FAILURE }, - { "NT_STATUS_ACCOUNT_RESTRICTION", NT_STATUS_ACCOUNT_RESTRICTION }, - { "NT_STATUS_INVALID_LOGON_HOURS", NT_STATUS_INVALID_LOGON_HOURS }, - { "NT_STATUS_INVALID_WORKSTATION", NT_STATUS_INVALID_WORKSTATION }, - { "NT_STATUS_PASSWORD_EXPIRED", NT_STATUS_PASSWORD_EXPIRED }, - { "NT_STATUS_ACCOUNT_DISABLED", NT_STATUS_ACCOUNT_DISABLED }, - { "NT_STATUS_NONE_MAPPED", NT_STATUS_NONE_MAPPED }, - { "NT_STATUS_TOO_MANY_LUIDS_REQUESTED", NT_STATUS_TOO_MANY_LUIDS_REQUESTED }, - { "NT_STATUS_LUIDS_EXHAUSTED", NT_STATUS_LUIDS_EXHAUSTED }, - { "NT_STATUS_INVALID_SUB_AUTHORITY", NT_STATUS_INVALID_SUB_AUTHORITY }, - { "NT_STATUS_INVALID_ACL", NT_STATUS_INVALID_ACL }, - { "NT_STATUS_INVALID_SID", NT_STATUS_INVALID_SID }, - { "NT_STATUS_INVALID_SECURITY_DESCR", NT_STATUS_INVALID_SECURITY_DESCR }, - { "NT_STATUS_PROCEDURE_NOT_FOUND", NT_STATUS_PROCEDURE_NOT_FOUND }, - { "NT_STATUS_INVALID_IMAGE_FORMAT", NT_STATUS_INVALID_IMAGE_FORMAT }, - { "NT_STATUS_NO_TOKEN", NT_STATUS_NO_TOKEN }, - { "NT_STATUS_BAD_INHERITANCE_ACL", NT_STATUS_BAD_INHERITANCE_ACL }, - { "NT_STATUS_RANGE_NOT_LOCKED", NT_STATUS_RANGE_NOT_LOCKED }, - { "NT_STATUS_DISK_FULL", NT_STATUS_DISK_FULL }, - { "NT_STATUS_SERVER_DISABLED", NT_STATUS_SERVER_DISABLED }, - { "NT_STATUS_SERVER_NOT_DISABLED", NT_STATUS_SERVER_NOT_DISABLED }, - { "NT_STATUS_TOO_MANY_GUIDS_REQUESTED", NT_STATUS_TOO_MANY_GUIDS_REQUESTED }, - { "NT_STATUS_GUIDS_EXHAUSTED", NT_STATUS_GUIDS_EXHAUSTED }, - { "NT_STATUS_INVALID_ID_AUTHORITY", NT_STATUS_INVALID_ID_AUTHORITY }, - { "NT_STATUS_AGENTS_EXHAUSTED", NT_STATUS_AGENTS_EXHAUSTED }, - { "NT_STATUS_INVALID_VOLUME_LABEL", NT_STATUS_INVALID_VOLUME_LABEL }, - { "NT_STATUS_SECTION_NOT_EXTENDED", NT_STATUS_SECTION_NOT_EXTENDED }, - { "NT_STATUS_NOT_MAPPED_DATA", NT_STATUS_NOT_MAPPED_DATA }, - { "NT_STATUS_RESOURCE_DATA_NOT_FOUND", NT_STATUS_RESOURCE_DATA_NOT_FOUND }, - { "NT_STATUS_RESOURCE_TYPE_NOT_FOUND", NT_STATUS_RESOURCE_TYPE_NOT_FOUND }, - { "NT_STATUS_RESOURCE_NAME_NOT_FOUND", NT_STATUS_RESOURCE_NAME_NOT_FOUND }, - { "NT_STATUS_ARRAY_BOUNDS_EXCEEDED", NT_STATUS_ARRAY_BOUNDS_EXCEEDED }, - { "NT_STATUS_FLOAT_DENORMAL_OPERAND", NT_STATUS_FLOAT_DENORMAL_OPERAND }, - { "NT_STATUS_FLOAT_DIVIDE_BY_ZERO", NT_STATUS_FLOAT_DIVIDE_BY_ZERO }, - { "NT_STATUS_FLOAT_INEXACT_RESULT", NT_STATUS_FLOAT_INEXACT_RESULT }, - { "NT_STATUS_FLOAT_INVALID_OPERATION", NT_STATUS_FLOAT_INVALID_OPERATION }, - { "NT_STATUS_FLOAT_OVERFLOW", NT_STATUS_FLOAT_OVERFLOW }, - { "NT_STATUS_FLOAT_STACK_CHECK", NT_STATUS_FLOAT_STACK_CHECK }, - { "NT_STATUS_FLOAT_UNDERFLOW", NT_STATUS_FLOAT_UNDERFLOW }, - { "NT_STATUS_INTEGER_DIVIDE_BY_ZERO", NT_STATUS_INTEGER_DIVIDE_BY_ZERO }, - { "NT_STATUS_INTEGER_OVERFLOW", NT_STATUS_INTEGER_OVERFLOW }, - { "NT_STATUS_PRIVILEGED_INSTRUCTION", NT_STATUS_PRIVILEGED_INSTRUCTION }, - { "NT_STATUS_TOO_MANY_PAGING_FILES", NT_STATUS_TOO_MANY_PAGING_FILES }, - { "NT_STATUS_FILE_INVALID", NT_STATUS_FILE_INVALID }, - { "NT_STATUS_ALLOTTED_SPACE_EXCEEDED", NT_STATUS_ALLOTTED_SPACE_EXCEEDED }, - { "NT_STATUS_INSUFFICIENT_RESOURCES", NT_STATUS_INSUFFICIENT_RESOURCES }, - { "NT_STATUS_DFS_EXIT_PATH_FOUND", NT_STATUS_DFS_EXIT_PATH_FOUND }, - { "NT_STATUS_DEVICE_DATA_ERROR", NT_STATUS_DEVICE_DATA_ERROR }, - { "NT_STATUS_DEVICE_NOT_CONNECTED", NT_STATUS_DEVICE_NOT_CONNECTED }, - { "NT_STATUS_DEVICE_POWER_FAILURE", NT_STATUS_DEVICE_POWER_FAILURE }, - { "NT_STATUS_FREE_VM_NOT_AT_BASE", NT_STATUS_FREE_VM_NOT_AT_BASE }, - { "NT_STATUS_MEMORY_NOT_ALLOCATED", NT_STATUS_MEMORY_NOT_ALLOCATED }, - { "NT_STATUS_WORKING_SET_QUOTA", NT_STATUS_WORKING_SET_QUOTA }, - { "NT_STATUS_MEDIA_WRITE_PROTECTED", NT_STATUS_MEDIA_WRITE_PROTECTED }, - { "NT_STATUS_DEVICE_NOT_READY", NT_STATUS_DEVICE_NOT_READY }, - { "NT_STATUS_INVALID_GROUP_ATTRIBUTES", NT_STATUS_INVALID_GROUP_ATTRIBUTES }, - { "NT_STATUS_BAD_IMPERSONATION_LEVEL", NT_STATUS_BAD_IMPERSONATION_LEVEL }, - { "NT_STATUS_CANT_OPEN_ANONYMOUS", NT_STATUS_CANT_OPEN_ANONYMOUS }, - { "NT_STATUS_BAD_VALIDATION_CLASS", NT_STATUS_BAD_VALIDATION_CLASS }, - { "NT_STATUS_BAD_TOKEN_TYPE", NT_STATUS_BAD_TOKEN_TYPE }, - { "NT_STATUS_BAD_MASTER_BOOT_RECORD", NT_STATUS_BAD_MASTER_BOOT_RECORD }, - { "NT_STATUS_INSTRUCTION_MISALIGNMENT", NT_STATUS_INSTRUCTION_MISALIGNMENT }, - { "NT_STATUS_INSTANCE_NOT_AVAILABLE", NT_STATUS_INSTANCE_NOT_AVAILABLE }, - { "NT_STATUS_PIPE_NOT_AVAILABLE", NT_STATUS_PIPE_NOT_AVAILABLE }, - { "NT_STATUS_INVALID_PIPE_STATE", NT_STATUS_INVALID_PIPE_STATE }, - { "NT_STATUS_PIPE_BUSY", NT_STATUS_PIPE_BUSY }, - { "NT_STATUS_ILLEGAL_FUNCTION", NT_STATUS_ILLEGAL_FUNCTION }, - { "NT_STATUS_PIPE_DISCONNECTED", NT_STATUS_PIPE_DISCONNECTED }, - { "NT_STATUS_PIPE_CLOSING", NT_STATUS_PIPE_CLOSING }, - { "NT_STATUS_PIPE_CONNECTED", NT_STATUS_PIPE_CONNECTED }, - { "NT_STATUS_PIPE_LISTENING", NT_STATUS_PIPE_LISTENING }, - { "NT_STATUS_INVALID_READ_MODE", NT_STATUS_INVALID_READ_MODE }, - { "NT_STATUS_IO_TIMEOUT", NT_STATUS_IO_TIMEOUT }, - { "NT_STATUS_FILE_FORCED_CLOSED", NT_STATUS_FILE_FORCED_CLOSED }, - { "NT_STATUS_PROFILING_NOT_STARTED", NT_STATUS_PROFILING_NOT_STARTED }, - { "NT_STATUS_PROFILING_NOT_STOPPED", NT_STATUS_PROFILING_NOT_STOPPED }, - { "NT_STATUS_COULD_NOT_INTERPRET", NT_STATUS_COULD_NOT_INTERPRET }, - { "NT_STATUS_FILE_IS_A_DIRECTORY", NT_STATUS_FILE_IS_A_DIRECTORY }, - { "NT_STATUS_NOT_SUPPORTED", NT_STATUS_NOT_SUPPORTED }, - { "NT_STATUS_REMOTE_NOT_LISTENING", NT_STATUS_REMOTE_NOT_LISTENING }, - { "NT_STATUS_DUPLICATE_NAME", NT_STATUS_DUPLICATE_NAME }, - { "NT_STATUS_BAD_NETWORK_PATH", NT_STATUS_BAD_NETWORK_PATH }, - { "NT_STATUS_NETWORK_BUSY", NT_STATUS_NETWORK_BUSY }, - { "NT_STATUS_DEVICE_DOES_NOT_EXIST", NT_STATUS_DEVICE_DOES_NOT_EXIST }, - { "NT_STATUS_TOO_MANY_COMMANDS", NT_STATUS_TOO_MANY_COMMANDS }, - { "NT_STATUS_ADAPTER_HARDWARE_ERROR", NT_STATUS_ADAPTER_HARDWARE_ERROR }, - { "NT_STATUS_INVALID_NETWORK_RESPONSE", NT_STATUS_INVALID_NETWORK_RESPONSE }, - { "NT_STATUS_UNEXPECTED_NETWORK_ERROR", NT_STATUS_UNEXPECTED_NETWORK_ERROR }, - { "NT_STATUS_BAD_REMOTE_ADAPTER", NT_STATUS_BAD_REMOTE_ADAPTER }, - { "NT_STATUS_PRINT_QUEUE_FULL", NT_STATUS_PRINT_QUEUE_FULL }, - { "NT_STATUS_NO_SPOOL_SPACE", NT_STATUS_NO_SPOOL_SPACE }, - { "NT_STATUS_PRINT_CANCELLED", NT_STATUS_PRINT_CANCELLED }, - { "NT_STATUS_NETWORK_NAME_DELETED", NT_STATUS_NETWORK_NAME_DELETED }, - { "NT_STATUS_NETWORK_ACCESS_DENIED", NT_STATUS_NETWORK_ACCESS_DENIED }, - { "NT_STATUS_BAD_DEVICE_TYPE", NT_STATUS_BAD_DEVICE_TYPE }, - { "NT_STATUS_BAD_NETWORK_NAME", NT_STATUS_BAD_NETWORK_NAME }, - { "NT_STATUS_TOO_MANY_NAMES", NT_STATUS_TOO_MANY_NAMES }, - { "NT_STATUS_TOO_MANY_SESSIONS", NT_STATUS_TOO_MANY_SESSIONS }, - { "NT_STATUS_SHARING_PAUSED", NT_STATUS_SHARING_PAUSED }, - { "NT_STATUS_REQUEST_NOT_ACCEPTED", NT_STATUS_REQUEST_NOT_ACCEPTED }, - { "NT_STATUS_REDIRECTOR_PAUSED", NT_STATUS_REDIRECTOR_PAUSED }, - { "NT_STATUS_NET_WRITE_FAULT", NT_STATUS_NET_WRITE_FAULT }, - { "NT_STATUS_PROFILING_AT_LIMIT", NT_STATUS_PROFILING_AT_LIMIT }, - { "NT_STATUS_NOT_SAME_DEVICE", NT_STATUS_NOT_SAME_DEVICE }, - { "NT_STATUS_FILE_RENAMED", NT_STATUS_FILE_RENAMED }, - { "NT_STATUS_VIRTUAL_CIRCUIT_CLOSED", NT_STATUS_VIRTUAL_CIRCUIT_CLOSED }, - { "NT_STATUS_NO_SECURITY_ON_OBJECT", NT_STATUS_NO_SECURITY_ON_OBJECT }, - { "NT_STATUS_CANT_WAIT", NT_STATUS_CANT_WAIT }, - { "NT_STATUS_PIPE_EMPTY", NT_STATUS_PIPE_EMPTY }, - { "NT_STATUS_CANT_ACCESS_DOMAIN_INFO", NT_STATUS_CANT_ACCESS_DOMAIN_INFO }, - { "NT_STATUS_CANT_TERMINATE_SELF", NT_STATUS_CANT_TERMINATE_SELF }, - { "NT_STATUS_INVALID_SERVER_STATE", NT_STATUS_INVALID_SERVER_STATE }, - { "NT_STATUS_INVALID_DOMAIN_STATE", NT_STATUS_INVALID_DOMAIN_STATE }, - { "NT_STATUS_INVALID_DOMAIN_ROLE", NT_STATUS_INVALID_DOMAIN_ROLE }, - { "NT_STATUS_NO_SUCH_DOMAIN", NT_STATUS_NO_SUCH_DOMAIN }, - { "NT_STATUS_DOMAIN_EXISTS", NT_STATUS_DOMAIN_EXISTS }, - { "NT_STATUS_DOMAIN_LIMIT_EXCEEDED", NT_STATUS_DOMAIN_LIMIT_EXCEEDED }, - { "NT_STATUS_OPLOCK_NOT_GRANTED", NT_STATUS_OPLOCK_NOT_GRANTED }, - { "NT_STATUS_INVALID_OPLOCK_PROTOCOL", NT_STATUS_INVALID_OPLOCK_PROTOCOL }, - { "NT_STATUS_INTERNAL_DB_CORRUPTION", NT_STATUS_INTERNAL_DB_CORRUPTION }, - { "NT_STATUS_INTERNAL_ERROR", NT_STATUS_INTERNAL_ERROR }, - { "NT_STATUS_GENERIC_NOT_MAPPED", NT_STATUS_GENERIC_NOT_MAPPED }, - { "NT_STATUS_BAD_DESCRIPTOR_FORMAT", NT_STATUS_BAD_DESCRIPTOR_FORMAT }, - { "NT_STATUS_INVALID_USER_BUFFER", NT_STATUS_INVALID_USER_BUFFER }, - { "NT_STATUS_UNEXPECTED_IO_ERROR", NT_STATUS_UNEXPECTED_IO_ERROR }, - { "NT_STATUS_UNEXPECTED_MM_CREATE_ERR", NT_STATUS_UNEXPECTED_MM_CREATE_ERR }, - { "NT_STATUS_UNEXPECTED_MM_MAP_ERROR", NT_STATUS_UNEXPECTED_MM_MAP_ERROR }, - { "NT_STATUS_UNEXPECTED_MM_EXTEND_ERR", NT_STATUS_UNEXPECTED_MM_EXTEND_ERR }, - { "NT_STATUS_NOT_LOGON_PROCESS", NT_STATUS_NOT_LOGON_PROCESS }, - { "NT_STATUS_LOGON_SESSION_EXISTS", NT_STATUS_LOGON_SESSION_EXISTS }, - { "NT_STATUS_INVALID_PARAMETER_1", NT_STATUS_INVALID_PARAMETER_1 }, - { "NT_STATUS_INVALID_PARAMETER_2", NT_STATUS_INVALID_PARAMETER_2 }, - { "NT_STATUS_INVALID_PARAMETER_3", NT_STATUS_INVALID_PARAMETER_3 }, - { "NT_STATUS_INVALID_PARAMETER_4", NT_STATUS_INVALID_PARAMETER_4 }, - { "NT_STATUS_INVALID_PARAMETER_5", NT_STATUS_INVALID_PARAMETER_5 }, - { "NT_STATUS_INVALID_PARAMETER_6", NT_STATUS_INVALID_PARAMETER_6 }, - { "NT_STATUS_INVALID_PARAMETER_7", NT_STATUS_INVALID_PARAMETER_7 }, - { "NT_STATUS_INVALID_PARAMETER_8", NT_STATUS_INVALID_PARAMETER_8 }, - { "NT_STATUS_INVALID_PARAMETER_9", NT_STATUS_INVALID_PARAMETER_9 }, - { "NT_STATUS_INVALID_PARAMETER_10", NT_STATUS_INVALID_PARAMETER_10 }, - { "NT_STATUS_INVALID_PARAMETER_11", NT_STATUS_INVALID_PARAMETER_11 }, - { "NT_STATUS_INVALID_PARAMETER_12", NT_STATUS_INVALID_PARAMETER_12 }, - { "NT_STATUS_REDIRECTOR_NOT_STARTED", NT_STATUS_REDIRECTOR_NOT_STARTED }, - { "NT_STATUS_REDIRECTOR_STARTED", NT_STATUS_REDIRECTOR_STARTED }, - { "NT_STATUS_STACK_OVERFLOW", NT_STATUS_STACK_OVERFLOW }, - { "NT_STATUS_NO_SUCH_PACKAGE", NT_STATUS_NO_SUCH_PACKAGE }, - { "NT_STATUS_BAD_FUNCTION_TABLE", NT_STATUS_BAD_FUNCTION_TABLE }, - { "NT_STATUS_DIRECTORY_NOT_EMPTY", NT_STATUS_DIRECTORY_NOT_EMPTY }, - { "NT_STATUS_FILE_CORRUPT_ERROR", NT_STATUS_FILE_CORRUPT_ERROR }, - { "NT_STATUS_NOT_A_DIRECTORY", NT_STATUS_NOT_A_DIRECTORY }, - { "NT_STATUS_BAD_LOGON_SESSION_STATE", NT_STATUS_BAD_LOGON_SESSION_STATE }, - { "NT_STATUS_LOGON_SESSION_COLLISION", NT_STATUS_LOGON_SESSION_COLLISION }, - { "NT_STATUS_NAME_TOO_LONG", NT_STATUS_NAME_TOO_LONG }, - { "NT_STATUS_FILES_OPEN", NT_STATUS_FILES_OPEN }, - { "NT_STATUS_CONNECTION_IN_USE", NT_STATUS_CONNECTION_IN_USE }, - { "NT_STATUS_MESSAGE_NOT_FOUND", NT_STATUS_MESSAGE_NOT_FOUND }, - { "NT_STATUS_PROCESS_IS_TERMINATING", NT_STATUS_PROCESS_IS_TERMINATING }, - { "NT_STATUS_INVALID_LOGON_TYPE", NT_STATUS_INVALID_LOGON_TYPE }, - { "NT_STATUS_NO_GUID_TRANSLATION", NT_STATUS_NO_GUID_TRANSLATION }, - { "NT_STATUS_CANNOT_IMPERSONATE", NT_STATUS_CANNOT_IMPERSONATE }, - { "NT_STATUS_IMAGE_ALREADY_LOADED", NT_STATUS_IMAGE_ALREADY_LOADED }, - { "NT_STATUS_ABIOS_NOT_PRESENT", NT_STATUS_ABIOS_NOT_PRESENT }, - { "NT_STATUS_ABIOS_LID_NOT_EXIST", NT_STATUS_ABIOS_LID_NOT_EXIST }, - { "NT_STATUS_ABIOS_LID_ALREADY_OWNED", NT_STATUS_ABIOS_LID_ALREADY_OWNED }, - { "NT_STATUS_ABIOS_NOT_LID_OWNER", NT_STATUS_ABIOS_NOT_LID_OWNER }, - { "NT_STATUS_ABIOS_INVALID_COMMAND", NT_STATUS_ABIOS_INVALID_COMMAND }, - { "NT_STATUS_ABIOS_INVALID_LID", NT_STATUS_ABIOS_INVALID_LID }, - { "NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE", NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE }, - { "NT_STATUS_ABIOS_INVALID_SELECTOR", NT_STATUS_ABIOS_INVALID_SELECTOR }, - { "NT_STATUS_NO_LDT", NT_STATUS_NO_LDT }, - { "NT_STATUS_INVALID_LDT_SIZE", NT_STATUS_INVALID_LDT_SIZE }, - { "NT_STATUS_INVALID_LDT_OFFSET", NT_STATUS_INVALID_LDT_OFFSET }, - { "NT_STATUS_INVALID_LDT_DESCRIPTOR", NT_STATUS_INVALID_LDT_DESCRIPTOR }, - { "NT_STATUS_INVALID_IMAGE_NE_FORMAT", NT_STATUS_INVALID_IMAGE_NE_FORMAT }, - { "NT_STATUS_RXACT_INVALID_STATE", NT_STATUS_RXACT_INVALID_STATE }, - { "NT_STATUS_RXACT_COMMIT_FAILURE", NT_STATUS_RXACT_COMMIT_FAILURE }, - { "NT_STATUS_MAPPED_FILE_SIZE_ZERO", NT_STATUS_MAPPED_FILE_SIZE_ZERO }, - { "NT_STATUS_TOO_MANY_OPENED_FILES", NT_STATUS_TOO_MANY_OPENED_FILES }, - { "NT_STATUS_CANCELLED", NT_STATUS_CANCELLED }, - { "NT_STATUS_CANNOT_DELETE", NT_STATUS_CANNOT_DELETE }, - { "NT_STATUS_INVALID_COMPUTER_NAME", NT_STATUS_INVALID_COMPUTER_NAME }, - { "NT_STATUS_FILE_DELETED", NT_STATUS_FILE_DELETED }, - { "NT_STATUS_SPECIAL_ACCOUNT", NT_STATUS_SPECIAL_ACCOUNT }, - { "NT_STATUS_SPECIAL_GROUP", NT_STATUS_SPECIAL_GROUP }, - { "NT_STATUS_SPECIAL_USER", NT_STATUS_SPECIAL_USER }, - { "NT_STATUS_MEMBERS_PRIMARY_GROUP", NT_STATUS_MEMBERS_PRIMARY_GROUP }, - { "NT_STATUS_FILE_CLOSED", NT_STATUS_FILE_CLOSED }, - { "NT_STATUS_TOO_MANY_THREADS", NT_STATUS_TOO_MANY_THREADS }, - { "NT_STATUS_THREAD_NOT_IN_PROCESS", NT_STATUS_THREAD_NOT_IN_PROCESS }, - { "NT_STATUS_TOKEN_ALREADY_IN_USE", NT_STATUS_TOKEN_ALREADY_IN_USE }, - { "NT_STATUS_PAGEFILE_QUOTA_EXCEEDED", NT_STATUS_PAGEFILE_QUOTA_EXCEEDED }, - { "NT_STATUS_COMMITMENT_LIMIT", NT_STATUS_COMMITMENT_LIMIT }, - { "NT_STATUS_INVALID_IMAGE_LE_FORMAT", NT_STATUS_INVALID_IMAGE_LE_FORMAT }, - { "NT_STATUS_INVALID_IMAGE_NOT_MZ", NT_STATUS_INVALID_IMAGE_NOT_MZ }, - { "NT_STATUS_INVALID_IMAGE_PROTECT", NT_STATUS_INVALID_IMAGE_PROTECT }, - { "NT_STATUS_INVALID_IMAGE_WIN_16", NT_STATUS_INVALID_IMAGE_WIN_16 }, - { "NT_STATUS_LOGON_SERVER_CONFLICT", NT_STATUS_LOGON_SERVER_CONFLICT }, - { "NT_STATUS_TIME_DIFFERENCE_AT_DC", NT_STATUS_TIME_DIFFERENCE_AT_DC }, - { "NT_STATUS_SYNCHRONIZATION_REQUIRED", NT_STATUS_SYNCHRONIZATION_REQUIRED }, - { "NT_STATUS_DLL_NOT_FOUND", NT_STATUS_DLL_NOT_FOUND }, - { "NT_STATUS_OPEN_FAILED", NT_STATUS_OPEN_FAILED }, - { "NT_STATUS_IO_PRIVILEGE_FAILED", NT_STATUS_IO_PRIVILEGE_FAILED }, - { "NT_STATUS_ORDINAL_NOT_FOUND", NT_STATUS_ORDINAL_NOT_FOUND }, - { "NT_STATUS_ENTRYPOINT_NOT_FOUND", NT_STATUS_ENTRYPOINT_NOT_FOUND }, - { "NT_STATUS_CONTROL_C_EXIT", NT_STATUS_CONTROL_C_EXIT }, - { "NT_STATUS_LOCAL_DISCONNECT", NT_STATUS_LOCAL_DISCONNECT }, - { "NT_STATUS_REMOTE_DISCONNECT", NT_STATUS_REMOTE_DISCONNECT }, - { "NT_STATUS_REMOTE_RESOURCES", NT_STATUS_REMOTE_RESOURCES }, - { "NT_STATUS_LINK_FAILED", NT_STATUS_LINK_FAILED }, - { "NT_STATUS_LINK_TIMEOUT", NT_STATUS_LINK_TIMEOUT }, - { "NT_STATUS_INVALID_CONNECTION", NT_STATUS_INVALID_CONNECTION }, - { "NT_STATUS_INVALID_ADDRESS", NT_STATUS_INVALID_ADDRESS }, - { "NT_STATUS_DLL_INIT_FAILED", NT_STATUS_DLL_INIT_FAILED }, - { "NT_STATUS_MISSING_SYSTEMFILE", NT_STATUS_MISSING_SYSTEMFILE }, - { "NT_STATUS_UNHANDLED_EXCEPTION", NT_STATUS_UNHANDLED_EXCEPTION }, - { "NT_STATUS_APP_INIT_FAILURE", NT_STATUS_APP_INIT_FAILURE }, - { "NT_STATUS_PAGEFILE_CREATE_FAILED", NT_STATUS_PAGEFILE_CREATE_FAILED }, - { "NT_STATUS_NO_PAGEFILE", NT_STATUS_NO_PAGEFILE }, - { "NT_STATUS_INVALID_LEVEL", NT_STATUS_INVALID_LEVEL }, - { "NT_STATUS_WRONG_PASSWORD_CORE", NT_STATUS_WRONG_PASSWORD_CORE }, - { "NT_STATUS_ILLEGAL_FLOAT_CONTEXT", NT_STATUS_ILLEGAL_FLOAT_CONTEXT }, - { "NT_STATUS_PIPE_BROKEN", NT_STATUS_PIPE_BROKEN }, - { "NT_STATUS_REGISTRY_CORRUPT", NT_STATUS_REGISTRY_CORRUPT }, - { "NT_STATUS_REGISTRY_IO_FAILED", NT_STATUS_REGISTRY_IO_FAILED }, - { "NT_STATUS_NO_EVENT_PAIR", NT_STATUS_NO_EVENT_PAIR }, - { "NT_STATUS_UNRECOGNIZED_VOLUME", NT_STATUS_UNRECOGNIZED_VOLUME }, - { "NT_STATUS_SERIAL_NO_DEVICE_INITED", NT_STATUS_SERIAL_NO_DEVICE_INITED }, - { "NT_STATUS_NO_SUCH_ALIAS", NT_STATUS_NO_SUCH_ALIAS }, - { "NT_STATUS_MEMBER_NOT_IN_ALIAS", NT_STATUS_MEMBER_NOT_IN_ALIAS }, - { "NT_STATUS_MEMBER_IN_ALIAS", NT_STATUS_MEMBER_IN_ALIAS }, - { "NT_STATUS_ALIAS_EXISTS", NT_STATUS_ALIAS_EXISTS }, - { "NT_STATUS_LOGON_NOT_GRANTED", NT_STATUS_LOGON_NOT_GRANTED }, - { "NT_STATUS_TOO_MANY_SECRETS", NT_STATUS_TOO_MANY_SECRETS }, - { "NT_STATUS_SECRET_TOO_LONG", NT_STATUS_SECRET_TOO_LONG }, - { "NT_STATUS_INTERNAL_DB_ERROR", NT_STATUS_INTERNAL_DB_ERROR }, - { "NT_STATUS_FULLSCREEN_MODE", NT_STATUS_FULLSCREEN_MODE }, - { "NT_STATUS_TOO_MANY_CONTEXT_IDS", NT_STATUS_TOO_MANY_CONTEXT_IDS }, - { "NT_STATUS_LOGON_TYPE_NOT_GRANTED", NT_STATUS_LOGON_TYPE_NOT_GRANTED }, - { "NT_STATUS_NOT_REGISTRY_FILE", NT_STATUS_NOT_REGISTRY_FILE }, - { "NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED", NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED }, - { "NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR", NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR }, - { "NT_STATUS_FT_MISSING_MEMBER", NT_STATUS_FT_MISSING_MEMBER }, - { "NT_STATUS_ILL_FORMED_SERVICE_ENTRY", NT_STATUS_ILL_FORMED_SERVICE_ENTRY }, - { "NT_STATUS_ILLEGAL_CHARACTER", NT_STATUS_ILLEGAL_CHARACTER }, - { "NT_STATUS_UNMAPPABLE_CHARACTER", NT_STATUS_UNMAPPABLE_CHARACTER }, - { "NT_STATUS_UNDEFINED_CHARACTER", NT_STATUS_UNDEFINED_CHARACTER }, - { "NT_STATUS_FLOPPY_VOLUME", NT_STATUS_FLOPPY_VOLUME }, - { "NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND", NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND }, - { "NT_STATUS_FLOPPY_WRONG_CYLINDER", NT_STATUS_FLOPPY_WRONG_CYLINDER }, - { "NT_STATUS_FLOPPY_UNKNOWN_ERROR", NT_STATUS_FLOPPY_UNKNOWN_ERROR }, - { "NT_STATUS_FLOPPY_BAD_REGISTERS", NT_STATUS_FLOPPY_BAD_REGISTERS }, - { "NT_STATUS_DISK_RECALIBRATE_FAILED", NT_STATUS_DISK_RECALIBRATE_FAILED }, - { "NT_STATUS_DISK_OPERATION_FAILED", NT_STATUS_DISK_OPERATION_FAILED }, - { "NT_STATUS_DISK_RESET_FAILED", NT_STATUS_DISK_RESET_FAILED }, - { "NT_STATUS_SHARED_IRQ_BUSY", NT_STATUS_SHARED_IRQ_BUSY }, - { "NT_STATUS_FT_ORPHANING", NT_STATUS_FT_ORPHANING }, - { "NT_STATUS_PARTITION_FAILURE", NT_STATUS_PARTITION_FAILURE }, - { "NT_STATUS_INVALID_BLOCK_LENGTH", NT_STATUS_INVALID_BLOCK_LENGTH }, - { "NT_STATUS_DEVICE_NOT_PARTITIONED", NT_STATUS_DEVICE_NOT_PARTITIONED }, - { "NT_STATUS_UNABLE_TO_LOCK_MEDIA", NT_STATUS_UNABLE_TO_LOCK_MEDIA }, - { "NT_STATUS_UNABLE_TO_UNLOAD_MEDIA", NT_STATUS_UNABLE_TO_UNLOAD_MEDIA }, - { "NT_STATUS_EOM_OVERFLOW", NT_STATUS_EOM_OVERFLOW }, - { "NT_STATUS_NO_MEDIA", NT_STATUS_NO_MEDIA }, - { "NT_STATUS_NO_SUCH_MEMBER", NT_STATUS_NO_SUCH_MEMBER }, - { "NT_STATUS_INVALID_MEMBER", NT_STATUS_INVALID_MEMBER }, - { "NT_STATUS_KEY_DELETED", NT_STATUS_KEY_DELETED }, - { "NT_STATUS_NO_LOG_SPACE", NT_STATUS_NO_LOG_SPACE }, - { "NT_STATUS_TOO_MANY_SIDS", NT_STATUS_TOO_MANY_SIDS }, - { "NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED", NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED }, - { "NT_STATUS_KEY_HAS_CHILDREN", NT_STATUS_KEY_HAS_CHILDREN }, - { "NT_STATUS_CHILD_MUST_BE_VOLATILE", NT_STATUS_CHILD_MUST_BE_VOLATILE }, - { "NT_STATUS_DEVICE_CONFIGURATION_ERROR", NT_STATUS_DEVICE_CONFIGURATION_ERROR }, - { "NT_STATUS_DRIVER_INTERNAL_ERROR", NT_STATUS_DRIVER_INTERNAL_ERROR }, - { "NT_STATUS_INVALID_DEVICE_STATE", NT_STATUS_INVALID_DEVICE_STATE }, - { "NT_STATUS_IO_DEVICE_ERROR", NT_STATUS_IO_DEVICE_ERROR }, - { "NT_STATUS_DEVICE_PROTOCOL_ERROR", NT_STATUS_DEVICE_PROTOCOL_ERROR }, - { "NT_STATUS_BACKUP_CONTROLLER", NT_STATUS_BACKUP_CONTROLLER }, - { "NT_STATUS_LOG_FILE_FULL", NT_STATUS_LOG_FILE_FULL }, - { "NT_STATUS_TOO_LATE", NT_STATUS_TOO_LATE }, - { "NT_STATUS_NO_TRUST_LSA_SECRET", NT_STATUS_NO_TRUST_LSA_SECRET }, - { "NT_STATUS_NO_TRUST_SAM_ACCOUNT", NT_STATUS_NO_TRUST_SAM_ACCOUNT }, - { "NT_STATUS_TRUSTED_DOMAIN_FAILURE", NT_STATUS_TRUSTED_DOMAIN_FAILURE }, - { "NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE", NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE }, - { "NT_STATUS_EVENTLOG_FILE_CORRUPT", NT_STATUS_EVENTLOG_FILE_CORRUPT }, - { "NT_STATUS_EVENTLOG_CANT_START", NT_STATUS_EVENTLOG_CANT_START }, - { "NT_STATUS_TRUST_FAILURE", NT_STATUS_TRUST_FAILURE }, - { "NT_STATUS_MUTANT_LIMIT_EXCEEDED", NT_STATUS_MUTANT_LIMIT_EXCEEDED }, - { "NT_STATUS_NETLOGON_NOT_STARTED", NT_STATUS_NETLOGON_NOT_STARTED }, - { "NT_STATUS_ACCOUNT_EXPIRED", NT_STATUS_ACCOUNT_EXPIRED }, - { "NT_STATUS_POSSIBLE_DEADLOCK", NT_STATUS_POSSIBLE_DEADLOCK }, - { "NT_STATUS_NETWORK_CREDENTIAL_CONFLICT", NT_STATUS_NETWORK_CREDENTIAL_CONFLICT }, - { "NT_STATUS_REMOTE_SESSION_LIMIT", NT_STATUS_REMOTE_SESSION_LIMIT }, - { "NT_STATUS_EVENTLOG_FILE_CHANGED", NT_STATUS_EVENTLOG_FILE_CHANGED }, - { "NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT", NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT }, - { "NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT", NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, - { "NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT", NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT }, - { "NT_STATUS_DOMAIN_TRUST_INCONSISTENT", NT_STATUS_DOMAIN_TRUST_INCONSISTENT }, - { "NT_STATUS_FS_DRIVER_REQUIRED", NT_STATUS_FS_DRIVER_REQUIRED }, - { "NT_STATUS_NO_USER_SESSION_KEY", NT_STATUS_NO_USER_SESSION_KEY }, - { "NT_STATUS_USER_SESSION_DELETED", NT_STATUS_USER_SESSION_DELETED }, - { "NT_STATUS_RESOURCE_LANG_NOT_FOUND", NT_STATUS_RESOURCE_LANG_NOT_FOUND }, - { "NT_STATUS_INSUFF_SERVER_RESOURCES", NT_STATUS_INSUFF_SERVER_RESOURCES }, - { "NT_STATUS_INVALID_BUFFER_SIZE", NT_STATUS_INVALID_BUFFER_SIZE }, - { "NT_STATUS_INVALID_ADDRESS_COMPONENT", NT_STATUS_INVALID_ADDRESS_COMPONENT }, - { "NT_STATUS_INVALID_ADDRESS_WILDCARD", NT_STATUS_INVALID_ADDRESS_WILDCARD }, - { "NT_STATUS_TOO_MANY_ADDRESSES", NT_STATUS_TOO_MANY_ADDRESSES }, - { "NT_STATUS_ADDRESS_ALREADY_EXISTS", NT_STATUS_ADDRESS_ALREADY_EXISTS }, - { "NT_STATUS_ADDRESS_CLOSED", NT_STATUS_ADDRESS_CLOSED }, - { "NT_STATUS_CONNECTION_DISCONNECTED", NT_STATUS_CONNECTION_DISCONNECTED }, - { "NT_STATUS_CONNECTION_RESET", NT_STATUS_CONNECTION_RESET }, - { "NT_STATUS_TOO_MANY_NODES", NT_STATUS_TOO_MANY_NODES }, - { "NT_STATUS_TRANSACTION_ABORTED", NT_STATUS_TRANSACTION_ABORTED }, - { "NT_STATUS_TRANSACTION_TIMED_OUT", NT_STATUS_TRANSACTION_TIMED_OUT }, - { "NT_STATUS_TRANSACTION_NO_RELEASE", NT_STATUS_TRANSACTION_NO_RELEASE }, - { "NT_STATUS_TRANSACTION_NO_MATCH", NT_STATUS_TRANSACTION_NO_MATCH }, - { "NT_STATUS_TRANSACTION_RESPONDED", NT_STATUS_TRANSACTION_RESPONDED }, - { "NT_STATUS_TRANSACTION_INVALID_ID", NT_STATUS_TRANSACTION_INVALID_ID }, - { "NT_STATUS_TRANSACTION_INVALID_TYPE", NT_STATUS_TRANSACTION_INVALID_TYPE }, - { "NT_STATUS_NOT_SERVER_SESSION", NT_STATUS_NOT_SERVER_SESSION }, - { "NT_STATUS_NOT_CLIENT_SESSION", NT_STATUS_NOT_CLIENT_SESSION }, - { "NT_STATUS_CANNOT_LOAD_REGISTRY_FILE", NT_STATUS_CANNOT_LOAD_REGISTRY_FILE }, - { "NT_STATUS_DEBUG_ATTACH_FAILED", NT_STATUS_DEBUG_ATTACH_FAILED }, - { "NT_STATUS_SYSTEM_PROCESS_TERMINATED", NT_STATUS_SYSTEM_PROCESS_TERMINATED }, - { "NT_STATUS_DATA_NOT_ACCEPTED", NT_STATUS_DATA_NOT_ACCEPTED }, - { "NT_STATUS_NO_BROWSER_SERVERS_FOUND", NT_STATUS_NO_BROWSER_SERVERS_FOUND }, - { "NT_STATUS_VDM_HARD_ERROR", NT_STATUS_VDM_HARD_ERROR }, - { "NT_STATUS_DRIVER_CANCEL_TIMEOUT", NT_STATUS_DRIVER_CANCEL_TIMEOUT }, - { "NT_STATUS_REPLY_MESSAGE_MISMATCH", NT_STATUS_REPLY_MESSAGE_MISMATCH }, - { "NT_STATUS_MAPPED_ALIGNMENT", NT_STATUS_MAPPED_ALIGNMENT }, - { "NT_STATUS_IMAGE_CHECKSUM_MISMATCH", NT_STATUS_IMAGE_CHECKSUM_MISMATCH }, - { "NT_STATUS_LOST_WRITEBEHIND_DATA", NT_STATUS_LOST_WRITEBEHIND_DATA }, - { "NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID", NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID }, - { "NT_STATUS_PASSWORD_MUST_CHANGE", NT_STATUS_PASSWORD_MUST_CHANGE }, - { "NT_STATUS_NOT_FOUND", NT_STATUS_NOT_FOUND }, - { "NT_STATUS_NOT_TINY_STREAM", NT_STATUS_NOT_TINY_STREAM }, - { "NT_STATUS_RECOVERY_FAILURE", NT_STATUS_RECOVERY_FAILURE }, - { "NT_STATUS_STACK_OVERFLOW_READ", NT_STATUS_STACK_OVERFLOW_READ }, - { "NT_STATUS_FAIL_CHECK", NT_STATUS_FAIL_CHECK }, - { "NT_STATUS_DUPLICATE_OBJECTID", NT_STATUS_DUPLICATE_OBJECTID }, - { "NT_STATUS_OBJECTID_EXISTS", NT_STATUS_OBJECTID_EXISTS }, - { "NT_STATUS_CONVERT_TO_LARGE", NT_STATUS_CONVERT_TO_LARGE }, - { "NT_STATUS_RETRY", NT_STATUS_RETRY }, - { "NT_STATUS_FOUND_OUT_OF_SCOPE", NT_STATUS_FOUND_OUT_OF_SCOPE }, - { "NT_STATUS_ALLOCATE_BUCKET", NT_STATUS_ALLOCATE_BUCKET }, - { "NT_STATUS_PROPSET_NOT_FOUND", NT_STATUS_PROPSET_NOT_FOUND }, - { "NT_STATUS_MARSHALL_OVERFLOW", NT_STATUS_MARSHALL_OVERFLOW }, - { "NT_STATUS_INVALID_VARIANT", NT_STATUS_INVALID_VARIANT }, - { "NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, - { "NT_STATUS_ACCOUNT_LOCKED_OUT", NT_STATUS_ACCOUNT_LOCKED_OUT }, - { "NT_STATUS_HANDLE_NOT_CLOSABLE", NT_STATUS_HANDLE_NOT_CLOSABLE }, - { "NT_STATUS_CONNECTION_REFUSED", NT_STATUS_CONNECTION_REFUSED }, - { "NT_STATUS_GRACEFUL_DISCONNECT", NT_STATUS_GRACEFUL_DISCONNECT }, - { "NT_STATUS_ADDRESS_ALREADY_ASSOCIATED", NT_STATUS_ADDRESS_ALREADY_ASSOCIATED }, - { "NT_STATUS_ADDRESS_NOT_ASSOCIATED", NT_STATUS_ADDRESS_NOT_ASSOCIATED }, - { "NT_STATUS_CONNECTION_INVALID", NT_STATUS_CONNECTION_INVALID }, - { "NT_STATUS_CONNECTION_ACTIVE", NT_STATUS_CONNECTION_ACTIVE }, - { "NT_STATUS_NETWORK_UNREACHABLE", NT_STATUS_NETWORK_UNREACHABLE }, - { "NT_STATUS_HOST_UNREACHABLE", NT_STATUS_HOST_UNREACHABLE }, - { "NT_STATUS_PROTOCOL_UNREACHABLE", NT_STATUS_PROTOCOL_UNREACHABLE }, - { "NT_STATUS_PORT_UNREACHABLE", NT_STATUS_PORT_UNREACHABLE }, - { "NT_STATUS_REQUEST_ABORTED", NT_STATUS_REQUEST_ABORTED }, - { "NT_STATUS_CONNECTION_ABORTED", NT_STATUS_CONNECTION_ABORTED }, - { "NT_STATUS_BAD_COMPRESSION_BUFFER", NT_STATUS_BAD_COMPRESSION_BUFFER }, - { "NT_STATUS_USER_MAPPED_FILE", NT_STATUS_USER_MAPPED_FILE }, - { "NT_STATUS_AUDIT_FAILED", NT_STATUS_AUDIT_FAILED }, - { "NT_STATUS_TIMER_RESOLUTION_NOT_SET", NT_STATUS_TIMER_RESOLUTION_NOT_SET }, - { "NT_STATUS_CONNECTION_COUNT_LIMIT", NT_STATUS_CONNECTION_COUNT_LIMIT }, - { "NT_STATUS_LOGIN_TIME_RESTRICTION", NT_STATUS_LOGIN_TIME_RESTRICTION }, - { "NT_STATUS_LOGIN_WKSTA_RESTRICTION", NT_STATUS_LOGIN_WKSTA_RESTRICTION }, - { "NT_STATUS_IMAGE_MP_UP_MISMATCH", NT_STATUS_IMAGE_MP_UP_MISMATCH }, - { "NT_STATUS_INSUFFICIENT_LOGON_INFO", NT_STATUS_INSUFFICIENT_LOGON_INFO }, - { "NT_STATUS_BAD_DLL_ENTRYPOINT", NT_STATUS_BAD_DLL_ENTRYPOINT }, - { "NT_STATUS_BAD_SERVICE_ENTRYPOINT", NT_STATUS_BAD_SERVICE_ENTRYPOINT }, - { "NT_STATUS_LPC_REPLY_LOST", NT_STATUS_LPC_REPLY_LOST }, - { "NT_STATUS_IP_ADDRESS_CONFLICT1", NT_STATUS_IP_ADDRESS_CONFLICT1 }, - { "NT_STATUS_IP_ADDRESS_CONFLICT2", NT_STATUS_IP_ADDRESS_CONFLICT2 }, - { "NT_STATUS_REGISTRY_QUOTA_LIMIT", NT_STATUS_REGISTRY_QUOTA_LIMIT }, - { "NT_STATUS_PATH_NOT_COVERED", NT_STATUS_PATH_NOT_COVERED }, - { "NT_STATUS_NO_CALLBACK_ACTIVE", NT_STATUS_NO_CALLBACK_ACTIVE }, - { "NT_STATUS_LICENSE_QUOTA_EXCEEDED", NT_STATUS_LICENSE_QUOTA_EXCEEDED }, - { "NT_STATUS_PWD_TOO_SHORT", NT_STATUS_PWD_TOO_SHORT }, - { "NT_STATUS_PWD_TOO_RECENT", NT_STATUS_PWD_TOO_RECENT }, - { "NT_STATUS_PWD_HISTORY_CONFLICT", NT_STATUS_PWD_HISTORY_CONFLICT }, - { "NT_STATUS_PLUGPLAY_NO_DEVICE", NT_STATUS_PLUGPLAY_NO_DEVICE }, - { "NT_STATUS_UNSUPPORTED_COMPRESSION", NT_STATUS_UNSUPPORTED_COMPRESSION }, - { "NT_STATUS_INVALID_HW_PROFILE", NT_STATUS_INVALID_HW_PROFILE }, - { "NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH", NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH }, - { "NT_STATUS_DRIVER_ORDINAL_NOT_FOUND", NT_STATUS_DRIVER_ORDINAL_NOT_FOUND }, - { "NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND", NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND }, - { "NT_STATUS_RESOURCE_NOT_OWNED", NT_STATUS_RESOURCE_NOT_OWNED }, - { "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS }, - { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, - { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, - { "NT_STATUS_DS_NO_MORE_RIDS", NT_STATUS_DS_NO_MORE_RIDS }, - { "NT_STATUS_NOT_A_REPARSE_POINT", NT_STATUS_NOT_A_REPARSE_POINT }, - { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, - { "NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED", NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED }, - { "NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX", NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX }, - { "NT_STATUS_RPC_UNKNOWN_IF", NT_STATUS_RPC_UNKNOWN_IF }, - { "NT_STATUS_RPC_CALL_FAILED", NT_STATUS_RPC_CALL_FAILED }, - { "NT_STATUS_RPC_PROTOCOL_ERROR", NT_STATUS_RPC_PROTOCOL_ERROR }, - { "NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE", NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE }, - { "NT_STATUS_RPC_CANNOT_SUPPORT", NT_STATUS_RPC_CANNOT_SUPPORT }, - { "NT_STATUS_RPC_SEC_PKG_ERROR", NT_STATUS_RPC_SEC_PKG_ERROR }, - { "NT_STATUS_RPC_SS_CONTEXT_MISMATCH", NT_STATUS_RPC_SS_CONTEXT_MISMATCH }, - { "NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE", NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE }, - { "NT_STATUS_RPC_BAD_STUB_DATA", NT_STATUS_RPC_BAD_STUB_DATA }, - { "NT_STATUS_RPC_INVALID_PIPE_OBJECT", NT_STATUS_RPC_INVALID_PIPE_OBJECT }, - { "NT_STATUS_RPC_INVALID_PIPE_OPERATION", NT_STATUS_RPC_INVALID_PIPE_OPERATION }, - { "NT_STATUS_RPC_WRONG_PIPE_VERSION", NT_STATUS_RPC_WRONG_PIPE_VERSION }, - { "NT_STATUS_RPC_PIPE_CLOSED", NT_STATUS_RPC_PIPE_CLOSED }, - { "NT_STATUS_RPC_PIPE_DISCIPLINE_ERROR", NT_STATUS_RPC_PIPE_DISCIPLINE_ERROR }, - { "NT_STATUS_RPC_PIPE_EMPTY", NT_STATUS_RPC_PIPE_EMPTY }, - { "NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED", NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED }, - { "NT_STATUS_OBJECTID_NOT_FOUND", NT_STATUS_OBJECTID_NOT_FOUND }, - { "NT_STATUS_DOWNGRADE_DETECTED", NT_STATUS_DOWNGRADE_DETECTED }, - { "NT_STATUS_INVALID_LOCK_RANGE", NT_STATUS_INVALID_LOCK_RANGE }, - { "NT_STATUS_ERROR_DS_OBJ_STRING_NAME_EXISTS", NT_STATUS_ERROR_DS_OBJ_STRING_NAME_EXISTS }, - { "NT_STATUS_ERROR_DS_INCOMPATIBLE_VERSION", NT_STATUS_ERROR_DS_INCOMPATIBLE_VERSION }, - { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, - { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, - { "STATUS_NOTIFY_CLEANUP", STATUS_NOTIFY_CLEANUP }, - { "STATUS_NOTIFY_ENUM_DIR", STATUS_NOTIFY_ENUM_DIR }, - - DOS_CODE(ERRDOS, ERRsuccess), - DOS_CODE(ERRDOS, ERRbadfunc), - DOS_CODE(ERRDOS, ERRbadfile), - DOS_CODE(ERRDOS, ERRbadpath), - DOS_CODE(ERRDOS, ERRnofids), - DOS_CODE(ERRDOS, ERRnoaccess), - DOS_CODE(ERRDOS, ERRbadfid), - DOS_CODE(ERRDOS, ERRbadmcb), - DOS_CODE(ERRDOS, ERRnomem), - DOS_CODE(ERRDOS, ERRbadmem), - DOS_CODE(ERRDOS, ERRbadenv), - DOS_CODE(ERRDOS, ERRbadaccess), - DOS_CODE(ERRDOS, ERRbaddata), - DOS_CODE(ERRDOS, ERRres), - DOS_CODE(ERRDOS, ERRbaddrive), - DOS_CODE(ERRDOS, ERRremcd), - DOS_CODE(ERRDOS, ERRdiffdevice), - DOS_CODE(ERRDOS, ERRnofiles), - DOS_CODE(ERRDOS, ERRgeneral), - DOS_CODE(ERRDOS, ERRbadshare), - DOS_CODE(ERRDOS, ERRlock), - DOS_CODE(ERRDOS, ERRunsup), - DOS_CODE(ERRDOS, ERRnetnamedel), - DOS_CODE(ERRDOS, ERRnosuchshare), - DOS_CODE(ERRDOS, ERRfilexists), - DOS_CODE(ERRDOS, ERRinvalidparam), - DOS_CODE(ERRDOS, ERRcannotopen), - DOS_CODE(ERRDOS, ERRinsufficientbuffer), - DOS_CODE(ERRDOS, ERRinvalidname), - DOS_CODE(ERRDOS, ERRunknownlevel), - DOS_CODE(ERRDOS, ERRnotlocked), - DOS_CODE(ERRDOS, ERRinvalidpath), - DOS_CODE(ERRDOS, ERRcancelviolation), - DOS_CODE(ERRDOS, ERRnoatomiclocks), - DOS_CODE(ERRDOS, ERRrename), - DOS_CODE(ERRDOS, ERRbadpipe), - DOS_CODE(ERRDOS, ERRpipebusy), - DOS_CODE(ERRDOS, ERRpipeclosing), - DOS_CODE(ERRDOS, ERRnotconnected), - DOS_CODE(ERRDOS, ERRmoredata), - DOS_CODE(ERRDOS, ERRnomoreitems), - DOS_CODE(ERRDOS, ERRbaddirectory), - DOS_CODE(ERRDOS, ERReasnotsupported), - DOS_CODE(ERRDOS, ERRlogonfailure), - DOS_CODE(ERRDOS, ERRbuftoosmall), - DOS_CODE(ERRDOS, ERRunknownipc), - DOS_CODE(ERRDOS, ERRnosuchprintjob), - DOS_CODE(ERRDOS, ERRinvgroup), - DOS_CODE(ERRDOS, ERRnoipc), - DOS_CODE(ERRDOS, ERRdriveralreadyinstalled), - DOS_CODE(ERRDOS, ERRunknownprinterport), - DOS_CODE(ERRDOS, ERRunknownprinterdriver), - DOS_CODE(ERRDOS, ERRunknownprintprocessor), - DOS_CODE(ERRDOS, ERRinvalidseparatorfile), - DOS_CODE(ERRDOS, ERRinvalidjobpriority), - DOS_CODE(ERRDOS, ERRinvalidprintername), - DOS_CODE(ERRDOS, ERRprinteralreadyexists), - DOS_CODE(ERRDOS, ERRinvalidprintercommand), - DOS_CODE(ERRDOS, ERRinvaliddatatype), - DOS_CODE(ERRDOS, ERRinvalidenvironment), - DOS_CODE(ERRDOS, ERRunknownprintmonitor), - DOS_CODE(ERRDOS, ERRprinterdriverinuse), - DOS_CODE(ERRDOS, ERRspoolfilenotfound), - DOS_CODE(ERRDOS, ERRnostartdoc), - DOS_CODE(ERRDOS, ERRnoaddjob), - DOS_CODE(ERRDOS, ERRprintprocessoralreadyinstalled), - DOS_CODE(ERRDOS, ERRprintmonitoralreadyinstalled), - DOS_CODE(ERRDOS, ERRinvalidprintmonitor), - DOS_CODE(ERRDOS, ERRprintmonitorinuse), - DOS_CODE(ERRDOS, ERRprinterhasjobsqueued), - DOS_CODE(ERRDOS, ERReainconsistent), - - DOS_CODE(ERRSRV, ERRerror), - DOS_CODE(ERRSRV, ERRbadpw), - DOS_CODE(ERRSRV, ERRbadtype), - DOS_CODE(ERRSRV, ERRaccess), - DOS_CODE(ERRSRV, ERRinvnid), - DOS_CODE(ERRSRV, ERRinvnetname), - DOS_CODE(ERRSRV, ERRinvdevice), - DOS_CODE(ERRSRV, ERRqfull), - DOS_CODE(ERRSRV, ERRqtoobig), - DOS_CODE(ERRSRV, ERRinvpfid), - DOS_CODE(ERRSRV, ERRsmbcmd), - DOS_CODE(ERRSRV, ERRsrverror), - DOS_CODE(ERRSRV, ERRfilespecs), - DOS_CODE(ERRSRV, ERRbadlink), - DOS_CODE(ERRSRV, ERRbadpermits), - DOS_CODE(ERRSRV, ERRbadpid), - DOS_CODE(ERRSRV, ERRsetattrmode), - DOS_CODE(ERRSRV, ERRpaused), - DOS_CODE(ERRSRV, ERRmsgoff), - DOS_CODE(ERRSRV, ERRnoroom), - DOS_CODE(ERRSRV, ERRrmuns), - DOS_CODE(ERRSRV, ERRtimeout), - DOS_CODE(ERRSRV, ERRnoresource), - DOS_CODE(ERRSRV, ERRtoomanyuids), - DOS_CODE(ERRSRV, ERRbaduid), - DOS_CODE(ERRSRV, ERRuseMPX), - DOS_CODE(ERRSRV, ERRuseSTD), - DOS_CODE(ERRSRV, ERRcontMPX), - DOS_CODE(ERRSRV, ERRnosupport), - DOS_CODE(ERRSRV, ERRunknownsmb), - - DOS_CODE(ERRHRD, ERRnowrite), - DOS_CODE(ERRHRD, ERRbadunit), - DOS_CODE(ERRHRD, ERRnotready), - DOS_CODE(ERRHRD, ERRbadcmd), - DOS_CODE(ERRHRD, ERRdata), - DOS_CODE(ERRHRD, ERRbadreq), - DOS_CODE(ERRHRD, ERRseek), - DOS_CODE(ERRHRD, ERRbadmedia), - DOS_CODE(ERRHRD, ERRbadsector), - DOS_CODE(ERRHRD, ERRnopaper), - DOS_CODE(ERRHRD, ERRwrite), - DOS_CODE(ERRHRD, ERRread), - DOS_CODE(ERRHRD, ERRgeneral), - DOS_CODE(ERRHRD, ERRwrongdisk), - DOS_CODE(ERRHRD, ERRFCBunavail), - DOS_CODE(ERRHRD, ERRsharebufexc), - DOS_CODE(ERRHRD, ERRdiskfull), - - LDAP_CODE(LDAP_SUCCESS), - LDAP_CODE(LDAP_OPERATIONS_ERROR), - LDAP_CODE(LDAP_PROTOCOL_ERROR), - LDAP_CODE(LDAP_TIME_LIMIT_EXCEEDED), - LDAP_CODE(LDAP_SIZE_LIMIT_EXCEEDED), - LDAP_CODE(LDAP_COMPARE_FALSE), - LDAP_CODE(LDAP_COMPARE_TRUE), - LDAP_CODE(LDAP_AUTH_METHOD_NOT_SUPPORTED), - LDAP_CODE(LDAP_STRONG_AUTH_REQUIRED), - LDAP_CODE(LDAP_REFERRAL), - LDAP_CODE(LDAP_ADMIN_LIMIT_EXCEEDED), - LDAP_CODE(LDAP_UNAVAILABLE_CRITICAL_EXTENSION), - LDAP_CODE(LDAP_CONFIDENTIALITY_REQUIRED), - LDAP_CODE(LDAP_SASL_BIND_IN_PROGRESS), - LDAP_CODE(LDAP_NO_SUCH_ATTRIBUTE), - LDAP_CODE(LDAP_UNDEFINED_ATTRIBUTE_TYPE), - LDAP_CODE(LDAP_INAPPROPRIATE_MATCHING), - LDAP_CODE(LDAP_CONSTRAINT_VIOLATION), - LDAP_CODE(LDAP_ATTRIBUTE_OR_VALUE_EXISTS), - LDAP_CODE(LDAP_INVALID_ATTRIBUTE_SYNTAX), - LDAP_CODE(LDAP_NO_SUCH_OBJECT), - LDAP_CODE(LDAP_ALIAS_PROBLEM), - LDAP_CODE(LDAP_INVALID_DN_SYNTAX), - LDAP_CODE(LDAP_ALIAS_DEREFERENCING_PROBLEM), - LDAP_CODE(LDAP_INAPPROPRIATE_AUTHENTICATION), - LDAP_CODE(LDAP_INVALID_CREDENTIALS), - LDAP_CODE(LDAP_INSUFFICIENT_ACCESS_RIGHTS), - LDAP_CODE(LDAP_BUSY), - LDAP_CODE(LDAP_UNAVAILABLE), - LDAP_CODE(LDAP_UNWILLING_TO_PERFORM), - LDAP_CODE(LDAP_LOOP_DETECT), - LDAP_CODE(LDAP_NAMING_VIOLATION), - LDAP_CODE(LDAP_OBJECT_CLASS_VIOLATION), - LDAP_CODE(LDAP_NOT_ALLOWED_ON_NON_LEAF), - LDAP_CODE(LDAP_NOT_ALLOWED_ON_RDN), - LDAP_CODE(LDAP_ENTRY_ALREADY_EXISTS), - LDAP_CODE(LDAP_OBJECT_CLASS_MODS_PROHIBITED), - LDAP_CODE(LDAP_AFFECTS_MULTIPLE_DSAS), - LDAP_CODE(LDAP_OTHER), - - { NULL, NT_STATUS(0) } -}; - -/* These need sorting..... */ - -static const nt_err_code_struct nt_err_desc[] = -{ - { N_("Success"), NT_STATUS_OK }, - { N_("Undetermined error"), NT_STATUS_UNSUCCESSFUL }, - { N_("Access denied"), NT_STATUS_ACCESS_DENIED }, - { N_("Account locked out"), NT_STATUS_ACCOUNT_LOCKED_OUT }, - { N_("Must change password"), NT_STATUS_PASSWORD_MUST_CHANGE }, - { N_("Password is too short"), NT_STATUS_PWD_TOO_SHORT }, - { N_("Password is too recent"), NT_STATUS_PWD_TOO_RECENT }, - { N_("Password history conflict"), NT_STATUS_PWD_HISTORY_CONFLICT }, - { N_("No logon servers"), NT_STATUS_NO_LOGON_SERVERS }, - { N_("Improperly formed account name"), NT_STATUS_INVALID_ACCOUNT_NAME }, - { N_("User exists"), NT_STATUS_USER_EXISTS }, - { N_("No such user"), NT_STATUS_NO_SUCH_USER }, - { N_("Group exists"), NT_STATUS_GROUP_EXISTS }, - { N_("No such group"), NT_STATUS_NO_SUCH_GROUP }, - { N_("Member not in group"), NT_STATUS_MEMBER_NOT_IN_GROUP }, - { N_("Wrong Password"), NT_STATUS_WRONG_PASSWORD }, - { N_("Ill formed password"), NT_STATUS_ILL_FORMED_PASSWORD }, - { N_("Password restriction"), NT_STATUS_PASSWORD_RESTRICTION }, - { N_("Logon failure"), NT_STATUS_LOGON_FAILURE }, - { N_("Account restriction"), NT_STATUS_ACCOUNT_RESTRICTION }, - { N_("Invalid logon hours"), NT_STATUS_INVALID_LOGON_HOURS }, - { N_("Invalid workstation"), NT_STATUS_INVALID_WORKSTATION }, - { N_("Password expired"), NT_STATUS_PASSWORD_EXPIRED }, - { N_("Account disabled"), NT_STATUS_ACCOUNT_DISABLED }, - { N_("Unexpected information received"), NT_STATUS_INVALID_PARAMETER }, - { N_("Memory allocation error"), NT_STATUS_NO_MEMORY }, - { N_("No domain controllers located"), NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, - { N_("Account locked out"), NT_STATUS_ACCOUNT_LOCKED_OUT }, - { N_("Named pipe not available"), NT_STATUS_PIPE_NOT_AVAILABLE }, - { N_("Not implemented"), NT_STATUS_NOT_IMPLEMENTED }, - { N_("Invalid information class"), NT_STATUS_INVALID_INFO_CLASS }, - { N_("Information length mismatch"), NT_STATUS_INFO_LENGTH_MISMATCH }, - { N_("Access violation"), NT_STATUS_ACCESS_VIOLATION }, - { N_("Invalid handle"), NT_STATUS_INVALID_HANDLE }, - { N_("Invalid parameter"), NT_STATUS_INVALID_PARAMETER }, - { N_("No memory"), NT_STATUS_NO_MEMORY }, - { N_("Buffer too small"), NT_STATUS_BUFFER_TOO_SMALL }, - { N_("Revision mismatch"), NT_STATUS_REVISION_MISMATCH }, - { N_("No logon servers"), NT_STATUS_NO_LOGON_SERVERS }, - { N_("No such logon session"), NT_STATUS_NO_SUCH_LOGON_SESSION }, - { N_("No such privilege"), NT_STATUS_NO_SUCH_PRIVILEGE }, - { N_("Procedure not found"), NT_STATUS_PROCEDURE_NOT_FOUND }, - { N_("Server disabled"), NT_STATUS_SERVER_DISABLED }, - { N_("Invalid pipe state"), NT_STATUS_INVALID_PIPE_STATE }, - { N_("Named pipe busy"), NT_STATUS_PIPE_BUSY }, - { N_("Illegal function"), NT_STATUS_ILLEGAL_FUNCTION }, - { N_("Named pipe disconnected"), NT_STATUS_PIPE_DISCONNECTED }, - { N_("Named pipe closing"), NT_STATUS_PIPE_CLOSING }, - { N_("Remote host not listening"), NT_STATUS_REMOTE_NOT_LISTENING }, - { N_("Duplicate name on network"), NT_STATUS_DUPLICATE_NAME }, - { N_("Print queue is full"), NT_STATUS_PRINT_QUEUE_FULL }, - { N_("No print spool space available"), NT_STATUS_NO_SPOOL_SPACE }, - { N_("The network name cannot be found"), NT_STATUS_BAD_NETWORK_NAME }, - { N_("The connection was refused"), NT_STATUS_CONNECTION_REFUSED }, - { N_("Too many names"), NT_STATUS_TOO_MANY_NAMES }, - { N_("Too many sessions"), NT_STATUS_TOO_MANY_SESSIONS }, - { N_("Invalid server state"), NT_STATUS_INVALID_SERVER_STATE }, - { N_("Invalid domain state"), NT_STATUS_INVALID_DOMAIN_STATE }, - { N_("Invalid domain role"), NT_STATUS_INVALID_DOMAIN_ROLE }, - { N_("No such domain"), NT_STATUS_NO_SUCH_DOMAIN }, - { N_("Domain exists"), NT_STATUS_DOMAIN_EXISTS }, - { N_("Domain limit exceeded"), NT_STATUS_DOMAIN_LIMIT_EXCEEDED }, - { N_("Bad logon session state"), NT_STATUS_BAD_LOGON_SESSION_STATE }, - { N_("Logon session collision"), NT_STATUS_LOGON_SESSION_COLLISION }, - { N_("Invalid logon type"), NT_STATUS_INVALID_LOGON_TYPE }, - { N_("Cancelled"), NT_STATUS_CANCELLED }, - { N_("Invalid computer name"), NT_STATUS_INVALID_COMPUTER_NAME }, - { N_("Logon server conflict"), NT_STATUS_LOGON_SERVER_CONFLICT }, - { N_("Time difference at domain controller"), NT_STATUS_TIME_DIFFERENCE_AT_DC }, - { N_("Pipe broken"), NT_STATUS_PIPE_BROKEN }, - { N_("Registry corrupt"), NT_STATUS_REGISTRY_CORRUPT }, - { N_("Too many secrets"), NT_STATUS_TOO_MANY_SECRETS }, - { N_("Too many SIDs"), NT_STATUS_TOO_MANY_SIDS }, - { N_("Lanmanager cross encryption required"), NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED }, - { N_("Log file full"), NT_STATUS_LOG_FILE_FULL }, - { N_("No trusted LSA secret"), NT_STATUS_NO_TRUST_LSA_SECRET }, - { N_("No trusted SAM account"), NT_STATUS_NO_TRUST_SAM_ACCOUNT }, - { N_("Trusted domain failure"), NT_STATUS_TRUSTED_DOMAIN_FAILURE }, - { N_("Trust relationship failure"), NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE }, - { N_("Trust failure"), NT_STATUS_TRUST_FAILURE }, - { N_("Netlogon service not started"), NT_STATUS_NETLOGON_NOT_STARTED }, - { N_("Account expired"), NT_STATUS_ACCOUNT_EXPIRED }, - { N_("Network credential conflict"), NT_STATUS_NETWORK_CREDENTIAL_CONFLICT }, - { N_("Remote session limit"), NT_STATUS_REMOTE_SESSION_LIMIT }, - { N_("No logon interdomain trust account"), NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT }, - { N_("No logon workstation trust account"), NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, - { N_("No logon server trust account"), NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT }, - { N_("Domain trust inconsistent"), NT_STATUS_DOMAIN_TRUST_INCONSISTENT }, - { N_("No user session key available"), NT_STATUS_NO_USER_SESSION_KEY }, - { N_("User session deleted"), NT_STATUS_USER_SESSION_DELETED }, - { N_("Insufficient server resources"), NT_STATUS_INSUFF_SERVER_RESOURCES }, - { N_("Insufficient logon information"), NT_STATUS_INSUFFICIENT_LOGON_INFO }, - - { N_("License quota exceeded"), NT_STATUS_LICENSE_QUOTA_EXCEEDED }, - { N_("No more files"), STATUS_NO_MORE_FILES }, - - { NULL, NT_STATUS(0) } -}; - -/***************************************************************************** - Returns an NT error message. not amazingly helpful, but better than a number. - *****************************************************************************/ - -const char *nt_errstr(NTSTATUS nt_code) -{ - static char msg[40]; - int idx = 0; - - while (nt_errs[idx].nt_errstr != NULL) { - if (NT_STATUS_V(nt_errs[idx].nt_errcode) == - NT_STATUS_V(nt_code)) { - return nt_errs[idx].nt_errstr; - } - idx++; - } - - if (NT_STATUS_IS_LDAP(nt_code)) { - slprintf(msg, sizeof(msg), "LDAP code %u", NT_STATUS_LDAP_CODE(nt_code)); - return msg; - } - - slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code)); - - return msg; -} - -/************************************************************************ - Print friendler version fo NT error code - ***********************************************************************/ - -const char *get_friendly_nt_error_msg(NTSTATUS nt_code) -{ - int idx = 0; - - while (nt_err_desc[idx].nt_errstr != NULL) { - if (NT_STATUS_V(nt_err_desc[idx].nt_errcode) == NT_STATUS_V(nt_code)) { - return nt_err_desc[idx].nt_errstr; - } - idx++; - } - - /* fall back to NT_STATUS_XXX string */ - - return nt_errstr(nt_code); -} - -/***************************************************************************** - Returns an NT_STATUS constant as a string for inclusion in autogen C code. - *****************************************************************************/ - -const char *get_nt_error_c_code(NTSTATUS nt_code) -{ - static char out[40]; - int idx = 0; - - while (nt_errs[idx].nt_errstr != NULL) { - if (NT_STATUS_V(nt_errs[idx].nt_errcode) == - NT_STATUS_V(nt_code)) { - return nt_errs[idx].nt_errstr; - } - idx++; - } - - slprintf(out, sizeof(out), "NT_STATUS(0x%08x)", NT_STATUS_V(nt_code)); - - return out; -} - -/***************************************************************************** - Returns the NT_STATUS constant matching the string supplied (as an NTSTATUS) - *****************************************************************************/ - -NTSTATUS nt_status_string_to_code(const char *nt_status_str) -{ - int idx = 0; - - while (nt_errs[idx].nt_errstr != NULL) { - if (strcasecmp(nt_errs[idx].nt_errstr, nt_status_str) == 0) { - return nt_errs[idx].nt_errcode; - } - idx++; - } - return NT_STATUS_UNSUCCESSFUL; -} - -/** - * Squash an NT_STATUS in line with security requirements. - * In an attempt to avoid giving the whole game away when users - * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and - * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations - * (session setups in particular). - * - * @param nt_status NTSTATUS input for squashing. - * @return the 'squashed' nt_status - **/ - -NTSTATUS nt_status_squash(NTSTATUS nt_status) -{ - if NT_STATUS_IS_OK(nt_status) { - return nt_status; - } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) { - /* Match WinXP and don't give the game away */ - return NT_STATUS_LOGON_FAILURE; - - } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) { - /* Match WinXP and don't give the game away */ - return NT_STATUS_LOGON_FAILURE; - } else { - return nt_status; - } -} diff --git a/source4/libcli/wbclient/wbclient.c b/source4/libcli/wbclient/wbclient.c index 5c4312cc66..4f50c10694 100644 --- a/source4/libcli/wbclient/wbclient.c +++ b/source4/libcli/wbclient/wbclient.c @@ -31,7 +31,7 @@ * \param */ struct wbc_context *wbc_init(TALLOC_CTX *mem_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, struct tevent_context *event_ctx) { struct wbc_context *ctx; diff --git a/source4/libcli/wbclient/wbclient.h b/source4/libcli/wbclient/wbclient.h index e7473e3e7b..1fa2f59c57 100644 --- a/source4/libcli/wbclient/wbclient.h +++ b/source4/libcli/wbclient/wbclient.h @@ -28,7 +28,7 @@ struct wbc_context { }; struct wbc_context *wbc_init(TALLOC_CTX *mem_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, struct tevent_context *event_ctx); struct composite_context *wbc_sids_to_xids_send(struct wbc_context *wbc_ctx, diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 842a35175e..c7f1ad07cb 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -136,8 +136,8 @@ NTSTATUS wrepl_socket_split_stream(struct wrepl_socket *wrepl_socket, const char *wrepl_best_ip(struct loadparm_context *lp_ctx, const char *peer_ip) { struct interface *ifaces; - load_interfaces(lp_ctx, lpcfg_interfaces(lp_ctx), &ifaces); - return iface_best_ip(ifaces, peer_ip); + load_interface_list(lp_ctx, lp_ctx, &ifaces); + return iface_list_best_ip(ifaces, peer_ip); } struct wrepl_connect_state { @@ -181,7 +181,7 @@ struct tevent_req *wrepl_connect_send(TALLOC_CTX *mem_ctx, our_ip, 0, &state->local_address); if (ret != 0) { - NTSTATUS status = map_nt_error_from_unix(errno); + NTSTATUS status = map_nt_error_from_unix_common(errno); tevent_req_nterror(req, status); return tevent_req_post(req, ev); } @@ -190,7 +190,7 @@ struct tevent_req *wrepl_connect_send(TALLOC_CTX *mem_ctx, peer_ip, WINS_REPLICATION_PORT, &state->remote_address); if (ret != 0) { - NTSTATUS status = map_nt_error_from_unix(errno); + NTSTATUS status = map_nt_error_from_unix_common(errno); tevent_req_nterror(req, status); return tevent_req_post(req, ev); } @@ -201,7 +201,7 @@ struct tevent_req *wrepl_connect_send(TALLOC_CTX *mem_ctx, wrepl_connect_trigger, NULL); if (!ok) { - tevent_req_nomem(NULL, req); + tevent_req_oom(req); return tevent_req_post(req, ev); } @@ -250,7 +250,7 @@ static void wrepl_connect_done(struct tevent_req *subreq) ret = tstream_inet_tcp_connect_recv(subreq, &sys_errno, state, &state->stream, NULL); if (ret != 0) { - NTSTATUS status = map_nt_error_from_unix(sys_errno); + NTSTATUS status = map_nt_error_from_unix_common(sys_errno); tevent_req_nterror(req, status); return; } @@ -382,7 +382,7 @@ struct tevent_req *wrepl_request_send(TALLOC_CTX *mem_ctx, wrepl_request_trigger, NULL); if (!ok) { - tevent_req_nomem(NULL, req); + tevent_req_oom(req); return tevent_req_post(req, ev); } @@ -443,7 +443,7 @@ static void wrepl_request_writev_done(struct tevent_req *subreq) ret = tstream_writev_recv(subreq, &sys_errno); TALLOC_FREE(subreq); if (ret == -1) { - NTSTATUS status = map_nt_error_from_unix(sys_errno); + NTSTATUS status = map_nt_error_from_unix_common(sys_errno); TALLOC_FREE(state->caller.wrepl_socket->stream); tevent_req_nterror(req, status); return; @@ -494,7 +494,7 @@ static void wrepl_request_disconnect_done(struct tevent_req *subreq) ret = tstream_disconnect_recv(subreq, &sys_errno); TALLOC_FREE(subreq); if (ret == -1) { - NTSTATUS status = map_nt_error_from_unix(sys_errno); + NTSTATUS status = map_nt_error_from_unix_common(sys_errno); TALLOC_FREE(state->caller.wrepl_socket->stream); tevent_req_nterror(req, status); return; diff --git a/source4/libcli/wscript_build b/source4/libcli/wscript_build index fbe13ea8e9..1799bcabad 100644 --- a/source4/libcli/wscript_build +++ b/source4/libcli/wscript_build @@ -3,15 +3,6 @@ bld.RECURSE('ldap') bld.RECURSE('wbclient') -bld.SAMBA_LIBRARY('errors', - source='../../libcli/util/doserr.c util/errormap.c util/nterr.c', - public_headers='../../libcli/util/error.h ../../libcli/util/ntstatus.h ../../libcli/util/doserr.h ../../libcli/util/werror.h', - header_path='core', - deps='talloc', - private_library=True - ) - - bld.SAMBA_SUBSYSTEM('LIBSAMBA_TSOCKET', source='../../libcli/util/tstream.c', public_deps='LIBTSOCKET UTIL_TEVENT' @@ -36,8 +27,8 @@ bld.SAMBA_SUBSYSTEM('LIBCLI_COMPOSITE', bld.SAMBA_SUBSYSTEM('LIBCLI_SMB_COMPOSITE', source='smb_composite/loadfile.c smb_composite/savefile.c smb_composite/connect.c smb_composite/sesssetup.c smb_composite/fetchfile.c smb_composite/appendacl.c smb_composite/fsinfo.c smb_composite/smb2.c', autoproto='smb_composite/proto.h', - deps='LIBCLI_SMB2', - public_deps='LIBCLI_COMPOSITE credentials gensec LIBCLI_RESOLVE' + deps='LIBCLI_SMB2 UTIL_TEVENT', + public_deps='LIBCLI_COMPOSITE credentials gensec LIBCLI_RESOLVE tevent' ) @@ -83,11 +74,12 @@ bld.SAMBA_SUBSYSTEM('LIBCLI_SMB', ) -bld.SAMBA_SUBSYSTEM('LIBCLI_RAW', +bld.SAMBA_LIBRARY('LIBCLI_RAW', source='raw/rawfile.c raw/smb_signing.c raw/clisocket.c raw/clitransport.c raw/clisession.c raw/clitree.c raw/clierror.c raw/rawrequest.c raw/rawreadwrite.c raw/rawsearch.c raw/rawsetfileinfo.c raw/raweas.c raw/rawtrans.c raw/clioplock.c raw/rawnegotiate.c raw/rawfsinfo.c raw/rawfileinfo.c raw/rawnotify.c raw/rawioctl.c raw/rawacl.c raw/rawdate.c raw/rawlpq.c raw/rawshadow.c', autoproto='raw/raw_proto.h', public_deps='samba_socket LIBPACKET LIBCRYPTO', - deps='LIBCLI_COMPOSITE LIBCLI_RESOLVE security ndr samba-util errors CHARSET talloc LIBCLI_SMB_COMPOSITE tevent NDR_NBT_BUF LIBCLI_SMB_COMMON' + deps='LIBCLI_COMPOSITE LIBCLI_RESOLVE security ndr samba-util errors CHARSET talloc LIBCLI_SMB_COMPOSITE tevent NDR_NBT_BUF LIBCLI_SMB_COMMON', + private_library=True ) bld.RECURSE('smb2') diff --git a/source4/libnet/libnet.c b/source4/libnet/libnet.c index 53ebb9e34a..32df85d527 100644 --- a/source4/libnet/libnet.c +++ b/source4/libnet/libnet.c @@ -43,7 +43,7 @@ struct libnet_context *libnet_context_init(struct tevent_context *ev, ctx->lp_ctx = lp_ctx; /* make sure dcerpc is initialized */ - dcerpc_init(lp_ctx); + dcerpc_init(); /* name resolution methods */ ctx->resolve_ctx = lpcfg_resolve_context(lp_ctx); diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c index a68f4c5ea0..4d845ca1f0 100644 --- a/source4/libnet/libnet_become_dc.c +++ b/source4/libnet/libnet_become_dc.c @@ -769,7 +769,7 @@ static void becomeDC_send_cldap(struct libnet_BecomeDC_state *s) lpcfg_cldap_port(s->libnet->lp_ctx), &dest_address); if (ret != 0) { - c->status = map_nt_error_from_unix(errno); + c->status = map_nt_error_from_unix_common(errno); if (!composite_is_ok(c)) return; } diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 6e76df43e3..a1124fdd62 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -889,9 +889,9 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } -static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, - TALLOC_CTX *mem_ctx, - struct libnet_Join *r) +NTSTATUS libnet_Join_member(struct libnet_context *ctx, + TALLOC_CTX *mem_ctx, + struct libnet_Join_member *r) { NTSTATUS status; TALLOC_CTX *tmp_mem; @@ -916,15 +916,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, return NT_STATUS_NO_MEMORY; } - if (r->in.join_type == SEC_CHAN_BDC) { - acct_type = ACB_SVRTRUST; - } else if (r->in.join_type == SEC_CHAN_WKSTA) { - acct_type = ACB_WSTRUST; - } else { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_INVALID_PARAMETER; - } + acct_type = ACB_WSTRUST; if (r->in.netbios_name != NULL) { netbios_name = r->in.netbios_name; @@ -972,7 +964,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, set_secrets->domain_name = r2->out.domain_name; set_secrets->realm = r2->out.realm; set_secrets->netbios_name = netbios_name; - set_secrets->secure_channel_type = r->in.join_type; + set_secrets->secure_channel_type = SEC_CHAN_WKSTA; set_secrets->machine_password = r2->out.join_password; set_secrets->key_version_number = r2->out.kvno; set_secrets->domain_sid = r2->out.domain_sid; @@ -996,21 +988,3 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, return NT_STATUS_OK; } -NTSTATUS libnet_Join(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_Join *r) -{ - switch (r->in.join_type) { - case SEC_CHAN_WKSTA: - return libnet_Join_primary_domain(ctx, mem_ctx, r); - case SEC_CHAN_BDC: - return libnet_Join_primary_domain(ctx, mem_ctx, r); - case SEC_CHAN_DOMAIN: - case SEC_CHAN_DNS_DOMAIN: - case SEC_CHAN_NULL: - break; - } - - r->out.error_string = talloc_asprintf(mem_ctx, - "Invalid join type specified (%08X) attempting to join domain %s", - r->in.join_type, r->in.domain_name); - return NT_STATUS_INVALID_PARAMETER; -} diff --git a/source4/libnet/libnet_join.h b/source4/libnet/libnet_join.h index 79884130d8..6acf374b38 100644 --- a/source4/libnet/libnet_join.h +++ b/source4/libnet/libnet_join.h @@ -63,11 +63,10 @@ struct libnet_JoinDomain { } out; }; -struct libnet_Join { +struct libnet_Join_member { struct { const char *domain_name; const char *netbios_name; - enum netr_SchannelType join_type; enum libnet_Join_level level; } in; diff --git a/source4/libnet/libnet_rpc.c b/source4/libnet/libnet_rpc.c index e0781c3816..8aacfc398a 100644 --- a/source4/libnet/libnet_rpc.c +++ b/source4/libnet/libnet_rpc.c @@ -109,6 +109,10 @@ static struct composite_context* libnet_RpcConnectSrv_send(struct libnet_context case LIBNET_RPC_CONNECT_SERVER: case LIBNET_RPC_CONNECT_SERVER_ADDRESS: b->flags = r->in.dcerpc_flags; + break; + default: + /* other types have already been checked before */ + break; } if (DEBUGLEVEL >= 10) { diff --git a/source4/libnet/libnet_site.c b/source4/libnet/libnet_site.c index 9bfca74a36..a74dd59a22 100644 --- a/source4/libnet/libnet_site.c +++ b/source4/libnet/libnet_site.c @@ -64,7 +64,7 @@ NTSTATUS libnet_FindSite(TALLOC_CTX *ctx, struct libnet_context *lctx, struct li &dest_address); if (ret != 0) { r->out.error_string = NULL; - status = map_nt_error_from_unix(errno); + status = map_nt_error_from_unix_common(errno); return status; } @@ -168,7 +168,9 @@ NTSTATUS libnet_JoinSite(struct libnet_context *ctx, } make_nbt_name_client(&name, libnet_r->out.samr_binding->host); - status = resolve_name(lpcfg_resolve_context(ctx->lp_ctx), &name, r, &dest_addr, ctx->event_ctx); + status = resolve_name_ex(lpcfg_resolve_context(ctx->lp_ctx), + 0, 0, + &name, r, &dest_addr, ctx->event_ctx); if (!NT_STATUS_IS_OK(status)) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); diff --git a/source4/libnet/libnet_unbecome_dc.c b/source4/libnet/libnet_unbecome_dc.c index 4bffc5079e..85d47a91f9 100644 --- a/source4/libnet/libnet_unbecome_dc.c +++ b/source4/libnet/libnet_unbecome_dc.c @@ -277,7 +277,7 @@ static void unbecomeDC_send_cldap(struct libnet_UnbecomeDC_state *s) lpcfg_cldap_port(s->libnet->lp_ctx), &dest_address); if (ret != 0) { - c->status = map_nt_error_from_unix(errno); + c->status = map_nt_error_from_unix_common(errno); if (!composite_is_ok(c)) return; } diff --git a/source4/libnet/py_net.c b/source4/libnet/py_net.c index b7f7d9eaaf..ffcd60da27 100644 --- a/source4/libnet/py_net.c +++ b/source4/libnet/py_net.c @@ -41,17 +41,17 @@ typedef struct { struct tevent_context *ev; } py_net_Object; -static PyObject *py_net_join(py_net_Object *self, PyObject *args, PyObject *kwargs) +static PyObject *py_net_join_member(py_net_Object *self, PyObject *args, PyObject *kwargs) { - struct libnet_Join r; + struct libnet_Join_member r; NTSTATUS status; PyObject *result; TALLOC_CTX *mem_ctx; - const char *kwnames[] = { "domain_name", "netbios_name", "join_type", "level", NULL }; + const char *kwnames[] = { "domain_name", "netbios_name", "level", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ssii:Join", discard_const_p(char *, kwnames), + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ssi:Join", discard_const_p(char *, kwnames), &r.in.domain_name, &r.in.netbios_name, - &r.in.join_type, &r.in.level)) + &r.in.level)) return NULL; mem_ctx = talloc_new(self->mem_ctx); @@ -60,7 +60,7 @@ static PyObject *py_net_join(py_net_Object *self, PyObject *args, PyObject *kwar return NULL; } - status = libnet_Join(self->libnet_ctx, mem_ctx, &r); + status = libnet_Join_member(self->libnet_ctx, mem_ctx, &r); if (NT_STATUS_IS_ERR(status)) { PyErr_SetString(PyExc_RuntimeError, r.out.error_string?r.out.error_string:nt_errstr(status)); talloc_free(mem_ctx); @@ -76,7 +76,7 @@ static PyObject *py_net_join(py_net_Object *self, PyObject *args, PyObject *kwar return result; } -static const char py_net_join_doc[] = "join(domain_name, netbios_name, join_type, level) -> (join_password, domain_sid, domain_name)\n\n" \ +static const char py_net_join_member_doc[] = "join_member(domain_name, netbios_name, level) -> (join_password, domain_sid, domain_name)\n\n" \ "Join the domain with the specified name."; static PyObject *py_net_set_password(py_net_Object *self, PyObject *args, PyObject *kwargs) @@ -526,7 +526,7 @@ static const char py_net_finddc_doc[] = "finddc(domain, server_type)\n" "find a DC with the specified server_type bits. Return the DNS name"; static PyMethodDef net_obj_methods[] = { - {"join", (PyCFunction)py_net_join, METH_VARARGS|METH_KEYWORDS, py_net_join_doc}, + {"join_member", (PyCFunction)py_net_join_member, METH_VARARGS|METH_KEYWORDS, py_net_join_member_doc}, {"set_password", (PyCFunction)py_net_set_password, METH_VARARGS|METH_KEYWORDS, py_net_set_password_doc}, {"export_keytab", (PyCFunction)py_net_export_keytab, METH_VARARGS|METH_KEYWORDS, py_net_export_keytab_doc}, {"time", (PyCFunction)py_net_time, METH_VARARGS|METH_KEYWORDS, py_net_time_doc}, diff --git a/source4/librpc/idl/opendb.idl b/source4/librpc/idl/opendb.idl index 4973cd0982..b76992960a 100644 --- a/source4/librpc/idl/opendb.idl +++ b/source4/librpc/idl/opendb.idl @@ -7,7 +7,7 @@ ntvfs/common/opendb.c */ -import "server_id4.idl"; +import "server_id.idl"; [ pointer_default(unique) diff --git a/source4/librpc/idl/s4_notify.idl b/source4/librpc/idl/s4_notify.idl deleted file mode 100644 index 89ade2991c..0000000000 --- a/source4/librpc/idl/s4_notify.idl +++ /dev/null @@ -1,58 +0,0 @@ -#include "idl_types.h" - -/* - IDL structures for notify change code - - this defines the structures used in the notify database code, and - the change notify buffers -*/ - -import "server_id4.idl"; - -[ - pointer_default(unique) -] -interface notify -{ - - /* structure used in the notify database */ - typedef [public] struct { - server_id server; - uint32 filter; /* filter to apply in this directory */ - uint32 subdir_filter; /* filter to apply in child directories */ - utf8string path; - uint32 path_len; /* saves some computation on search */ - pointer private_data; - } notify_entry; - - /* - to allow for efficient search for matching entries, we - divide them by the directory depth, with a separate array - per depth. The entries within each depth are sorted by path, - allowing for a bisection search. - - The max_mask and max_mask_subdir at each depth is the - bitwise or of the filters and subdir filters for all entries - at that depth. This allows a depth to be quickly skipped if - no entries will match the target filter - */ - typedef struct { - uint32 max_mask; - uint32 max_mask_subdir; - uint32 num_entries; - notify_entry entries[num_entries]; - } notify_depth; - - typedef [public] struct { - uint32 num_depths; - notify_depth depth[num_depths]; - } notify_array; - - /* structure sent between servers in notify messages */ - typedef [public] struct { - uint32 action; - utf8string path; - pointer private_data; - } notify_event; - -} diff --git a/source4/librpc/idl/server_id4.idl b/source4/librpc/idl/server_id4.idl deleted file mode 100644 index 486143546b..0000000000 --- a/source4/librpc/idl/server_id4.idl +++ /dev/null @@ -1,12 +0,0 @@ -[ - pointer_default(unique) -] -interface server_id -{ - /* id used to identify a endpoint, possibly in a cluster */ - typedef [public] struct { - hyper id; - uint32 id2; - uint32 node; - } server_id; -} diff --git a/source4/librpc/idl/wscript_build b/source4/librpc/idl/wscript_build index 6fe3690b33..59b16766ea 100644 --- a/source4/librpc/idl/wscript_build +++ b/source4/librpc/idl/wscript_build @@ -5,8 +5,8 @@ import os topinclude=os.path.join(bld.srcnode.abspath(), 'librpc/idl') bld.SAMBA_PIDL_LIST('PIDL', - source='''irpc.idl nfs4acl.idl s4_notify.idl ntp_signd.idl - opendb.idl sasl_helpers.idl server_id4.idl winbind.idl + source='''irpc.idl nfs4acl.idl ntp_signd.idl + opendb.idl sasl_helpers.idl winbind.idl winsif.idl winsrepl.idl winstation.idl''', options="--includedir=%s --header --ndr-parser --client --python --server" % topinclude, output_dir='../gen_ndr') diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index cc72866866..110da57c93 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -76,9 +76,9 @@ struct rpc_request { } async; }; -_PUBLIC_ NTSTATUS dcerpc_init(struct loadparm_context *lp_ctx) +_PUBLIC_ NTSTATUS dcerpc_init(void) { - return gensec_init(lp_ctx); + return gensec_init(); } static void dcerpc_connection_dead(struct dcecli_connection *conn, NTSTATUS status); diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index 5ca6246343..22afdf880f 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -198,7 +198,7 @@ NTSTATUS dcerpc_bind_auth_schannel(TALLOC_CTX *tmp_ctx, struct loadparm_context *lp_ctx, uint8_t auth_level); struct tevent_context *dcerpc_event_context(struct dcerpc_pipe *p); -NTSTATUS dcerpc_init(struct loadparm_context *lp_ctx); +NTSTATUS dcerpc_init(void); struct smbcli_tree *dcerpc_smb_tree(struct dcecli_connection *c); uint16_t dcerpc_smb_fnum(struct dcecli_connection *c); NTSTATUS dcerpc_secondary_context(struct dcerpc_pipe *p, diff --git a/source4/librpc/rpc/dcerpc_connect.c b/source4/librpc/rpc/dcerpc_connect.c index 842ef43206..c236399b52 100644 --- a/source4/librpc/rpc/dcerpc_connect.c +++ b/source4/librpc/rpc/dcerpc_connect.c @@ -186,16 +186,18 @@ static void continue_pipe_open_smb2(struct composite_context *ctx) /* Stage 2 of ncacn_np_smb2: Open a named pipe after successful smb2 connection */ -static void continue_smb2_connect(struct composite_context *ctx) +static void continue_smb2_connect(struct tevent_req *subreq) { struct composite_context *open_req; - struct composite_context *c = talloc_get_type(ctx->async.private_data, - struct composite_context); + struct composite_context *c = + tevent_req_callback_data(subreq, + struct composite_context); struct pipe_np_smb2_state *s = talloc_get_type(c->private_data, struct pipe_np_smb2_state); /* receive result of smb2 connect request */ - c->status = smb2_connect_recv(ctx, c, &s->tree); + c->status = smb2_connect_recv(subreq, c, &s->tree); + TALLOC_FREE(subreq); if (!composite_is_ok(c)) return; /* prepare named pipe open parameters */ @@ -220,7 +222,7 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb2_send( { struct composite_context *c; struct pipe_np_smb2_state *s; - struct composite_context *conn_req; + struct tevent_req *subreq; struct smbcli_options options; /* composite context allocation and setup */ @@ -247,17 +249,17 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb2_send( lpcfg_smbcli_options(lp_ctx, &options); /* send smb2 connect request */ - conn_req = smb2_connect_send(mem_ctx, s->io.binding->host, + subreq = smb2_connect_send(s, c->event_ctx, + s->io.binding->host, lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "smb2", "ports", NULL), - "IPC$", - s->io.resolve_ctx, - s->io.creds, - c->event_ctx, - &options, - lpcfg_socket_options(lp_ctx), - lpcfg_gensec_settings(mem_ctx, lp_ctx) - ); - composite_continue(c, conn_req, continue_smb2_connect, c); + "IPC$", + s->io.resolve_ctx, + s->io.creds, + &options, + lpcfg_socket_options(lp_ctx), + lpcfg_gensec_settings(mem_ctx, lp_ctx)); + if (composite_nomem(subreq, c)) return c; + tevent_req_set_callback(subreq, continue_smb2_connect, c); return c; } diff --git a/source4/librpc/rpc/dcerpc_sock.c b/source4/librpc/rpc/dcerpc_sock.c index f0451ac674..1dd993d94b 100644 --- a/source4/librpc/rpc/dcerpc_sock.c +++ b/source4/librpc/rpc/dcerpc_sock.c @@ -371,10 +371,7 @@ struct pipe_tcp_state { }; -#if 0 /* disabled till we can resolve names to ipv6 addresses */ -static void continue_ipv6_open_socket(struct composite_context *ctx); -#endif -static void continue_ipv4_open_socket(struct composite_context *ctx); +static void continue_ip_open_socket(struct composite_context *ctx); static void continue_ip_resolve_name(struct composite_context *ctx); static void continue_ip_resolve_name(struct composite_context *ctx) @@ -383,62 +380,28 @@ static void continue_ip_resolve_name(struct composite_context *ctx) struct composite_context); struct pipe_tcp_state *s = talloc_get_type(c->private_data, struct pipe_tcp_state); - struct composite_context *sock_ipv4_req; + struct composite_context *sock_ip_req; c->status = resolve_name_recv(ctx, s, &s->address); if (!composite_is_ok(c)) return; /* prepare server address using host ip:port and transport name */ - s->srvaddr = socket_address_from_strings(s->conn, "ipv4", s->address, s->port); + s->srvaddr = socket_address_from_strings(s->conn, "ip", s->address, s->port); if (composite_nomem(s->srvaddr, c)) return; - /* resolve_nbt_name gives only ipv4 ... - send socket open request */ - sock_ipv4_req = dcerpc_pipe_open_socket_send(c, s->conn, s->localaddr, + sock_ip_req = dcerpc_pipe_open_socket_send(c, s->conn, s->localaddr, s->srvaddr, s->target_hostname, NULL, NCACN_IP_TCP); - composite_continue(c, sock_ipv4_req, continue_ipv4_open_socket, c); + composite_continue(c, sock_ip_req, continue_ip_open_socket, c); } -/* - Stage 2 of dcerpc_pipe_open_tcp_send: receive result of pipe open request - on IPv6 and send the request on IPv4 unless IPv6 transport succeeded. -*/ -#if 0 /* disabled till we can resolve names to ipv6 addresses */ -static void continue_ipv6_open_socket(struct composite_context *ctx) -{ - struct composite_context *c = talloc_get_type(ctx->async.private_data, - struct composite_context); - struct pipe_tcp_state *s = talloc_get_type(c->private_data, - struct pipe_tcp_state); - struct composite_context *sock_ipv4_req; - - /* receive result of socket open request */ - c->status = dcerpc_pipe_open_socket_recv(ctx); - if (NT_STATUS_IS_OK(c->status)) { - composite_done(c); - return; - } - - talloc_free(s->srvaddr); - - /* prepare server address using host:ip and transport name */ - s->srvaddr = socket_address_from_strings(s->conn, "ipv4", s->address, s->port); - if (composite_nomem(s->srvaddr, c)) return; - - /* try IPv4 if IPv6 fails */ - sock_ipv4_req = dcerpc_pipe_open_socket_send(c, s->conn, s->localaddr, - s->srvaddr, s->target_hostname, - NCACN_IP_TCP); - composite_continue(c, sock_ipv4_req, continue_ipv4_open_socket, c); -} -#endif /* Stage 2 of dcerpc_pipe_open_tcp_send: receive result of pipe open request - on IPv4 transport. + on IP transport. */ -static void continue_ipv4_open_socket(struct composite_context *ctx) +static void continue_ip_open_socket(struct composite_context *ctx) { struct composite_context *c = talloc_get_type(ctx->async.private_data, struct composite_context); diff --git a/source4/librpc/rpc/pyrpc_util.c b/source4/librpc/rpc/pyrpc_util.c index 3821638fb3..385acc87e5 100644 --- a/source4/librpc/rpc/pyrpc_util.c +++ b/source4/librpc/rpc/pyrpc_util.c @@ -72,9 +72,9 @@ static NTSTATUS pyrpc_irpc_connect(TALLOC_CTX *mem_ctx, const char *irpc_server, struct loadparm_context *lp_ctx, struct dcerpc_binding_handle **binding_handle) { - struct messaging_context *msg; + struct imessaging_context *msg; - msg = messaging_client_init(mem_ctx, lpcfg_messaging_path(mem_ctx, lp_ctx), event_ctx); + msg = imessaging_client_init(mem_ctx, lpcfg_imessaging_path(mem_ctx, lp_ctx), event_ctx); NT_STATUS_HAVE_NO_MEMORY(msg); *binding_handle = irpc_binding_handle_by_name(mem_ctx, msg, irpc_server, table); @@ -119,7 +119,7 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py return NULL; } - status = dcerpc_init(lp_ctx); + status = dcerpc_init(); if (!NT_STATUS_IS_OK(status)) { PyErr_SetNTSTATUS(status); talloc_free(mem_ctx); diff --git a/source4/librpc/wscript_build b/source4/librpc/wscript_build index ce015ccaa5..39541b6a33 100755 --- a/source4/librpc/wscript_build +++ b/source4/librpc/wscript_build @@ -4,13 +4,6 @@ bld.RECURSE('../../librpc/idl') bld.RECURSE('../../librpc/tools') bld.RECURSE('idl') -bld.SAMBA_SUBSYSTEM('NDR_SERVER_ID4', - source='gen_ndr/ndr_server_id4.c', - deps='ndr', - public_headers='gen_ndr/server_id4.h', - header_path='gen_ndr' - ) - bld.SAMBA_SUBSYSTEM('NDR_WINSTATION', source='gen_ndr/ndr_winstation.c', @@ -50,12 +43,6 @@ bld.SAMBA_SUBSYSTEM('NDR_OPENDB', ) -bld.SAMBA_SUBSYSTEM('NDR_NOTIFY', - source='gen_ndr/ndr_s4_notify.c', - public_deps='ndr NDR_SERVER_ID4' - ) - - bld.SAMBA_SUBSYSTEM('NDR_NTP_SIGND', source='gen_ndr/ndr_ntp_signd.c', public_deps='ndr' @@ -76,7 +63,7 @@ bld.SAMBA_SUBSYSTEM('NDR_WINBIND', # create a grouping library to consolidate our samba4 specific NDR code bld.SAMBA_LIBRARY('ndr-samba4', source=[], - deps='NDR_WINBIND NDR_IRPC NDR_NFS4ACL NDR_OPENDB NDR_NOTIFY ndr-table', + deps='NDR_WINBIND NDR_IRPC NDR_NFS4ACL NDR_OPENDB ndr-table', private_library=True, grouping_library=True ) @@ -92,11 +79,6 @@ bld.SAMBA_LIBRARY('dcerpc-samba4', bld.SAMBA_PIDL_TABLES('GEN_NDR_TABLES', 'gen_ndr/tables.c') -if bld.env.enable_s3build: - s3_ndr = "NDR_WBINT" -else: - s3_ndr = "" - bld.SAMBA_SUBSYSTEM('ndr-table', source='../../librpc/ndr/ndr_table.c gen_ndr/tables.c', public_deps='''ndr-standard NDR_AUDIOSRV NDR_DSBACKUP NDR_EFS @@ -109,7 +91,7 @@ bld.SAMBA_SUBSYSTEM('ndr-table', NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND NDR_FRSRPC NDR_FRSAPI NDR_FRSTRANS NDR_NFS4ACL NDR_NTP_SIGND NDR_DCOM NDR_WMI NDR_NAMED_PIPE_AUTH NDR_NTLMSSP NDR_DFSBLOBS NDR_DNSP - NDR_NTPRINTING NDR_DNS NDR_BACKUPKEY NDR_PREG ''' + s3_ndr, + NDR_NTPRINTING NDR_DNS NDR_BACKUPKEY NDR_PREG NDR_WBINT''', depends_on='GEN_NDR_TABLES' ) diff --git a/source4/nbt_server/interfaces.c b/source4/nbt_server/interfaces.c index bd2143e26c..ccbc89accf 100644 --- a/source4/nbt_server/interfaces.c +++ b/source4/nbt_server/interfaces.c @@ -276,7 +276,7 @@ static NTSTATUS nbtd_add_wins_socket(struct nbtd_server *nbtsrv) NTSTATUS nbtd_startup_interfaces(struct nbtd_server *nbtsrv, struct loadparm_context *lp_ctx, struct interface *ifaces) { - int num_interfaces = iface_count(ifaces); + int num_interfaces = iface_list_count(ifaces); int i; TALLOC_CTX *tmp_ctx = talloc_new(nbtsrv); NTSTATUS status; @@ -286,15 +286,16 @@ NTSTATUS nbtd_startup_interfaces(struct nbtd_server *nbtsrv, struct loadparm_con if (!lpcfg_bind_interfaces_only(lp_ctx)) { const char *primary_address; + primary_address = iface_list_first_v4(ifaces); + /* the primary address is the address we will return for non-WINS queries not made on a specific interface */ - if (num_interfaces > 0) { - primary_address = iface_n_ip(ifaces, 0); - } else { + if (primary_address == NULL) { primary_address = inet_ntoa(interpret_addr2( - lpcfg_netbios_name(lp_ctx))); + lpcfg_netbios_name(lp_ctx))); } + primary_address = talloc_strdup(tmp_ctx, primary_address); NT_STATUS_HAVE_NO_MEMORY(primary_address); @@ -308,15 +309,21 @@ NTSTATUS nbtd_startup_interfaces(struct nbtd_server *nbtsrv, struct loadparm_con } for (i=0; i<num_interfaces; i++) { - const char *bcast = iface_n_bcast(ifaces, i); + const char *bcast; const char *address, *netmask; + if (!iface_list_n_is_v4(ifaces, i)) { + /* v4 only for NBT protocol */ + continue; + } + + bcast = iface_list_n_bcast(ifaces, i); /* we can't assume every interface is broadcast capable */ if (bcast == NULL) continue; - address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i)); + address = talloc_strdup(tmp_ctx, iface_list_n_ip(ifaces, i)); bcast = talloc_strdup(tmp_ctx, bcast); - netmask = talloc_strdup(tmp_ctx, iface_n_netmask(ifaces, i)); + netmask = talloc_strdup(tmp_ctx, iface_list_n_netmask(ifaces, i)); status = nbtd_add_socket(nbtsrv, lp_ctx, address, address, bcast, netmask); @@ -346,7 +353,7 @@ const char **nbtd_address_list(struct nbtd_interface *iface, TALLOC_CTX *mem_ctx bool is_loopback = false; if (iface->ip_address) { - is_loopback = iface_same_net(iface->ip_address, "127.0.0.1", "255.0.0.0"); + is_loopback = iface_list_same_net(iface->ip_address, "127.0.0.1", "255.0.0.0"); ret = str_list_add(ret, iface->ip_address); } @@ -356,7 +363,7 @@ const char **nbtd_address_list(struct nbtd_interface *iface, TALLOC_CTX *mem_ctx if (!iface2->ip_address) continue; if (!is_loopback) { - if (iface_same_net(iface2->ip_address, "127.0.0.1", "255.0.0.0")) { + if (iface_list_same_net(iface2->ip_address, "127.0.0.1", "255.0.0.0")) { continue; } } @@ -380,7 +387,7 @@ struct nbtd_interface *nbtd_find_request_iface(struct nbtd_server *nbtd_server, /* try to find a exact match */ for (cur=nbtd_server->interfaces;cur;cur=cur->next) { - if (iface_same_net(address, cur->ip_address, cur->netmask)) { + if (iface_list_same_net(address, cur->ip_address, cur->netmask)) { DEBUG(10,("find interface for dst[%s] ip: %s/%s (iface[%p])\n", address, cur->ip_address, cur->netmask, cur)); return cur; diff --git a/source4/nbt_server/nbt_server.c b/source4/nbt_server/nbt_server.c index 6dbdaf9f54..175ad5e4a4 100644 --- a/source4/nbt_server/nbt_server.c +++ b/source4/nbt_server/nbt_server.c @@ -41,9 +41,9 @@ static void nbtd_task_init(struct task_server *task) NTSTATUS status; struct interface *ifaces; - load_interfaces(task, lpcfg_interfaces(task->lp_ctx), &ifaces); + load_interface_list(task, task->lp_ctx, &ifaces); - if (iface_count(ifaces) == 0) { + if (iface_list_count(ifaces) == 0) { task_server_terminate(task, "nbtd: no network interfaces configured", false); return; } diff --git a/source4/nbt_server/wins/wins_ldb.c b/source4/nbt_server/wins/wins_ldb.c index 0896e1d74e..304c98d803 100644 --- a/source4/nbt_server/wins/wins_ldb.c +++ b/source4/nbt_server/wins/wins_ldb.c @@ -92,8 +92,8 @@ static int wins_ldb_init(struct ldb_module *module) owner = lpcfg_parm_string(lp_ctx, NULL, "winsdb", "local_owner"); if (!owner) { struct interface *ifaces; - load_interfaces(module, lpcfg_interfaces(lp_ctx), &ifaces); - owner = iface_n_ip(ifaces, 0); + load_interface_list(module, lp_ctx, &ifaces); + owner = iface_list_first_v4(ifaces); if (!owner) { owner = "0.0.0.0"; } diff --git a/source4/nbt_server/wins/winsdb.c b/source4/nbt_server/wins/winsdb.c index 791ce957c7..4a1486092b 100644 --- a/source4/nbt_server/wins/winsdb.c +++ b/source4/nbt_server/wins/winsdb.c @@ -975,7 +975,7 @@ static bool winsdb_check_or_add_module_list(struct tevent_context *ev_ctx, flags |= LDB_FLG_NOSYNC; } - h->ldb = ldb_wrap_connect(h, ev_ctx, lp_ctx, lock_path(h, lp_ctx, lpcfg_wins_url(lp_ctx)), + h->ldb = ldb_wrap_connect(h, ev_ctx, lp_ctx, lpcfg_lock_path(h, lp_ctx, lpcfg_wins_url(lp_ctx)), NULL, NULL, flags); if (!h->ldb) goto failed; @@ -1011,7 +1011,7 @@ struct winsdb_handle *winsdb_connect(TALLOC_CTX *mem_ctx, flags |= LDB_FLG_NOSYNC; } - h->ldb = ldb_wrap_connect(h, ev_ctx, lp_ctx, lock_path(h, lp_ctx, lpcfg_wins_url(lp_ctx)), + h->ldb = ldb_wrap_connect(h, ev_ctx, lp_ctx, lpcfg_lock_path(h, lp_ctx, lpcfg_wins_url(lp_ctx)), NULL, NULL, flags); if (!h->ldb) goto failed; diff --git a/source4/nbt_server/wins/winsserver.c b/source4/nbt_server/wins/winsserver.c index 1e6a0cfca8..5f1f41747f 100644 --- a/source4/nbt_server/wins/winsserver.c +++ b/source4/nbt_server/wins/winsserver.c @@ -688,7 +688,7 @@ static void nbtd_wins_randomize1Clist(struct loadparm_context *lp_ctx, bool same; /* if the current one is in the same subnet, use it */ - same = iface_same_net(addresses[idx], src->addr, mask); + same = iface_list_same_net(addresses[idx], src->addr, mask); if (same) { sidx = idx; break; @@ -1057,8 +1057,8 @@ NTSTATUS nbtd_winsserver_init(struct nbtd_server *nbtsrv) if (owner == NULL) { struct interface *ifaces; - load_interfaces(nbtsrv->task, lpcfg_interfaces(nbtsrv->task->lp_ctx), &ifaces); - owner = iface_n_ip(ifaces, 0); + load_interface_list(nbtsrv->task, nbtsrv->task->lp_ctx, &ifaces); + owner = iface_list_first_v4(ifaces); } nbtsrv->winssrv->wins_db = winsdb_connect(nbtsrv->winssrv, nbtsrv->task->event_ctx, diff --git a/source4/ntptr/ntptr_base.c b/source4/ntptr/ntptr_base.c index 268e84b127..42e7b10d4a 100644 --- a/source4/ntptr/ntptr_base.c +++ b/source4/ntptr/ntptr_base.c @@ -68,12 +68,12 @@ NTSTATUS ntptr_register(const void *_ops) return NT_STATUS_OK; } -NTSTATUS ntptr_init(struct loadparm_context *lp_ctx) +NTSTATUS ntptr_init(void) { #define _MODULE_PROTO(init) extern NTSTATUS init(void); STATIC_ntptr_MODULES_PROTO; init_module_fn static_init[] = { STATIC_ntptr_MODULES }; - init_module_fn *shared_init = load_samba_modules(NULL, lp_ctx, "ntptr"); + init_module_fn *shared_init = load_samba_modules(NULL, "ntptr"); run_init_functions(static_init); run_init_functions(shared_init); diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 27bf1ead24..91ca08d2de 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -99,10 +99,12 @@ NTSTATUS ntvfs_cifs_init(void); #define CIFS_DOMAIN "cifs:domain" #define CIFS_SHARE "cifs:share" #define CIFS_USE_MACHINE_ACCT "cifs:use-machine-account" +#define CIFS_USE_S4U2PROXY "cifs:use-s4u2proxy" #define CIFS_MAP_GENERIC "cifs:map-generic" #define CIFS_MAP_TRANS2 "cifs:map-trans2" #define CIFS_USE_MACHINE_ACCT_DEFAULT false +#define CIFS_USE_S4U2PROXY_DEFAULT false #define CIFS_MAP_GENERIC_DEFAULT false #define CIFS_MAP_TRANS2_DEFAULT true @@ -150,6 +152,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, struct cli_credentials *credentials; bool machine_account; + bool s4u2proxy; const char* sharename; switch (tcon->generic.level) { @@ -187,6 +190,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, } machine_account = share_bool_option(scfg, CIFS_USE_MACHINE_ACCT, CIFS_USE_MACHINE_ACCT_DEFAULT); + s4u2proxy = share_bool_option(scfg, CIFS_USE_S4U2PROXY, CIFS_USE_S4U2PROXY_DEFAULT); p = talloc_zero(ntvfs, struct cvfs_private); if (!p) { @@ -226,9 +230,54 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, } else if (req->session_info->credentials) { DEBUG(5, ("CIFS backend: Using delegated credentials\n")); credentials = req->session_info->credentials; + } else if (s4u2proxy) { + struct ccache_container *ccc = NULL; + const char *err_str = NULL; + int ret; + char *impersonate_principal; + char *self_service; + char *target_service; + + impersonate_principal = talloc_asprintf(req, "%s@%s", + req->session_info->info->account_name, + req->session_info->info->domain_name); + + self_service = talloc_asprintf(req, "cifs/%s", + lpcfg_netbios_name(ntvfs->ctx->lp_ctx)); + + target_service = talloc_asprintf(req, "cifs/%s", host); + + DEBUG(5, ("CIFS backend: Using S4U2Proxy credentials\n")); + + credentials = cli_credentials_init(p); + cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx); + if (domain) { + cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); + } + status = cli_credentials_set_machine_account(credentials, ntvfs->ctx->lp_ctx); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED); + cli_credentials_set_impersonate_principal(credentials, + impersonate_principal, + self_service); + cli_credentials_set_target_service(credentials, target_service); + ret = cli_credentials_get_ccache(credentials, + ntvfs->ctx->event_ctx, + ntvfs->ctx->lp_ctx, + &ccc, + &err_str); + if (ret != 0) { + status = NT_STATUS_CROSSREALM_DELEGATION_FAILURE; + DEBUG(1,("S4U2Proxy: cli_credentials_get_ccache() gave: ret[%d] str[%s] - %s\n", + ret, err_str, nt_errstr(status))); + return status; + } + } else { DEBUG(1,("CIFS backend: NO delegated credentials found: You must supply server, user and password or the client must supply delegated credentials\n")); - return NT_STATUS_INVALID_PARAMETER; + return NT_STATUS_INTERNAL_ERROR; } /* connect to the server, using the smbd event context */ diff --git a/source4/ntvfs/cifs_posix_cli/svfs_util.c b/source4/ntvfs/cifs_posix_cli/svfs_util.c index d8a7909390..f351c5840e 100644 --- a/source4/ntvfs/cifs_posix_cli/svfs_util.c +++ b/source4/ntvfs/cifs_posix_cli/svfs_util.c @@ -41,16 +41,15 @@ char *cifspsx_unix_path(struct ntvfs_module_context *ntvfs, { struct cifspsx_private *p = ntvfs->private_data; char *ret; + char *name_lower = strlower_talloc(p, name); if (*name != '\\') { - ret = talloc_asprintf(req, "%s/%s", p->connectpath, name); + ret = talloc_asprintf(req, "%s/%s", p->connectpath, name_lower); } else { - ret = talloc_asprintf(req, "%s%s", p->connectpath, name); + ret = talloc_asprintf(req, "%s%s", p->connectpath, name_lower); } all_string_sub(ret, "\\", "/", 0); - - strlower(ret + strlen(p->connectpath)); - + talloc_free(name_lower); return ret; } @@ -85,9 +84,8 @@ struct cifspsx_dir *cifspsx_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request /* the wildcard pattern is the last part */ mask = p+1; - low_mask = talloc_strdup(mem_ctx, mask); + low_mask = strlower_talloc(mem_ctx, mask); if (!low_mask) { return NULL; } - strlower(low_mask); odir = opendir(dir->unix_dir); if (!odir) { return NULL; } @@ -102,12 +100,11 @@ struct cifspsx_dir *cifspsx_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request continue; } - low_name = talloc_strdup(mem_ctx, dent->d_name); + low_name = strlower_talloc(mem_ctx, dent->d_name); if (!low_name) { continue; } - strlower(low_name); /* check it matches the wildcard pattern */ - if (ms_fnmatch(low_mask, low_name, PROTOCOL_NT1) != 0) { + if (ms_fnmatch_protocol(low_mask, low_name, PROTOCOL_NT1) != 0) { continue; } diff --git a/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c b/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c index 2a8c69e220..949b6dbbb7 100644 --- a/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c +++ b/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c @@ -150,7 +150,7 @@ static NTSTATUS cifspsx_unlink(struct ntvfs_module_context *ntvfs, /* ignoring wildcards ... */ if (unlink(unix_path) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } return NT_STATUS_OK; @@ -179,7 +179,7 @@ static NTSTATUS cifspsx_chkpath(struct ntvfs_module_context *ntvfs, unix_path = cifspsx_unix_path(ntvfs, req, cp->chkpath.in.path); if (stat(unix_path, &st) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } if (!S_ISDIR(st.st_mode)) { @@ -294,7 +294,7 @@ static NTSTATUS cifspsx_qpathinfo(struct ntvfs_module_context *ntvfs, DEBUG(19,("cifspsx_qpathinfo: file %s\n", unix_path)); if (stat(unix_path, &st) == -1) { DEBUG(19,("cifspsx_qpathinfo: file %s errno=%d\n", unix_path, errno)); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } DEBUG(19,("cifspsx_qpathinfo: file %s, stat done\n", unix_path)); return cifspsx_map_fileinfo(ntvfs, req, info, &st, unix_path); @@ -320,7 +320,7 @@ static NTSTATUS cifspsx_qfileinfo(struct ntvfs_module_context *ntvfs, } if (fstat(f->fd, &st) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } return cifspsx_map_fileinfo(ntvfs, req,info, &st, f->name); @@ -389,13 +389,13 @@ static NTSTATUS cifspsx_open(struct ntvfs_module_context *ntvfs, case NTCREATEX_DISP_CREATE: if (mkdir(unix_path, 0755) == -1) { DEBUG(9,("cifspsx_open: mkdir %s errno=%d\n", unix_path, errno)); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } break; case NTCREATEX_DISP_OPEN_IF: if (mkdir(unix_path, 0755) == -1 && errno != EEXIST) { DEBUG(9,("cifspsx_open: mkdir %s errno=%d\n", unix_path, errno)); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } break; } @@ -404,13 +404,13 @@ static NTSTATUS cifspsx_open(struct ntvfs_module_context *ntvfs, do_open: fd = open(unix_path, flags, 0644); if (fd == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } if (fstat(fd, &st) == -1) { DEBUG(9,("cifspsx_open: fstat errno=%d\n", errno)); close(fd); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } status = ntvfs_handle_new(ntvfs, req, &handle); @@ -459,7 +459,7 @@ static NTSTATUS cifspsx_mkdir(struct ntvfs_module_context *ntvfs, unix_path = cifspsx_unix_path(ntvfs, req, md->mkdir.in.path); if (mkdir(unix_path, 0777) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } return NT_STATUS_OK; @@ -478,7 +478,7 @@ static NTSTATUS cifspsx_rmdir(struct ntvfs_module_context *ntvfs, unix_path = cifspsx_unix_path(ntvfs, req, rd->in.path); if (rmdir(unix_path) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } return NT_STATUS_OK; @@ -502,7 +502,7 @@ static NTSTATUS cifspsx_rename(struct ntvfs_module_context *ntvfs, unix_path2 = cifspsx_unix_path(ntvfs, req, ren->rename.in.pattern2); if (rename(unix_path1, unix_path2) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } return NT_STATUS_OK; @@ -541,7 +541,7 @@ static NTSTATUS cifspsx_read(struct ntvfs_module_context *ntvfs, rd->readx.in.maxcnt, rd->readx.in.offset); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } rd->readx.out.nread = ret; @@ -577,7 +577,7 @@ static NTSTATUS cifspsx_write(struct ntvfs_module_context *ntvfs, wr->writex.in.count, wr->writex.in.offset); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } wr->writex.out.nwritten = ret; @@ -648,7 +648,7 @@ static NTSTATUS cifspsx_close(struct ntvfs_module_context *ntvfs, } if (close(f->fd) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } DLIST_REMOVE(p->open_files, f); @@ -738,7 +738,7 @@ static NTSTATUS cifspsx_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_END_OF_FILE_INFORMATION: if (ftruncate(f->fd, info->end_of_file_info.in.size) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } break; case RAW_SFILEINFO_SETATTRE: @@ -784,7 +784,7 @@ static NTSTATUS cifspsx_fsinfo(struct ntvfs_module_context *ntvfs, if (sys_fsusage(p->connectpath, &fs->generic.out.blocks_free, &fs->generic.out.blocks_total) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } fs->generic.out.block_size = 512; @@ -824,7 +824,7 @@ static NTSTATUS cifspsx_fsattr(struct ntvfs_module_context *ntvfs, } if (stat(p->connectpath, &st) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 94041d2014..a6232f8596 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -26,7 +26,7 @@ #include "includes.h" #include "system/filesys.h" -#include <tdb.h> +#include "tdb_compat.h" #include "messaging/messaging.h" #include "lib/messaging/irpc.h" #include "libcli/libcli.h" @@ -38,26 +38,26 @@ static const struct brlock_ops *ops; /* set the brl backend ops */ -void brl_set_ops(const struct brlock_ops *new_ops) +void brlock_set_ops(const struct brlock_ops *new_ops) { ops = new_ops; } /* Open up the brlock database. Close it down using talloc_free(). We - need the messaging_ctx to allow for pending lock notifications. + need the imessaging_ctx to allow for pending lock notifications. */ -struct brl_context *brl_init(TALLOC_CTX *mem_ctx, struct server_id server, +struct brl_context *brlock_init(TALLOC_CTX *mem_ctx, struct server_id server, struct loadparm_context *lp_ctx, - struct messaging_context *messaging_ctx) + struct imessaging_context *imessaging_ctx) { if (ops == NULL) { brl_tdb_init_ops(); } - return ops->brl_init(mem_ctx, server, lp_ctx, messaging_ctx); + return ops->brl_init(mem_ctx, server, lp_ctx, imessaging_ctx); } -struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, struct ntvfs_handle *ntvfs, DATA_BLOB *file_key) +struct brl_handle *brlock_create_handle(TALLOC_CTX *mem_ctx, struct ntvfs_handle *ntvfs, DATA_BLOB *file_key) { return ops->brl_create_handle(mem_ctx, ntvfs, file_key); } @@ -69,7 +69,7 @@ struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, struct ntvfs_handle *n someone else closing an overlapping lock range) a messaging notification is sent, identified by the notify_ptr */ -NTSTATUS brl_lock(struct brl_context *brl, +NTSTATUS brlock_lock(struct brl_context *brl, struct brl_handle *brlh, uint32_t smbpid, uint64_t start, uint64_t size, @@ -83,7 +83,7 @@ NTSTATUS brl_lock(struct brl_context *brl, /* Unlock a range of bytes. */ -NTSTATUS brl_unlock(struct brl_context *brl, +NTSTATUS brlock_unlock(struct brl_context *brl, struct brl_handle *brlh, uint32_t smbpid, uint64_t start, uint64_t size) @@ -96,7 +96,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, given up trying to establish a lock or when they have succeeded in getting it. In either case they no longer need to be notified. */ -NTSTATUS brl_remove_pending(struct brl_context *brl, +NTSTATUS brlock_remove_pending(struct brl_context *brl, struct brl_handle *brlh, void *notify_ptr) { @@ -107,7 +107,7 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, /* Test if we are allowed to perform IO on a region of an open file */ -NTSTATUS brl_locktest(struct brl_context *brl, +NTSTATUS brlock_locktest(struct brl_context *brl, struct brl_handle *brlh, uint32_t smbpid, uint64_t start, uint64_t size, @@ -120,7 +120,7 @@ NTSTATUS brl_locktest(struct brl_context *brl, /* Remove any locks associated with a open file. */ -NTSTATUS brl_close(struct brl_context *brl, +NTSTATUS brlock_close(struct brl_context *brl, struct brl_handle *brlh) { return ops->brl_close(brl, brlh); @@ -129,7 +129,7 @@ NTSTATUS brl_close(struct brl_context *brl, /* Get a number of locks associated with a open file. */ -NTSTATUS brl_count(struct brl_context *brl, +NTSTATUS brlock_count(struct brl_context *brl, struct brl_handle *brlh, int *count) { diff --git a/source4/ntvfs/common/brlock.h b/source4/ntvfs/common/brlock.h index e5e618d045..703538f073 100644 --- a/source4/ntvfs/common/brlock.h +++ b/source4/ntvfs/common/brlock.h @@ -24,7 +24,7 @@ struct brlock_ops { struct brl_context *(*brl_init)(TALLOC_CTX *, struct server_id , struct loadparm_context *lp_ctx, - struct messaging_context *); + struct imessaging_context *); struct brl_handle *(*brl_create_handle)(TALLOC_CTX *, struct ntvfs_handle *, DATA_BLOB *); NTSTATUS (*brl_lock)(struct brl_context *, struct brl_handle *, @@ -52,7 +52,7 @@ struct brlock_ops { }; -void brl_set_ops(const struct brlock_ops *new_ops); +void brlock_set_ops(const struct brlock_ops *new_ops); void brl_tdb_init_ops(void); void brl_ctdb_init_ops(void); diff --git a/source4/ntvfs/common/brlock_tdb.c b/source4/ntvfs/common/brlock_tdb.c index 35d4c27d0f..817448377c 100644 --- a/source4/ntvfs/common/brlock_tdb.c +++ b/source4/ntvfs/common/brlock_tdb.c @@ -26,9 +26,9 @@ #include "includes.h" #include "system/filesys.h" -#include <tdb.h> +#include "tdb_compat.h" #include "messaging/messaging.h" -#include "tdb_wrap.h" +#include "lib/util/tdb_wrap.h" #include "lib/messaging/irpc.h" #include "libcli/libcli.h" #include "cluster/cluster.h" @@ -48,7 +48,7 @@ struct brl_context { struct tdb_wrap *w; struct server_id server; - struct messaging_context *messaging_ctx; + struct imessaging_context *imessaging_ctx; }; /* @@ -89,12 +89,12 @@ static bool brl_invalid_lock_range(uint64_t start, uint64_t size) /* Open up the brlock.tdb database. Close it down using - talloc_free(). We need the messaging_ctx to allow for + talloc_free(). We need the imessaging_ctx to allow for pending lock notifications. */ static struct brl_context *brl_tdb_init(TALLOC_CTX *mem_ctx, struct server_id server, struct loadparm_context *lp_ctx, - struct messaging_context *messaging_ctx) + struct imessaging_context *imessaging_ctx) { struct brl_context *brl; @@ -110,7 +110,7 @@ static struct brl_context *brl_tdb_init(TALLOC_CTX *mem_ctx, struct server_id se } brl->server = server; - brl->messaging_ctx = messaging_ctx; + brl->imessaging_ctx = imessaging_ctx; return brl; } @@ -333,7 +333,7 @@ static NTSTATUS brl_tdb_lock(struct brl_context *brl, } } - dbuf = tdb_fetch(brl->w->tdb, kbuf); + dbuf = tdb_fetch_compat(brl->w->tdb, kbuf); lock.context.smbpid = smbpid; lock.context.server = brl->server; @@ -419,7 +419,7 @@ static void brl_tdb_notify_unlock(struct brl_context *brl, if (locks[i].lock_type == PENDING_WRITE_LOCK) { last_notice = i; } - messaging_send_ptr(brl->messaging_ctx, locks[i].context.server, + imessaging_send_ptr(brl->imessaging_ctx, locks[i].context.server, MSG_BRL_RETRY, locks[i].notify_ptr); } } @@ -468,7 +468,7 @@ static NTSTATUS brl_tdb_unlock(struct brl_context *brl, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - dbuf = tdb_fetch(brl->w->tdb, kbuf); + dbuf = tdb_fetch_compat(brl->w->tdb, kbuf); if (!dbuf.dptr) { tdb_chainunlock(brl->w->tdb, kbuf); return NT_STATUS_RANGE_NOT_LOCKED; @@ -568,7 +568,7 @@ static NTSTATUS brl_tdb_remove_pending(struct brl_context *brl, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - dbuf = tdb_fetch(brl->w->tdb, kbuf); + dbuf = tdb_fetch_compat(brl->w->tdb, kbuf); if (!dbuf.dptr) { tdb_chainunlock(brl->w->tdb, kbuf); return NT_STATUS_RANGE_NOT_LOCKED; @@ -639,7 +639,7 @@ static NTSTATUS brl_tdb_locktest(struct brl_context *brl, return NT_STATUS_INVALID_LOCK_RANGE; } - dbuf = tdb_fetch(brl->w->tdb, kbuf); + dbuf = tdb_fetch_compat(brl->w->tdb, kbuf); if (dbuf.dptr == NULL) { return NT_STATUS_OK; } @@ -686,7 +686,7 @@ static NTSTATUS brl_tdb_close(struct brl_context *brl, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - dbuf = tdb_fetch(brl->w->tdb, kbuf); + dbuf = tdb_fetch_compat(brl->w->tdb, kbuf); if (!dbuf.dptr) { tdb_chainunlock(brl->w->tdb, kbuf); return NT_STATUS_OK; @@ -751,7 +751,7 @@ static NTSTATUS brl_tdb_count(struct brl_context *brl, struct brl_handle *brlh, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - dbuf = tdb_fetch(brl->w->tdb, kbuf); + dbuf = tdb_fetch_compat(brl->w->tdb, kbuf); if (!dbuf.dptr) { tdb_chainunlock(brl->w->tdb, kbuf); return NT_STATUS_OK; @@ -779,5 +779,5 @@ static const struct brlock_ops brlock_tdb_ops = { void brl_tdb_init_ops(void) { - brl_set_ops(&brlock_tdb_ops); + brlock_set_ops(&brlock_tdb_ops); } diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 0b5f91bfe1..98f17a6565 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -25,12 +25,12 @@ #include "includes.h" #include "system/filesys.h" -#include <tdb.h> +#include "../lib/tdb_compat/tdb_compat.h" #include "../lib/util/util_tdb.h" #include "messaging/messaging.h" -#include "tdb_wrap.h" +#include "lib/util/tdb_wrap.h" #include "lib/messaging/irpc.h" -#include "librpc/gen_ndr/ndr_s4_notify.h" +#include "librpc/gen_ndr/ndr_notify.h" #include "../lib/util/dlinklist.h" #include "ntvfs/common/ntvfs_common.h" #include "ntvfs/sysdep/sys_notify.h" @@ -41,7 +41,7 @@ struct notify_context { struct tdb_wrap *w; struct server_id server; - struct messaging_context *messaging_ctx; + struct imessaging_context *imessaging_ctx; struct notify_list *list; struct notify_array *array; int seqnum; @@ -63,7 +63,7 @@ struct notify_list { #define NOTIFY_ENABLE_DEFAULT true static NTSTATUS notify_remove_all(struct notify_context *notify); -static void notify_handler(struct messaging_context *msg_ctx, void *private_data, +static void notify_handler(struct imessaging_context *msg_ctx, void *private_data, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data); /* @@ -71,18 +71,18 @@ static void notify_handler(struct messaging_context *msg_ctx, void *private_data */ static int notify_destructor(struct notify_context *notify) { - messaging_deregister(notify->messaging_ctx, MSG_PVFS_NOTIFY, notify); + imessaging_deregister(notify->imessaging_ctx, MSG_PVFS_NOTIFY, notify); notify_remove_all(notify); return 0; } /* Open up the notify.tdb database. You should close it down using - talloc_free(). We need the messaging_ctx to allow for notifications + talloc_free(). We need the imessaging_ctx to allow for notifications via internal messages */ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server, - struct messaging_context *messaging_ctx, + struct imessaging_context *imessaging_ctx, struct loadparm_context *lp_ctx, struct tevent_context *ev, struct share_config *scfg) @@ -109,7 +109,7 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server, } notify->server = server; - notify->messaging_ctx = messaging_ctx; + notify->imessaging_ctx = imessaging_ctx; notify->list = NULL; notify->array = NULL; notify->seqnum = tdb_get_seqnum(notify->w->tdb); @@ -118,7 +118,7 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server, /* register with the messaging subsystem for the notify message type */ - messaging_register(notify->messaging_ctx, notify, + imessaging_register(notify->imessaging_ctx, notify, MSG_PVFS_NOTIFY, notify_handler); notify->sys_notify_ctx = sys_notify_context_create(scfg, notify, ev); @@ -247,7 +247,7 @@ static NTSTATUS notify_save(struct notify_context *notify) /* handle incoming notify messages */ -static void notify_handler(struct messaging_context *msg_ctx, void *private_data, +static void notify_handler(struct imessaging_context *msg_ctx, void *private_data, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data) { struct notify_context *notify = talloc_get_type(private_data, struct notify_context); @@ -563,7 +563,7 @@ static void notify_send(struct notify_context *notify, struct notify_entry *e, return; } - status = messaging_send(notify->messaging_ctx, e->server, + status = imessaging_send(notify->imessaging_ctx, e->server, MSG_PVFS_NOTIFY, &data); talloc_free(tmp_ctx); } diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 12fe7015a7..29081ef7d6 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -55,7 +55,7 @@ void odb_set_ops(const struct opendb_ops *new_ops) /* Open up the openfiles.tdb database. Close it down using - talloc_free(). We need the messaging_ctx to allow for pending open + talloc_free(). We need the imessaging_ctx to allow for pending open notifications. */ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 881fd5b57a..9884e1f8b0 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -40,9 +40,9 @@ #include "includes.h" #include "system/filesys.h" -#include <tdb.h> +#include "../lib/tdb_compat/tdb_compat.h" #include "messaging/messaging.h" -#include "tdb_wrap.h" +#include "lib/util/tdb_wrap.h" #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_opendb.h" #include "ntvfs/ntvfs.h" @@ -74,13 +74,13 @@ struct odb_lock { } can_open; }; -static NTSTATUS odb_oplock_break_send(struct messaging_context *msg_ctx, +static NTSTATUS odb_oplock_break_send(struct imessaging_context *msg_ctx, struct opendb_entry *e, uint8_t level); /* Open up the openfiles.tdb database. Close it down using - talloc_free(). We need the messaging_ctx to allow for pending open + talloc_free(). We need the imessaging_ctx to allow for pending open notifications. */ static struct odb_context *odb_tdb_init(TALLOC_CTX *mem_ctx, @@ -238,7 +238,7 @@ static NTSTATUS odb_pull_record(struct odb_lock *lck, struct opendb_file *file) DATA_BLOB blob; enum ndr_err_code ndr_err; - dbuf = tdb_fetch(odb->w->tdb, lck->key); + dbuf = tdb_fetch_compat(odb->w->tdb, lck->key); if (dbuf.dptr == NULL) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } @@ -294,7 +294,7 @@ static NTSTATUS odb_push_record(struct odb_lock *lck, struct opendb_file *file) /* send an oplock break to a client */ -static NTSTATUS odb_oplock_break_send(struct messaging_context *msg_ctx, +static NTSTATUS odb_oplock_break_send(struct imessaging_context *msg_ctx, struct opendb_entry *e, uint8_t level) { @@ -311,7 +311,7 @@ static NTSTATUS odb_oplock_break_send(struct messaging_context *msg_ctx, blob = data_blob_const(&op_break, sizeof(op_break)); - status = messaging_send(msg_ctx, e->server, + status = imessaging_send(msg_ctx, e->server, MSG_NTVFS_OPLOCK_BREAK, &blob); NT_STATUS_NOT_OK_RETURN(status); @@ -611,7 +611,7 @@ static NTSTATUS odb_tdb_close_file(struct odb_lock *lck, void *file_handle, /* send any pending notifications, removing them once sent */ for (i=0;i<lck->file.num_pending;i++) { - messaging_send_ptr(odb->ntvfs_ctx->msg_ctx, + imessaging_send_ptr(odb->ntvfs_ctx->msg_ctx, lck->file.pending[i].server, MSG_PVFS_RETRY_OPEN, lck->file.pending[i].notify_ptr); @@ -666,7 +666,7 @@ static NTSTATUS odb_tdb_update_oplock(struct odb_lock *lck, void *file_handle, /* send any pending notifications, removing them once sent */ for (i=0;i<lck->file.num_pending;i++) { - messaging_send_ptr(odb->ntvfs_ctx->msg_ctx, + imessaging_send_ptr(odb->ntvfs_ctx->msg_ctx, lck->file.pending[i].server, MSG_PVFS_RETRY_OPEN, lck->file.pending[i].notify_ptr); diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 185e72cfb0..fc9ff4fb12 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -353,7 +353,7 @@ static void ipc_open_done(struct tevent_req *subreq) &p->allocation_size); TALLOC_FREE(subreq); if (ret == -1) { - status = map_nt_error_from_unix(sys_errno); + status = map_nt_error_from_unix_common(sys_errno); goto reply; } @@ -602,7 +602,7 @@ static void ipc_read_done(struct tevent_req *subreq) ret = tstream_readv_pdu_queue_recv(subreq, &sys_errno); TALLOC_FREE(subreq); if (ret == -1) { - status = map_nt_error_from_unix(sys_errno); + status = map_nt_error_from_unix_common(sys_errno); goto reply; } @@ -687,7 +687,7 @@ static void ipc_write_done(struct tevent_req *subreq) ret = tstream_writev_queue_recv(subreq, &sys_errno); TALLOC_FREE(subreq); if (ret == -1) { - status = map_nt_error_from_unix(sys_errno); + status = map_nt_error_from_unix_common(sys_errno); goto reply; } @@ -1009,7 +1009,7 @@ static void ipc_trans_writev_done(struct tevent_req *subreq) status = NT_STATUS_PIPE_DISCONNECTED; goto reply; } else if (ret == -1) { - status = map_nt_error_from_unix(sys_errno); + status = map_nt_error_from_unix_common(sys_errno); goto reply; } @@ -1045,7 +1045,7 @@ static void ipc_trans_readv_done(struct tevent_req *subreq) ret = tstream_readv_pdu_queue_recv(subreq, &sys_errno); TALLOC_FREE(subreq); if (ret == -1) { - status = map_nt_error_from_unix(sys_errno); + status = map_nt_error_from_unix_common(sys_errno); goto reply; } @@ -1215,7 +1215,7 @@ static void ipc_ioctl_writev_done(struct tevent_req *subreq) ret = tstream_writev_queue_recv(subreq, &sys_errno); TALLOC_FREE(subreq); if (ret == -1) { - status = map_nt_error_from_unix(sys_errno); + status = map_nt_error_from_unix_common(sys_errno); goto reply; } @@ -1251,7 +1251,7 @@ static void ipc_ioctl_readv_done(struct tevent_req *subreq) ret = tstream_readv_pdu_queue_recv(subreq, &sys_errno); TALLOC_FREE(subreq); if (ret == -1) { - status = map_nt_error_from_unix(sys_errno); + status = map_nt_error_from_unix_common(sys_errno); goto reply; } diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 35cd86f34d..565f2dafed 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -165,10 +165,9 @@ static NTSTATUS nbench_disconnect(struct ntvfs_module_context *ntvfs) static void nbench_unlink_send(struct ntvfs_request *req) { union smb_unlink *unl = req->async_states->private_data; - nbench_log(req, "Unlink \"%s\" 0x%x %s\n", unl->unlink.in.pattern, unl->unlink.in.attrib, - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); PASS_THRU_REP_POST(req); } @@ -213,7 +212,7 @@ static void nbench_chkpath_send(struct ntvfs_request *req) nbench_log(req, "Chkpath \"%s\" %s\n", cp->chkpath.in.path, - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); PASS_THRU_REP_POST(req); } @@ -239,7 +238,7 @@ static void nbench_qpathinfo_send(struct ntvfs_request *req) nbench_log(req, "QUERY_PATH_INFORMATION \"%s\" %d %s\n", info->generic.in.file.path, info->generic.level, - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); PASS_THRU_REP_POST(req); } @@ -264,7 +263,7 @@ static void nbench_qfileinfo_send(struct ntvfs_request *req) nbench_log(req, "QUERY_FILE_INFORMATION %s %d %s\n", nbench_ntvfs_handle_string(req, info->generic.in.file.ntvfs), info->generic.level, - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); PASS_THRU_REP_POST(req); } @@ -289,7 +288,7 @@ static void nbench_setpathinfo_send(struct ntvfs_request *req) nbench_log(req, "SET_PATH_INFORMATION \"%s\" %d %s\n", st->generic.in.file.path, st->generic.level, - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); PASS_THRU_REP_POST(req); } @@ -321,7 +320,7 @@ static void nbench_open_send(struct ntvfs_request *req) io->ntcreatex.in.create_options, io->ntcreatex.in.open_disposition, nbench_ntvfs_handle_string(req, io->ntcreatex.out.file.ntvfs), - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); break; default: @@ -373,7 +372,7 @@ static void nbench_rmdir_send(struct ntvfs_request *req) nbench_log(req, "Rmdir \"%s\" %s\n", rd->in.path, - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); PASS_THRU_REP_POST(req); } @@ -400,7 +399,7 @@ static void nbench_rename_send(struct ntvfs_request *req) nbench_log(req, "Rename \"%s\" \"%s\" %s\n", ren->rename.in.pattern1, ren->rename.in.pattern2, - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); break; default: @@ -459,7 +458,7 @@ static void nbench_read_send(struct ntvfs_request *req) (int)rd->readx.in.offset, rd->readx.in.maxcnt, rd->readx.out.nread, - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); break; default: nbench_log(req, "Read-%d - NOT HANDLED\n", @@ -497,7 +496,7 @@ static void nbench_write_send(struct ntvfs_request *req) (int)wr->writex.in.offset, wr->writex.in.count, wr->writex.out.nwritten, - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); break; case RAW_WRITE_WRITE: @@ -509,7 +508,7 @@ static void nbench_write_send(struct ntvfs_request *req) wr->write.in.offset, wr->write.in.count, wr->write.out.nwritten, - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); break; default: @@ -563,12 +562,12 @@ static void nbench_flush_send(struct ntvfs_request *req) case RAW_FLUSH_FLUSH: nbench_log(req, "Flush %s %s\n", nbench_ntvfs_handle_string(req, io->flush.in.file.ntvfs), - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); break; case RAW_FLUSH_ALL: nbench_log(req, "Flush %d %s\n", 0xFFFF, - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); break; default: nbench_log(req, "Flush-%d - NOT HANDLED\n", @@ -601,7 +600,7 @@ static void nbench_close_send(struct ntvfs_request *req) case RAW_CLOSE_CLOSE: nbench_log(req, "Close %s %s\n", nbench_ntvfs_handle_string(req, io->close.in.file.ntvfs), - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); break; default: @@ -718,14 +717,14 @@ static void nbench_lock_send(struct ntvfs_request *req) nbench_ntvfs_handle_string(req, lck->lockx.in.file.ntvfs), (int)lck->lockx.in.locks[0].offset, (int)lck->lockx.in.locks[0].count, - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); } else if (lck->generic.level == RAW_LOCK_LOCKX && lck->lockx.in.ulock_cnt == 1) { nbench_log(req, "UnlockX %s %d %d %s\n", nbench_ntvfs_handle_string(req, lck->lockx.in.file.ntvfs), (int)lck->lockx.in.locks[0].offset, (int)lck->lockx.in.locks[0].count, - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); } else { nbench_log(req, "Lock-%d - NOT HANDLED\n", lck->generic.level); } @@ -753,7 +752,7 @@ static void nbench_setfileinfo_send(struct ntvfs_request *req) nbench_log(req, "SET_FILE_INFORMATION %s %d %s\n", nbench_ntvfs_handle_string(req, info->generic.in.file.ntvfs), info->generic.level, - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); PASS_THRU_REP_POST(req); } @@ -778,7 +777,7 @@ static void nbench_fsinfo_send(struct ntvfs_request *req) nbench_log(req, "QUERY_FS_INFORMATION %d %s\n", fs->generic.level, - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); PASS_THRU_REP_POST(req); } @@ -832,7 +831,7 @@ static void nbench_search_first_send(struct ntvfs_request *req) io->t2ffirst.data_level, io->t2ffirst.in.max_count, io->t2ffirst.out.count, - get_nt_error_c_code(req->async_states->status)); + get_nt_error_c_code(req, req->async_states->status)); break; default: diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 203b588e08..463acc3c80 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -24,7 +24,7 @@ #include "libcli/raw/interfaces.h" #include "param/share.h" #include "librpc/gen_ndr/security.h" -#include "librpc/gen_ndr/server_id4.h" +#include "librpc/gen_ndr/server_id.h" /* modules can use the following to determine if the interface has changed */ /* version 1 -> 0 - make module stacking easier -- metze */ @@ -201,7 +201,7 @@ struct ntvfs_context { struct server_id server_id; struct loadparm_context *lp_ctx; struct tevent_context *event_ctx; - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; struct { void *private_data; @@ -330,9 +330,9 @@ struct ntvfs_critical_sizes { .sizeof_ntvfs_handle_data = sizeof(struct ntvfs_handle_data), \ } -struct messaging_context; +struct imessaging_context; #include "librpc/gen_ndr/security.h" -#include "librpc/gen_ndr/s4_notify.h" +#include "librpc/gen_ndr/notify.h" #include "ntvfs/ntvfs_proto.h" #endif /* _NTVFS_H_ */ diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 1b1a53361b..448d2919df 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -153,7 +153,7 @@ bool ntvfs_interface_differs(const struct ntvfs_critical_sizes *const iface) NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, enum ntvfs_type type, enum protocol_types protocol, uint64_t ntvfs_client_caps, - struct tevent_context *ev, struct messaging_context *msg, + struct tevent_context *ev, struct imessaging_context *msg, struct loadparm_context *lp_ctx, struct server_id server_id, struct ntvfs_context **_ctx) { @@ -235,7 +235,7 @@ NTSTATUS ntvfs_init(struct loadparm_context *lp_ctx) if (initialized) return NT_STATUS_OK; initialized = true; - shared_init = load_samba_modules(NULL, lp_ctx, "ntvfs"); + shared_init = load_samba_modules(NULL, "ntvfs"); run_init_functions(static_init); run_init_functions(shared_init); diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 8e1eb0bc66..bed9c9c755 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -576,9 +576,6 @@ static NTSTATUS ntvfs_map_fsinfo_finish(struct ntvfs_module_context *ntvfs, /* and convert it to the required level */ switch (fs->generic.level) { - case RAW_QFS_GENERIC: - return NT_STATUS_INVALID_LEVEL; - case RAW_QFS_DSKATTR: { /* map from generic to DSKATTR */ unsigned int bpunit = 64; @@ -666,8 +663,11 @@ static NTSTATUS ntvfs_map_fsinfo_finish(struct ntvfs_module_context *ntvfs, fs->objectid_information.out.guid = fs2->generic.out.guid; ZERO_STRUCT(fs->objectid_information.out.unknown); return NT_STATUS_OK; - } + case RAW_QFS_GENERIC: + case RAW_QFS_UNIX_INFO: + return NT_STATUS_INVALID_LEVEL; + } return NT_STATUS_INVALID_LEVEL; } @@ -715,8 +715,6 @@ NTSTATUS ntvfs_map_fileinfo(TALLOC_CTX *mem_ctx, int i; /* and convert it to the required level using results in info2 */ switch (info->generic.level) { - case RAW_FILEINFO_GENERIC: - return NT_STATUS_INVALID_LEVEL; case RAW_FILEINFO_GETATTR: info->getattr.out.attrib = info2->generic.out.attrib & 0xff; info->getattr.out.size = info2->generic.out.size; @@ -931,6 +929,13 @@ NTSTATUS ntvfs_map_fileinfo(TALLOC_CTX *mem_ctx, info->unix_link_info.out.link_dest = info2->generic.out.link_dest; return NT_STATUS_OK; #endif + case RAW_FILEINFO_GENERIC: + case RAW_FILEINFO_SEC_DESC: + case RAW_FILEINFO_EA_LIST: + case RAW_FILEINFO_UNIX_INFO2: + case RAW_FILEINFO_SMB2_ALL_EAS: + case RAW_FILEINFO_SMB2_ALL_INFORMATION: + return NT_STATUS_INVALID_LEVEL; } return NT_STATUS_INVALID_LEVEL; diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 67b544d4de..d7a778e1f7 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -89,7 +89,7 @@ const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name) return NULL; } -NTSTATUS pvfs_acl_init(struct loadparm_context *lp_ctx) +NTSTATUS pvfs_acl_init(void) { static bool initialized = false; #define _MODULE_PROTO(init) extern NTSTATUS init(void); @@ -100,7 +100,7 @@ NTSTATUS pvfs_acl_init(struct loadparm_context *lp_ctx) if (initialized) return NT_STATUS_OK; initialized = true; - shared_init = load_samba_modules(NULL, lp_ctx, "pvfs_acl"); + shared_init = load_samba_modules(NULL, "pvfs_acl"); run_init_functions(static_init); run_init_functions(shared_init); diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 77f19c3585..1bc91c1c78 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -199,7 +199,7 @@ const char *pvfs_list_next(struct pvfs_dir *dir, off_t *ofs) if (*ofs == DIR_OFFSET_DOT) { (*ofs) = DIR_OFFSET_DOTDOT; dir->offset = *ofs; - if (ms_fnmatch(dir->pattern, ".", protocol) == 0) { + if (ms_fnmatch_protocol(dir->pattern, ".", protocol) == 0) { dcache_add(dir, "."); return "."; } @@ -208,7 +208,7 @@ const char *pvfs_list_next(struct pvfs_dir *dir, off_t *ofs) if (*ofs == DIR_OFFSET_DOTDOT) { (*ofs) = DIR_OFFSET_BASE; dir->offset = *ofs; - if (ms_fnmatch(dir->pattern, "..", protocol) == 0) { + if (ms_fnmatch_protocol(dir->pattern, "..", protocol) == 0) { dcache_add(dir, ".."); return ".."; } @@ -228,10 +228,10 @@ const char *pvfs_list_next(struct pvfs_dir *dir, off_t *ofs) continue; } - if (ms_fnmatch(dir->pattern, dname, protocol) != 0) { + if (ms_fnmatch_protocol(dir->pattern, dname, protocol) != 0) { char *short_name = pvfs_short_name_component(dir->pvfs, dname); if (short_name == NULL || - ms_fnmatch(dir->pattern, short_name, protocol) != 0) { + ms_fnmatch_protocol(dir->pattern, short_name, protocol) != 0) { talloc_free(short_name); continue; } diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 11757deea4..0d99860e59 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -39,7 +39,7 @@ NTSTATUS pvfs_check_lock(struct pvfs_state *pvfs, return NT_STATUS_OK; } - return brl_locktest(pvfs->brl_context, + return brlock_locktest(pvfs->brl_context, f->brl_handle, smbpid, offset, count, rw); @@ -70,7 +70,7 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs, { /* undo the locks we just did */ for (i--;i>=0;i--) { - brl_unlock(pvfs->brl_context, + brlock_unlock(pvfs->brl_context, f->brl_handle, locks[i].pid, locks[i].offset, @@ -127,7 +127,7 @@ static void pvfs_pending_lock_continue(void *private_data, enum pvfs_wait_notice * because with this we'll get the correct error code * FILE_LOCK_CONFLICT in the error case */ - status = brl_lock(pvfs->brl_context, + status = brlock_lock(pvfs->brl_context, f->brl_handle, locks[pending->pending_lock].pid, locks[pending->pending_lock].offset, @@ -143,7 +143,7 @@ static void pvfs_pending_lock_continue(void *private_data, enum pvfs_wait_notice don't need the pending lock any more */ if (NT_STATUS_IS_OK(status) || timed_out) { NTSTATUS status2; - status2 = brl_remove_pending(pvfs->brl_context, + status2 = brlock_remove_pending(pvfs->brl_context, f->brl_handle, pending); if (!NT_STATUS_IS_OK(status2)) { DEBUG(0,("pvfs_lock: failed to remove pending lock - %s\n", nt_errstr(status2))); @@ -177,7 +177,7 @@ static void pvfs_pending_lock_continue(void *private_data, enum pvfs_wait_notice pending->pending_lock = i; } - status = brl_lock(pvfs->brl_context, + status = brlock_lock(pvfs->brl_context, f->brl_handle, locks[i].pid, locks[i].offset, @@ -225,7 +225,7 @@ void pvfs_lock_close(struct pvfs_state *pvfs, struct pvfs_file *f) if (f->lock_count || f->pending_list) { DEBUG(5,("pvfs_lock: removing %.0f locks on close\n", (double)f->lock_count)); - brl_close(f->pvfs->brl_context, f->brl_handle); + brlock_close(f->pvfs->brl_context, f->brl_handle); f->lock_count = 0; } @@ -324,8 +324,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, pending->req = req; pending->end_time = - timeval_current_ofs(lck->lockx.in.timeout/1000, - 1000*(lck->lockx.in.timeout%1000)); + timeval_current_ofs_msec(lck->lockx.in.timeout); } if (lck->lockx.in.mode & LOCKING_ANDX_SHARED_LOCK) { @@ -350,7 +349,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, locks = lck->lockx.in.locks; for (i=0;i<lck->lockx.in.ulock_cnt;i++) { - status = brl_unlock(pvfs->brl_context, + status = brlock_unlock(pvfs->brl_context, f->brl_handle, locks[i].pid, locks[i].offset, @@ -369,7 +368,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, pending->pending_lock = i; } - status = brl_lock(pvfs->brl_context, + status = brlock_lock(pvfs->brl_context, f->brl_handle, locks[i].pid, locks[i].offset, @@ -394,7 +393,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, /* undo the locks we just did */ for (i--;i>=0;i--) { - brl_unlock(pvfs->brl_context, + brlock_unlock(pvfs->brl_context, f->brl_handle, locks[i].pid, locks[i].offset, diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 08a54f8e42..d56bce58f7 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -590,7 +590,7 @@ static NTSTATUS pvfs_brl_locking_handle(TALLOC_CTX *mem_ctx, data_blob_free(&odb_key); } - h = brl_create_handle(mem_ctx, ntvfs, &key); + h = brlock_create_handle(mem_ctx, ntvfs, &key); NT_STATUS_HAVE_NO_MEMORY(h); *_h = h; @@ -1174,7 +1174,7 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, *final_timeout = timeval_add(&req->statistics.request_time, pvfs->oplock_break_timeout, 0); - end_time = timeval_current_ofs(0, (pvfs->sharing_violation_delay*4)/5); + end_time = timeval_current_ofs_usec((pvfs->sharing_violation_delay*4)/5); end_time = timeval_min(final_timeout, &end_time); } else { return NT_STATUS_INTERNAL_ERROR; @@ -1569,7 +1569,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->handle->fd = fd; - status = brl_count(f->pvfs->brl_context, f->brl_handle, &count); + status = brlock_count(f->pvfs->brl_context, f->brl_handle, &count); if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); return status; diff --git a/source4/ntvfs/posix/pvfs_oplock.c b/source4/ntvfs/posix/pvfs_oplock.c index a10188f3eb..5b9f3a318c 100644 --- a/source4/ntvfs/posix/pvfs_oplock.c +++ b/source4/ntvfs/posix/pvfs_oplock.c @@ -32,7 +32,7 @@ struct pvfs_oplock { uint32_t level; struct timeval break_to_level_II; struct timeval break_to_none; - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; }; static NTSTATUS pvfs_oplock_release_internal(struct pvfs_file_handle *h, @@ -158,7 +158,7 @@ static void pvfs_oplock_break(struct pvfs_oplock *opl, uint8_t level) } } -static void pvfs_oplock_break_dispatch(struct messaging_context *msg, +static void pvfs_oplock_break_dispatch(struct imessaging_context *msg, void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *data) { @@ -169,7 +169,7 @@ static void pvfs_oplock_break_dispatch(struct messaging_context *msg, ZERO_STRUCT(opb); /* we need to check that this one is for us. See - messaging_send_ptr() for the other side of this. + imessaging_send_ptr() for the other side of this. */ if (data->length == sizeof(struct opendb_oplock_break)) { struct opendb_oplock_break *p; @@ -192,7 +192,7 @@ static void pvfs_oplock_break_dispatch(struct messaging_context *msg, static int pvfs_oplock_destructor(struct pvfs_oplock *opl) { - messaging_deregister(opl->msg_ctx, MSG_NTVFS_OPLOCK_BREAK, opl); + imessaging_deregister(opl->msg_ctx, MSG_NTVFS_OPLOCK_BREAK, opl); return 0; } @@ -228,7 +228,7 @@ NTSTATUS pvfs_setup_oplock(struct pvfs_file *f, uint32_t oplock_granted) opl->level = level; opl->msg_ctx = f->pvfs->ntvfs->ctx->msg_ctx; - status = messaging_register(opl->msg_ctx, + status = imessaging_register(opl->msg_ctx, opl, MSG_NTVFS_OPLOCK_BREAK, pvfs_oplock_break_dispatch); diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index e54fc2d669..9284306753 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -149,9 +149,6 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, int fd) { switch (info->generic.level) { - case RAW_FILEINFO_GENERIC: - return NT_STATUS_INVALID_LEVEL; - case RAW_FILEINFO_GETATTR: info->getattr.out.attrib = name->dos.attrib; info->getattr.out.size = name->st.st_size; @@ -333,6 +330,12 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, name->original_name); NT_STATUS_HAVE_NO_MEMORY(info->all_info2.out.fname.s); return NT_STATUS_OK; + + case RAW_FILEINFO_GENERIC: + case RAW_FILEINFO_UNIX_BASIC: + case RAW_FILEINFO_UNIX_INFO2: + case RAW_FILEINFO_UNIX_LINK: + return NT_STATUS_INVALID_LEVEL; } return NT_STATUS_INVALID_LEVEL; diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index a050de1ec3..893f55c5ac 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -221,7 +221,9 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, return NT_STATUS_OK; case RAW_SEARCH_DATA_GENERIC: - break; + case RAW_SEARCH_DATA_UNIX_INFO: + case RAW_SEARCH_DATA_UNIX_INFO2: + return NT_STATUS_INVALID_LEVEL; } return NT_STATUS_INVALID_LEVEL; diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index 8dedf13a63..c6c6eaa13c 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -40,7 +40,7 @@ bool pvfs_has_wildcard(const char *str) NTSTATUS pvfs_map_errno(struct pvfs_state *pvfs, int unix_errno) { NTSTATUS status; - status = map_nt_error_from_unix(unix_errno); + status = map_nt_error_from_unix_common(unix_errno); DEBUG(10,(__location__ " mapped unix errno %d -> %s\n", unix_errno, nt_errstr(status))); return status; } diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 876ce52797..013de69889 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -33,7 +33,7 @@ struct pvfs_wait { void (*handler)(void *, enum pvfs_wait_notice); void *private_data; int msg_type; - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; struct tevent_context *ev; struct ntvfs_request *req; enum pvfs_wait_notice reason; @@ -56,7 +56,7 @@ NTSTATUS pvfs_async_setup(struct ntvfs_module_context *ntvfs, /* receive a completion message for a wait */ -static void pvfs_wait_dispatch(struct messaging_context *msg, +static void pvfs_wait_dispatch(struct imessaging_context *msg, void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *data) { @@ -66,7 +66,7 @@ static void pvfs_wait_dispatch(struct messaging_context *msg, void *p = NULL; /* we need to check that this one is for us. See - messaging_send_ptr() for the other side of this. + imessaging_send_ptr() for the other side of this. */ if (data->length == sizeof(void *)) { void **pp; @@ -116,7 +116,7 @@ static void pvfs_wait_timeout(struct tevent_context *ev, static int pvfs_wait_destructor(struct pvfs_wait *pwait) { if (pwait->msg_type != -1) { - messaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait); + imessaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait); } DLIST_REMOVE(pwait->pvfs->wait_list, pwait); return 0; @@ -162,7 +162,7 @@ struct pvfs_wait *pvfs_wait_message(struct pvfs_state *pvfs, /* register with the messaging subsystem for this message type */ if (msg_type != -1) { - messaging_register(pwait->msg_ctx, + imessaging_register(pwait->msg_ctx, pwait, msg_type, pvfs_wait_dispatch); diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index fb629a87fb..892d3dd749 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -64,7 +64,7 @@ static void pvfs_trigger_write_time_update(struct pvfs_file_handle *h) return; } - tv = timeval_current_ofs(0, pvfs->writetime_delay); + tv = timeval_current_ofs_usec(pvfs->writetime_delay); h->write_time.update_triggered = true; h->write_time.update_on_close = true; diff --git a/source4/ntvfs/posix/python/pyxattr_tdb.c b/source4/ntvfs/posix/python/pyxattr_tdb.c index 5e72ac9dde..2b28aca365 100644 --- a/source4/ntvfs/posix/python/pyxattr_tdb.c +++ b/source4/ntvfs/posix/python/pyxattr_tdb.c @@ -20,8 +20,8 @@ #include <Python.h> #include "includes.h" -#include <tdb.h> -#include "tdb_wrap.h" +#include "tdb_compat.h" +#include "lib/util/tdb_wrap.h" #include "librpc/ndr/libndr.h" #include "lib/util/wrap_xattr.h" #include "ntvfs/posix/vfs_posix.h" diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index ca1d163327..00ed146c96 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -26,8 +26,8 @@ #include "includes.h" #include "vfs_posix.h" #include "librpc/gen_ndr/security.h" -#include <tdb.h> -#include "tdb_wrap.h" +#include "tdb_compat.h" +#include "lib/util/tdb_wrap.h" #include "libcli/security/security.h" #include "lib/events/events.h" #include "param/param.h" @@ -212,7 +212,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, * TODO: call this from ntvfs_posix_init() * but currently we don't have a lp_ctx there */ - status = pvfs_acl_init(ntvfs->ctx->lp_ctx); + status = pvfs_acl_init(); NT_STATUS_NOT_OK_RETURN(status); pvfs = talloc_zero(ntvfs, struct pvfs_state); @@ -249,7 +249,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, ntvfs->private_data = pvfs; - pvfs->brl_context = brl_init(pvfs, + pvfs->brl_context = brlock_init(pvfs, pvfs->ntvfs->ctx->server_id, pvfs->ntvfs->ctx->lp_ctx, pvfs->ntvfs->ctx->msg_ctx); diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index d60369df50..e1593a38cf 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -204,7 +204,7 @@ struct pvfs_file { /* a file handle to be used for byte range locking */ struct brl_handle *brl_handle; - /* a count of active locks - used to avoid calling brl_close on + /* a count of active locks - used to avoid calling brlock_close on file close */ uint64_t lock_count; diff --git a/source4/ntvfs/posix/xattr_tdb.c b/source4/ntvfs/posix/xattr_tdb.c index de7c83677a..07b3712215 100644 --- a/source4/ntvfs/posix/xattr_tdb.c +++ b/source4/ntvfs/posix/xattr_tdb.c @@ -20,8 +20,8 @@ */ #include "includes.h" -#include "tdb_wrap.h" -#include <tdb.h> +#include "lib/util/tdb_wrap.h" +#include "tdb_compat.h" #include "vfs_posix.h" #define XATTR_LIST_ATTR ".xattr_list" @@ -129,7 +129,7 @@ NTSTATUS pull_xattr_blob_tdb_raw(struct tdb_wrap *ea_tdb, return status; } - tdata = tdb_fetch(ea_tdb->tdb, tkey); + tdata = tdb_fetch_compat(ea_tdb->tdb, tkey); if (tdata.dptr == NULL) { return NT_STATUS_NOT_FOUND; } @@ -185,7 +185,7 @@ NTSTATUS push_xattr_blob_tdb_raw(struct tdb_wrap *ea_tdb, goto done; } - if (tdb_store(ea_tdb->tdb, tkey, tdata, TDB_REPLACE) == -1) { + if (tdb_store(ea_tdb->tdb, tkey, tdata, TDB_REPLACE) != 0) { status = NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -218,7 +218,7 @@ NTSTATUS delete_xattr_tdb(struct pvfs_state *pvfs, const char *attr_name, return status; } - if (tdb_delete(pvfs->ea_db->tdb, tkey) == -1) { + if (tdb_delete(pvfs->ea_db->tdb, tkey) != 0) { talloc_free(tkey.dptr); return NT_STATUS_INTERNAL_DB_CORRUPTION; } diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index 2a01c2d5de..c4e015668c 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -38,16 +38,15 @@ char *svfs_unix_path(struct ntvfs_module_context *ntvfs, { struct svfs_private *p = ntvfs->private_data; char *ret; + char *name_lower = strlower_talloc(p, name); if (*name != '\\') { - ret = talloc_asprintf(req, "%s/%s", p->connectpath, name); + ret = talloc_asprintf(req, "%s/%s", p->connectpath, name_lower); } else { - ret = talloc_asprintf(req, "%s%s", p->connectpath, name); + ret = talloc_asprintf(req, "%s%s", p->connectpath, name_lower); } all_string_sub(ret, "\\", "/", 0); - - strlower(ret + strlen(p->connectpath)); - + talloc_free(name_lower); return ret; } @@ -82,9 +81,8 @@ struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request *req, /* the wildcard pattern is the last part */ mask = p+1; - low_mask = talloc_strdup(mem_ctx, mask); + low_mask = strlower_talloc(mem_ctx, mask); if (!low_mask) { return NULL; } - strlower(low_mask); odir = opendir(dir->unix_dir); if (!odir) { return NULL; } @@ -99,12 +97,11 @@ struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request *req, continue; } - low_name = talloc_strdup(mem_ctx, dent->d_name); + low_name = strlower_talloc(mem_ctx, dent->d_name); if (!low_name) { continue; } - strlower(low_name); /* check it matches the wildcard pattern */ - if (ms_fnmatch(low_mask, low_name, PROTOCOL_NT1) != 0) { + if (ms_fnmatch_protocol(low_mask, low_name, PROTOCOL_NT1) != 0) { continue; } diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 03bf76634d..7ae41db521 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -147,7 +147,7 @@ static NTSTATUS svfs_unlink(struct ntvfs_module_context *ntvfs, /* ignoring wildcards ... */ if (unlink(unix_path) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } return NT_STATUS_OK; @@ -176,7 +176,7 @@ static NTSTATUS svfs_chkpath(struct ntvfs_module_context *ntvfs, unix_path = svfs_unix_path(ntvfs, req, cp->chkpath.in.path); if (stat(unix_path, &st) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } if (!S_ISDIR(st.st_mode)) { @@ -291,7 +291,7 @@ static NTSTATUS svfs_qpathinfo(struct ntvfs_module_context *ntvfs, DEBUG(19,("svfs_qpathinfo: file %s\n", unix_path)); if (stat(unix_path, &st) == -1) { DEBUG(19,("svfs_qpathinfo: file %s errno=%d\n", unix_path, errno)); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } DEBUG(19,("svfs_qpathinfo: file %s, stat done\n", unix_path)); return svfs_map_fileinfo(ntvfs, req, info, &st, unix_path); @@ -317,7 +317,7 @@ static NTSTATUS svfs_qfileinfo(struct ntvfs_module_context *ntvfs, } if (fstat(f->fd, &st) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } return svfs_map_fileinfo(ntvfs, req,info, &st, f->name); @@ -386,13 +386,13 @@ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, case NTCREATEX_DISP_CREATE: if (mkdir(unix_path, 0755) == -1) { DEBUG(9,("svfs_open: mkdir %s errno=%d\n", unix_path, errno)); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } break; case NTCREATEX_DISP_OPEN_IF: if (mkdir(unix_path, 0755) == -1 && errno != EEXIST) { DEBUG(9,("svfs_open: mkdir %s errno=%d\n", unix_path, errno)); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } break; } @@ -401,13 +401,13 @@ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, do_open: fd = open(unix_path, flags, 0644); if (fd == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } if (fstat(fd, &st) == -1) { DEBUG(9,("svfs_open: fstat errno=%d\n", errno)); close(fd); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } status = ntvfs_handle_new(ntvfs, req, &handle); @@ -456,7 +456,7 @@ static NTSTATUS svfs_mkdir(struct ntvfs_module_context *ntvfs, unix_path = svfs_unix_path(ntvfs, req, md->mkdir.in.path); if (mkdir(unix_path, 0777) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } return NT_STATUS_OK; @@ -475,7 +475,7 @@ static NTSTATUS svfs_rmdir(struct ntvfs_module_context *ntvfs, unix_path = svfs_unix_path(ntvfs, req, rd->in.path); if (rmdir(unix_path) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } return NT_STATUS_OK; @@ -499,7 +499,7 @@ static NTSTATUS svfs_rename(struct ntvfs_module_context *ntvfs, unix_path2 = svfs_unix_path(ntvfs, req, ren->rename.in.pattern2); if (rename(unix_path1, unix_path2) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } return NT_STATUS_OK; @@ -538,7 +538,7 @@ static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs, rd->readx.in.maxcnt, rd->readx.in.offset); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } rd->readx.out.nread = ret; @@ -574,7 +574,7 @@ static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, wr->writex.in.count, wr->writex.in.offset); if (ret == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } wr->writex.out.nwritten = ret; @@ -645,7 +645,7 @@ static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs, } if (close(f->fd) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } DLIST_REMOVE(p->open_files, f); @@ -735,7 +735,7 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_END_OF_FILE_INFORMATION: if (ftruncate(f->fd, info->end_of_file_info.in.size) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } break; case RAW_SFILEINFO_SETATTRE: @@ -781,7 +781,7 @@ static NTSTATUS svfs_fsinfo(struct ntvfs_module_context *ntvfs, if (sys_fsusage(p->connectpath, &fs->generic.out.blocks_free, &fs->generic.out.blocks_total) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } fs->generic.out.block_size = 512; @@ -821,7 +821,7 @@ static NTSTATUS svfs_fsattr(struct ntvfs_module_context *ntvfs, } if (stat(p->connectpath, &st) == -1) { - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); diff --git a/source4/ntvfs/smb2/vfs_smb2.c b/source4/ntvfs/smb2/vfs_smb2.c index 6c78997686..889c534dd0 100644 --- a/source4/ntvfs/smb2/vfs_smb2.c +++ b/source4/ntvfs/smb2/vfs_smb2.c @@ -162,7 +162,6 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, NTSTATUS status; struct cvfs_private *p; const char *host, *user, *pass, *domain, *remote_share, *sharename; - struct composite_context *creq; struct share_config *scfg = ntvfs->ctx->config; struct smb2_tree *tree; struct cli_credentials *credentials; @@ -250,17 +249,15 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, lpcfg_smbcli_options(ntvfs->ctx->lp_ctx, &options); - creq = smb2_connect_send(p, host, + status = smb2_connect(p, host, lpcfg_parm_string_list(p, ntvfs->ctx->lp_ctx, NULL, "smb2", "ports", NULL), - remote_share, - lpcfg_resolve_context(ntvfs->ctx->lp_ctx), - credentials, - ntvfs->ctx->event_ctx, &options, - lpcfg_socket_options(ntvfs->ctx->lp_ctx), - lpcfg_gensec_settings(p, ntvfs->ctx->lp_ctx) - ); - - status = smb2_connect_recv(creq, p, &tree); + remote_share, + lpcfg_resolve_context(ntvfs->ctx->lp_ctx), + credentials, + &tree, + ntvfs->ctx->event_ctx, &options, + lpcfg_socket_options(ntvfs->ctx->lp_ctx), + lpcfg_gensec_settings(p, ntvfs->ctx->lp_ctx)); NT_STATUS_NOT_OK_RETURN(status); status = smb2_get_roothandle(tree, &p->roothandle); diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index 42aac0b097..28ea32e8a0 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -258,7 +258,7 @@ static NTSTATUS inotify_setup(struct sys_notify_context *ctx) if (in->fd == -1) { DEBUG(0,("Failed to init inotify - %s\n", strerror(errno))); talloc_free(in); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } in->ctx = ctx; in->watches = NULL; @@ -274,7 +274,7 @@ static NTSTATUS inotify_setup(struct sys_notify_context *ctx) } DEBUG(0,("Failed to tevent_add_fd() - %s\n", strerror(errno))); talloc_free(in); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } tevent_fd_set_auto_close(fde); @@ -373,7 +373,7 @@ static NTSTATUS inotify_watch(struct sys_notify_context *ctx, wd = inotify_add_watch(in->fd, e->path, mask); if (wd == -1) { e->filter = filter; - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } w = talloc(in, struct inotify_watch_context); diff --git a/source4/ntvfs/sysdep/sys_lease.c b/source4/ntvfs/sysdep/sys_lease.c index 8b0b3a5110..7865f717a4 100644 --- a/source4/ntvfs/sysdep/sys_lease.c +++ b/source4/ntvfs/sysdep/sys_lease.c @@ -40,7 +40,7 @@ static uint32_t num_backends; _PUBLIC_ struct sys_lease_context *sys_lease_context_create(struct share_config *scfg, TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, sys_lease_send_break_fn break_send) { struct sys_lease_context *ctx; diff --git a/source4/ntvfs/sysdep/sys_lease.h b/source4/ntvfs/sysdep/sys_lease.h index 422797b0b8..57a5e0a35f 100644 --- a/source4/ntvfs/sysdep/sys_lease.h +++ b/source4/ntvfs/sysdep/sys_lease.h @@ -21,10 +21,10 @@ struct sys_lease_context; struct opendb_entry; -struct messaging_context; +struct imessaging_context; struct tevent_context; -typedef NTSTATUS (*sys_lease_send_break_fn)(struct messaging_context *, +typedef NTSTATUS (*sys_lease_send_break_fn)(struct imessaging_context *, struct opendb_entry *, uint8_t level); @@ -41,7 +41,7 @@ struct sys_lease_ops { struct sys_lease_context { struct tevent_context *event_ctx; - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; sys_lease_send_break_fn break_send; void *private_data; /* for use of backend */ const struct sys_lease_ops *ops; @@ -53,7 +53,7 @@ NTSTATUS sys_lease_init(void); struct sys_lease_context *sys_lease_context_create(struct share_config *scfg, TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, sys_lease_send_break_fn break_send); NTSTATUS sys_lease_setup(struct sys_lease_context *ctx, diff --git a/source4/ntvfs/sysdep/sys_lease_linux.c b/source4/ntvfs/sysdep/sys_lease_linux.c index c0fb4335d9..3b0605b73b 100644 --- a/source4/ntvfs/sysdep/sys_lease_linux.c +++ b/source4/ntvfs/sysdep/sys_lease_linux.c @@ -131,13 +131,13 @@ static NTSTATUS linux_lease_setup(struct sys_lease_context *ctx, ret = fcntl(*fd, F_SETSIG, LINUX_LEASE_RT_SIGNAL); if (ret == -1) { talloc_free(p); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } ret = fcntl(*fd, F_SETLEASE, F_WRLCK); if (ret == -1) { talloc_free(p); - return map_nt_error_from_unix(errno); + return map_nt_error_from_unix_common(errno); } DLIST_ADD(leases, p); diff --git a/source4/ntvfs/sysdep/sys_notify.h b/source4/ntvfs/sysdep/sys_notify.h index c474d4e6a0..d912a9bdaf 100644 --- a/source4/ntvfs/sysdep/sys_notify.h +++ b/source4/ntvfs/sysdep/sys_notify.h @@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "librpc/gen_ndr/s4_notify.h" +#include "librpc/gen_ndr/notify.h" #include "param/share.h" struct sys_notify_context; diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index 95460c6235..14285be017 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -68,172 +68,39 @@ #include "rpc_server/common/common.h" #include "lib/socket/socket.h" #include "auth/gensec/gensec.h" +#include "s3_param.h" #define standard_sub_basic talloc_strdup static bool do_parameter(const char *, const char *, void *); static bool defaults_saved = false; -/** - * This structure describes global (ie., server-wide) parameters. - */ -struct loadparm_global -{ - enum server_role server_role; - enum sid_generator sid_generator; - - const char **smb_ports; - char *ncalrpc_dir; - char *dos_charset; - char *unix_charset; - char *display_charset; - char *szLockDir; - char *szModulesDir; - char *szPidDir; - char *szServerString; - char *szAutoServices; - char *szPasswdChat; - char *szShareBackend; - char *szSAM_URL; - char *szIDMAP_URL; - char *szSECRETS_URL; - char *szSPOOLSS_URL; - char *szWINS_CONFIG_URL; - char *szWINS_URL; - char *szPrivateDir; - const char **szPasswordServers; - char *szSocketOptions; - char *szRealm; - char *szRealm_upper; - char *szRealm_lower; - const char **szWINSservers; - const char **szInterfaces; - char *szSocketAddress; - char *szAnnounceVersion; /* This is initialised in init_globals */ - char *szWorkgroup; - char *szNetbiosName; - const char **szNetbiosAliases; - char *szNetbiosScope; - char *szDomainOtherSIDs; - const char **szNameResolveOrder; - const char **dcerpc_ep_servers; - const char **server_services; - char *ntptr_providor; - char *szWinbindSeparator; - char *szWinbinddPrivilegedSocketDirectory; - char *szWinbinddSocketDirectory; - char *szTemplateShell; - char *szTemplateHomedir; - int bWinbindSealedPipes; - int bIdmapTrustedOnly; - int tls_enabled; - char *tls_keyfile; - char *tls_certfile; - char *tls_cafile; - char *tls_crlfile; - char *tls_dhpfile; - char *logfile; - char *loglevel; - char *panic_action; - int max_mux; - int debuglevel; - int max_xmit; - int pwordlevel; - int srv_maxprotocol; - int srv_minprotocol; - int cli_maxprotocol; - int cli_minprotocol; - int security; - int paranoid_server_security; - int max_wins_ttl; - int min_wins_ttl; - int announce_as; /* This is initialised in init_globals */ - int nbt_port; - int dgram_port; - int cldap_port; - int krb5_port; - int kpasswd_port; - int web_port; - char *socket_options; - int bWINSsupport; - int bWINSdnsProxy; - char *szWINSHook; - int bLocalMaster; - int bPreferredMaster; - int bEncryptPasswords; - int bNullPasswords; - int bObeyPamRestrictions; - int bLargeReadwrite; - int bReadRaw; - int bWriteRaw; - int bTimeServer; - int bBindInterfacesOnly; - int bNTSmbSupport; - int bNTStatusSupport; - int bLanmanAuth; - int bNTLMAuth; - int bUseSpnego; - int server_signing; - int client_signing; - int bClientPlaintextAuth; - int bClientLanManAuth; - int bClientNTLMv2Auth; - int client_use_spnego_principal; - int bHostMSDfs; - int bUnicode; - int bUnixExtensions; - int bDisableNetbios; - int bRpcBigEndian; - char *szNTPSignDSocketDirectory; - const char **szRNDCCommand; - const char **szDNSUpdateCommand; - const char **szSPNUpdateCommand; - const char **szNSUpdateCommand; - struct parmlist_entry *param_opt; -}; - - -/** - * This structure describes a single service. - */ -struct loadparm_service -{ - char *szService; - char *szPath; - char *szCopy; - char *szInclude; - char *szPrintername; - char **szHostsallow; - char **szHostsdeny; - char *comment; - char *volume; - char *fstype; - char **ntvfs_handler; - int iMaxPrintJobs; - int iMaxConnections; - int iCSCPolicy; - int bAvailable; - int bBrowseable; - int bRead_only; - int bPrint_ok; - int bMap_system; - int bMap_hidden; - int bMap_archive; - int bStrictLocking; - int bOplocks; - int iCreate_mask; - int iCreate_force_mode; - int iDir_mask; - int iDir_force_mode; - int *copymap; - int bMSDfsRoot; - int bStrictSync; - int bCIFileSystem; - struct parmlist_entry *param_opt; - +#define LOADPARM_EXTRA_GLOBALS \ + struct parmlist_entry *param_opt; \ + char *szRealm; \ + char *tls_keyfile; \ + char *tls_certfile; \ + char *tls_cafile; \ + char *tls_crlfile; \ + char *tls_dhpfile; \ + char *loglevel; \ + char *panic_action; \ + int bPreferredMaster; \ + char *szAnnounceVersion; /* This is initialised in init_globals */ +#define LOADPARM_EXTRA_LOCALS \ + struct parmlist_entry *param_opt; \ + char *szService; \ + char *szCopy; \ + char *szInclude; \ + char *szPrintername; \ + int bAvailable; \ + int iMaxPrintJobs; \ + char *volume; \ + int *copymap; \ char dummy[3]; /* for alignment */ -}; +#include "param_global.h" +#include "param_local.h" #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct)) @@ -264,15 +131,7 @@ static const struct enum_list enum_protocol[] = { static const struct enum_list enum_security[] = { {SEC_SHARE, "SHARE"}, {SEC_USER, "USER"}, - {-1, NULL} -}; - -static const struct enum_list enum_announce_as[] = { - {ANNOUNCE_AS_NT_SERVER, "NT"}, - {ANNOUNCE_AS_NT_SERVER, "NT Server"}, - {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"}, - {ANNOUNCE_AS_WIN95, "win95"}, - {ANNOUNCE_AS_WFW, "WfW"}, + {SEC_ADS, "ADS"}, {-1, NULL} }; @@ -333,23 +192,14 @@ static const struct enum_list enum_server_role[] = { {-1, NULL} }; -static const struct enum_list enum_sid_generator[] = { - {SID_GENERATOR_INTERNAL, "internal"}, - {SID_GENERATOR_BACKEND, "backend"}, - {-1, NULL} -}; - #define GLOBAL_VAR(name) offsetof(struct loadparm_global, name) #define LOCAL_VAR(name) offsetof(struct loadparm_service, name) static struct parm_struct parm_table[] = { {"server role", P_ENUM, P_GLOBAL, GLOBAL_VAR(server_role), NULL, enum_server_role}, - {"sid generator", P_ENUM, P_GLOBAL, GLOBAL_VAR(sid_generator), NULL, enum_sid_generator}, - {"dos charset", P_STRING, P_GLOBAL, GLOBAL_VAR(dos_charset), NULL, NULL}, {"unix charset", P_STRING, P_GLOBAL, GLOBAL_VAR(unix_charset), NULL, NULL}, {"ncalrpc dir", P_STRING, P_GLOBAL, GLOBAL_VAR(ncalrpc_dir), NULL, NULL}, - {"display charset", P_STRING, P_GLOBAL, GLOBAL_VAR(display_charset), NULL, NULL}, {"comment", P_STRING, P_LOCAL, LOCAL_VAR(comment), NULL, NULL}, {"path", P_STRING, P_LOCAL, LOCAL_VAR(szPath), NULL, NULL}, {"directory", P_STRING, P_LOCAL, LOCAL_VAR(szPath), NULL, NULL}, @@ -371,9 +221,6 @@ static struct parm_struct parm_table[] = { {"null passwords", P_BOOL, P_GLOBAL, GLOBAL_VAR(bNullPasswords), NULL, NULL}, {"obey pam restrictions", P_BOOL, P_GLOBAL, GLOBAL_VAR(bObeyPamRestrictions), NULL, NULL}, {"password server", P_LIST, P_GLOBAL, GLOBAL_VAR(szPasswordServers), NULL, NULL}, - {"sam database", P_STRING, P_GLOBAL, GLOBAL_VAR(szSAM_URL), NULL, NULL}, - {"idmap database", P_STRING, P_GLOBAL, GLOBAL_VAR(szIDMAP_URL), NULL, NULL}, - {"secrets database", P_STRING, P_GLOBAL, GLOBAL_VAR(szSECRETS_URL), NULL, NULL}, {"spoolss database", P_STRING, P_GLOBAL, GLOBAL_VAR(szSPOOLSS_URL), NULL, NULL}, {"wins config database", P_STRING, P_GLOBAL, GLOBAL_VAR(szWINS_CONFIG_URL), NULL, NULL}, {"wins database", P_STRING, P_GLOBAL, GLOBAL_VAR(szWINS_URL), NULL, NULL}, @@ -427,7 +274,6 @@ static struct parm_struct parm_table[] = { {"nt status support", P_BOOL, P_GLOBAL, GLOBAL_VAR(bNTStatusSupport), NULL, NULL}, {"announce version", P_STRING, P_GLOBAL, GLOBAL_VAR(szAnnounceVersion), NULL, NULL}, - {"announce as", P_ENUM, P_GLOBAL, GLOBAL_VAR(announce_as), NULL, enum_announce_as}, {"max mux", P_INTEGER, P_GLOBAL, GLOBAL_VAR(max_mux), NULL, NULL}, {"max xmit", P_BYTES, P_GLOBAL, GLOBAL_VAR(max_xmit), NULL, NULL}, @@ -480,7 +326,6 @@ static struct parm_struct parm_table[] = { {"auto services", P_STRING, P_GLOBAL, GLOBAL_VAR(szAutoServices), NULL, NULL}, {"lock dir", P_STRING, P_GLOBAL, GLOBAL_VAR(szLockDir), NULL, NULL}, {"lock directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szLockDir), NULL, NULL}, - {"modules dir", P_STRING, P_GLOBAL, GLOBAL_VAR(szModulesDir), NULL, NULL}, {"pid directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szPidDir), NULL, NULL}, {"socket address", P_STRING, P_GLOBAL, GLOBAL_VAR(szSocketAddress), NULL, NULL}, @@ -532,6 +377,9 @@ struct loadparm_context { unsigned int flags[NUMPARAMETERS]; bool loaded; bool refuse_free; + bool global; /* Is this the global context, which may set + * global variables such as debug level etc? */ + const struct loadparm_s3_context *s3_fns; }; @@ -613,35 +461,80 @@ static struct loadparm_context *global_loadparm_context; #define lpcfg_default_service global_loadparm_context->sDefault #define lpcfg_global_service(i) global_loadparm_context->services[i] -#define FN_GLOBAL_STRING(fn_name,var_name) \ - _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return NULL; return lp_ctx->globals->var_name ? lp_string(lp_ctx->globals->var_name) : "";} +#define FN_GLOBAL_STRING(fn_name,var_name) \ + _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \ + if (lp_ctx == NULL) return NULL; \ + if (lp_ctx->s3_fns) { \ + SMB_ASSERT(lp_ctx->s3_fns->fn_name); \ + return lp_ctx->s3_fns->fn_name(); \ + } \ + return lp_ctx->globals->var_name ? lp_string(lp_ctx->globals->var_name) : ""; \ +} #define FN_GLOBAL_CONST_STRING(fn_name,var_name) \ - _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return NULL; return lp_ctx->globals->var_name ? lp_ctx->globals->var_name : "";} - -#define FN_GLOBAL_LIST(fn_name,var_name) \ - _PUBLIC_ const char **lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return NULL; return lp_ctx->globals->var_name;} + _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {\ + if (lp_ctx == NULL) return NULL; \ + if (lp_ctx->s3_fns) { \ + SMB_ASSERT(lp_ctx->s3_fns->fn_name); \ + return lp_ctx->s3_fns->fn_name(); \ + } \ + return lp_ctx->globals->var_name ? lp_string(lp_ctx->globals->var_name) : ""; \ + } + +#define FN_GLOBAL_LIST(fn_name,var_name) \ + _PUBLIC_ const char **lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \ + if (lp_ctx == NULL) return NULL; \ + if (lp_ctx->s3_fns) { \ + SMB_ASSERT(lp_ctx->s3_fns->fn_name); \ + return lp_ctx->s3_fns->fn_name(); \ + } \ + return lp_ctx->globals->var_name; \ + } #define FN_GLOBAL_BOOL(fn_name,var_name) \ - _PUBLIC_ bool lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return false; return lp_ctx->globals->var_name;} + _PUBLIC_ bool lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {\ + if (lp_ctx == NULL) return false; \ + if (lp_ctx->s3_fns) { \ + SMB_ASSERT(lp_ctx->s3_fns->fn_name); \ + return lp_ctx->s3_fns->fn_name(); \ + } \ + return lp_ctx->globals->var_name; \ +} #define FN_GLOBAL_INTEGER(fn_name,var_name) \ - _PUBLIC_ int lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {return lp_ctx->globals->var_name;} + _PUBLIC_ int lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \ + if (lp_ctx->s3_fns) { \ + SMB_ASSERT(lp_ctx->s3_fns->fn_name); \ + return lp_ctx->s3_fns->fn_name(); \ + } \ + return lp_ctx->globals->var_name; \ + } #define FN_LOCAL_STRING(fn_name,val) \ - _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_service *service, struct loadparm_service *sDefault) {return(lp_string((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault->val)));} + _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_service *service, \ + struct loadparm_service *sDefault) { \ + return(lp_string((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault->val))); \ + } #define FN_LOCAL_LIST(fn_name,val) \ - _PUBLIC_ const char **lpcfg_ ## fn_name(struct loadparm_service *service, struct loadparm_service *sDefault) {return(const char **)(service != NULL && service->val != NULL? service->val : sDefault->val);} + _PUBLIC_ const char **lpcfg_ ## fn_name(struct loadparm_service *service, \ + struct loadparm_service *sDefault) {\ + return(const char **)(service != NULL && service->val != NULL? service->val : sDefault->val); \ + } #define FN_LOCAL_BOOL(fn_name,val) \ - _PUBLIC_ bool lpcfg_ ## fn_name(struct loadparm_service *service, struct loadparm_service *sDefault) {return((service != NULL)? service->val : sDefault->val);} + _PUBLIC_ bool lpcfg_ ## fn_name(struct loadparm_service *service, \ + struct loadparm_service *sDefault) { \ + return((service != NULL)? service->val : sDefault->val); \ + } #define FN_LOCAL_INTEGER(fn_name,val) \ - _PUBLIC_ int lpcfg_ ## fn_name(struct loadparm_service *service, struct loadparm_service *sDefault) {return((service != NULL)? service->val : sDefault->val);} + _PUBLIC_ int lpcfg_ ## fn_name(struct loadparm_service *service, \ + struct loadparm_service *sDefault) { \ + return((service != NULL)? service->val : sDefault->val); \ + } FN_GLOBAL_INTEGER(server_role, server_role) -FN_GLOBAL_INTEGER(sid_generator, sid_generator) FN_GLOBAL_LIST(smb_ports, smb_ports) FN_GLOBAL_INTEGER(nbt_port, nbt_port) FN_GLOBAL_INTEGER(dgram_port, dgram_port) @@ -652,9 +545,6 @@ FN_GLOBAL_INTEGER(web_port, web_port) FN_GLOBAL_BOOL(tls_enabled, tls_enabled) FN_GLOBAL_STRING(logfile, logfile) FN_GLOBAL_STRING(share_backend, szShareBackend) -FN_GLOBAL_STRING(sam_url, szSAM_URL) -FN_GLOBAL_STRING(idmap_url, szIDMAP_URL) -FN_GLOBAL_STRING(secrets_url, szSECRETS_URL) FN_GLOBAL_STRING(spoolss_url, szSPOOLSS_URL) FN_GLOBAL_STRING(wins_config_url, szWINS_CONFIG_URL) FN_GLOBAL_STRING(wins_url, szWINS_URL) @@ -668,11 +558,9 @@ FN_GLOBAL_BOOL(idmap_trusted_only, bIdmapTrustedOnly) FN_GLOBAL_STRING(private_dir, szPrivateDir) FN_GLOBAL_STRING(serverstring, szServerString) FN_GLOBAL_STRING(lockdir, szLockDir) -FN_GLOBAL_STRING(modulesdir, szModulesDir) FN_GLOBAL_STRING(ncalrpc_dir, ncalrpc_dir) FN_GLOBAL_STRING(dos_charset, dos_charset) FN_GLOBAL_STRING(unix_charset, unix_charset) -FN_GLOBAL_STRING(display_charset, display_charset) FN_GLOBAL_STRING(piddir, szPidDir) FN_GLOBAL_LIST(rndc_command, szRNDCCommand) FN_GLOBAL_LIST(dns_update_command, szDNSUpdateCommand) @@ -731,7 +619,6 @@ FN_GLOBAL_INTEGER(cli_maxprotocol, cli_maxprotocol) FN_GLOBAL_INTEGER(cli_minprotocol, cli_minprotocol) FN_GLOBAL_INTEGER(security, security) FN_GLOBAL_BOOL(paranoid_server_security, paranoid_server_security) -FN_GLOBAL_INTEGER(announce_as, announce_as) FN_LOCAL_STRING(pathname, szPath) FN_LOCAL_LIST(hostsallow, szHostsallow) @@ -779,21 +666,28 @@ const char *lpcfg_get_parametric(struct loadparm_context *lp_ctx, struct loadparm_service *service, const char *type, const char *option) { + char *vfskey_tmp = NULL; char *vfskey = NULL; struct parmlist_entry *data; if (lp_ctx == NULL) return NULL; + if (lp_ctx->s3_fns) { + SMB_ASSERT(service == NULL); + return lp_ctx->s3_fns->get_parametric(type, option); + } + data = (service == NULL ? lp_ctx->globals->param_opt : service->param_opt); - asprintf(&vfskey, "%s:%s", type, option); - if (vfskey == NULL) return NULL; - strlower(vfskey); + vfskey_tmp = talloc_asprintf(NULL, "%s:%s", type, option); + if (vfskey_tmp == NULL) return NULL; + vfskey = strlower_talloc(NULL, vfskey_tmp); + talloc_free(vfskey_tmp); while (data) { if (strcmp(data->key, vfskey) == 0) { - free(vfskey); + talloc_free(vfskey); return data->value; } data = data->next; @@ -805,13 +699,13 @@ const char *lpcfg_get_parametric(struct loadparm_context *lp_ctx, for (data = lp_ctx->globals->param_opt; data; data = data->next) { if (strcmp(data->key, vfskey) == 0) { - free(vfskey); + talloc_free(vfskey); return data->value; } } } - free(vfskey); + talloc_free(vfskey); return NULL; } @@ -949,7 +843,7 @@ int lpcfg_parm_bytes(struct loadparm_context *lp_ctx, const char *value = lpcfg_get_parametric(lp_ctx, service, type, option); - if (value && conv_str_size(value, &bval)) { + if (value && conv_str_size_error(value, &bval)) { if (bval <= INT_MAX) { return (int)bval; } @@ -1031,7 +925,27 @@ static bool string_set(TALLOC_CTX *mem_ctx, char **dest, const char *src) *dest = talloc_strdup(mem_ctx, src); if ((*dest) == NULL) { - DEBUG(0,("Out of memory in string_init\n")); + DEBUG(0,("Out of memory in string_set\n")); + return false; + } + + return true; +} + +/** + * Set a string value, deallocating any existing space, and allocing the space + * for the string + */ +static bool string_set_upper(TALLOC_CTX *mem_ctx, char **dest, const char *src) +{ + talloc_free(*dest); + + if (src == NULL) + src = ""; + + *dest = strupper_talloc(mem_ctx, src); + if ((*dest) == NULL) { + DEBUG(0,("Out of memory in string_set_upper\n")); return false; } @@ -1151,9 +1065,9 @@ bool lpcfg_add_home(struct loadparm_context *lp_ctx, * Add a new printer service, with defaults coming from service iFrom. */ -bool lp_add_printer(struct loadparm_context *lp_ctx, - const char *pszPrintername, - struct loadparm_service *default_service) +bool lpcfg_add_printer(struct loadparm_context *lp_ctx, + const char *pszPrintername, + struct loadparm_service *default_service) { const char *comment = "From Printcap"; struct loadparm_service *service; @@ -1292,10 +1206,9 @@ static void copy_service(struct loadparm_service *pserviceDest, break; case P_USTRING: - string_set(pserviceDest, - (char **)dest_ptr, - *(char **)src_ptr); - strupper(*(char **)dest_ptr); + string_set_upper(pserviceDest, + (char **)dest_ptr, + *(char **)src_ptr); break; case P_LIST: *(const char ***)dest_ptr = (const char **)str_list_copy(pserviceDest, @@ -1422,7 +1335,7 @@ static void add_to_file_list(struct loadparm_context *lp_ctx, /******************************************************************* Check if a config file has changed date. ********************************************************************/ -bool lp_file_list_changed(struct loadparm_context *lp_ctx) +bool lpcfg_file_list_changed(struct loadparm_context *lp_ctx) { struct file_lists *f; DEBUG(6, ("lp_file_list_changed()\n")); @@ -1528,14 +1441,19 @@ static bool handle_debuglevel(struct loadparm_context *lp_ctx, { string_set(lp_ctx, ptr, pszParmValue); - return debug_parse_levels(pszParmValue); + if (lp_ctx->global) { + return debug_parse_levels(pszParmValue); + } + return true; } static bool handle_logfile(struct loadparm_context *lp_ctx, const char *pszParmValue, char **ptr) { debug_set_logfile(pszParmValue); - string_set(lp_ctx, ptr, pszParmValue); + if (lp_ctx->global) { + string_set(lp_ctx, ptr, pszParmValue); + } return true; } @@ -1574,11 +1492,9 @@ static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx, pszParmName++; } - name = strdup(pszParmName); + name = strlower_talloc(lp_ctx, pszParmName); if (!name) return false; - strlower(name); - if (service == NULL) { data = lp_ctx->globals->param_opt; mem_ctx = lp_ctx->globals; @@ -1594,13 +1510,14 @@ static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx, if (strcmp(paramo->key, name) == 0) { if ((paramo->priority & FLAG_CMDLINE) && !(flags & FLAG_CMDLINE)) { + talloc_free(name); return true; } talloc_free(paramo->value); paramo->value = talloc_strdup(paramo, pszParmValue); paramo->priority = flags; - free(name); + talloc_free(name); return true; } } @@ -1617,7 +1534,7 @@ static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx, DLIST_ADD(service->param_opt, paramo); } - free(name); + talloc_free(name); return true; } @@ -1662,7 +1579,7 @@ static bool set_variable(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr, case P_BYTES: { uint64_t val; - if (conv_str_size(pszParmValue, &val)) { + if (conv_str_size_error(pszParmValue, &val)) { if (val <= INT_MAX) { *(int *)parm_ptr = (int)val; break; @@ -1683,17 +1600,23 @@ static bool set_variable(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr, char **new_list = str_list_make(mem_ctx, pszParmValue, NULL); for (i=0; new_list[i]; i++) { - if (new_list[i][0] == '+' && new_list[i][1]) { + if (new_list[i][0] == '+' && new_list[i][1] && + (!str_list_check(*(const char ***)parm_ptr, + &new_list[i][1]))) { *(const char ***)parm_ptr = str_list_add(*(const char ***)parm_ptr, &new_list[i][1]); } else if (new_list[i][0] == '-' && new_list[i][1]) { +#if 0 /* This is commented out because we sometimes parse the list + * twice, and so we can't assert on this */ if (!str_list_check(*(const char ***)parm_ptr, &new_list[i][1])) { - DEBUG(0, ("Unsupported value for: %s = %s, %s is not in the original list\n", - pszParmName, pszParmValue, new_list[i])); + DEBUG(0, ("Unsupported value for: %s = %s, %s is not in the original list [%s]\n", + pszParmName, pszParmValue, new_list[i], + str_list_join_shell(mem_ctx, *(const char ***)parm_ptr, ' '))); return false; } +#endif str_list_remove(*(const char ***)parm_ptr, &new_list[i][1]); } else { @@ -1713,8 +1636,7 @@ static bool set_variable(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr, break; case P_USTRING: - string_set(mem_ctx, (char **)parm_ptr, pszParmValue); - strupper(*(char **)parm_ptr); + string_set_upper(mem_ctx, (char **)parm_ptr, pszParmValue); break; case P_ENUM: @@ -2275,7 +2197,7 @@ static void lpcfg_add_auto_services(struct loadparm_context *lp_ctx, * Unload unused services. */ -void lp_killunused(struct loadparm_context *lp_ctx, +void lpcfg_killunused(struct loadparm_context *lp_ctx, struct smbsrv_connection *smb, bool (*snumused) (struct smbsrv_connection *, int)) { @@ -2292,7 +2214,7 @@ void lp_killunused(struct loadparm_context *lp_ctx, } -static int lp_destructor(struct loadparm_context *lp_ctx) +static int lpcfg_destructor(struct loadparm_context *lp_ctx) { struct parmlist_entry *data; @@ -2333,7 +2255,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) if (lp_ctx == NULL) return NULL; - talloc_set_destructor(lp_ctx, lp_destructor); + talloc_set_destructor(lp_ctx, lpcfg_destructor); lp_ctx->bInGlobalSection = true; lp_ctx->globals = talloc_zero(lp_ctx, struct loadparm_global); lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service); @@ -2400,13 +2322,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "ntptr providor", "simple_ldb"); /* the winbind method for domain controllers is for both RODC auth forwarding and for trusted domains */ - lpcfg_do_global_parameter(lp_ctx, "auth methods:domain controller", "anonymous sam_ignoredomain winbind"); - lpcfg_do_global_parameter(lp_ctx, "auth methods:member server", "anonymous sam winbind"); - lpcfg_do_global_parameter(lp_ctx, "auth methods:standalone", "anonymous sam_ignoredomain"); lpcfg_do_global_parameter(lp_ctx, "private dir", dyn_PRIVATE_DIR); - lpcfg_do_global_parameter(lp_ctx, "sam database", "sam.ldb"); - lpcfg_do_global_parameter(lp_ctx, "idmap database", "idmap.ldb"); - lpcfg_do_global_parameter(lp_ctx, "secrets database", "secrets.ldb"); lpcfg_do_global_parameter(lp_ctx, "spoolss database", "spoolss.ldb"); lpcfg_do_global_parameter(lp_ctx, "wins config database", "wins_config.ldb"); lpcfg_do_global_parameter(lp_ctx, "wins database", "wins.ldb"); @@ -2430,10 +2346,9 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "pid directory", dyn_PIDDIR); lpcfg_do_global_parameter(lp_ctx, "lock dir", dyn_LOCKDIR); - lpcfg_do_global_parameter(lp_ctx, "modules dir", dyn_MODULESDIR); lpcfg_do_global_parameter(lp_ctx, "ncalrpc dir", dyn_NCALRPCDIR); - lpcfg_do_global_parameter(lp_ctx, "socket address", "0.0.0.0"); + lpcfg_do_global_parameter(lp_ctx, "socket address", ""); lpcfg_do_global_parameter_var(lp_ctx, "server string", "Samba %s", SAMBA_VERSION_STRING); @@ -2541,6 +2456,7 @@ struct loadparm_context *loadparm_init_global(bool load_default) if (global_loadparm_context == NULL) { return NULL; } + global_loadparm_context->global = true; if (load_default && !global_loadparm_context->loaded) { lpcfg_load_default(global_loadparm_context); } @@ -2548,6 +2464,20 @@ struct loadparm_context *loadparm_init_global(bool load_default) return global_loadparm_context; } +/** + * Initialise the global parameter structure. + */ +struct loadparm_context *loadparm_init_s3(TALLOC_CTX *mem_ctx, + const struct loadparm_s3_context *s3_fns) +{ + struct loadparm_context *loadparm_context = loadparm_init(mem_ctx); + if (!loadparm_context) { + return NULL; + } + loadparm_context->s3_fns = s3_fns; + return loadparm_context; +} + const char *lpcfg_configfile(struct loadparm_context *lp_ctx) { return lp_ctx->szConfigFile; @@ -2574,6 +2504,10 @@ static bool lpcfg_update(struct loadparm_context *lp_ctx) lpcfg_do_global_parameter(lp_ctx, "wins server", "127.0.0.1"); } + if (!lp_ctx->global) { + return true; + } + panic_action = lp_ctx->globals->panic_action; reload_charcnv(lp_ctx); @@ -2584,8 +2518,6 @@ static bool lpcfg_update(struct loadparm_context *lp_ctx) settings.timestamp_logs = true; debug_set_settings(&settings); - /* FIXME: ntstatus_check_dos_mapping = lpcfg_nt_status_support(lp_ctx); */ - /* FIXME: This is a bit of a hack, but we can't use a global, since * not everything that uses lp also uses the socket library */ if (lpcfg_parm_bool(lp_ctx, NULL, "socket", "testnonblock", false)) { @@ -2594,12 +2526,6 @@ static bool lpcfg_update(struct loadparm_context *lp_ctx) unsetenv("SOCKET_TESTNONBLOCK"); } - /* FIXME: Check locale in environment for this: */ - if (strcmp(lpcfg_display_charset(lp_ctx), lpcfg_unix_charset(lp_ctx)) != 0) - d_set_iconv(smb_iconv_open(lpcfg_display_charset(lp_ctx), lpcfg_unix_charset(lp_ctx))); - else - d_set_iconv((smb_iconv_t)-1); - return true; } @@ -2750,7 +2676,7 @@ const char *lpcfg_servicename(const struct loadparm_service *service) /** * A useful volume label function. */ -const char *volume_label(struct loadparm_service *service, struct loadparm_service *sDefault) +const char *lpcfg_volume_label(struct loadparm_service *service, struct loadparm_service *sDefault) { const char *ret; ret = lp_string((const char *)((service != NULL && service->volume != NULL) ? @@ -2798,6 +2724,10 @@ struct smb_iconv_handle *lpcfg_iconv_handle(struct loadparm_context *lp_ctx) _PUBLIC_ void reload_charcnv(struct loadparm_context *lp_ctx) { struct smb_iconv_handle *old_ic = lp_ctx->iconv_handle; + if (!lp_ctx->global) { + return; + } + if (old_ic == NULL) { old_ic = global_iconv_handle; } @@ -2830,27 +2760,27 @@ void lpcfg_smbcli_session_options(struct loadparm_context *lp_ctx, _PUBLIC_ char *lpcfg_tls_keyfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) { - return private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_keyfile); + return lpcfg_private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_keyfile); } _PUBLIC_ char *lpcfg_tls_certfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) { - return private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_certfile); + return lpcfg_private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_certfile); } _PUBLIC_ char *lpcfg_tls_cafile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) { - return private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_cafile); + return lpcfg_private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_cafile); } _PUBLIC_ char *lpcfg_tls_crlfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) { - return private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_crlfile); + return lpcfg_private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_crlfile); } _PUBLIC_ char *lpcfg_tls_dhpfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) { - return private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_dhpfile); + return lpcfg_private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_dhpfile); } _PUBLIC_ struct dcerpc_server_info *lpcfg_dcerpc_server_info(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) diff --git a/source4/param/param.h b/source4/param/param.h index b8fb369bdb..ebf41f7213 100644 --- a/source4/param/param.h +++ b/source4/param/param.h @@ -20,6 +20,8 @@ #ifndef _PARAM_H /* _PARAM_H */ #define _PARAM_H +struct loadparm_s3_context; + struct parmlist_entry; struct param_context { @@ -45,23 +47,7 @@ typedef NTSTATUS (*init_module_fn) (void); function init_module() which makes a system call */ #define SAMBA_INIT_MODULE "samba_init_module" -enum server_role { - ROLE_STANDALONE=0, - ROLE_DOMAIN_MEMBER=1, - ROLE_DOMAIN_CONTROLLER=2, -}; - -enum sid_generator { - SID_GENERATOR_INTERNAL=0, - SID_GENERATOR_BACKEND=1, -}; - -enum announce_as {/* Types of machine we can announce as. */ - ANNOUNCE_AS_NT_SERVER=1, - ANNOUNCE_AS_WIN95=2, - ANNOUNCE_AS_WFW=3, - ANNOUNCE_AS_NT_WORKSTATION=4 -}; +#include "libds/common/roles.h" struct loadparm_context; struct loadparm_service; @@ -211,7 +197,7 @@ struct loadparm_service *lpcfg_service(struct loadparm_context *lp_ctx, /** * A useful volume label function. */ -const char *volume_label(struct loadparm_service *service, struct loadparm_service *sDefault); +const char *lp_cfg_volume_label(struct loadparm_service *service, struct loadparm_service *sDefault); /** * If we are PDC then prefer us as DMB @@ -274,7 +260,7 @@ bool lpcfg_is_myname(struct loadparm_context *lp_ctx, const char *name); /** A useful function for returning a path in the Samba lock directory. **/ -char *lock_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, +char *lpcfg_lock_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, const char *name); /** @@ -284,7 +270,7 @@ char *lock_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, * * @retval Pointer to a talloc'ed string containing the full path. **/ -char *config_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, +char *lpcfg_config_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, const char *name); /** @@ -295,7 +281,7 @@ char *config_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, * * @retval Pointer to a talloc'ed string containing the full path. **/ -char *private_path(TALLOC_CTX* mem_ctx, +char *lpcfg_private_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, const char *name); @@ -331,8 +317,8 @@ bool run_init_functions(init_module_fn *fns); * * Will return an array of function pointers to initialization functions */ -init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, const char *subsystem); -const char *lpcfg_messaging_path(TALLOC_CTX *mem_ctx, +init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, const char *subsystem); +const char *lpcfg_imessaging_path(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); struct smb_iconv_handle *smb_iconv_handle_reinit_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, diff --git a/source4/param/pyparam.c b/source4/param/pyparam.c index 3ba8146860..e1ba18415d 100644 --- a/source4/param/pyparam.c +++ b/source4/param/pyparam.c @@ -229,7 +229,7 @@ static PyObject *py_lp_ctx_private_path(py_talloc_Object *self, PyObject *args) if (!PyArg_ParseTuple(args, "s", &name)) return NULL; - path = private_path(NULL, PyLoadparmContext_AsLoadparmContext(self), name); + path = lpcfg_private_path(NULL, PyLoadparmContext_AsLoadparmContext(self), name); ret = PyString_FromString(path); talloc_free(path); @@ -272,6 +272,12 @@ static PyObject *py_lp_dump(PyObject *self, PyObject *args) Py_RETURN_NONE; } +static PyObject *py_samdb_url(PyObject *self) +{ + struct loadparm_context *lp_ctx = PyLoadparmContext_AsLoadparmContext(self); + return PyString_FromFormat("tdb://%s/sam.ldb", lpcfg_private_dir(lp_ctx)); +} + static PyMethodDef py_lp_ctx_methods[] = { { "load", (PyCFunction)py_lp_ctx_load, METH_VARARGS, @@ -298,6 +304,9 @@ static PyMethodDef py_lp_ctx_methods[] = { "S.services() -> list" }, { "dump", (PyCFunction)py_lp_dump, METH_VARARGS, "S.dump(stream, show_defaults=False)" }, + { "samdb_url", (PyCFunction)py_samdb_url, METH_NOARGS, + "S.samdb_url() -> string\n" + "Returns the current URL for sam.ldb." }, { NULL } }; @@ -431,11 +440,18 @@ static PyObject *py_setup_dir(PyObject *self) return PyString_FromString(dyn_SETUPDIR); } +static PyObject *py_modules_dir(PyObject *self) +{ + return PyString_FromString(dyn_MODULESDIR); +} + static PyMethodDef pyparam_methods[] = { { "default_path", (PyCFunction)py_default_path, METH_NOARGS, "Returns the default smb.conf path." }, { "setup_dir", (PyCFunction)py_setup_dir, METH_NOARGS, "Returns the compiled in location of provision tempates." }, + { "modules_dir", (PyCFunction)py_modules_dir, METH_NOARGS, + "Returns the compiled in location of modules." }, { NULL } }; diff --git a/source4/param/secrets.c b/source4/param/secrets.c index 13bfcc5e96..55d1aa779b 100644 --- a/source4/param/secrets.c +++ b/source4/param/secrets.c @@ -25,7 +25,7 @@ #include "secrets.h" #include "param/param.h" #include "system/filesys.h" -#include "tdb_wrap.h" +#include "lib/util/tdb_wrap.h" #include "lib/ldb-samba/ldb_wrap.h" #include <ldb.h> #include "../lib/util/util_tdb.h" @@ -49,22 +49,22 @@ static void get_rand_seed(struct tdb_wrap *secretsdb, int *new_seed) } /** - * open up the secrets database + * open up the randseed database and set the random number generator callback */ -struct tdb_wrap *secrets_init(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) +bool randseed_init(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) { char *fname; uint8_t dummy; struct tdb_wrap *tdb; - fname = private_path(mem_ctx, lp_ctx, "secrets.tdb"); + fname = lpcfg_private_path(mem_ctx, lp_ctx, "randseed.tdb"); tdb = tdb_wrap_open(mem_ctx, fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); if (!tdb) { DEBUG(0,("Failed to open %s\n", fname)); talloc_free(fname); - return NULL; + return false; } talloc_free(fname); @@ -79,7 +79,7 @@ struct tdb_wrap *secrets_init(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_c /* Ensure that the reseed is done now, while we are root, etc */ generate_random_buffer(&dummy, sizeof(dummy)); - return tdb; + return true; } /** @@ -88,7 +88,7 @@ struct tdb_wrap *secrets_init(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_c struct ldb_context *secrets_db_connect(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) { - return ldb_wrap_connect(mem_ctx, NULL, lp_ctx, lpcfg_secrets_url(lp_ctx), + return ldb_wrap_connect(mem_ctx, NULL, lp_ctx, "secrets.ldb", NULL, NULL, 0); } diff --git a/source4/param/secrets.h b/source4/param/secrets.h index 4cab9ccadd..6576929a0d 100644 --- a/source4/param/secrets.h +++ b/source4/param/secrets.h @@ -43,7 +43,8 @@ struct ldb_context; #include "librpc/gen_ndr/misc.h" -struct tdb_wrap *secrets_init(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); +bool randseed_init(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); + struct ldb_context *secrets_db_connect(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); struct dom_sid *secrets_get_domain_sid(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, diff --git a/source4/param/share_classic.c b/source4/param/share_classic.c index 3d5bef91e1..3442d6bd50 100644 --- a/source4/param/share_classic.c +++ b/source4/param/share_classic.c @@ -84,7 +84,7 @@ static const char *sclassic_string_option(struct share_config *scfg, } if (strcmp(opt_name, SHARE_VOLUME) == 0) { - return volume_label(s, lpcfg_default_service(lp_ctx)); + return lpcfg_volume_label(s, lpcfg_default_service(lp_ctx)); } if (strcmp(opt_name, SHARE_TYPE) == 0) { diff --git a/source4/param/share_ldb.c b/source4/param/share_ldb.c index c4ab319398..f4d02b295a 100644 --- a/source4/param/share_ldb.c +++ b/source4/param/share_ldb.c @@ -43,7 +43,7 @@ static NTSTATUS sldb_init(TALLOC_CTX *mem_ctx, const struct share_ops *ops, } sdb = ldb_wrap_connect(*ctx, ev_ctx, lp_ctx, - private_path(*ctx, lp_ctx, "share.ldb"), + lpcfg_private_path(*ctx, lp_ctx, "share.ldb"), system_session(lp_ctx), NULL, 0); diff --git a/source4/param/util.c b/source4/param/util.c index 3413f25e49..b1a7a571e6 100644 --- a/source4/param/util.c +++ b/source4/param/util.c @@ -75,7 +75,7 @@ bool lpcfg_is_myname(struct loadparm_context *lp_ctx, const char *name) /** A useful function for returning a path in the Samba lock directory. **/ -char *lock_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, +char *lpcfg_lock_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, const char *name) { char *fname, *dname; @@ -108,7 +108,7 @@ char *lock_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, * @retval Pointer to a talloc'ed string containing the full path. **/ -char *config_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, +char *lpcfg_config_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, const char *name) { char *fname, *config_dir, *p; @@ -139,7 +139,7 @@ char *config_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, * * @retval Pointer to a talloc'ed string containing the full path. **/ -char *private_path(TALLOC_CTX* mem_ctx, +char *lpcfg_private_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, const char *name) { @@ -165,7 +165,7 @@ char *smbd_tmp_path(TALLOC_CTX *mem_ctx, { char *fname, *dname; - dname = private_path(mem_ctx, lp_ctx, "smbd.tmp"); + dname = lpcfg_private_path(mem_ctx, lp_ctx, "smbd.tmp"); if (!directory_exist(dname)) { mkdir(dname,0755); } @@ -266,23 +266,15 @@ bool run_init_functions(init_module_fn *fns) return ret; } -static char *modules_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, - const char *name) -{ - return talloc_asprintf(mem_ctx, "%s/%s", - lpcfg_modulesdir(lp_ctx), - name); -} - /** * Load the initialization functions from DSO files for a specific subsystem. * * Will return an array of function pointers to initialization functions */ -init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, const char *subsystem) +init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, const char *subsystem) { - char *path = modules_path(mem_ctx, lp_ctx, subsystem); + char *path = modules_path(mem_ctx, subsystem); init_module_fn *ret; ret = load_modules(mem_ctx, path); @@ -292,7 +284,7 @@ init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, struct loadparm_context return ret; } -const char *lpcfg_messaging_path(TALLOC_CTX *mem_ctx, +const char *lpcfg_imessaging_path(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) { return smbd_tmp_path(mem_ctx, lp_ctx, "msg"); @@ -304,7 +296,6 @@ struct smb_iconv_handle *smb_iconv_handle_reinit_lp(TALLOC_CTX *mem_ctx, { return smb_iconv_handle_reinit(mem_ctx, lpcfg_dos_charset(lp_ctx), lpcfg_unix_charset(lp_ctx), - lpcfg_display_charset(lp_ctx), lpcfg_parm_bool(lp_ctx, NULL, "iconv", "native", true), old_ic); } @@ -313,7 +304,8 @@ struct smb_iconv_handle *smb_iconv_handle_reinit_lp(TALLOC_CTX *mem_ctx, const char *lpcfg_sam_name(struct loadparm_context *lp_ctx) { switch (lpcfg_server_role(lp_ctx)) { - case ROLE_DOMAIN_CONTROLLER: + case ROLE_DOMAIN_BDC: + case ROLE_DOMAIN_PDC: return lpcfg_workgroup(lp_ctx); default: return lpcfg_netbios_name(lp_ctx); diff --git a/source4/param/wscript_build b/source4/param/wscript_build index 72674e5574..da10565c6c 100644 --- a/source4/param/wscript_build +++ b/source4/param/wscript_build @@ -1,5 +1,20 @@ #!/usr/bin/env python +bld.SAMBA_GENERATOR('s3_param_h', + source= 'loadparm.c ../script/mks3param.pl', + target='s3_param.h', + rule='${PERL} ${SRC[1].abspath(env)} ${SRC[0].abspath(env)} --file ${TGT}') + +bld.SAMBA_GENERATOR('param_local_h', + source= 'loadparm.c ../script/mkparamdefs.pl', + target='param_local.h', + rule='${PERL} ${SRC[1].abspath(env)} ${SRC[0].abspath(env)} --file ${TGT} --generate-scope=LOCAL') + +bld.SAMBA_GENERATOR('param_global_h', + source= 'loadparm.c ../script/mkparamdefs.pl', + target='param_global.h', + rule='${PERL} ${SRC[1].abspath(env)} ${SRC[0].abspath(env)} --file ${TGT} --generate-scope=GLOBAL') + bld.SAMBA_LIBRARY('samba-hostconfig', source='loadparm.c generic.c util.c', pc_files='samba-hostconfig.pc', diff --git a/source4/partition-upgrade.txt b/source4/partition-upgrade.txt deleted file mode 100644 index 0abc810c3a..0000000000 --- a/source4/partition-upgrade.txt +++ /dev/null @@ -1,21 +0,0 @@ -PARTITIONS UPGRADE -================== - -Notes on using Samba4 after the partitions code upgrade on 21 Oct 2009 - -The data previously stored in Samba4 partitions is no longer -accessible, as we have changed the filenames. - -To access your Samba4 tree again, backup your Samba4 prefix, and -re-run provision with the same settings as in the past. - -This will create new databases in your PREFIX/private directory, like -DC=SAMBA,DC=EXAMPLE,DC=COM.ldb. - -Restore your users.ldb to the DC=SAMBA,DC=EXAMPLE,DC=COM.ldb, -configuration.ldb to CN=CONFIGURATION,DC=SAMBA,DC=EXAMPLE,DC=COM.ldb -and schema.ldb to -CN=SCHEMA,CN=CONFIGURATION,DC=SAMBA,DC=EXAMPLE,DC=COM.ldb - -Also remember to restore your secrets.ldb. - diff --git a/source4/rpc_server/common/server_info.c b/source4/rpc_server/common/server_info.c index 7f533ecf77..68985d81aa 100644 --- a/source4/rpc_server/common/server_info.c +++ b/source4/rpc_server/common/server_info.c @@ -68,22 +68,8 @@ uint32_t dcesrv_common_get_server_type(TALLOC_CTX *mem_ctx, struct tevent_contex default_server_announce |= SV_TYPE_SERVER; default_server_announce |= SV_TYPE_SERVER_UNIX; - switch (lpcfg_announce_as(dce_ctx->lp_ctx)) { - case ANNOUNCE_AS_NT_SERVER: - default_server_announce |= SV_TYPE_SERVER_NT; - /* fall through... */ - case ANNOUNCE_AS_NT_WORKSTATION: - default_server_announce |= SV_TYPE_NT; - break; - case ANNOUNCE_AS_WIN95: - default_server_announce |= SV_TYPE_WIN95_PLUS; - break; - case ANNOUNCE_AS_WFW: - default_server_announce |= SV_TYPE_WFW; - break; - default: - break; - } + default_server_announce |= SV_TYPE_SERVER_NT; + default_server_announce |= SV_TYPE_NT; switch (lpcfg_server_role(dce_ctx->lp_ctx)) { case ROLE_DOMAIN_MEMBER: diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index cd079da5c9..cbba5e2408 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -366,7 +366,7 @@ _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint *ep, struct auth_session_info *session_info, struct tevent_context *event_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, struct server_id server_id, uint32_t state_flags, struct dcesrv_connection **_p) @@ -1235,7 +1235,7 @@ void dcerpc_server_init(struct loadparm_context *lp_ctx) } initialized = true; - shared_init = load_samba_modules(NULL, lp_ctx, "dcerpc_server"); + shared_init = load_samba_modules(NULL, "dcerpc_server"); run_init_functions(static_init); run_init_functions(shared_init); @@ -1353,7 +1353,7 @@ static void dcesrv_sock_reply_done(struct tevent_req *subreq) ret = tstream_writev_queue_recv(subreq, &sys_errno); TALLOC_FREE(subreq); if (ret == -1) { - status = map_nt_error_from_unix(sys_errno); + status = map_nt_error_from_unix_common(sys_errno); dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status)); return; } @@ -1436,7 +1436,7 @@ static void dcesrv_sock_accept(struct stream_connection *srv_conn) socket_get_fd(srv_conn->socket), &dcesrv_conn->stream); if (ret == -1) { - status = map_nt_error_from_unix(errno); + status = map_nt_error_from_unix_common(errno); DEBUG(0, ("dcesrv_sock_accept: " "failed to setup tstream: %s\n", nt_errstr(status))); @@ -1648,7 +1648,7 @@ static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx, model_ops, &dcesrv_stream_ops, - "ipv4", address, &port, + "ip", address, &port, lpcfg_socket_options(dce_ctx->lp_ctx), dcesrv_sock); if (!NT_STATUS_IS_OK(status)) { @@ -1678,18 +1678,24 @@ static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, int i; struct interface *ifaces; - load_interfaces(dce_ctx, lpcfg_interfaces(lp_ctx), &ifaces); + load_interface_list(dce_ctx, lp_ctx, &ifaces); - num_interfaces = iface_count(ifaces); + num_interfaces = iface_list_count(ifaces); for(i = 0; i < num_interfaces; i++) { - const char *address = iface_n_ip(ifaces, i); + const char *address = iface_list_n_ip(ifaces, i); status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address); NT_STATUS_NOT_OK_RETURN(status); } } else { - status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, - lpcfg_socket_address(lp_ctx)); - NT_STATUS_NOT_OK_RETURN(status); + const char **wcard; + int i; + wcard = iface_list_wildcard(dce_ctx, lp_ctx); + NT_STATUS_HAVE_NO_MEMORY(wcard); + for (i=0; wcard[i]; i++) { + status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]); + NT_STATUS_NOT_OK_RETURN(status); + } + talloc_free(wcard); } return NT_STATUS_OK; diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 024009ab70..4fcb5c50a1 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -23,7 +23,7 @@ #ifndef SAMBA_DCERPC_SERVER_H #define SAMBA_DCERPC_SERVER_H -#include "librpc/gen_ndr/server_id4.h" +#include "librpc/gen_ndr/server_id.h" #include "librpc/rpc/dcerpc.h" #include "librpc/ndr/libndr.h" @@ -111,7 +111,7 @@ struct dcesrv_call_state { struct tevent_context *event_ctx; /* the message_context that will be used for async replies */ - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; /* this is the pointer to the allocated function struct */ void *r; @@ -200,7 +200,7 @@ struct dcesrv_connection { struct tevent_context *event_ctx; /* the message_context that will be used for this connection */ - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; /* the server_id that will be used for this connection */ struct server_id server_id; @@ -319,7 +319,7 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint *ep, struct auth_session_info *session_info, struct tevent_context *event_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, struct server_id server_id, uint32_t state_flags, struct dcesrv_connection **_p); diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index 8ae536823d..c57fec2049 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -360,27 +360,37 @@ static WERROR get_nc_changes_add_la(TALLOC_CTX *mem_ctx, la->attid = sa->attributeID_id; la->flags = active?DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE:0; - status = dsdb_get_extended_dn_nttime(dsdb_dn->dn, &la->originating_add_time, "RMD_ADDTIME"); - if (!NT_STATUS_IS_OK(status)) { - return ntstatus_to_werror(status); - } status = dsdb_get_extended_dn_uint32(dsdb_dn->dn, &la->meta_data.version, "RMD_VERSION"); if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,(__location__ " No RMD_VERSION in linked attribute '%s' in '%s'\n", + sa->lDAPDisplayName, ldb_dn_get_linearized(msg->dn))); return ntstatus_to_werror(status); } status = dsdb_get_extended_dn_nttime(dsdb_dn->dn, &la->meta_data.originating_change_time, "RMD_CHANGETIME"); if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,(__location__ " No RMD_CHANGETIME in linked attribute '%s' in '%s'\n", + sa->lDAPDisplayName, ldb_dn_get_linearized(msg->dn))); return ntstatus_to_werror(status); } status = dsdb_get_extended_dn_guid(dsdb_dn->dn, &la->meta_data.originating_invocation_id, "RMD_INVOCID"); if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,(__location__ " No RMD_INVOCID in linked attribute '%s' in '%s'\n", + sa->lDAPDisplayName, ldb_dn_get_linearized(msg->dn))); return ntstatus_to_werror(status); } status = dsdb_get_extended_dn_uint64(dsdb_dn->dn, &la->meta_data.originating_usn, "RMD_ORIGINATING_USN"); if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,(__location__ " No RMD_ORIGINATING_USN in linked attribute '%s' in '%s'\n", + sa->lDAPDisplayName, ldb_dn_get_linearized(msg->dn))); return ntstatus_to_werror(status); } + status = dsdb_get_extended_dn_nttime(dsdb_dn->dn, &la->originating_add_time, "RMD_ADDTIME"); + if (!NT_STATUS_IS_OK(status)) { + /* this is possible for upgraded links */ + la->originating_add_time = la->meta_data.originating_change_time; + } + werr = dsdb_dn_la_to_blob(sam_ctx, sa, schema, *la_list, dsdb_dn, &la->value.blob); W_ERROR_NOT_OK_RETURN(werr); @@ -993,12 +1003,14 @@ static WERROR getncchanges_change_master(struct drsuapi_bind_state *b_state, msg->dn = drs_ObjectIdentifier_to_dn(msg, ldb, req10->naming_context); W_ERROR_HAVE_NO_MEMORY(msg->dn); + /* TODO: make sure ntds_dn is a valid nTDSDSA object */ ret = dsdb_find_dn_by_guid(ldb, msg, &req10->destination_dsa_guid, &ntds_dn); if (ret != LDB_SUCCESS) { DEBUG(0, (__location__ ": Unable to find NTDS object for guid %s - %s\n", GUID_string(mem_ctx, &req10->destination_dsa_guid), ldb_errstring(ldb))); talloc_free(msg); - return WERR_DS_DRA_INTERNAL_ERROR; + ctr6->extended_ret = DRSUAPI_EXOP_ERR_UNKNOWN_CALLER; + return WERR_OK; } ret = ldb_msg_add_string(msg, "fSMORoleOwner", ldb_dn_get_linearized(ntds_dn)); @@ -1161,6 +1173,91 @@ getncchanges_map_req8(TALLOC_CTX *mem_ctx, } +/** + * Collects object for normal replication cycle. + */ +static WERROR getncchanges_collect_objects(struct drsuapi_bind_state *b_state, + TALLOC_CTX *mem_ctx, + struct drsuapi_DsGetNCChangesRequest10 *req10, + struct ldb_dn *search_dn, + const char *extra_filter, + struct ldb_result **search_res) +{ + int ret; + char* search_filter; + enum ldb_scope scope = LDB_SCOPE_SUBTREE; + //const char *extra_filter; + struct drsuapi_getncchanges_state *getnc_state = b_state->getncchanges_state; + const char *attrs[] = { "uSNChanged", + "objectGUID" , + NULL }; + + if (req10->extended_op == DRSUAPI_EXOP_REPL_OBJ || + req10->extended_op == DRSUAPI_EXOP_REPL_SECRET) { + scope = LDB_SCOPE_BASE; + } + + //extra_filter = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "drs", "object filter"); + + //getnc_state->min_usn = req10->highwatermark.highest_usn; + + /* Construct response. */ + search_filter = talloc_asprintf(mem_ctx, + "(uSNChanged>=%llu)", + (unsigned long long)(getnc_state->min_usn+1)); + + if (extra_filter) { + search_filter = talloc_asprintf(mem_ctx, "(&%s(%s))", search_filter, extra_filter); + } + + if (req10->replica_flags & DRSUAPI_DRS_CRITICAL_ONLY) { + search_filter = talloc_asprintf(mem_ctx, + "(&%s(isCriticalSystemObject=TRUE))", + search_filter); + } + + if (req10->replica_flags & DRSUAPI_DRS_ASYNC_REP) { + scope = LDB_SCOPE_BASE; + } + + if (!search_dn) { + search_dn = getnc_state->ncRoot_dn; + } + + DEBUG(2,(__location__ ": getncchanges on %s using filter %s\n", + ldb_dn_get_linearized(getnc_state->ncRoot_dn), search_filter)); + ret = drsuapi_search_with_extended_dn(b_state->sam_ctx, getnc_state, search_res, + search_dn, scope, attrs, + search_filter); + if (ret != LDB_SUCCESS) { + return WERR_DS_DRA_INTERNAL_ERROR; + } + + return WERR_OK; +} + +/** + * Collects object for normal replication cycle. + */ +static WERROR getncchanges_collect_objects_exop(struct drsuapi_bind_state *b_state, + TALLOC_CTX *mem_ctx, + struct drsuapi_DsGetNCChangesRequest10 *req10, + struct drsuapi_DsGetNCChangesCtr6 *ctr6, + struct ldb_dn *search_dn, + const char *extra_filter, + struct ldb_result **search_res) +{ + /* we have nothing to do in case of ex-op failure */ + if (ctr6->extended_ret != DRSUAPI_EXOP_ERR_SUCCESS) { + return WERR_OK; + } + + /* TODO: implement extended op specific collection + * of objects. Right now we just normal procedure + * for collecting objects */ + return getncchanges_collect_objects(b_state, mem_ctx, req10, search_dn, extra_filter, search_res); +} + /* drsuapi_DsGetNCChanges @@ -1177,9 +1274,6 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ struct drsuapi_DsReplicaObjectListItemEx **currentObject; NTSTATUS status; DATA_BLOB session_key; - const char *attrs[] = { "uSNChanged", - "objectGUID" , - NULL }; WERROR werr; struct dcesrv_handle *h; struct drsuapi_bind_state *b_state; @@ -1327,6 +1421,10 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ ldb_get_schema_basedn(b_state->sam_ctx)); getnc_state->is_schema_nc = (0 == ret); + if (req10->extended_op != DRSUAPI_EXOP_NONE) { + r->out.ctr->ctr6.extended_ret = DRSUAPI_EXOP_ERR_SUCCESS; + } + /* * This is the first replication cycle and it is * a good place to handle extended operations @@ -1391,64 +1489,39 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ Work out if this is the start of a new cycle */ if (getnc_state->guids == NULL) { - char* search_filter; - enum ldb_scope scope = LDB_SCOPE_SUBTREE; const char *extra_filter; - struct ldb_result *search_res; - - if (req10->extended_op == DRSUAPI_EXOP_REPL_OBJ || - req10->extended_op == DRSUAPI_EXOP_REPL_SECRET) { - scope = LDB_SCOPE_BASE; - } + struct ldb_result *search_res = NULL; extra_filter = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "drs", "object filter"); getnc_state->min_usn = req10->highwatermark.highest_usn; - /* Construct response. */ - search_filter = talloc_asprintf(mem_ctx, - "(uSNChanged>=%llu)", - (unsigned long long)(getnc_state->min_usn+1)); - - if (extra_filter) { - search_filter = talloc_asprintf(mem_ctx, "(&%s(%s))", search_filter, extra_filter); - } - - if (req10->replica_flags & DRSUAPI_DRS_CRITICAL_ONLY) { - search_filter = talloc_asprintf(mem_ctx, - "(&%s(isCriticalSystemObject=TRUE))", - search_filter); - } - - if (req10->replica_flags & DRSUAPI_DRS_ASYNC_REP) { - scope = LDB_SCOPE_BASE; - } - - if (!search_dn) { - search_dn = getnc_state->ncRoot_dn; - } - - DEBUG(2,(__location__ ": getncchanges on %s using filter %s\n", - ldb_dn_get_linearized(getnc_state->ncRoot_dn), search_filter)); - ret = drsuapi_search_with_extended_dn(sam_ctx, getnc_state, &search_res, - search_dn, scope, attrs, - search_filter); - if (ret != LDB_SUCCESS) { - return WERR_DS_DRA_INTERNAL_ERROR; - } - - if (req10->replica_flags & DRSUAPI_DRS_GET_ANC) { - TYPESAFE_QSORT(search_res->msgs, - search_res->count, - site_res_cmp_parent_order); + if (req10->extended_op == DRSUAPI_EXOP_NONE) { + werr = getncchanges_collect_objects(b_state, mem_ctx, req10, + search_dn, extra_filter, + &search_res); } else { - TYPESAFE_QSORT(search_res->msgs, - search_res->count, - site_res_cmp_usn_order); + werr = getncchanges_collect_objects_exop(b_state, mem_ctx, req10, + &r->out.ctr->ctr6, + search_dn, extra_filter, + &search_res); + } + W_ERROR_NOT_OK_RETURN(werr); + + if (search_res) { + if (req10->replica_flags & DRSUAPI_DRS_GET_ANC) { + TYPESAFE_QSORT(search_res->msgs, + search_res->count, + site_res_cmp_parent_order); + } else { + TYPESAFE_QSORT(search_res->msgs, + search_res->count, + site_res_cmp_usn_order); + } } /* extract out the GUIDs list */ - getnc_state->num_records = search_res->count; + getnc_state->num_records = search_res ? search_res->count : 0; getnc_state->guids = talloc_array(getnc_state, struct GUID, getnc_state->num_records); W_ERROR_HAVE_NO_MEMORY(getnc_state->guids); @@ -1705,7 +1778,6 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ r->out.ctr->ctr6.uptodateness_vector = NULL; r->out.ctr->ctr6.nc_object_count = 0; ZERO_STRUCT(r->out.ctr->ctr6.new_highwatermark); - r->out.ctr->ctr6.extended_ret = DRSUAPI_EXOP_ERR_SUCCESS; } DEBUG(r->out.ctr->ctr6.more_data?4:2, diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index b9fe5a3f40..50ce2346ad 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -1429,7 +1429,7 @@ static NTSTATUS update_uint32_t_value(TALLOC_CTX *mem_ctx, { const struct ldb_val *orig_val; uint32_t orig_uint = 0; - int flags = 0; + unsigned int flags = 0; int ret; orig_val = ldb_msg_find_ldb_val(orig, attribute); diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index bf8b4844a0..d5a7eebb55 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -37,6 +37,7 @@ #include "lib/tsocket/tsocket.h" #include "librpc/gen_ndr/ndr_netlogon.h" #include "librpc/gen_ndr/ndr_irpc.h" +#include "lib/socket/netif.h" struct netlogon_server_pipe_state { struct netr_Credential client_challenge; @@ -600,7 +601,7 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_check(const struct netr_LogonSamLogonE static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_LogonSamLogonEx *r, struct netlogon_creds_CredentialState *creds) { - struct auth_context *auth_context; + struct auth4_context *auth_context; struct auth_usersupplied_info *user_info; struct auth_user_info_dc *user_info_dc; NTSTATUS nt_status; @@ -1233,6 +1234,7 @@ static NTSTATUS dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_LogonGetCapabilities *r) { + /* we don't support AES yet */ return NT_STATUS_NOT_IMPLEMENTED; } @@ -1710,6 +1712,8 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, NTSTATUS status; const char *dc_name = NULL; const char *domain_name = NULL; + struct interface *ifaces; + const char *pdc_ip; ZERO_STRUCTP(r->out.info); @@ -1815,10 +1819,15 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, W_ERROR_HAVE_NO_MEMORY(info); info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s", dc_name); W_ERROR_HAVE_NO_MEMORY(info->dc_unc); - info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s", - response.data.nt5_ex.sockaddr.pdc_ip); + + load_interface_list(mem_ctx, lp_ctx, &ifaces); + pdc_ip = iface_list_best_ip(ifaces, addr); + if (pdc_ip == NULL) { + pdc_ip = "127.0.0.1"; + } + info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s", pdc_ip); W_ERROR_HAVE_NO_MEMORY(info->dc_address); - info->dc_address_type = DS_ADDRESS_TYPE_INET; /* TODO: make this dynamic? for ipv6 */ + info->dc_address_type = DS_ADDRESS_TYPE_INET; info->domain_guid = response.data.nt5_ex.domain_uuid; info->domain_name = domain_name; info->forest_name = response.data.nt5_ex.forest; diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 1c7416cb7b..32aafcd23f 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -510,6 +510,9 @@ static NTSTATUS dcesrv_samr_info_DomGeneralInformation(struct samr_domain_state info->role = SAMR_ROLE_DOMAIN_BDC; } break; + case ROLE_DOMAIN_PDC: + info->role = SAMR_ROLE_DOMAIN_PDC; + break; case ROLE_DOMAIN_MEMBER: info->role = SAMR_ROLE_DOMAIN_MEMBER; break; @@ -613,6 +616,9 @@ static NTSTATUS dcesrv_samr_info_DomInfo7(struct samr_domain_state *state, info->role = SAMR_ROLE_DOMAIN_BDC; } break; + case ROLE_DOMAIN_PDC: + info->role = SAMR_ROLE_DOMAIN_PDC; + break; case ROLE_DOMAIN_MEMBER: info->role = SAMR_ROLE_DOMAIN_MEMBER; break; @@ -1205,7 +1211,6 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL } a_state = talloc(mem_ctx, struct samr_account_state); if (!a_state) { - ldb_transaction_cancel(d_state->sam_ctx); return NT_STATUS_NO_MEMORY; } a_state->sam_ctx = d_state->sam_ctx; diff --git a/source4/samba_tool/samba_tool.c b/source4/samba_tool/samba_tool.c index 8dfbb83298..ce22944420 100644 --- a/source4/samba_tool/samba_tool.c +++ b/source4/samba_tool/samba_tool.c @@ -299,7 +299,7 @@ static int binary_net(int argc, const char **argv) setlinebuf(stdout); - dcerpc_init(cmdline_lp_ctx); + dcerpc_init(); ev = s4_event_context_init(NULL); if (!ev) { diff --git a/source4/script/mkparamdefs.pl b/source4/script/mkparamdefs.pl new file mode 100644 index 0000000000..9b255a86fc --- /dev/null +++ b/source4/script/mkparamdefs.pl @@ -0,0 +1,192 @@ +#!/usr/bin/perl +# Generate loadparm tables for loadparm.c +# by Andrew Bartlett +# based on mkproto.pl Written by Jelmer Vernooij +# based on the original mkproto.sh by Andrew Tridgell + +use strict; + +# don't use warnings module as it is not portable enough +# use warnings; + +use Getopt::Long; +use File::Basename; +use File::Path; + +##################################################################### +# read a file into a string + +my $file = undef; +my $public_define = undef; +my $_public = ""; +my $_private = ""; +my $public_data = \$_public; +my $builddir = "."; +my $srcdir = "."; +my $generate_scope = undef; + +sub public($) +{ + my ($d) = @_; + $$public_data .= $d; +} + +sub usage() +{ + print "Usage: mkparamdefs.pl [options] [c files]\n"; + print "OPTIONS:\n"; + print " --srcdir=path Read files relative to this directory\n"; + print " --builddir=path Write file relative to this directory\n"; + print " --generate-scope=[GLOBAL|LOCAL] Filter which definitions to generate\n"; + print " --help Print this help message\n\n"; + exit 0; +} + +GetOptions( + 'file=s' => sub { my ($f,$v) = @_; $file = $v; }, + 'srcdir=s' => sub { my ($f,$v) = @_; $srcdir = $v; }, + 'builddir=s' => sub { my ($f,$v) = @_; $builddir = $v; }, + 'generate-scope=s' => sub { my ($f,$v) = @_; $generate_scope = $v; }, + 'help' => \&usage +) or exit(1); + +sub normalize_define($$) +{ + my ($define, $file) = @_; + + if (not defined($define) and defined($file)) { + $define = "__" . uc($file) . "__"; + $define =~ tr{./}{__}; + $define =~ tr{\-}{_}; + } elsif (not defined($define)) { + $define = '_S3_PARAM_H_'; + } + + return $define; +} + +$public_define = normalize_define($public_define, $file); + +sub file_load($) +{ + my($filename) = @_; + local(*INPUTFILE); + open(INPUTFILE, $filename) or return undef; + my($saved_delim) = $/; + undef $/; + my($data) = <INPUTFILE>; + close(INPUTFILE); + $/ = $saved_delim; + return $data; +} + +sub print_header($$$) +{ + my ($file, $header_name,$generate_scope) = @_; + $file->("#ifndef $header_name\n"); + $file->("#define $header_name\n\n"); +$file->("/* This file was automatically generated by mkparmdefs.pl. DO NOT EDIT */\n\n"); + $file->("/**\n"); + if ($generate_scope eq "GLOBAL") { + $file->(" * This structure describes global (ie., server-wide) parameters.\n"); + $file->(" */\n"); + $file->("struct loadparm_global \n"); + } elsif ($generate_scope eq "LOCAL") { + $file->(" * This structure describes a single service.\n"); + $file->(" */\n"); + $file->("struct loadparm_service \n"); + } +$file->("{\n"); +} + +sub print_footer($$$) +{ + my ($file, $header_name, $generate_scope) = @_; + $file->("LOADPARM_EXTRA_" . $generate_scope . "S\n"); + $file->("};\n"); + $file->("\n#endif /* $header_name */\n\n"); +} + +sub handle_loadparm($$$) +{ + my ($file,$line,$generate_scope) = @_; + + if ($line =~ /^FN_(GLOBAL|LOCAL)_(CONST_STRING|STRING|BOOL|bool|CHAR|INTEGER|LIST)\((\w+),(.*)\)/o) { + my $scope = $1; + my $type = $2; + my $name = $3; + my $var = $4; + + my %tmap = ( + "BOOL" => "int ", + "CONST_STRING" => "char *", + "STRING" => "char *", + "INTEGER" => "int ", + "CHAR" => "char ", + "LIST" => "const char **", + ); + + if ($scope eq $generate_scope) { + $file->("\t$tmap{$type} $var;\n"); + } + } +} + +sub process_file($$) +{ + my ($file, $filename) = @_; + + $filename =~ s/\.o$/\.c/g; + + if ($filename =~ /^\//) { + open(FH, "<$filename") or die("Failed to open $filename"); + } elsif (!open(FH, "< $builddir/$filename")) { + open(FH, "< $srcdir/$filename") || die "Failed to open $filename"; + } + + my $comment = undef; + my $incomment = 0; + while (my $line = <FH>) { + if ($line =~ /^\/\*\*/) { + $comment = ""; + $incomment = 1; + } + + if ($incomment) { + $comment .= $line; + if ($line =~ /\*\//) { + $incomment = 0; + } + } + + # these are ordered for maximum speed + next if ($line =~ /^\s/); + + next unless ($line =~ /\(/); + + next if ($line =~ /^\/|[;]/); + + if ($line =~ /^FN_/) { + handle_loadparm($file, $line, $generate_scope); + } + next; + } + + close(FH); +} + + +print_header(\&public, $public_define, $generate_scope); + +process_file(\&public, $_) foreach (@ARGV); +print_footer(\&public, $public_define, $generate_scope); + +if (not defined($file)) { + print STDOUT $$public_data; +} + +mkpath(dirname($file), 0, 0755); +open(PUBLIC, ">$file") or die("Can't open `$file': $!"); +print PUBLIC "$$public_data"; +close(PUBLIC); + diff --git a/source4/script/mkrelease.sh b/source4/script/mkrelease.sh index 6ad927b982..19a1ade376 100755 --- a/source4/script/mkrelease.sh +++ b/source4/script/mkrelease.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash if [ ! -d ".git" -o `dirname $0` != "./source4/script" ]; then echo "Run this script from the top-level directory in the" @@ -6,8 +6,7 @@ if [ ! -d ".git" -o `dirname $0` != "./source4/script" ]; then exit 1 fi -cd source4 -../buildtools/bin/waf dist +./buildtools/bin/waf dist TGZFILE="`echo *.tar.gz`" gunzip $TGZFILE TARFILE="`echo *.tar`" diff --git a/source4/script/mks3param.pl b/source4/script/mks3param.pl new file mode 100644 index 0000000000..2d99ad59a9 --- /dev/null +++ b/source4/script/mks3param.pl @@ -0,0 +1,177 @@ +#!/usr/bin/perl +# Generate loadparm interfaces tables for Samba3/Samba4 integration +# by Andrew Bartlett +# based on mkproto.pl Written by Jelmer Vernooij +# based on the original mkproto.sh by Andrew Tridgell + +use strict; + +# don't use warnings module as it is not portable enough +# use warnings; + +use Getopt::Long; +use File::Basename; +use File::Path; + +##################################################################### +# read a file into a string + +my $file = undef; +my $public_define = undef; +my $_public = ""; +my $_private = ""; +my $public_data = \$_public; +my $builddir = "."; +my $srcdir = "."; + +sub public($) +{ + my ($d) = @_; + $$public_data .= $d; +} + +sub usage() +{ + print "Usage: mks3param.pl [options] [c files]\n"; + print "OPTIONS:\n"; + print " --srcdir=path Read files relative to this directory\n"; + print " --builddir=path Write file relative to this directory\n"; + print " --help Print this help message\n\n"; + exit 0; +} + +GetOptions( + 'file=s' => sub { my ($f,$v) = @_; $file = $v; }, + 'srcdir=s' => sub { my ($f,$v) = @_; $srcdir = $v; }, + 'builddir=s' => sub { my ($f,$v) = @_; $builddir = $v; }, + 'help' => \&usage +) or exit(1); + +sub normalize_define($$) +{ + my ($define, $file) = @_; + + if (not defined($define) and defined($file)) { + $define = "__" . uc($file) . "__"; + $define =~ tr{./}{__}; + $define =~ tr{\-}{_}; + } elsif (not defined($define)) { + $define = '_S3_PARAM_H_'; + } + + return $define; +} + +$public_define = normalize_define($public_define, $file); + +sub file_load($) +{ + my($filename) = @_; + local(*INPUTFILE); + open(INPUTFILE, $filename) or return undef; + my($saved_delim) = $/; + undef $/; + my($data) = <INPUTFILE>; + close(INPUTFILE); + $/ = $saved_delim; + return $data; +} + +sub print_header($$) +{ + my ($file, $header_name) = @_; + $file->("#ifndef $header_name\n"); + $file->("#define $header_name\n\n"); + $file->("/* This file was automatically generated by mks3param.pl. DO NOT EDIT */\n\n"); + $file->("struct loadparm_s3_context\n"); + $file->("{\n"); + $file->("\tconst char * (*get_parametric)(const char *type, const char *option);"); +} + +sub print_footer($$) +{ + my ($file, $header_name) = @_; + $file->("};"); + $file->("\n#endif /* $header_name */\n\n"); +} + +sub handle_loadparm($$) +{ + my ($file,$line) = @_; + + if ($line =~ /^FN_(GLOBAL|LOCAL)_(CONST_STRING|STRING|BOOL|bool|CHAR|INTEGER|LIST)\((\w+),.*\)/o) { + my $scope = $1; + my $type = $2; + my $name = $3; + + my %tmap = ( + "BOOL" => "bool ", + "CONST_STRING" => "const char *", + "STRING" => "const char *", + "INTEGER" => "int ", + "CHAR" => "char ", + "LIST" => "const char **", + ); + + $file->("\t$tmap{$type} (*$name)(void);\n"); + } +} + +sub process_file($$) +{ + my ($file, $filename) = @_; + + $filename =~ s/\.o$/\.c/g; + + if ($filename =~ /^\//) { + open(FH, "<$filename") or die("Failed to open $filename"); + } elsif (!open(FH, "< $builddir/$filename")) { + open(FH, "< $srcdir/$filename") || die "Failed to open $filename"; + } + + my $comment = undef; + my $incomment = 0; + while (my $line = <FH>) { + if ($line =~ /^\/\*\*/) { + $comment = ""; + $incomment = 1; + } + + if ($incomment) { + $comment .= $line; + if ($line =~ /\*\//) { + $incomment = 0; + } + } + + # these are ordered for maximum speed + next if ($line =~ /^\s/); + + next unless ($line =~ /\(/); + + next if ($line =~ /^\/|[;]/); + + if ($line =~ /^FN_/) { + handle_loadparm($file, $line); + } + next; + } + + close(FH); +} + + +print_header(\&public, $public_define); + +process_file(\&public, $_) foreach (@ARGV); +print_footer(\&public, $public_define); + +if (not defined($file)) { + print STDOUT $$public_data; +} + +mkpath(dirname($file), 0, 0755); +open(PUBLIC, ">$file") or die("Can't open `$file': $!"); +print PUBLIC "$$public_data"; +close(PUBLIC); + diff --git a/source4/scripting/bin/findprovisionusnranges b/source4/scripting/bin/findprovisionusnranges new file mode 100755 index 0000000000..c91e42e936 --- /dev/null +++ b/source4/scripting/bin/findprovisionusnranges @@ -0,0 +1,174 @@ +#!/usr/bin/python +# +# Helper for determining USN ranges created of modified by provision and +# upgradeprovision. +# Copyright (C) Matthieu Patou <mat@matws.net> 2009-2011 +# +# +# 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 <http://www.gnu.org/licenses/>. +# + +import sys +import optparse +import tempfile +sys.path.insert(0, "bin/python") + +from samba.credentials import DONT_USE_KERBEROS +from samba.auth import system_session +from samba import Ldb +import ldb + +import samba.getopt as options +from samba import param +from samba import _glue +from samba.upgradehelpers import get_paths +from samba.ndr import ndr_unpack +from samba.dcerpc import drsblobs, misc + +parser = optparse.OptionParser("provision [options]") +sambaopts = options.SambaOptions(parser) +parser.add_option_group(sambaopts) +parser.add_option_group(options.VersionOptions(parser)) +parser.add_option("--storedir", type="string", help="Directory where to store result files") +credopts = options.CredentialsOptions(parser) +parser.add_option_group(credopts) +opts = parser.parse_args()[0] +lp = sambaopts.get_loadparm() +smbconf = lp.configfile + +creds = credopts.get_credentials(lp) +creds.set_kerberos_state(DONT_USE_KERBEROS) +session = system_session() +paths = get_paths(param, smbconf=smbconf) +basedn="DC=" + lp.get("realm").replace(".",",DC=") +samdb = Ldb(paths.samdb, session_info=session, credentials=creds,lp=lp) + +hash_id = {} +ldif = "" +nb_obj = 0 + +res = samdb.search(base="", scope=ldb.SCOPE_BASE, attrs=["dsServiceName"]) + +invocation = None +if res and len(res) == 1 and res[0]["dsServiceName"] != None: + dn = ldb.Dn(samdb, str(res[0]["dsServiceName"])) + res = samdb.search(base=str(dn), scope=ldb.SCOPE_BASE, attrs=["invocationId"], + controls=["search_options:1:2"]) + + if res and len(res) == 1 and res[0]["invocationId"]: + invocation = str(ndr_unpack(misc.GUID, res[0]["invocationId"][0])) + else: + print "Unable to find invocation ID" + sys.exit(1) +else: + print "Unable to find attribute dsServiceName in rootDSE" + sys.exit(1) + +res = samdb.search(base=basedn, expression="objectClass=*", + scope=ldb.SCOPE_SUBTREE, + attrs=["replPropertyMetaData"], + controls=["search_options:1:2"]) + +for e in res: + nb_obj = nb_obj + 1 + obj = ndr_unpack(drsblobs.replPropertyMetaDataBlob, + str(e["replPropertyMetaData"])).ctr + + for o in obj.array: + # like a timestamp but with the resolution of 1 minute + minutestamp =_glue.nttime2unix(o.originating_change_time)/60 + hash_ts = hash_id.get(str(o.originating_invocation_id)) + if hash_ts == None: + ob = {} + ob["min"] = o.originating_usn + ob["max"] = o.originating_usn + ob["num"] = 1 + ob["list"] = [str(e.dn)] + hash_ts = {} + else: + ob = hash_ts.get(minutestamp) + if ob == None: + ob = {} + ob["min"] = o.originating_usn + ob["max"] = o.originating_usn + ob["num"] = 1 + ob["list"] = [str(e.dn)] + else: + if ob["min"] > o.originating_usn: + ob["min"] = o.originating_usn + if ob["max"] < o.originating_usn: + ob["max"] = o.originating_usn + if not (str(e.dn) in ob["list"]): + ob["num"] = ob["num"] + 1 + ob["list"].append(str(e.dn)) + hash_ts[minutestamp] = ob + hash_id[str(o.originating_invocation_id)] = hash_ts + +minobj = 5 +print "Here is a list of changes that modified more than %d objects in 1 minute." % minobj +print "Usually changes made by provision and upgradeprovision are those who affect a couple"\ + " of hundred of objects or more" +print "Total number of objects: %d" % nb_obj +print + +for id in hash_id: + hash_ts = hash_id[id] + sorted_keys = [] + sorted_keys.extend(hash_ts.keys()) + sorted_keys.sort() + + kept_record = [] + for k in sorted_keys: + obj = hash_ts[k] + if obj["num"] > minobj: + dt = _glue.nttime2string(_glue.unix2nttime(k*60)) + print "%s # of modification: %d \tmin: %d max: %d" % (dt , obj["num"], + obj["min"], + obj["max"]) + if hash_ts[k]["num"] > 600: + kept_record.append(k) + + # Let's try to concatenate consecutive block if they are in the almost same minutestamp + for i in range(0, len(kept_record)): + if i != 0: + key1 = kept_record[i] + key2 = kept_record[i-1] + if key1 - key2 == 1: + # previous record is just 1 minute away from current + if int(hash_ts[key1]["min"]) == int(hash_ts[key2]["max"]) + 1: + # Copy the highest USN in the previous record + # and mark the current as skipped + hash_ts[key2]["max"] = hash_ts[key1]["max"] + hash_ts[key1]["skipped"] = True + + for k in kept_record: + obj = hash_ts[k] + if obj.get("skipped") == None: + ldif = "%slastProvisionUSN: %d-%d;%s\n" % (ldif, obj["min"], + obj["max"], id) + +if ldif != "": + dest = opts.storedir + if dest == None: + dest = "/tmp" + + file = tempfile.mktemp(dir=dest, prefix="usnprov", suffix=".ldif") + print + print "To track the USNs modified/created by provision and upgrade proivsion," + print " the following ranges are proposed to be added to your provision sam.ldb: \n%s" % ldif + print "We recommend to review them, and if it's correct to integrate the following ldif: %s in your sam.ldb" % file + print "You can load this file like this: ldbadd -H %s %s\n"%(str(paths.samdb),file) + ldif = "dn: @PROVISION\nprovisionnerID: %s\n%s" % (invocation, ldif) + open(file,'w').write(ldif) + diff --git a/source4/scripting/bin/renamedc b/source4/scripting/bin/renamedc new file mode 100755 index 0000000000..0915b15783 --- /dev/null +++ b/source4/scripting/bin/renamedc @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# vim: expandtab +# +# Copyright (C) Matthieu Patou <mat@matws.net> 2011 +# +# 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 <http://www.gnu.org/licenses/>. + + +import optparse +import sys +# Allow to run from s4 source directory (without installing samba) +sys.path.insert(0, "bin/python") + +import ldb +import samba +import samba.getopt as options +import os + +from samba.credentials import DONT_USE_KERBEROS +from samba.auth import system_session +from samba import param +from samba.provision import find_provision_key_parameters, secretsdb_self_join +from samba.upgradehelpers import get_ldbs, get_paths + + +__docformat__ = "restructuredText" + +parser = optparse.OptionParser("provision [options]") +sambaopts = options.SambaOptions(parser) +parser.add_option_group(sambaopts) +parser.add_option_group(options.VersionOptions(parser)) +credopts = options.CredentialsOptions(parser) +parser.add_option_group(credopts) +parser.add_option("--oldname", + help="Old DC name") +parser.add_option("--newname", + help="New DC name") + +opts = parser.parse_args()[0] + +if len(sys.argv) == 1: + opts.interactive = True +lp = sambaopts.get_loadparm() +smbconf = lp.configfile + +creds = credopts.get_credentials(lp) +creds.set_kerberos_state(DONT_USE_KERBEROS) + + +if __name__ == '__main__': + global defSDmodified + defSDmodified = False + # 1) First get files paths + paths = get_paths(param, smbconf=smbconf) + # Get ldbs with the system session, it is needed for searching + # provision parameters + session = system_session() + + ldbs = get_ldbs(paths, creds, session, lp) + ldbs.sam.transaction_start() + ldbs.secrets.transaction_start() + + if opts.oldname is None or opts.newname is None: + raise Exception("Option oldname or newname is missing") + res = ldbs.sam.search(expression="(&(name=%s)(serverReferenceBL=*))" % opts.oldname) + if res is None or len(res) != 1: + raise Exception("Wrong number of result returned, are you sure of the old name %s" % + opts.oldname) + + # Ok got it then check that the new name is not used as well + res2 = ldbs.sam.search(expression="(&(name=%s)(objectclass=computer))" % opts.newname) + if len(res2) != 0: + raise Exception("Seems that %s is a name that already exists, pick another one" % + opts.newname) + + names = find_provision_key_parameters(ldbs.sam, ldbs.secrets, ldbs.idmap, + paths, smbconf, lp) + + #First rename the entry + # provision put the name in upper case so let's do it too ! + newdn = str(res[0].dn).replace("CN=%s" % opts.oldname, "CN=%s" % opts.newname.upper()) + dnobj = ldb.Dn(ldbs.sam, newdn) + ldbs.sam.rename(res[0].dn, dnobj) + + # Then change password and samaccountname and dnshostname + msg = ldb.Message(dnobj) + machinepass = samba.generate_random_password(128, 255) + mputf16 = machinepass.encode('utf-16-le') + + account = "%s$" % opts.newname.upper() + msg["clearTextPassword"] = ldb.MessageElement(mputf16, + ldb.FLAG_MOD_REPLACE, + "clearTextPassword") + + msg["sAMAccountName"] = ldb.MessageElement(account, + ldb.FLAG_MOD_REPLACE, + "sAMAccountName") + + msg["dNSHostName"] = ldb.MessageElement("%s.%s" % (opts.newname, + names.dnsdomain), + ldb.FLAG_MOD_REPLACE, + "dNSHostName") + ldbs.sam.modify(msg) + + # Do a self join one more time to resync the secrets file + res = ldbs.sam.search(expression=("dn=%s" % newdn), + attrs=["msDs-keyVersionNumber", "serverReferenceBL"]) + assert(len(res) == 1) + kvno = int(str(res[0]["msDs-keyVersionNumber"])) + serverbldn = ldb.Dn(ldbs.sam, str(res[0]["serverReferenceBL"])) + + secrets_msg = ldbs.secrets.search(expression="sAMAccountName=%s$" % + opts.oldname.upper(), + attrs=["secureChannelType"]) + + secChanType = int(secrets_msg[0]["secureChannelType"][0]) + + secretsdb_self_join(ldbs.secrets, domain=names.domain, + realm=names.realm, + domainsid=names.domainsid, + dnsdomain=names.dnsdomain, + netbiosname=opts.newname.upper(), + machinepass=machinepass, + key_version_number=kvno, + secure_channel_type=secChanType) + + # Update RID set reference as there is no back link for the moment. + + res = ldbs.sam.search(expression="(objectClass=rIDSet)", base=newdn, attrs=[]) + assert(len(res) == 1) + newridset = str(res[0].dn) + msg = ldb.Message(dnobj) + + msg["rIDSetReferences"] = ldb.MessageElement(newridset, + ldb.FLAG_MOD_REPLACE, + "rIDSetReferences") + ldbs.sam.modify(msg) + + # Update the server's sites configuration + if False: + # Desactivated for the moment we have a couple of issues with site + # renaming first one is that it's currently forbidden + # second one is that a lot of links are not backlinked + # and so won't be updated when the DN change (ie. fmsowner ...) + serverbl = str(serverbldn) + dnparts = serverbl.split(",") + dnparts[0] = "CN=%s" % opts.newname.upper() + newserverref = ",".join(dnparts) + + newserverrefdn = ldb.Dn(ldbs.sam, newserverref) + + ldbs.sam.rename(serverbldn, newserverrefdn) + + msg = ldb.Message(newserverrefdn) + msg["dNSHostName"] = ldb.MessageElement("%s.%s" % (opts.newname, + names.dnsdomain), + ldb.FLAG_MOD_REPLACE, + "dNSHostName") + ldbs.sam.modify(msg) + + try: + ldbs.sam.transaction_prepare_commit() + ldbs.secrets.transaction_prepare_commit() + except Exception: + ldbs.sam.rollback() + ldbs.secrets.rollback() + sys.exit(1) + + try: + ldbs.sam.transaction_commit() + ldbs.secrets.transaction_commit() + except Exception: + ldbs.sam.rollback() + ldbs.secrets.rollback() + + # All good so far + #print lp.get("private dir") + cf = open(lp.configfile) + ncfname = "%s.new" % lp.configfile + newconf = open(ncfname, 'w') + for l in cf.readlines(): + if l.find("netbios name") > 0: + newconf.write("\tnetbios name = %s\n" % opts.newname.upper()) + else: + newconf.write(l) + newconf.close() + cf.close() + os.rename(ncfname, lp.configfile) + diff --git a/source4/scripting/bin/samba_dnsupdate b/source4/scripting/bin/samba_dnsupdate index e86fba2983..78d7dc1712 100755 --- a/source4/scripting/bin/samba_dnsupdate +++ b/source4/scripting/bin/samba_dnsupdate @@ -89,6 +89,17 @@ if len(IPs) == 0: print "No IP interfaces - skipping DNS updates" sys.exit(0) +IP6s = [] +IP4s = [] +for i in IPs: + if i.find(':') != -1: + if i.find('%') == -1: + # we don't want link local addresses for DNS updates + IP6s.append(i) + else: + IP4s.append(i) + + if opts.verbose: print "IPs: %s" % IPs @@ -122,7 +133,7 @@ class dnsobj(object): if self.type == 'SRV': self.dest = list[2].lower() self.port = list[3] - elif self.type == 'A': + elif self.type in ['A', 'AAAA']: self.ip = list[2] # usually $IP, which gets replaced elif self.type == 'CNAME': self.dest = list[2].lower() @@ -132,6 +143,7 @@ class dnsobj(object): def __str__(self): if d.type == "A": return "%s %s %s" % (self.type, self.name, self.ip) + if d.type == "AAAA": return "%s %s %s" % (self.type, self.name, self.ip) if d.type == "SRV": return "%s %s %s %s" % (self.type, self.name, self.dest, self.port) if d.type == "CNAME": return "%s %s %s" % (self.type, self.name, self.dest) @@ -178,7 +190,7 @@ def check_dns_name(d): if opts.verbose: print "Failed to find DNS entry %s" % d return False - if d.type == 'A': + if d.type in ['A', 'AAAA']: # we need to be sure that our IP is there for rdata in ans: if str(rdata) == str(d.ip): @@ -210,7 +222,7 @@ def get_subst_vars(): global lp, am_rodc vars = {} - samdb = SamDB(url=lp.get("sam database"), session_info=system_session(), + samdb = SamDB(url=lp.samdb_url(), session_info=system_session(), lp=lp) vars['DNSDOMAIN'] = lp.get('realm').lower() @@ -247,6 +259,8 @@ def call_nsupdate(d): f = os.fdopen(tmp_fd, 'w') if d.type == "A": f.write("update add %s %u A %s\n" % (normalised_name, default_ttl, d.ip)) + if d.type == "AAAA": + f.write("update add %s %u AAAA %s\n" % (normalised_name, default_ttl, d.ip)) if d.type == "SRV": if d.existing_port is not None: f.write("update delete %s SRV 0 %s %s %s\n" % (normalised_name, d.existing_weight, @@ -264,7 +278,7 @@ def call_nsupdate(d): try: cmd = nsupdate_cmd[:] cmd.append(tmpfile) - ret = subprocess.call(cmd, shell=False) + ret = subprocess.call(cmd, shell=False, env={"KRB5CCNAME": ccachename}) if ret != 0: if opts.fail_immediately: sys.exit(1) @@ -382,16 +396,28 @@ for line in file: if line == '' or line[0] == "#": continue d = parse_dns_line(line, sub_vars) + if d.type == 'A' and len(IP4s) == 0: + continue + if d.type == 'AAAA' and len(IP6s) == 0: + continue dns_list.append(d) # now expand the entries, if any are A record with ip set to $IP # then replace with multiple entries, one for each interface IP for d in dns_list: - if d.type == 'A' and d.ip == "$IP": - d.ip = IPs[0] - for i in range(len(IPs)-1): + if d.ip != "$IP": + continue + if d.type == 'A': + d.ip = IP4s[0] + for i in range(len(IP4s)-1): + d2 = dnsobj(str(d)) + d2.ip = IP4s[i+1] + dns_list.append(d2) + if d.type == 'AAAA': + d.ip = IP6s[0] + for i in range(len(IP6s)-1): d2 = dnsobj(str(d)) - d2.ip = IPs[i+1] + d2.ip = IP6s[i+1] dns_list.append(d2) # now check if the entries already exist on the DNS server @@ -412,7 +438,7 @@ for d in update_list: if am_rodc: if d.name.lower() == domain.lower(): continue - if d.type != 'A': + if not d.type in [ 'A', 'AAAA' ]: call_rodc_update(d) else: call_nsupdate(d) diff --git a/source4/scripting/bin/samba_spnupdate b/source4/scripting/bin/samba_spnupdate index 1794f2bd26..9f8f4073d3 100755 --- a/source4/scripting/bin/samba_spnupdate +++ b/source4/scripting/bin/samba_spnupdate @@ -82,7 +82,7 @@ def get_subst_vars(samdb): try: private_dir = lp.get("private dir") - secrets_path = os.path.join(private_dir, lp.get("secrets database")) + secrets_path = os.path.join(private_dir, "secrets.ldb") secrets_db = Ldb(url=secrets_path, session_info=system_session(), credentials=creds, lp=lp) @@ -103,9 +103,9 @@ try: else: credentials = None - samdb = SamDB(url=lp.get("sam database"), session_info=system_session(), credentials=credentials, lp=lp) + samdb = SamDB(url=lp.samdb_url(), session_info=system_session(), credentials=credentials, lp=lp) except ldb.LdbError, (num, msg): - print("Unable to open sam database %s : %s" % (lp.get("sam database"), msg)) + print("Unable to open sam database %s : %s" % (lp.samdb_url(), msg)) sys.exit(1) diff --git a/source4/scripting/bin/setup_dns.sh b/source4/scripting/bin/setup_dns.sh index de4485fc07..bc2ae96b84 100755 --- a/source4/scripting/bin/setup_dns.sh +++ b/source4/scripting/bin/setup_dns.sh @@ -13,7 +13,7 @@ IP="$3" RSUFFIX=$(echo $DOMAIN | sed s/[\.]/,DC=/g) [ -z "$PRIVATEDIR" ] && { - PRIVATEDIR=$(bin/testparm --section-name=global --parameter-name='private dir' --suppress-prompt 2> /dev/null) + PRIVATEDIR=$(bin/samba-tool testparm --section-name=global --parameter-name='private dir' --suppress-prompt 2> /dev/null) } OBJECTGUID=$(bin/ldbsearch -s base -H "$PRIVATEDIR/sam.ldb" -b "CN=NTDS Settings,CN=$HOSTNAME,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=$RSUFFIX" objectguid|grep ^objectGUID| cut -d: -f2) diff --git a/source4/scripting/bin/testparm b/source4/scripting/bin/testparm deleted file mode 100755 index c30e46148c..0000000000 --- a/source4/scripting/bin/testparm +++ /dev/null @@ -1,219 +0,0 @@ -#!/usr/bin/env python -# vim: expandtab ft=python -# -# Unix SMB/CIFS implementation. -# Test validity of smb.conf -# Copyright (C) Karl Auer 1993, 1994-1998 -# -# Extensively modified by Andrew Tridgell, 1995 -# Converted to popt by Jelmer Vernooij (jelmer@nl.linux.org), 2002 -# Updated for Samba4 by Andrew Bartlett <abartlet@samba.org> 2006 -# Converted to Python by Jelmer Vernooij <jelmer@samba.org> 2010 -# -# 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 <http://www.gnu.org/licenses/>. -# -# Testbed for loadparm.c/params.c -# -# This module simply loads a specified configuration file and -# if successful, dumps it's contents to stdout. Note that the -# operation is performed with DEBUGLEVEL at 3. -# -# Useful for a quick 'syntax check' of a configuration file. -# - -import logging -import optparse -import os -import sys - -# Find right directory when running from source tree -sys.path.insert(0, "bin/python") - -import samba -from samba import getopt as options - -# Here we do a set of 'hard coded' checks for bad -# configuration settings. - -def do_global_checks(lp, logger): - valid = True - - netbios_name = lp.get("netbios name") - if not samba.valid_netbios_name(netbios_name): - logger.error("netbios name %s is not a valid netbios name", - netbios_name) - valid = False - - workgroup = lp.get("workgroup") - if not samba.valid_netbios_name(workgroup): - logger.error("workgroup name %s is not a valid netbios name", - workgroup) - valid = False - - lockdir = lp.get("lockdir") - - if not os.path.isdir(lockdir): - logger.error("lock directory %s does not exist", lockdir) - valid = False - - piddir = lp.get("pid directory") - - if not os.path.isdir(piddir): - logger.error("pid directory %s does not exist", piddir) - valid = False - - winbind_separator = lp.get("winbind separator") - - if len(winbind_separator) != 1: - logger.error("the 'winbind separator' parameter must be a single " - "character.") - valid = False - - if winbind_separator == '+': - logger.error("'winbind separator = +' might cause problems with group " - "membership.") - valid = False - - return valid - - -def allow_access(deny_list, allow_list, cname, caddr): - raise NotImplementedError(allow_access) - - -def do_share_checks(lp, logger): - valid = True - for s in lp.services(): - if len(s) > 12: - logger.warning("You have some share names that are longer than 12 " - "characters. These may not be accessible to some older " - "clients. (Eg. Windows9x, WindowsMe, and not listed in " - "smbclient in Samba 3.0.)") - break - - for s in lp.services(): - deny_list = lp.get("hosts deny", s) - allow_list = lp.get("hosts allow", s) - if deny_list: - for entry in deny_list: - if "*" in entry or "?" in entry: - logger.error("Invalid character (* or ?) in hosts deny " - "list (%s) for service %s.", entry, s) - valid = False - - if allow_list: - for entry in allow_list: - if "*" in entry or "?" in entry: - logger.error("Invalid character (* or ?) in hosts allow " - "list (%s) for service %s.", entry, s) - valid = False - return valid - -def check_client_access(lp, cname, caddr): - # this is totally ugly, a real `quick' hack - for s in lp.services(): - if (allow_access(lp.get("hosts deny"), lp.get("hosts allow"), cname, - caddr) and - allow_access(lp.get("hosts deny", s), lp.get("hosts allow", s), - cname, caddr)): - logger.info("Allow connection from %s (%s) to %s", cname, caddr, s) - else: - logger.info("Deny connection from %s (%s) to %s", cname, caddr, s) - - -if __name__ == '__main__': - parser = optparse.OptionParser("testparm [OPTION...] [host-name] [host-ip]") - parser.add_option("--section-name", type="string", metavar="SECTION", - help="Limit testparm to a named section") - parser.add_option("--parameter-name", type="string", metavar="PARAMETER", - help="Limit testparm to a named parameter") - parser.add_option("--client-name", type="string", metavar="HOSTNAME", - help="Client DNS name for 'hosts allow' checking " - "(should match reverse lookup)") - parser.add_option("--client-ip", type="string", metavar="IP", - help="Client IP address for 'hosts allow' checking") - parser.add_option("--suppress-prompt", action="store_true", default=False, - help="Suppress prompt for enter") - parser.add_option("-v", "--verbose", action="store_true", - default=False, help="Show default options too") - parser.add_option_group(options.VersionOptions(parser)) - # We need support for smb.conf macros before this will work again - parser.add_option("--server", type="string", - help="Set %%L macro to servername") - # These are harder to do with the new code structure - parser.add_option("--show-all-parameters", action="store_true", - default=False, help="Show the parameters, type, possible values") - - sambaopts = options.SambaOptions(parser) - parser.add_option_group(sambaopts) - - opts, args = parser.parse_args() - -# -# if (show_all_parameters) { -# show_parameter_list() -# exit(0) -# } - - if len(args) > 0: - cname = args[0] - else: - cname = None - if len(args) > 1: - caddr = args[1] - else: - caddr = None - - if cname is not None and caddr is None: - print "Both a DNS name and an IP address are required for the host " \ - "access check." - sys.exit(1) - -# FIXME: We need support for smb.conf macros before this will work again -# -# if (new_local_machine) { -# set_local_machine_name(new_local_machine, True) -# } - - lp = sambaopts.get_loadparm() - - # We need this to force the output - samba.set_debug_level(2) - - logger = logging.getLogger("testparm") - logger.addHandler(logging.StreamHandler(sys.stdout)) - - logger.info("Loaded smb config files from %s", lp.configfile) - logger.info("Loaded services file OK.") - - valid = do_global_checks(lp, logger) - valid = valid and do_share_checks(lp, logger) - if cname is not None: - check_client_access(lp, cname, caddr) - else: - if opts.section_name is not None or opts.parameter_name is not None: - if opts.parameter_name is None: - lp[opts.section_name].dump(sys.stdout, lp.default_service, - opts.verbose) - else: - print lp.get(opts.parameter_name, opts.section_name) - else: - if not opts.suppress_prompt: - print "Press enter to see a dump of your service definitions\n" - sys.stdin.readline() - lp.dump(sys.stdout, opts.verbose) - if valid: - sys.exit(0) - else: - sys.exit(1) diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index 8c79917d5e..e98b642776 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -42,9 +42,10 @@ from samba.credentials import DONT_USE_KERBEROS from samba.auth import system_session, admin_session from ldb import (SCOPE_SUBTREE, SCOPE_BASE, FLAG_MOD_REPLACE, FLAG_MOD_ADD, FLAG_MOD_DELETE, - MessageElement, Message, Dn) + MessageElement, Message, Dn, LdbError) from samba import param, dsdb, Ldb -from samba.provision import (get_domain_descriptor, +from samba.common import confirm +from samba.provision import (get_domain_descriptor, find_provision_key_parameters, get_config_descriptor, ProvisioningError, get_last_provision_usn, get_max_usn, update_provision_usn, setup_path) @@ -52,7 +53,7 @@ from samba.schema import get_linked_attributes, Schema, get_schema_descriptor from samba.dcerpc import security, drsblobs, xattr from samba.ndr import ndr_unpack from samba.upgradehelpers import (dn_sort, get_paths, newprovision, - find_provision_key_parameters, get_ldbs, + get_ldbs, usn_in_range, identic_rename, get_diff_sddls, update_secrets, CHANGE, ERROR, SIMPLE, CHANGEALL, GUESS, CHANGESD, PROVISION, @@ -81,20 +82,25 @@ __docformat__ = "restructuredText" # This is most probably because they are populated automatcally when object is # created # This also apply to imported object from reference provision -hashAttrNotCopied = { "dn": 1, "whenCreated": 1, "whenChanged": 1, - "objectGUID": 1, "uSNCreated": 1, - "replPropertyMetaData": 1, "uSNChanged": 1, - "parentGUID": 1, "objectCategory": 1, - "distinguishedName": 1, "nTMixedDomain": 1, - "showInAdvancedViewOnly": 1, "instanceType": 1, - "msDS-Behavior-Version":1, "nextRid":1, "cn": 1, - "lmPwdHistory":1, "pwdLastSet": 1, - "ntPwdHistory":1, "unicodePwd":1,"dBCSPwd":1, - "supplementalCredentials":1, "gPCUserExtensionNames":1, - "gPCMachineExtensionNames":1,"maxPwdAge":1, "secret":1, - "possibleInferiors":1, "privilege":1, - "sAMAccountType":1 } +replAttrNotCopied = [ "dn", "whenCreated", "whenChanged", "objectGUID", + "parentGUID", "objectCategory", "distinguishedName", + "nTMixedDomain", "showInAdvancedViewOnly", + "instanceType", "msDS-Behavior-Version", "cn", + "lmPwdHistory", "pwdLastSet", "ntPwdHistory", + "unicodePwd", "dBCSPwd", "supplementalCredentials", + "gPCUserExtensionNames", "gPCMachineExtensionNames", + "maxPwdAge", "secret", "possibleInferiors", "privilege", + "sAMAccountType", "oEMInformation", "creationTime" ] +nonreplAttrNotCopied = ["uSNCreated", "replPropertyMetaData", "uSNChanged", + "nextRid" ,"rIDNextRID", "rIDPreviousAllocationPool"] + +nonDSDBAttrNotCopied = ["msDS-KeyVersionNumber", "priorSecret", "priorWhenChanged"] + + +attrNotCopied = replAttrNotCopied +attrNotCopied.extend(nonreplAttrNotCopied) +attrNotCopied.extend(nonDSDBAttrNotCopied) # Usually for an object that already exists we do not overwrite attributes as # they might have been changed for good reasons. Anyway for a few of them it's # mandatory to replace them otherwise the provision will be broken somehow. @@ -108,15 +114,19 @@ hashOverwrittenAtt = { "prefixMap": replace, "systemMayContain": replace, "wellKnownObjects":replace, "privilege":never, "defaultSecurityDescriptor": replace, "rIDAvailablePool": never, + "versionNumber" : add, "rIDNextRID": add, "rIDUsedPool": never, "defaultSecurityDescriptor": replace + add, "isMemberOfPartialAttributeSet": delete, "attributeDisplayNames": replace + add, "versionNumber": add} +dnNotToRecalculate = [] +dnToRecalculate = [] backlinked = [] forwardlinked = set() dn_syntax_att = [] +not_replicated = [] def define_what_to_log(opts): what = 0 if opts.debugchange: @@ -151,6 +161,8 @@ parser.add_option("--debugall", action="store_true", help="Print all available information (very verbose)") parser.add_option("--resetfileacl", action="store_true", help="Force a reset on filesystem acls in sysvol / netlogon share") +parser.add_option("--fixntacl", action="store_true", + help="Only fix NT ACLs in sysvol / netlogon share") parser.add_option("--full", action="store_true", help="Perform full upgrade of the samdb (schema, configuration, new objects, ...") @@ -236,6 +248,26 @@ def populate_links(samdb, schemadn): for t in linkedAttHash.keys(): forwardlinked.add(t) +def isReplicated(att): + """ Indicate if the attribute is replicated or not + + :param att: Name of the attribute to be tested + :return: True is the attribute is replicated, False otherwise + """ + + return (att not in not_replicated) + +def populateNotReplicated(samdb, schemadn): + """Populate an array with all the attributes that are not replicated + + :param samdb: A LDB object for sam.ldb file + :param schemadn: DN of the schema for the partition""" + res = samdb.search(expression="(&(objectclass=attributeSchema)(systemflags:1.2.840.113556.1.4.803:=1))", base=Dn(samdb, + str(schemadn)), scope=SCOPE_SUBTREE, + attrs=["lDAPDisplayName"]) + for elem in res: + not_replicated.append(str(elem["lDAPDisplayName"])) + def populate_dnsyntax(samdb, schemadn): """Populate an array with all the attributes that have DN synthax @@ -295,7 +327,7 @@ def print_provision_key_parameters(names): message(GUESS, "domainlevel :" + str(names.domainlevel)) -def handle_special_case(att, delta, new, old, usn, basedn, aldb): +def handle_special_case(att, delta, new, old, useReplMetadata, basedn, aldb): """Define more complicate update rules for some attributes :param att: The attribute to be updated @@ -303,7 +335,8 @@ def handle_special_case(att, delta, new, old, usn, basedn, aldb): between the updated object and the reference one :param new: The reference object :param old: The Updated object - :param usn: The highest usn modified by a previous (upgrade)provision + :param useReplMetadata: A boolean that indicate if the update process + use replPropertyMetaData to decide what has to be updated. :param basedn: The base DN of the provision :param aldb: An ldb object used to build DN :return: True to indicate that the attribute should be kept, False for @@ -313,7 +346,7 @@ def handle_special_case(att, delta, new, old, usn, basedn, aldb): # We do most of the special case handle if we do not have the # highest usn as otherwise the replPropertyMetaData will guide us more # correctly - if usn is None: + if not useReplMetadata: if (att == "sPNMappings" and flag == FLAG_MOD_REPLACE and ldb.Dn(aldb, "CN=Directory Service,CN=Windows NT," "CN=Services,CN=Configuration,%s" % basedn) @@ -389,14 +422,14 @@ def handle_special_case(att, delta, new, old, usn, basedn, aldb): if (att == "servicePrincipalName" and flag == FLAG_MOD_REPLACE): hash = {} newval = [] - changeDelta=0 + changeDelta = 0 for elem in old[0][att]: hash[str(elem)]=1 newval.append(str(elem)) for elem in new[0][att]: if not hash.has_key(str(elem)): - changeDelta=1 + changeDelta = 1 newval.append(str(elem)) if changeDelta == 1: delta[att] = MessageElement(newval, FLAG_MOD_REPLACE, att) @@ -583,7 +616,7 @@ def add_missing_object(ref_samdb, samdb, dn, names, basedn, hash, index): m = re.match(r".*-(\d+)$", sid) if m and int(m.group(1))>999: delta.remove("objectSid") - for att in hashAttrNotCopied.keys(): + for att in attrNotCopied: delta.remove(att) for att in backlinked: delta.remove(att) @@ -650,7 +683,7 @@ def add_deletedobj_containers(ref_samdb, samdb, names): delta = samdb.msg_diff(empty, reference[0]) delta.dn = Dn(samdb, str(reference[0]["dn"])) - for att in hashAttrNotCopied.keys(): + for att in attrNotCopied: delta.remove(att) modcontrols = ["relax:0", "provision:0"] @@ -771,8 +804,192 @@ msg_elt_flag_strs = { ldb.FLAG_MOD_REPLACE: "MOD_REPLACE", ldb.FLAG_MOD_DELETE: "MOD_DELETE" } +def checkKeepAttributeOldMtd(delta, att, reference, current, + basedn, samdb): + """ Check if we should keep the attribute modification or not. + This function didn't use replicationMetadata to take a decision. + + :param delta: A message diff object + :param att: An attribute + :param reference: A message object for the current entry comming from + the reference provision. + :param current: A message object for the current entry commin from + the current provision. + :param basedn: The DN of the partition + :param samdb: A ldb connection to the sam database of the current provision. + + :return: The modified message diff. + """ + # Old school way of handling things for pre alpha12 upgrade + global defSDmodified + isFirst = False + txt = "" + dn = current[0].dn + + for att in list(delta): + msgElt = delta.get(att) + + if att == "nTSecurityDescriptor": + defSDmodified = True + delta.remove(att) + continue + + if att == "dn": + continue + + if not hashOverwrittenAtt.has_key(att): + if msgElt.flags() != FLAG_MOD_ADD: + if not handle_special_case(att, delta, reference, current, + False, basedn, samdb): + if opts.debugchange or opts.debugall: + try: + dump_denied_change(dn, att, + msg_elt_flag_strs[msgElt.flags()], + current[0][att], reference[0][att]) + except KeyError: + dump_denied_change(dn, att, + msg_elt_flag_strs[msgElt.flags()], + current[0][att], None) + delta.remove(att) + continue + else: + if hashOverwrittenAtt.get(att)&2**msgElt.flags() : + continue + elif hashOverwrittenAtt.get(att)==never: + delta.remove(att) + continue + + return delta + +def checkKeepAttributeWithMetadata(delta, att, message, reference, current, + hash_attr_usn, basedn, usns, samdb): + """ Check if we should keep the attribute modification or not + + :param delta: A message diff object + :param att: An attribute + :param message: A function to print messages + :param reference: A message object for the current entry comming from + the reference provision. + :param current: A message object for the current entry commin from + the current provision. + :param hash_attr_usn: A dictionnary with attribute name as keys, + USN and invocation id as values. + :param basedn: The DN of the partition + :param usns: A dictionnary with invocation ID as keys and USN ranges + as values. + :param samdb: A ldb object pointing to the sam DB + + :return: The modified message diff. + """ + global defSDmodified + isFirst = True + txt = "" + dn = current[0].dn + + for att in list(delta): + if att in ["dn", "objectSid"]: + delta.remove(att) + continue + + # We have updated by provision usn information so let's exploit + # replMetadataProperties + if att in forwardlinked: + curval = current[0].get(att, ()) + refval = reference[0].get(att, ()) + handle_links(samdb, att, basedn, current[0]["dn"], + curval, refval, delta) + continue + + if isFirst and len(delta.items())>1: + isFirst = False + txt = "%s\n" % (str(dn)) + + if handle_special_case(att, delta, reference, current, True, None, None): + # This attribute is "complicated" to handle and handling + # was done in handle_special_case + continue + + attrUSN = None + if hash_attr_usn.get(att): + [attrUSN, attInvId] = hash_attr_usn.get(att) + + if attrUSN is None: + # If it's a replicated attribute and we don't have any USN + # information about it. It means that we never saw it before + # so let's add it ! + # If it is a replicated attribute but we are not master on it + # (ie. not initially added in the provision we masterize). + # attrUSN will be -1 + if isReplicated(att): + continue + else: + message(CHANGE, "Non replicated attribute %s changed" % att) + continue -def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid): + if att == "nTSecurityDescriptor": + cursd = ndr_unpack(security.descriptor, + str(current[0]["nTSecurityDescriptor"])) + cursddl = cursd.as_sddl(names.domainsid) + refsd = ndr_unpack(security.descriptor, + str(reference[0]["nTSecurityDescriptor"])) + refsddl = refsd.as_sddl(names.domainsid) + + diff = get_diff_sddls(refsddl, cursddl) + if diff == "": + # FIXME find a way to have it only with huge huge verbose mode + # message(CHANGE, "%ssd are identical" % txt) + # txt = "" + delta.remove(att) + continue + else: + delta.remove(att) + message(CHANGESD, "%ssd are not identical:\n%s" % (txt, diff)) + txt = "" + if attrUSN == -1: + message(CHANGESD, "But the SD has been changed by someonelse "\ + "so it's impossible to know if the difference"\ + " cames from the modification or from a previous bug") + dnNotToRecalculate.append(str(dn)) + else: + dnToRecalculate.append(str(dn)) + continue + + if attrUSN == -1: + # This attribute was last modified by another DC forget + # about it + message(CHANGE, "%sAttribute: %s has been " + "created/modified/deleted by another DC. " + "Doing nothing" % (txt, att)) + txt = "" + delta.remove(att) + continue + elif not usn_in_range(int(attrUSN), usns.get(attInvId)): + message(CHANGE, "%sAttribute: %s was not " + "created/modified/deleted during a " + "provision or upgradeprovision. Current " + "usn: %d. Doing nothing" % (txt, att, + attrUSN)) + txt = "" + delta.remove(att) + continue + else: + if att == "defaultSecurityDescriptor": + defSDmodified = True + if attrUSN: + message(CHANGE, "%sAttribute: %s will be modified" + "/deleted it was last modified " + "during a provision. Current usn: " + "%d" % (txt, att, attrUSN)) + txt = "" + else: + message(CHANGE, "%sAttribute: %s will be added because " + "it did not exist before" % (txt, att)) + txt = "" + continue + + return delta + +def update_present(ref_samdb, samdb, basedn, listPresent, usns): """ This function updates the object that are already present in the provision @@ -782,10 +999,9 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid): (ie. DC=foo, DC=bar) :param listPresent: A list of object that is present in the provision :param usns: A list of USN range modified by previous provision and - upgradeprovision - :param invocationid: The value of the invocationid for the current DC""" + upgradeprovision grouped by invocation ID + """ - global defSDmodified # This hash is meant to speedup lookup of attribute name from an oid, # it's for the replPropertyMetaData handling hash_oid_name = {} @@ -801,7 +1017,9 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid): raise ProvisioningError(msg) changed = 0 - controls = ["search_options:1:2", "sd_flags:1:2"] + controls = ["search_options:1:2", "sd_flags:1:0"] + if usns is not None: + message(CHANGE, "Using replPropertyMetadata for change selection") for dn in listPresent: reference = ref_samdb.search(expression="dn=%s" % (str(dn)), base=basedn, scope=SCOPE_SUBTREE, @@ -823,14 +1041,17 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid): delta = samdb.msg_diff(current[0], reference[0]) - for att in hashAttrNotCopied.keys(): + for att in backlinked: delta.remove(att) - for att in backlinked: + for att in attrNotCopied: delta.remove(att) delta.remove("name") + if len(delta.items()) == 1: + continue + if len(delta.items()) > 1 and usns is not None: # Fetch the replPropertyMetaData res = samdb.search(expression="dn=%s" % (str(dn)), base=basedn, @@ -844,145 +1065,25 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid): # We put in this hash only modification # made on the current host att = hash_oid_name[samdb.get_oid_from_attid(o.attid)] - if str(o.originating_invocation_id) == str(invocationid): - # Note we could just use 1 here - hash_attr_usn[att] = o.originating_usn + if str(o.originating_invocation_id) in usns.keys(): + hash_attr_usn[att] = [o.originating_usn, str(o.originating_invocation_id)] else: - hash_attr_usn[att] = -1 - - isFirst = 0 - txt = "" - - for att in list(delta): - if usns is not None: - # We have updated by provision usn information so let's exploit - # replMetadataProperties - if att in forwardlinked: - curval = current[0].get(att, ()) - refval = reference[0].get(att, ()) - handle_links(samdb, att, basedn, current[0]["dn"], - curval, refval, delta) - continue - - if isFirst == 0 and len(delta.items())>1: - isFirst = 1 - txt = "%s\n" % (str(dn)) - if att == "dn": - # There is always a dn attribute after a msg_diff - continue - if att == "rIDAvailablePool": - delta.remove(att) - continue - if att == "objectSid": - delta.remove(att) - continue - if att == "creationTime": - delta.remove(att) - continue - if att == "oEMInformation": - delta.remove(att) - continue - if att == "msDs-KeyVersionNumber": - # This is the kvno of the computer/user it's a very bad - # idea to change it - delta.remove(att) - continue - if handle_special_case(att, delta, reference, current, usns, basedn, samdb): - # This attribute is "complicated" to handle and handling - # was done in handle_special_case - continue - attrUSN = hash_attr_usn.get(att) - if att == "forceLogoff" and attrUSN is None: - continue - if attrUSN is None: - delta.remove(att) - continue - if att == "nTSecurityDescriptor": - cursd = ndr_unpack(security.descriptor, - str(current[0]["nTSecurityDescriptor"])) - cursddl = cursd.as_sddl(names.domainsid) - refsd = ndr_unpack(security.descriptor, - str(reference[0]["nTSecurityDescriptor"])) - refsddl = cursd.as_sddl(names.domainsid) - - if get_diff_sddls(refsddl, cursddl) == "": - message(CHANGE, "sd are identical") - else: - message(CHANGE, "sd are not identical") - if attrUSN == -1: - # This attribute was last modified by another DC forget - # about it - message(CHANGE, "%sAttribute: %s has been " - "created/modified/deleted by another DC. " - "Doing nothing" % (txt, att)) - txt = "" - delta.remove(att) - continue - elif not usn_in_range(int(attrUSN), usns): - message(CHANGE, "%sAttribute: %s was not " - "created/modified/deleted during a " - "provision or upgradeprovision. Current " - "usn: %d. Doing nothing" % (txt, att, - attrUSN)) - txt = "" - delta.remove(att) - continue - else: - if att == "defaultSecurityDescriptor": - defSDmodified = True - if attrUSN: - message(CHANGE, "%sAttribute: %s will be modified" - "/deleted it was last modified " - "during a provision. Current usn: " - "%d" % (txt, att, attrUSN)) - txt = "" - else: - message(CHANGE, "%sAttribute: %s will be added because " - "it did not exist before" % (txt, att)) - txt = "" - continue + hash_attr_usn[att] = [-1, None] - else: - # Old school way of handling things for pre alpha12 upgrade - defSDmodified = True - msgElt = delta.get(att) - - if att == "nTSecurityDescriptor": - delta.remove(att) - continue - - if att == "dn": - continue - - if not hashOverwrittenAtt.has_key(att): - if msgElt.flags() != FLAG_MOD_ADD: - if not handle_special_case(att, delta, reference, current, - usns, basedn, samdb): - if opts.debugchange or opts.debugall: - try: - dump_denied_change(dn, att, - msg_elt_flag_strs[msgElt.flags()], - current[0][att], reference[0][att]) - except KeyError: - dump_denied_change(dn, att, - msg_elt_flag_strs[msgElt.flags()], - current[0][att], None) - delta.remove(att) - continue - else: - if hashOverwrittenAtt.get(att)&2**msgElt.flags() : - continue - elif hashOverwrittenAtt.get(att)==never: - delta.remove(att) - continue + if usns is not None: + delta = checkKeepAttributeWithMetadata(delta, att, message, reference, + current, hash_attr_usn, + basedn, usns, samdb) + else: + delta = checkKeepAttributeOldMtd(delta, att, reference, current, basedn, samdb) delta.dn = dn if len(delta.items()) >1: - attributes=", ".join(delta.keys()) + # Skip dn as the value is not really changed ... + attributes=", ".join(delta.keys()[1:]) modcontrols = [] relaxedatt = ['iscriticalsystemobject', 'grouptype'] # Let's try to reduce as much as possible the use of relax control - #for checkedatt in relaxedatt: for attr in delta.keys(): if attr.lower() in relaxedatt: modcontrols = ["relax:0", "provision:0"] @@ -1033,8 +1134,8 @@ def update_partition(ref_samdb, samdb, basedn, names, schema, provisionUSNs, pre :param basedn: String value of the DN of the partition :param names: List of key provision parameters :param schema: A Schema object - :param provisionUSNs: The USNs modified by provision/upgradeprovision - last time + :param provisionUSNs: A dictionnary with range of USN modified during provision + or upgradeprovision. Ranges are grouped by invocationID. :param prereloadfunc: A function that must be executed just before the reload of the schema """ @@ -1096,7 +1197,7 @@ def update_partition(ref_samdb, samdb, basedn, names, schema, provisionUSNs, pre message(SIMPLE, "Schema reloaded!") changed = update_present(ref_samdb, samdb, basedn, listPresent, - provisionUSNs, names.invocation) + provisionUSNs) message(SIMPLE, "There are %d changed objects" % (changed)) return 1 @@ -1138,7 +1239,7 @@ def check_updated_sd(ref_sam, cur_sam, names): str(current[i]["nTSecurityDescriptor"])) sddl = cursd.as_sddl(names.domainsid) if sddl != hash[key]: - txt = get_diff_sddls(hash[key], sddl) + txt = get_diff_sddls(hash[key], sddl, False) if txt != "": message(CHANGESD, "On object %s ACL is different" " \n%s" % (current[i]["dn"], txt)) @@ -1152,37 +1253,38 @@ def fix_partition_sd(samdb, names): :param samdb: An LDB object pointing to the sam of the current provision :param names: A list of key provision parameters """ + alwaysRecalculate = False + if len(dnToRecalculate) == 0 and len(dnNotToRecalculate) == 0: + alwaysRecalculate = True + + + # NC's DN can't be both in dnToRecalculate and dnNotToRecalculate # First update the SD for the rootdn - res = samdb.search(expression="objectClass=*", base=str(names.rootdn), - scope=SCOPE_BASE, attrs=["dn", "whenCreated"], - controls=["search_options:1:2"]) - delta = Message() - delta.dn = Dn(samdb, str(res[0]["dn"])) - descr = get_domain_descriptor(names.domainsid) - delta["nTSecurityDescriptor"] = MessageElement(descr, FLAG_MOD_REPLACE, - "nTSecurityDescriptor") - samdb.modify(delta) + if alwaysRecalculate or str(names.rootdn) in dnToRecalculate: + delta = Message() + delta.dn = Dn(samdb, str(names.rootdn)) + descr = get_domain_descriptor(names.domainsid) + delta["nTSecurityDescriptor"] = MessageElement(descr, FLAG_MOD_REPLACE, + "nTSecurityDescriptor") + samdb.modify(delta) + # Then the config dn - res = samdb.search(expression="objectClass=*", base=str(names.configdn), - scope=SCOPE_BASE, attrs=["dn", "whenCreated"], - controls=["search_options:1:2"]) - delta = Message() - delta.dn = Dn(samdb, str(res[0]["dn"])) - descr = get_config_descriptor(names.domainsid) - delta["nTSecurityDescriptor"] = MessageElement(descr, FLAG_MOD_REPLACE, - "nTSecurityDescriptor" ) - samdb.modify(delta) - # Then the schema dn - res = samdb.search(expression="objectClass=*", base=str(names.schemadn), - scope=SCOPE_BASE, attrs=["dn", "whenCreated"], - controls=["search_options:1:2"]) + if alwaysRecalculate or str(names.configdn) in dnToRecalculate: + delta = Message() + delta.dn = Dn(samdb, str(names.configdn)) + descr = get_config_descriptor(names.domainsid) + delta["nTSecurityDescriptor"] = MessageElement(descr, FLAG_MOD_REPLACE, + "nTSecurityDescriptor" ) + samdb.modify(delta) - delta = Message() - delta.dn = Dn(samdb, str(res[0]["dn"])) - descr = get_schema_descriptor(names.domainsid) - delta["nTSecurityDescriptor"] = MessageElement(descr, FLAG_MOD_REPLACE, - "nTSecurityDescriptor" ) - samdb.modify(delta) + # Then the schema dn + if alwaysRecalculate or str(names.schemadn) in dnToRecalculate: + delta = Message() + delta.dn = Dn(samdb, str(names.schemadn)) + descr = get_schema_descriptor(names.domainsid) + delta["nTSecurityDescriptor"] = MessageElement(descr, FLAG_MOD_REPLACE, + "nTSecurityDescriptor" ) + samdb.modify(delta) def rebuild_sd(samdb, names): """Rebuild security descriptor of the current provision from scratch @@ -1195,30 +1297,46 @@ def rebuild_sd(samdb, names): :param names: List of key provision parameters""" + fix_partition_sd(samdb, names) + # List of namming contexts + listNC = [str(names.rootdn), str(names.configdn), str(names.schemadn)] hash = {} - res = samdb.search(expression="objectClass=*", base=str(names.rootdn), + if len(dnToRecalculate) == 0: + res = samdb.search(expression="objectClass=*", base=str(names.rootdn), scope=SCOPE_SUBTREE, attrs=["dn", "whenCreated"], controls=["search_options:1:2"]) - for obj in res: - if not (str(obj["dn"]) == str(names.rootdn) or - str(obj["dn"]) == str(names.configdn) or - str(obj["dn"]) == str(names.schemadn)): - hash[str(obj["dn"])] = obj["whenCreated"] - - listkeys = hash.keys() - listkeys.sort(dn_sort) - - for key in listkeys: + for obj in res: + hash[str(obj["dn"])] = obj["whenCreated"] + else: + for dn in dnToRecalculate: + if hash.has_key(dn): + continue + # fetch each dn to recalculate and their child within the same partition + res = samdb.search(expression="objectClass=*", base=dn, + scope=SCOPE_SUBTREE, attrs=["dn", "whenCreated"]) + for obj in res: + hash[str(obj["dn"])] = obj["whenCreated"] + + listKeys = list(set(hash.keys())) + listKeys.sort(dn_sort) + + if len(dnToRecalculate) != 0: + message(CHANGESD, "%d DNs have been marked as needed to be recalculated"\ + ", recalculating %d due to inheritance" + % (len(dnToRecalculate), len(listKeys))) + + for key in listKeys: + if (key in listNC or + key in dnNotToRecalculate): + continue + delta = Message() + delta.dn = Dn(samdb, key) try: - delta = Message() - delta.dn = Dn(samdb, key) delta["whenCreated"] = MessageElement(hash[key], FLAG_MOD_REPLACE, "whenCreated" ) - samdb.modify(delta, ["recalculate_sd:0"]) - except: - # XXX: We should always catch an explicit exception. - # What could go wrong here? + samdb.modify(delta, ["recalculate_sd:0","relax:0"]) + except LdbError, e: samdb.transaction_cancel() res = samdb.search(expression="objectClass=*", base=str(names.rootdn), scope=SCOPE_SUBTREE, @@ -1226,14 +1344,13 @@ def rebuild_sd(samdb, names): controls=["search_options:1:2"]) badsd = ndr_unpack(security.descriptor, str(res[0]["nTSecurityDescriptor"])) - print "bad stuff %s" % badsd.as_sddl(names.domainsid) + message(ERROR, "On %s bad stuff %s" % (str(delta.dn),badsd.as_sddl(names.domainsid))) return def removeProvisionUSN(samdb): attrs = [samba.provision.LAST_PROVISION_USN_ATTRIBUTE, "dn"] entry = samdb.search(expression="dn=@PROVISION", base = "", scope=SCOPE_SUBTREE, - controls=["search_options:1:2"], attrs=attrs) empty = Message() empty.dn = entry[0].dn @@ -1303,7 +1420,7 @@ def update_privilege(ref_private_path, cur_private_path): os.path.join(cur_private_path, "privilege.ldb")) -def update_samdb(ref_samdb, samdb, names, highestUSN, schema, prereloadfunc): +def update_samdb(ref_samdb, samdb, names, provisionUSNs, schema, prereloadfunc): """Upgrade the SAM DB contents for all the provision partitions :param ref_sambdb: An LDB object conntected to the sam.ldb of the reference @@ -1311,8 +1428,8 @@ def update_samdb(ref_samdb, samdb, names, highestUSN, schema, prereloadfunc): :param samdb: An LDB object connected to the sam.ldb of the update provision :param names: List of key provision parameters - :param highestUSN: The highest USN modified by provision/upgradeprovision - last time + :param provisionUSNs: A dictionnary with range of USN modified during provision + or upgradeprovision. Ranges are grouped by invocationID. :param schema: A Schema object that represent the schema of the provision :param prereloadfunc: A function that must be executed just before the reload of the schema @@ -1320,7 +1437,7 @@ def update_samdb(ref_samdb, samdb, names, highestUSN, schema, prereloadfunc): message(SIMPLE, "Starting update of samdb") ret = update_partition(ref_samdb, samdb, str(names.rootdn), names, - schema, highestUSN, prereloadfunc) + schema, provisionUSNs, prereloadfunc) if ret: message(SIMPLE, "Update of samdb finished") return 1 @@ -1537,7 +1654,7 @@ def sync_calculated_attributes(samdb, names): # This resulting object is filtered to remove all the back link attribute # (ie. memberOf) as they will be created by the other linked object (ie. # the one with the member attribute) -# All attributes specified in the hashAttrNotCopied associative array are +# All attributes specified in the attrNotCopied array are # also removed it's most of the time generated attributes # After missing entries have been added the update_partition function will @@ -1601,202 +1718,226 @@ if __name__ == '__main__': # 4) lastProvisionUSNs = get_last_provision_usn(ldbs.sam) if lastProvisionUSNs is not None: + v = 0 + for k in lastProvisionUSNs.keys(): + for r in lastProvisionUSNs[k]: + v = v + 1 + message(CHANGE, - "Find a last provision USN, %d range(s)" % len(lastProvisionUSNs)) + "Find last provision USN, %d invocation(s) for a total of %d ranges" % \ + (len(lastProvisionUSNs.keys()), v /2 )) + + if lastProvisionUSNs.get("default") != None: + message(CHANGE, "Old style for usn ranges used") + lastProvisionUSNs[str(names.invocation)] = lastProvisionUSNs["default"] + del lastProvisionUSNs["default"] + else: + message(SIMPLE, "Your provision lacks provision range information") + if confirm("Do you want to run findprovisionusnranges to try to find them ?", False): + ldbs.groupedRollback() + os.system("%s %s %s %s %s" % (os.path.join(os.path.dirname(sys.argv[0]), + "findprovisionusnranges"), + "--storedir", + paths.private_dir, + "-s", + smbconf)) + message(SIMPLE, "Once you applied/adapted the change(s) please restart the upgradeprovision script") + sys.exit(0) # Objects will be created with the admin session # (not anymore system session) adm_session = admin_session(lp, str(names.domainsid)) # So we reget handle on objects # ldbs = get_ldbs(paths, creds, adm_session, lp) - - if not sanitychecks(ldbs.sam, names): - message(SIMPLE, "Sanity checks for the upgrade have failed. " - "Check the messages and correct the errors " - "before rerunning upgradeprovision") - sys.exit(1) - - # Let's see provision parameters - print_provision_key_parameters(names) - - # 5) With all this information let's create a fresh new provision used as - # reference - message(SIMPLE, "Creating a reference provision") - provisiondir = tempfile.mkdtemp(dir=paths.private_dir, - prefix="referenceprovision") - newprovision(names, creds, session, smbconf, provisiondir, - provision_logger) - - # TODO - # 6) and 7) - # We need to get a list of object which SD is directly computed from - # defaultSecurityDescriptor. - # This will allow us to know which object we can rebuild the SD in case - # of change of the parent's SD or of the defaultSD. - # Get file paths of this new provision - newpaths = get_paths(param, targetdir=provisiondir) - new_ldbs = get_ldbs(newpaths, creds, session, lp) - new_ldbs.startTransactions() - - # 8) Populate some associative array to ease the update process - # List of attribute which are link and backlink - populate_links(new_ldbs.sam, names.schemadn) - # List of attribute with ASN DN synthax) - populate_dnsyntax(new_ldbs.sam, names.schemadn) - # 9) - update_privilege(newpaths.private_dir, paths.private_dir) - # 10) - oem = getOEMInfo(ldbs.sam, str(names.rootdn)) - # Do some modification on sam.ldb - ldbs.groupedCommit() - new_ldbs.groupedCommit() - deltaattr = None -# 11) - if re.match(".*alpha((9)|(\d\d+)).*", str(oem)): - # 11) A - # Starting from alpha9 we can consider that the structure is quite ok - # and that we should do only dela - deltaattr = delta_update_basesamdb(newpaths.samdb, - paths.samdb, - creds, - session, - lp, - message) - else: - # 11) B - simple_update_basesamdb(newpaths, paths, names) - ldbs = get_ldbs(paths, creds, session, lp) - removeProvisionUSN(ldbs.sam) - - ldbs.startTransactions() - minUSN = int(str(get_max_usn(ldbs.sam, str(names.rootdn)))) + 1 - new_ldbs.startTransactions() - - # 12) - schema = Schema(names.domainsid, schemadn=str(names.schemadn)) - # We create a closure that will be invoked just before schema reload - def schemareloadclosure(): - basesam = Ldb(paths.samdb, session_info=session, credentials=creds, lp=lp, - options=["modules:"]) - doit = False - if deltaattr is not None and len(deltaattr) > 1: - doit = True - if doit: - deltaattr.remove("dn") - for att in deltaattr: - if att.lower() == "dn": - continue - if (deltaattr.get(att) is not None - and deltaattr.get(att).flags() != FLAG_MOD_ADD): - doit = False - elif deltaattr.get(att) is None: - doit = False - if doit: - message(CHANGE, "Applying delta to @ATTRIBUTES") - deltaattr.dn = ldb.Dn(basesam, "@ATTRIBUTES") - basesam.modify(deltaattr) - else: - message(CHANGE, "Not applying delta to @ATTRIBUTES because " - "there is not only add") - # 13) - if opts.full: - if not update_samdb(new_ldbs.sam, ldbs.sam, names, lastProvisionUSNs, - schema, schemareloadclosure): - message(SIMPLE, "Rolling back all changes. Check the cause" - " of the problem") - message(SIMPLE, "Your system is as it was before the upgrade") + if not opts.fixntacl: + if not sanitychecks(ldbs.sam, names): + message(SIMPLE, "Sanity checks for the upgrade have failed. " + "Check the messages and correct the errors " + "before rerunning upgradeprovision") ldbs.groupedRollback() - new_ldbs.groupedRollback() - shutil.rmtree(provisiondir) sys.exit(1) - else: - # Try to reapply the change also when we do not change the sam - # as the delta_upgrade - schemareloadclosure() - sync_calculated_attributes(ldbs.sam, names) + + # Let's see provision parameters + print_provision_key_parameters(names) + + # 5) With all this information let's create a fresh new provision used as + # reference + message(SIMPLE, "Creating a reference provision") + provisiondir = tempfile.mkdtemp(dir=paths.private_dir, + prefix="referenceprovision") + newprovision(names, creds, session, smbconf, provisiondir, + provision_logger) + + # TODO + # 6) and 7) + # We need to get a list of object which SD is directly computed from + # defaultSecurityDescriptor. + # This will allow us to know which object we can rebuild the SD in case + # of change of the parent's SD or of the defaultSD. + # Get file paths of this new provision + newpaths = get_paths(param, targetdir=provisiondir) + new_ldbs = get_ldbs(newpaths, creds, session, lp) + new_ldbs.startTransactions() + + populateNotReplicated(new_ldbs.sam, names.schemadn) + # 8) Populate some associative array to ease the update process + # List of attribute which are link and backlink + populate_links(new_ldbs.sam, names.schemadn) + # List of attribute with ASN DN synthax) + populate_dnsyntax(new_ldbs.sam, names.schemadn) + # 9) + update_privilege(newpaths.private_dir, paths.private_dir) + # 10) + oem = getOEMInfo(ldbs.sam, str(names.rootdn)) + # Do some modification on sam.ldb + ldbs.groupedCommit() + new_ldbs.groupedCommit() + deltaattr = None + # 11) + if re.match(".*alpha((9)|(\d\d+)).*", str(oem)): + # 11) A + # Starting from alpha9 we can consider that the structure is quite ok + # and that we should do only dela + deltaattr = delta_update_basesamdb(newpaths.samdb, + paths.samdb, + creds, + session, + lp, + message) + else: + # 11) B + simple_update_basesamdb(newpaths, paths, names) + ldbs = get_ldbs(paths, creds, session, lp) + removeProvisionUSN(ldbs.sam) + + ldbs.startTransactions() + minUSN = int(str(get_max_usn(ldbs.sam, str(names.rootdn)))) + 1 + new_ldbs.startTransactions() + + # 12) + schema = Schema(names.domainsid, schemadn=str(names.schemadn)) + # We create a closure that will be invoked just before schema reload + def schemareloadclosure(): + basesam = Ldb(paths.samdb, session_info=session, credentials=creds, lp=lp, + options=["modules:"]) + doit = False + if deltaattr is not None and len(deltaattr) > 1: + doit = True + if doit: + deltaattr.remove("dn") + for att in deltaattr: + if att.lower() == "dn": + continue + if (deltaattr.get(att) is not None + and deltaattr.get(att).flags() != FLAG_MOD_ADD): + doit = False + elif deltaattr.get(att) is None: + doit = False + if doit: + message(CHANGE, "Applying delta to @ATTRIBUTES") + deltaattr.dn = ldb.Dn(basesam, "@ATTRIBUTES") + basesam.modify(deltaattr) + else: + message(CHANGE, "Not applying delta to @ATTRIBUTES because " + "there is not only add") + # 13) + if opts.full: + if not update_samdb(new_ldbs.sam, ldbs.sam, names, lastProvisionUSNs, + schema, schemareloadclosure): + message(SIMPLE, "Rolling back all changes. Check the cause" + " of the problem") + message(SIMPLE, "Your system is as it was before the upgrade") + ldbs.groupedRollback() + new_ldbs.groupedRollback() + shutil.rmtree(provisiondir) + sys.exit(1) + else: + # Try to reapply the change also when we do not change the sam + # as the delta_upgrade + schemareloadclosure() + sync_calculated_attributes(ldbs.sam, names) + res = ldbs.sam.search(expression="(samaccountname=dns)", + scope=SCOPE_SUBTREE, attrs=["dn"], + controls=["search_options:1:2"]) + if len(res) > 0: + message(SIMPLE, "You still have the old DNS object for managing " + "dynamic DNS, but you didn't supply --full so " + "a correct update can't be done") + ldbs.groupedRollback() + new_ldbs.groupedRollback() + shutil.rmtree(provisiondir) + sys.exit(1) + # 14) + update_secrets(new_ldbs.secrets, ldbs.secrets, message) + # 14bis) res = ldbs.sam.search(expression="(samaccountname=dns)", - scope=SCOPE_SUBTREE, attrs=["dn"], - controls=["search_options:1:2"]) - if len(res) > 0: - message(SIMPLE, "You still have the old DNS object for managing " - "dynamic DNS, but you didn't supply --full so " - "a correct update can't be done") - ldbs.groupedRollback() - new_ldbs.groupedRollback() - shutil.rmtree(provisiondir) - sys.exit(1) - # 14) - update_secrets(new_ldbs.secrets, ldbs.secrets, message) - # 14bis) - res = ldbs.sam.search(expression="(samaccountname=dns)", - scope=SCOPE_SUBTREE, attrs=["dn"], - controls=["search_options:1:2"]) - - if (len(res) == 1): - ldbs.sam.delete(res[0]["dn"]) - res2 = ldbs.secrets.search(expression="(samaccountname=dns)", - scope=SCOPE_SUBTREE, attrs=["dn"]) - update_dns_account_password(ldbs.sam, ldbs.secrets, names) - message(SIMPLE, "IMPORTANT!!! " - "If you were using Dynamic DNS before you need " - "to update your configuration, so that the " - "tkey-gssapi-credential has the following value: " - "DNS/%s.%s" % (names.netbiosname.lower(), - names.realm.lower())) - # 15) - message(SIMPLE, "Update machine account") - update_machine_account_password(ldbs.sam, ldbs.secrets, names) - - # 16) SD should be created with admin but as some previous acl were so wrong - # that admin can't modify them we have first to recreate them with the good - # form but with system account and then give the ownership to admin ... - if not re.match(r'.*alpha(9|\d\d+)', str(oem)): - message(SIMPLE, "Fixing old povision SD") - fix_partition_sd(ldbs.sam, names) - rebuild_sd(ldbs.sam, names) - - # We calculate the max USN before recalculating the SD because we might - # touch object that have been modified after a provision and we do not - # want that the next upgradeprovision thinks that it has a green light - # to modify them - - # 17) - maxUSN = get_max_usn(ldbs.sam, str(names.rootdn)) - - # 18) We rebuild SD only if defaultSecurityDescriptor is modified - # But in fact we should do it also if one object has its SD modified as - # child might need rebuild - if defSDmodified: - message(SIMPLE, "Updating SD") - ldbs.sam.set_session_info(adm_session) - # Alpha10 was a bit broken still - if re.match(r'.*alpha(\d|10)', str(oem)): - fix_partition_sd(ldbs.sam, names) - rebuild_sd(ldbs.sam, names) - - # 19) - # Now we are quite confident in the recalculate process of the SD, we make - # it optional. - # Also the check must be done in a clever way as for the moment we just - # compare SDDL - if opts.debugchangesd: - check_updated_sd(new_ldbs.sam, ldbs.sam, names) - - # 20) - updateOEMInfo(ldbs.sam, str(names.rootdn)) - # 21) - check_for_DNS(newpaths.private_dir, paths.private_dir) - # 22) - if lastProvisionUSNs is not None: - update_provision_usn(ldbs.sam, minUSN, maxUSN) - if opts.full and (names.policyid is None or names.policyid_dc is None): - update_policyids(names, ldbs.sam) - if opts.full or opts.resetfileacl: + scope=SCOPE_SUBTREE, attrs=["dn"], + controls=["search_options:1:2"]) + + if (len(res) == 1): + ldbs.sam.delete(res[0]["dn"]) + res2 = ldbs.secrets.search(expression="(samaccountname=dns)", + scope=SCOPE_SUBTREE, attrs=["dn"]) + update_dns_account_password(ldbs.sam, ldbs.secrets, names) + message(SIMPLE, "IMPORTANT!!! " + "If you were using Dynamic DNS before you need " + "to update your configuration, so that the " + "tkey-gssapi-credential has the following value: " + "DNS/%s.%s" % (names.netbiosname.lower(), + names.realm.lower())) + # 15) + message(SIMPLE, "Update machine account") + update_machine_account_password(ldbs.sam, ldbs.secrets, names) + + dnToRecalculate.sort(dn_sort) + # 16) SD should be created with admin but as some previous acl were so wrong + # that admin can't modify them we have first to recreate them with the good + # form but with system account and then give the ownership to admin ... + if str(oem) != "" and not re.match(r'.*alpha(9|\d\d+)', str(oem)): + message(SIMPLE, "Fixing very old provision SD") + rebuild_sd(ldbs.sam, names) + + # We calculate the max USN before recalculating the SD because we might + # touch object that have been modified after a provision and we do not + # want that the next upgradeprovision thinks that it has a green light + # to modify them + + # 17) + maxUSN = get_max_usn(ldbs.sam, str(names.rootdn)) + + # 18) We rebuild SD if a we have a list of DN to recalculate or if the + # defSDmodified is set. + if defSDmodified or len(dnToRecalculate) >0: + message(SIMPLE, "Some defaultSecurityDescriptors and/or" + "securityDescriptor have changed, recalculating SD ") + ldbs.sam.set_session_info(adm_session) + rebuild_sd(ldbs.sam, names) + + # 19) + # Now we are quite confident in the recalculate process of the SD, we make + # it optional. And we don't do it if there is DN that we must touch + # as we are assured that on this DNs we will have differences ! + # Also the check must be done in a clever way as for the moment we just + # compare SDDL + if len(dnNotToRecalculate) == 0 and (opts.debugchangesd or opts.debugall): + message(CHANGESD, "Checking recalculated SDs") + check_updated_sd(new_ldbs.sam, ldbs.sam, names) + + # 20) + updateOEMInfo(ldbs.sam, str(names.rootdn)) + # 21) + check_for_DNS(newpaths.private_dir, paths.private_dir) + # 22) + if lastProvisionUSNs is not None: + update_provision_usn(ldbs.sam, minUSN, maxUSN, names.invocation) + if opts.full and (names.policyid is None or names.policyid_dc is None): + update_policyids(names, ldbs.sam) + if opts.full or opts.resetfileacl or opts.fixntacl: try: update_gpo(paths, ldbs.sam, names, lp, message, 1) except ProvisioningError, e: message(ERROR, "The policy for domain controller is missing. " - "You should restart upgradeprovision with --full") + "You should restart upgradeprovision with --full") except IOError, e: message(ERROR, "Setting ACL not supported on your filesystem") else: @@ -1804,25 +1945,29 @@ if __name__ == '__main__': update_gpo(paths, ldbs.sam, names, lp, message, 0) except ProvisioningError, e: message(ERROR, "The policy for domain controller is missing. " - "You should restart upgradeprovision with --full") - ldbs.groupedCommit() - new_ldbs.groupedCommit() - message(SIMPLE, "Upgrade finished!") - # remove reference provision now that everything is done ! - # So we have reindexed first if need when the merged schema was reloaded - # (as new attributes could have quick in) - # But the second part of the update (when we update existing objects - # can also have an influence on indexing as some attribute might have their - # searchflag modificated - message(SIMPLE, "Reopenning samdb to trigger reindexing if needed " - "after modification") - samdb = Ldb(paths.samdb, session_info=session, credentials=creds, lp=lp) - message(SIMPLE, "Reindexing finished") - - shutil.rmtree(provisiondir) + "You should restart upgradeprovision with --full") + if not opts.fixntacl: + ldbs.groupedCommit() + new_ldbs.groupedCommit() + message(SIMPLE, "Upgrade finished!") + # remove reference provision now that everything is done ! + # So we have reindexed first if need when the merged schema was reloaded + # (as new attributes could have quick in) + # But the second part of the update (when we update existing objects + # can also have an influence on indexing as some attribute might have their + # searchflag modificated + message(SIMPLE, "Reopenning samdb to trigger reindexing if needed " + "after modification") + samdb = Ldb(paths.samdb, session_info=session, credentials=creds, lp=lp) + message(SIMPLE, "Reindexing finished") + + shutil.rmtree(provisiondir) + else: + ldbs.groupedRollback() + message(SIMPLE, "ACLs fixed !") except StandardError, err: message(ERROR, "A problem occurred while trying to upgrade your " - "provision. A full backup is located at %s" % backupdir) + "provision. A full backup is located at %s" % backupdir) if opts.debugall or opts.debugchange: (typ, val, tb) = sys.exc_info() traceback.print_exception(typ, val, tb) diff --git a/source4/scripting/bin/wscript_build b/source4/scripting/bin/wscript_build new file mode 100644 index 0000000000..e52b32bc02 --- /dev/null +++ b/source4/scripting/bin/wscript_build @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +bld.SAMBA_SCRIPT('samba_dnsupdate', pattern='samba_dnsupdate', installdir='.') +bld.SAMBA_SCRIPT('samba_spnupdate', pattern='samba_spnupdate', installdir='.') +bld.SAMBA_SCRIPT('upgradeprovision', pattern='upgradeprovision', installdir='.') diff --git a/source4/scripting/devel/chgtdcpass b/source4/scripting/devel/chgtdcpass index dc249834e0..4f5ea15a80 100755 --- a/source4/scripting/devel/chgtdcpass +++ b/source4/scripting/devel/chgtdcpass @@ -29,8 +29,9 @@ import samba.getopt as options from samba.credentials import DONT_USE_KERBEROS from samba.auth import system_session from samba import param +from samba.provision import find_provision_key_parameters from samba.upgradehelpers import (get_paths, - find_provision_key_parameters, get_ldbs, + get_ldbs, update_machine_account_password) parser = optparse.OptionParser("chgtdcpass [options]") diff --git a/source4/scripting/devel/demodirsync.py b/source4/scripting/devel/demodirsync.py new file mode 100755 index 0000000000..41dac6ff51 --- /dev/null +++ b/source4/scripting/devel/demodirsync.py @@ -0,0 +1,156 @@ +#!/usr/bin/python + + +import optparse +import sys +import base64 + +sys.path.insert(0, "bin/python") + +import samba.getopt as options +from samba.dcerpc import drsblobs, misc +from samba.ndr import ndr_pack, ndr_unpack +from samba import Ldb + +parser = optparse.OptionParser("get-descriptor [options]") +sambaopts = options.SambaOptions(parser) +credopts = options.CredentialsOptions(parser) +parser.add_option_group(credopts) + +parser.add_option("-b", type="string", metavar="BASE", + help="set base DN for the search") +parser.add_option("--host", type="string", metavar="HOST", + help="Ip of the host") + +lp = sambaopts.get_loadparm() +creds = credopts.get_credentials(lp) + +opts = parser.parse_args()[0] + +def printdirsync(ctl): + arr = ctl.split(':') + if arr[0] == 'dirsync': + print "Need to continue: %s" % arr[1] + cookie = ndr_unpack(drsblobs.ldapControlDirSyncCookie, base64.b64decode(arr[3])) + print "DC's NTDS guid: %s " % cookie.blob.guid1 + print "highest usn %s" % cookie.blob.highwatermark.highest_usn + print "tmp higest usn %s" % cookie.blob.highwatermark.tmp_highest_usn + print "reserved usn %s" % cookie.blob.highwatermark.reserved_usn + if cookie.blob.extra_length >0: + print "highest usn in extra %s" % cookie.blob.extra.ctr.cursors[0].highest_usn + return cookie + +remote_ldb= Ldb("ldap://" + opts.host + ":389", credentials=creds, lp=lp) +tab = [] +if opts.b: + base = opts.b +else: + base = None + +guid = None +(msgs, ctrls) = remote_ldb.search(expression="(samaccountname=administrator)", base=base, attrs=["objectClass"], controls=["dirsync:1:1:50"]) +if (len(ctrls)): + for ctl in ctrls: + arr = ctl.split(':') + if arr[0] == 'dirsync': + cookie = ndr_unpack(drsblobs.ldapControlDirSyncCookie, base64.b64decode(arr[3])) + guid = cookie.blob.guid1 + pass +if not guid: + print "No dirsync control ... strange" + sys.exit(1) + +print "" +print "Getting first guest without any cookie" +(msgs, ctrls) = remote_ldb.searchex(expression="(samaccountname=guest)", base=base, attrs=["objectClass"], controls=["dirsync:1:1:50"]) +cookie = None +if (len(ctrls)): + for ctl in ctrls: + cookie = printdirsync(ctl) + print "Returned %d entries" % len(msgs) + +savedcookie = cookie + +print "" +print "Getting allusers with cookie" +controls=["dirsync:1:1:50:%s" % base64.b64encode(ndr_pack(cookie))] +(msgs, ctrls) = remote_ldb.searchex(expression="(samaccountname=*)", base=base, attrs=["objectClass"], controls=controls) +if (len(ctrls)): + for ctl in ctrls: + cookie = printdirsync(ctl) + print "Returned %d entries" % len(msgs) + +cookie = savedcookie +cookie.blob.guid1 = misc.GUID("128a99bf-e2df-4832-ac0a-1fb625e530db") +if cookie.blob.extra_length > 0: + cookie.blob.extra.ctr.cursors[0].source_dsa_invocation_id = misc.GUID("128a99bf-e2df-4832-ac0a-1fb625e530db") + +print "" +print "Getting all the entries" +controls=["dirsync:1:1:50:%s" % base64.b64encode(ndr_pack(cookie))] +(msgs, ctrls) = remote_ldb.searchex(expression="(objectclass=*)", base=base, controls=controls) +cont = 0 +if (len(ctrls)): + for ctl in ctrls: + cookie = printdirsync(ctl) + if cookie != None: + cont = (ctl.split(':'))[1] + print "Returned %d entries" % len(msgs) + +usn = cookie.blob.highwatermark.tmp_highest_usn +if cookie.blob.extra_length > 0: + bigusn = cookie.blob.extra.ctr.cursors[0].highest_usn +else: + bigusn = usn + 1000 +while (cont == "1"): + print "" + controls=["dirsync:1:1:50:%s" % base64.b64encode(ndr_pack(cookie))] + (msgs, ctrls) = remote_ldb.searchex(expression="(objectclass=*)", base=base, controls=controls) + if (len(ctrls)): + for ctl in ctrls: + cookie = printdirsync(ctl) + if cookie != None: + cont = (ctl.split(':'))[1] + print "Returned %d entries" % len(msgs) + +print "" +print "Getting with cookie but usn changed to %d we should use the one in extra" % (bigusn - 1) +cookie.blob.highwatermark.highest_usn = 0 +cookie.blob.highwatermark.tmp_highest_usn = usn - 2 +if cookie.blob.extra_length > 0: + print "here" + cookie.blob.extra.ctr.cursors[0].highest_usn = bigusn - 1 +controls=["dirsync:1:1:50:%s" % base64.b64encode(ndr_pack(cookie))] +(msgs, ctrls) = remote_ldb.searchex(expression="(objectclass=*)", base=base, controls=controls) +if (len(ctrls)): + for ctl in ctrls: + cookie = printdirsync(ctl) + print "Returned %d entries" % len(msgs) + +print "" +print "Getting with cookie but usn %d changed and extra/cursor GUID too" % (usn - 2) +print " so that it's (tmp)highest_usn that drives the limit" +cookie.blob.highwatermark.highest_usn = 0 +cookie.blob.highwatermark.tmp_highest_usn = usn - 2 +if cookie.blob.extra_length > 0: + cookie.blob.extra.ctr.cursors[0].source_dsa_invocation_id = misc.GUID("128a99bf-e2df-4832-ac0a-1fb625e530db") + cookie.blob.extra.ctr.cursors[0].highest_usn = bigusn - 1 +controls=["dirsync:1:1:50:%s" % base64.b64encode(ndr_pack(cookie))] +(msgs, ctrls) = remote_ldb.searchex(expression="(objectclass=*)", base=base, controls=controls) +if (len(ctrls)): + for ctl in ctrls: + cookie = printdirsync(ctl) + print "Returned %d entries" % len(msgs) + +print "" +print "Getting with cookie but usn changed to %d" % (usn - 2) +cookie.blob.highwatermark.highest_usn = 0 +cookie.blob.highwatermark.tmp_highest_usn = (usn - 2) +if cookie.blob.extra_length > 0: + cookie.blob.extra.ctr.cursors[0].highest_usn = (usn - 2) +controls=["dirsync:1:1:50:%s" % base64.b64encode(ndr_pack(cookie))] +(msgs, ctrls) = remote_ldb.searchex(expression="(objectclass=*)", base=base, controls=controls) +if (len(ctrls)): + for ctl in ctrls: + cookie = printdirsync(ctl) + print "Returned %d entries" % len(msgs) diff --git a/source4/scripting/devel/selftest-vars.sh b/source4/scripting/devel/selftest-vars.sh index bc73c05407..a8f323dbda 100644 --- a/source4/scripting/devel/selftest-vars.sh +++ b/source4/scripting/devel/selftest-vars.sh @@ -2,38 +2,42 @@ # outside the test environment export UID_WRAPPER=1 -export NSS_WRAPPER_PASSWD=st/dc/passwd -export NSS_WRAPPER_GROUP=st/dc/group +export NSS_WRAPPER_PASSWD=$PWD/st/dc/passwd +export NSS_WRAPPER_GROUP=$PWD/st/dc/group export CONFIGURATION="--configfile=$PWD/st/dc/etc/smb.conf" +export VAMPIRE_DC_SERVER=localvampiredc +export VAMPIRE_DC_SERVER_IP=127.0.0.22 +export VAMPIRE_DC_NETBIOSNAME=localvampiredc1 +export VAMPIRE_DC_NETBIOSALIAS=localvampiredc export MEMBER_SERVER=localmember3 -export MEMBER_SERVER_IP=127.0.0.3 +export MEMBER_SERVER_IP=127.0.0.23 export MEMBER_NETBIOSNAME=localmember3 export MEMBER_NETBIOSALIAS=localmember export RPC_PROXY_SERVER=localrpcproxy4 -export RPC_PROXY_SERVER_IP=127.0.0.4 +export RPC_PROXY_SERVER_IP=127.0.0.24 export RPC_PROXY_NETBIOSNAME=localrpcproxy4 export RPC_PROXY_NETBIOSALIAS=localrpcproxy export SELFTEST_MAXTIME=1200 export NETBIOSNAME=localdc1 export REALM=SAMBA.EXAMPLE.COM -export SOCKET_WRAPPER_DEFAULT_IFACE=1 +export SOCKET_WRAPPER_DEFAULT_IFACE=21 export SERVER=localdc1 export WINBINDD_SOCKET_DIR=$PWD/st/dc/winbindd_socket export SELFTEST_PREFIX=$PWD/st export DOMAIN=SAMBADOMAIN export BINDIR=./bin -export DC_SERVER_IP=127.0.0.1 +export DC_SERVER_IP=127.0.0.21 export SELFTEST_INTERFACES=127.0.0.6/8,127.0.0.7/8,127.0.0.8/8,127.0.0.9/8,127.0.0.10/8,127.0.0.11/8 export SOCKET_WRAPPER_DIR=$PWD/st/w export DC_USERNAME=Administrator export USERNAME=Administrator -export SERVER_IP=127.0.0.1 +export SERVER_IP=127.0.0.21 export KRB5_CONFIG=$PWD/st/dc/etc/krb5.conf export PREFIX_ABS=$PWD/st export SRCDIR_ABS=$PWD -export PREFIX=./st -export KRB5CCNAME=./st/krb5ticket -export SRCDIR=. +export PREFIX=$PWD/st +export KRB5CCNAME=$PWD/st/krb5ticket +export SRCDIR=$PWD/ export TLS_ENABLED=yes export DC_NETBIOSALIAS=localdc export DC_NETBIOSNAME=localdc1 diff --git a/source4/scripting/python/pyglue.c b/source4/scripting/python/pyglue.c index f89785f971..8a82f3502a 100644 --- a/source4/scripting/python/pyglue.c +++ b/source4/scripting/python/pyglue.c @@ -25,6 +25,10 @@ void init_glue(void); +#ifndef Py_RETURN_NONE +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None +#endif + static PyObject *py_generate_random_str(PyObject *self, PyObject *args) { int len; @@ -149,22 +153,22 @@ static PyObject *py_interface_ips(PyObject *self, PyObject *args) return NULL; } - load_interfaces(tmp_ctx, lpcfg_interfaces(lp_ctx), &ifaces); + load_interface_list(tmp_ctx, lp_ctx, &ifaces); - count = iface_count(ifaces); + count = iface_list_count(ifaces); /* first count how many are not loopback addresses */ for (ifcount = i = 0; i<count; i++) { - const char *ip = iface_n_ip(ifaces, i); - if (!(!all_interfaces && iface_same_net(ip, "127.0.0.1", "255.0.0.0"))) { + const char *ip = iface_list_n_ip(ifaces, i); + if (!(!all_interfaces && iface_list_same_net(ip, "127.0.0.1", "255.0.0.0"))) { ifcount++; } } pylist = PyList_New(ifcount); for (ifcount = i = 0; i<count; i++) { - const char *ip = iface_n_ip(ifaces, i); - if (!(!all_interfaces && iface_same_net(ip, "127.0.0.1", "255.0.0.0"))) { + const char *ip = iface_list_n_ip(ifaces, i); + if (!(!all_interfaces && iface_list_same_net(ip, "127.0.0.1", "255.0.0.0"))) { PyList_SetItem(pylist, ifcount, PyString_FromString(ip)); ifcount++; } @@ -173,6 +177,30 @@ static PyObject *py_interface_ips(PyObject *self, PyObject *args) return pylist; } +static PyObject *py_strcasecmp_m(PyObject *self, PyObject *args) +{ + char *s1, *s2; + + if (!PyArg_ParseTuple(args, "ss", &s1, &s2)) + return NULL; + + return PyInt_FromLong(strcasecmp_m(s1, s2)); +} + +static PyObject *py_strstr_m(PyObject *self, PyObject *args) +{ + char *s1, *s2, *ret; + + if (!PyArg_ParseTuple(args, "ss", &s1, &s2)) + return NULL; + + ret = strstr_m(s1, s2); + if (!ret) { + Py_RETURN_NONE; + } + return PyString_FromString(ret); +} + static PyMethodDef py_misc_methods[] = { { "generate_random_str", (PyCFunction)py_generate_random_str, METH_VARARGS, "generate_random_str(len) -> string\n" @@ -192,6 +220,10 @@ static PyMethodDef py_misc_methods[] = { "get debug level" }, { "interface_ips", (PyCFunction)py_interface_ips, METH_VARARGS, "get interface IP address list"}, + { "strcasecmp_m", (PyCFunction)py_strcasecmp_m, METH_VARARGS, + "(for testing) compare two strings using Samba's strcasecmp_m()"}, + { "strstr_m", (PyCFunction)py_strstr_m, METH_VARARGS, + "(for testing) find one string in another with Samba's strstr_m()"}, { NULL } }; diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 2a54f47d2b..76eb44ce92 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -26,6 +26,7 @@ __docformat__ = "restructuredText" import os import sys +import samba.param def source_tree_topdir(): '''return the top level directory (the one containing the source4 directory)''' @@ -77,8 +78,8 @@ class Ldb(_Ldb): if modules_dir is not None: self.set_modules_dir(modules_dir) - elif lp is not None: - self.set_modules_dir(os.path.join(lp.get("modules dir"), "ldb")) + else: + self.set_modules_dir(os.path.join(samba.param.modules_dir(), "ldb")) if session_info is not None: self.set_session_info(session_info) @@ -348,3 +349,5 @@ nttime2string = _glue.nttime2string nttime2unix = _glue.nttime2unix unix2nttime = _glue.unix2nttime generate_random_password = _glue.generate_random_password +strcasecmp_m = _glue.strcasecmp_m +strstr_m = _glue.strstr_m diff --git a/source4/scripting/python/samba/common.py b/source4/scripting/python/samba/common.py new file mode 100644 index 0000000000..a2a4962797 --- /dev/null +++ b/source4/scripting/python/samba/common.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# +# Samba common functions +# +# Copyright (C) Matthieu Patou <mat@matws.net> +# +# 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 <http://www.gnu.org/licenses/>. +# + +def confirm(msg, forced = False): + """confirm an action with the user + :param msg: A string to print to the user + :param forced: Are the answer forced + """ + if forced: + print("%s [YES]" % msg) + return True + + v = raw_input(msg + ' [y/N] ') + return v.upper() in ['Y', 'YES'] + + diff --git a/source4/scripting/python/samba/dbchecker.py b/source4/scripting/python/samba/dbchecker.py new file mode 100644 index 0000000000..88fd0edf00 --- /dev/null +++ b/source4/scripting/python/samba/dbchecker.py @@ -0,0 +1,317 @@ +#!/usr/bin/env python +# +# Samba4 AD database checker +# +# Copyright (C) Andrew Tridgell 2011 +# +# 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 <http://www.gnu.org/licenses/>. +# + +import ldb +from samba import dsdb +from samba import common +from samba.dcerpc import misc + + +class dsdb_DN(object): + '''a class to manipulate DN components''' + + def __init__(self, samdb, dnstring, syntax_oid): + if syntax_oid in [ dsdb.DSDB_SYNTAX_BINARY_DN, dsdb.DSDB_SYNTAX_STRING_DN ]: + colons = dnstring.split(':') + if len(colons) < 4: + raise Exception("invalid DN prefix") + prefix_len = 4 + len(colons[1]) + int(colons[1]) + self.prefix = dnstring[0:prefix_len] + self.dnstring = dnstring[prefix_len:] + else: + self.dnstring = dnstring + self.prefix = '' + try: + self.dn = ldb.Dn(samdb, self.dnstring) + except Exception, msg: + print("ERROR: bad DN string '%s'" % self.dnstring) + raise + + def __str__(self): + return self.prefix + str(self.dn.extended_str(mode=1)) + +class dbcheck(object): + """check a SAM database for errors""" + + def __init__(self, samdb, samdb_schema=None, verbose=False, fix=False, yes=False, quiet=False): + self.samdb = samdb + self.samdb_schema = (samdb_schema or samdb) + self.verbose = verbose + self.fix = fix + self.yes = yes + self.quiet = quiet + + def check_database(self, DN=None, scope=ldb.SCOPE_SUBTREE, controls=[], attrs=['*']): + '''perform a database check, returning the number of errors found''' + + res = self.samdb.search(base=DN, scope=scope, attrs=['dn'], controls=controls) + self.report('Checking %u objects' % len(res)) + error_count = 0 + for object in res: + error_count += self.check_object(object.dn, attrs=attrs) + if error_count != 0 and not self.fix: + self.report("Please use --fix to fix these errors") + self.report('Checked %u objects (%u errors)' % (len(res), error_count)) + + return error_count + + + def report(self, msg): + '''print a message unless quiet is set''' + if not self.quiet: + print(msg) + + + ################################################################ + # a local confirm function that obeys the --fix and --yes options + def confirm(self, msg): + '''confirm a change''' + if not self.fix: + return False + if self.quiet: + return self.yes + return common.confirm(msg, forced=self.yes) + + + ################################################################ + # handle empty attributes + def err_empty_attribute(self, dn, attrname): + '''fix empty attributes''' + self.report("ERROR: Empty attribute %s in %s" % (attrname, dn)) + if not self.confirm('Remove empty attribute %s from %s?' % (attrname, dn)): + self.report("Not fixing empty attribute %s" % attrname) + return + + m = ldb.Message() + m.dn = dn + m[attrname] = ldb.MessageElement('', ldb.FLAG_MOD_DELETE, attrname) + if self.verbose: + self.report(self.samdb.write_ldif(m, ldb.CHANGETYPE_MODIFY)) + try: + self.samdb.modify(m, controls=["relax:0"], validate=False) + except Exception, msg: + self.report("Failed to remove empty attribute %s : %s" % (attrname, msg)) + return + self.report("Removed empty attribute %s" % attrname) + + + ################################################################ + # handle normalisation mismatches + def err_normalise_mismatch(self, dn, attrname, values): + '''fix attribute normalisation errors''' + self.report("ERROR: Normalisation error for attribute %s in %s" % (attrname, dn)) + mod_list = [] + for val in values: + normalised = self.samdb.dsdb_normalise_attributes(self.samdb_schema, attrname, [val]) + if len(normalised) != 1: + self.report("Unable to normalise value '%s'" % val) + mod_list.append((val, '')) + elif (normalised[0] != val): + self.report("value '%s' should be '%s'" % (val, normalised[0])) + mod_list.append((val, normalised[0])) + if not self.confirm('Fix normalisation for %s from %s?' % (attrname, dn)): + self.report("Not fixing attribute %s" % attrname) + return + + m = ldb.Message() + m.dn = dn + for i in range(0, len(mod_list)): + (val, nval) = mod_list[i] + m['value_%u' % i] = ldb.MessageElement(val, ldb.FLAG_MOD_DELETE, attrname) + if nval != '': + m['normv_%u' % i] = ldb.MessageElement(nval, ldb.FLAG_MOD_ADD, attrname) + + if self.verbose: + self.report(self.samdb.write_ldif(m, ldb.CHANGETYPE_MODIFY)) + try: + self.samdb.modify(m, controls=["relax:0"], validate=False) + except Exception, msg: + self.report("Failed to normalise attribute %s : %s" % (attrname, msg)) + return + self.report("Normalised attribute %s" % attrname) + + def is_deleted_objects_dn(self, dsdb_dn): + '''see if a dsdb_DN is the special Deleted Objects DN''' + return dsdb_dn.prefix == "B:32:18E2EA80684F11D2B9AA00C04F79F805:" + + + ################################################################ + # handle a missing GUID extended DN component + def err_incorrect_dn_GUID(self, dn, attrname, val, dsdb_dn, errstr): + self.report("ERROR: %s component for %s in object %s - %s" % (errstr, attrname, dn, val)) + controls=["extended_dn:1:1"] + if self.is_deleted_objects_dn(dsdb_dn): + controls.append("show_deleted:1") + try: + res = self.samdb.search(base=str(dsdb_dn.dn), scope=ldb.SCOPE_BASE, + attrs=[], controls=controls) + except ldb.LdbError, (enum, estr): + self.report("unable to find object for DN %s - cannot fix (%s)" % (dsdb_dn.dn, estr)) + return + dsdb_dn.dn = res[0].dn + + if not self.confirm('Change DN to %s?' % str(dsdb_dn)): + self.report("Not fixing %s" % errstr) + return + m = ldb.Message() + m.dn = dn + m['old_value'] = ldb.MessageElement(val, ldb.FLAG_MOD_DELETE, attrname) + m['new_value'] = ldb.MessageElement(str(dsdb_dn), ldb.FLAG_MOD_ADD, attrname) + if self.verbose: + self.report(self.samdb.write_ldif(m, ldb.CHANGETYPE_MODIFY)) + try: + self.samdb.modify(m) + except Exception, msg: + self.report("Failed to fix %s on attribute %s : %s" % (errstr, attrname, msg)) + return + self.report("Fixed %s on attribute %s" % (errstr, attrname)) + + + ################################################################ + # handle a DN pointing to a deleted object + def err_deleted_dn(self, dn, attrname, val, dsdb_dn, correct_dn): + self.report("ERROR: target DN is deleted for %s in object %s - %s" % (attrname, dn, val)) + self.report("Target GUID points at deleted DN %s" % correct_dn) + if not self.confirm('Remove DN?'): + self.report("Not removing") + return + m = ldb.Message() + m.dn = dn + m['old_value'] = ldb.MessageElement(val, ldb.FLAG_MOD_DELETE, attrname) + if self.verbose: + self.report(self.samdb.write_ldif(m, ldb.CHANGETYPE_MODIFY)) + try: + self.samdb.modify(m) + except Exception, msg: + self.report("Failed to remove deleted DN attribute %s : %s" % (attrname, msg)) + return + self.report("Removed deleted DN on attribute %s" % attrname) + + + ################################################################ + # handle a DN string being incorrect + def err_dn_target_mismatch(self, dn, attrname, val, dsdb_dn, correct_dn, errstr): + self.report("ERROR: incorrect DN string component for %s in object %s - %s" % (attrname, dn, val)) + dsdb_dn.dn = correct_dn + + if not self.confirm('Change DN to %s?' % str(dsdb_dn)): + self.report("Not fixing %s" % errstr) + return + m = ldb.Message() + m.dn = dn + m['old_value'] = ldb.MessageElement(val, ldb.FLAG_MOD_DELETE, attrname) + m['new_value'] = ldb.MessageElement(str(dsdb_dn), ldb.FLAG_MOD_ADD, attrname) + if self.verbose: + self.report(self.samdb.write_ldif(m, ldb.CHANGETYPE_MODIFY)) + try: + self.samdb.modify(m) + except Exception, msg: + self.report("Failed to fix incorrect DN string on attribute %s : %s" % (attrname, msg)) + return + self.report("Fixed incorrect DN string on attribute %s" % (attrname)) + + + ################################################################ + # specialised checking for a dn attribute + def check_dn(self, obj, attrname, syntax_oid): + '''check a DN attribute for correctness''' + error_count = 0 + for val in obj[attrname]: + dsdb_dn = dsdb_DN(self.samdb, val, syntax_oid) + + # all DNs should have a GUID component + guid = dsdb_dn.dn.get_extended_component("GUID") + if guid is None: + error_count += 1 + self.err_incorrect_dn_GUID(obj.dn, attrname, val, dsdb_dn, "missing GUID") + continue + + guidstr = str(misc.GUID(guid)) + + # check its the right GUID + try: + res = self.samdb.search(base="<GUID=%s>" % guidstr, scope=ldb.SCOPE_BASE, + attrs=['isDeleted'], controls=["extended_dn:1:1", "show_deleted:1"]) + except ldb.LdbError, (enum, estr): + error_count += 1 + self.err_incorrect_dn_GUID(obj.dn, attrname, val, dsdb_dn, "incorrect GUID") + continue + + # the target DN might be deleted + if ((not self.is_deleted_objects_dn(dsdb_dn)) and + 'isDeleted' in res[0] and + res[0]['isDeleted'][0].upper() == "TRUE"): + # note that we don't check this for the special wellKnownObjects prefix + # for Deleted Objects, as we expect that to be deleted + error_count += 1 + self.err_deleted_dn(obj.dn, attrname, val, dsdb_dn, res[0].dn) + continue + + # check the DN matches in string form + if res[0].dn.extended_str() != dsdb_dn.dn.extended_str(): + error_count += 1 + self.err_dn_target_mismatch(obj.dn, attrname, val, dsdb_dn, + res[0].dn, "incorrect string version of DN") + continue + + return error_count + + + + ################################################################ + # check one object - calls to individual error handlers above + def check_object(self, dn, attrs=['*']): + '''check one object''' + if self.verbose: + self.report("Checking object %s" % dn) + res = self.samdb.search(base=dn, scope=ldb.SCOPE_BASE, controls=["extended_dn:1:1"], attrs=attrs) + if len(res) != 1: + self.report("Object %s disappeared during check" % dn) + return 1 + obj = res[0] + error_count = 0 + for attrname in obj: + if attrname == 'dn': + continue + + # check for empty attributes + for val in obj[attrname]: + if val == '': + self.err_empty_attribute(dn, attrname) + error_count += 1 + continue + + # get the syntax oid for the attribute, so we can can have + # special handling for some specific attribute types + syntax_oid = self.samdb_schema.get_syntax_oid_from_lDAPDisplayName(attrname) + + if syntax_oid in [ dsdb.DSDB_SYNTAX_BINARY_DN, dsdb.DSDB_SYNTAX_OR_NAME, + dsdb.DSDB_SYNTAX_STRING_DN, ldb.LDB_SYNTAX_DN ]: + # it's some form of DN, do specialised checking on those + error_count += self.check_dn(obj, attrname, syntax_oid) + + # check for incorrectly normalised attributes + for val in obj[attrname]: + normalised = self.samdb.dsdb_normalise_attributes(self.samdb_schema, attrname, [val]) + if len(normalised) != 1 or normalised[0] != val: + self.err_normalise_mismatch(dn, attrname, obj[attrname]) + error_count += 1 + break + return error_count diff --git a/source4/scripting/python/samba/hostconfig.py b/source4/scripting/python/samba/hostconfig.py index 3e6dc6b1dd..c50b944c98 100644 --- a/source4/scripting/python/samba/hostconfig.py +++ b/source4/scripting/python/samba/hostconfig.py @@ -37,7 +37,7 @@ class Hostconfig(object): :param session_info: Session info to use :param credentials: Credentials to access the SamDB with """ - return SamDB(url=self.lp.get("sam database"), + return SamDB(url=self.lp.samdb_url(), session_info=session_info, credentials=credentials, lp=self.lp) diff --git a/source4/scripting/python/samba/idmap.py b/source4/scripting/python/samba/idmap.py index 93fca46edd..9d957341de 100644 --- a/source4/scripting/python/samba/idmap.py +++ b/source4/scripting/python/samba/idmap.py @@ -41,7 +41,7 @@ class IDmapDB(samba.Ldb): self.lp = lp if url is None: - url = lp.get("idmap database") + url = lp.private_path("idmap.ldb") super(IDmapDB, self).__init__(url=url, lp=lp, modules_dir=modules_dir, session_info=session_info, credentials=credentials, flags=flags, diff --git a/source4/scripting/python/samba/join.py b/source4/scripting/python/samba/join.py index c0aee71407..b586e2cd5b 100644 --- a/source4/scripting/python/samba/join.py +++ b/source4/scripting/python/samba/join.py @@ -36,6 +36,11 @@ import talloc # this makes debugging easier talloc.enable_null_tracking() +class DCJoinException(Exception): + + def __init__(self, msg): + super(DCJoinException, self).__init__("Can't join, error: %s" % msg) + class dc_join(object): '''perform a DC join''' @@ -62,6 +67,12 @@ class dc_join(object): session_info=system_session(), credentials=ctx.creds, lp=ctx.lp) + try: + ctx.samdb.search(scope=ldb.SCOPE_ONELEVEL, attrs=["dn"]) + except ldb.LdbError, (enum, estr): + raise DCJoinException(estr) + + ctx.myname = netbios_name ctx.samname = "%s$" % ctx.myname ctx.base_dn = str(ctx.samdb.get_default_basedn()) diff --git a/source4/scripting/python/samba/netcmd/__init__.py b/source4/scripting/python/samba/netcmd/__init__.py index cf514d5c49..1373cb289b 100644 --- a/source4/scripting/python/samba/netcmd/__init__.py +++ b/source4/scripting/python/samba/netcmd/__init__.py @@ -2,6 +2,7 @@ # Unix SMB/CIFS implementation. # Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2009 +# Copyright (C) Theresa Halloran <theresahalloran@gmail.com> 2011 # # 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 @@ -179,10 +180,6 @@ from samba.netcmd.domainlevel import cmd_domainlevel commands["domainlevel"] = cmd_domainlevel() from samba.netcmd.setpassword import cmd_setpassword commands["setpassword"] = cmd_setpassword() -from samba.netcmd.setexpiry import cmd_setexpiry -commands["setexpiry"] = cmd_setexpiry() -from samba.netcmd.enableaccount import cmd_enableaccount -commands["enableaccount"] = cmd_enableaccount() from samba.netcmd.newuser import cmd_newuser commands["newuser"] = cmd_newuser() from samba.netcmd.netacl import cmd_acl @@ -215,3 +212,5 @@ from samba.netcmd.ldapcmp import cmd_ldapcmp commands["ldapcmp"] = cmd_ldapcmp() from samba.netcmd.testparm import cmd_testparm commands["testparm"] = cmd_testparm() +from samba.netcmd.dbcheck import cmd_dbcheck +commands["dbcheck"] = cmd_dbcheck() diff --git a/source4/scripting/python/samba/netcmd/dbcheck.py b/source4/scripting/python/samba/netcmd/dbcheck.py new file mode 100644 index 0000000000..3cc50eb814 --- /dev/null +++ b/source4/scripting/python/samba/netcmd/dbcheck.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# +# Samba4 AD database checker +# +# Copyright (C) Andrew Tridgell 2011 +# +# 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 <http://www.gnu.org/licenses/>. +# + +import ldb, sys +import samba.getopt as options +from samba.auth import system_session +from samba.samdb import SamDB +from samba.netcmd import ( + Command, + CommandError, + Option + ) +from samba.dbchecker import dbcheck + + +class cmd_dbcheck(Command): + """check local AD database for errors""" + synopsis = "dbcheck <DN> [options]" + + takes_optiongroups = { + "sambaopts": options.SambaOptions, + "versionopts": options.VersionOptions, + "credopts": options.CredentialsOptionsDouble, + } + + takes_args = ["DN?"] + + takes_options = [ + Option("--scope", dest="scope", default="SUB", + help="Pass search scope that builds DN list. Options: SUB, ONE, BASE"), + Option("--fix", dest="fix", default=False, action='store_true', + help='Fix any errors found'), + Option("--yes", dest="yes", default=False, action='store_true', + help="don't confirm changes, just do them all as a single transaction"), + Option("--cross-ncs", dest="cross_ncs", default=False, action='store_true', + help="cross naming context boundaries"), + Option("-v", "--verbose", dest="verbose", action="store_true", default=False, + help="Print more details of checking"), + Option("--quiet", dest="quiet", action="store_true", default=False, + help="don't print details of checking"), + Option("--attrs", dest="attrs", default=None, help="list of attributes to check (space separated)"), + Option("-H", help="LDB URL for database or target server (defaults to local SAM database)", type=str), + ] + + def run(self, DN=None, H=None, verbose=False, fix=False, yes=False, cross_ncs=False, quiet=False, + scope="SUB", credopts=None, sambaopts=None, versionopts=None, attrs=None): + + lp = sambaopts.get_loadparm() + creds = credopts.get_credentials(lp, fallback_machine=True) + + samdb = SamDB(session_info=system_session(), url=H, + credentials=creds, lp=lp) + if H is None: + samdb_schema = samdb + else: + samdb_schema = SamDB(session_info=system_session(), url=None, + credentials=creds, lp=lp) + + scope_map = { "SUB": ldb.SCOPE_SUBTREE, "BASE":ldb.SCOPE_BASE, "ONE":ldb.SCOPE_ONELEVEL } + scope = scope.upper() + if not scope in scope_map: + raise CommandError("Unknown scope %s" % scope) + search_scope = scope_map[scope] + + controls = [] + if H is not None: + controls.append('paged_results:1:1000') + if cross_ncs: + controls.append("search_options:1:2") + + if not attrs: + attrs = ['*'] + else: + attrs = attrs.split() + + if yes and fix: + samdb.transaction_start() + + chk = dbcheck(samdb, samdb_schema=samdb_schema, verbose=verbose, fix=fix, yes=yes, quiet=quiet) + error_count = chk.check_database(DN=DN, scope=search_scope, controls=controls, attrs=attrs) + + if yes and fix: + samdb.transaction_commit() + + if error_count != 0: + sys.exit(1) + diff --git a/source4/scripting/python/samba/netcmd/drs.py b/source4/scripting/python/samba/netcmd/drs.py index 56c0e39a59..61717a70e9 100644 --- a/source4/scripting/python/samba/netcmd/drs.py +++ b/source4/scripting/python/samba/netcmd/drs.py @@ -233,6 +233,39 @@ class cmd_drs_kcc(Command): self.message("Consistency check on %s successful." % DC) +def drs_local_replicate(self, SOURCE_DC, NC): + '''replicate from a source DC to the local SAM''' + self.server = SOURCE_DC + drsuapi_connect(self) + + self.local_samdb = SamDB(session_info=system_session(), url=None, + credentials=self.creds, lp=self.lp) + + self.samdb = SamDB(url="ldap://%s" % self.server, + session_info=system_session(), + credentials=self.creds, lp=self.lp) + + # work out the source and destination GUIDs + res = self.local_samdb.search(base="", scope=ldb.SCOPE_BASE, attrs=["dsServiceName"]) + self.ntds_dn = res[0]["dsServiceName"][0] + + res = self.local_samdb.search(base=self.ntds_dn, scope=ldb.SCOPE_BASE, attrs=["objectGUID"]) + self.ntds_guid = misc.GUID(self.samdb.schema_format_value("objectGUID", res[0]["objectGUID"][0])) + + + source_dsa_invocation_id = misc.GUID(self.samdb.get_invocation_id()) + destination_dsa_guid = self.ntds_guid + + self.samdb.transaction_start() + repl = drs_utils.drs_Replicate("ncacn_ip_tcp:%s[seal]" % self.server, self.lp, + self.creds, self.local_samdb) + try: + repl.replicate(NC, source_dsa_invocation_id, destination_dsa_guid) + except Exception, e: + raise CommandError("Error replicating DN %s" % NC, e) + self.samdb.transaction_commit() + + class cmd_drs_replicate(Command): """replicate a naming context between two DCs""" @@ -250,9 +283,10 @@ class cmd_drs_replicate(Command): takes_options = [ Option("--add-ref", help="use ADD_REF to add to repsTo on source", action="store_true"), Option("--sync-forced", help="use SYNC_FORCED to force inbound replication", action="store_true"), + Option("--local", help="pull changes directly into the local database (destination DC is ignored)", action="store_true"), ] - def run(self, DEST_DC, SOURCE_DC, NC, add_ref=False, sync_forced=False, + def run(self, DEST_DC, SOURCE_DC, NC, add_ref=False, sync_forced=False, local=False, sambaopts=None, credopts=None, versionopts=None, server=None): @@ -261,6 +295,10 @@ class cmd_drs_replicate(Command): self.creds = credopts.get_credentials(self.lp, fallback_machine=True) + if local: + drs_local_replicate(self, SOURCE_DC, NC) + return + drsuapi_connect(self) samdb_connect(self) diff --git a/source4/scripting/python/samba/netcmd/enableaccount.py b/source4/scripting/python/samba/netcmd/enableaccount.py deleted file mode 100644 index 3ceddb3fd9..0000000000 --- a/source4/scripting/python/samba/netcmd/enableaccount.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env python -# -# Enables an user account on a Samba4 server -# Copyright Jelmer Vernooij 2008 -# -# Based on the original in EJS: -# Copyright 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 <http://www.gnu.org/licenses/>. -# - -import samba.getopt as options - -from samba.auth import system_session -from samba.netcmd import Command, CommandError, Option -from samba.samdb import SamDB - -class cmd_enableaccount(Command): - """Enables a user""" - - synopsis = "enableaccount [username] [options]" - - takes_optiongroups = { - "sambaopts": options.SambaOptions, - "versionopts": options.VersionOptions, - "credopts": options.CredentialsOptions, - } - - takes_options = [ - Option("-H", help="LDB URL for database or target server", type=str), - Option("--filter", help="LDAP Filter to set password on", type=str), - ] - - takes_args = ["username?"] - - def run(self, username=None, sambaopts=None, credopts=None, - versionopts=None, filter=None, H=None): - if username is None and filter is None: - raise CommandError("Either the username or '--filter' must be specified!") - - if filter is None: - filter = "(&(objectClass=user)(sAMAccountName=%s))" % (username) - - lp = sambaopts.get_loadparm() - creds = credopts.get_credentials(lp, fallback_machine=True) - - samdb = SamDB(url=H, session_info=system_session(), - credentials=creds, lp=lp) - samdb.enable_account(filter) diff --git a/source4/scripting/python/samba/netcmd/gpo.py b/source4/scripting/python/samba/netcmd/gpo.py index 19007b361c..fac9167076 100644 --- a/source4/scripting/python/samba/netcmd/gpo.py +++ b/source4/scripting/python/samba/netcmd/gpo.py @@ -126,7 +126,7 @@ class cmd_listall(Command): print("display name : %s" % m['displayName'][0]) print("path : %s" % m['gPCFileSysPath'][0]) print("dn : %s" % m.dn) - print("version : %s" % attr_default(m, 'version', '0')) + print("version : %s" % attr_default(m, 'versionNumber', '0')) print("flags : %s" % flags_string(gpo_flags, int(attr_default(m, 'flags', 0)))) print("") diff --git a/source4/scripting/python/samba/netcmd/group.py b/source4/scripting/python/samba/netcmd/group.py index 620a7be866..95db21adfc 100644 --- a/source4/scripting/python/samba/netcmd/group.py +++ b/source4/scripting/python/samba/netcmd/group.py @@ -85,6 +85,7 @@ class cmd_group_add(Command): description=description, mailaddress=mail_address, notes=notes) except Exception, e: raise CommandError('Failed to create group "%s"' % groupname, e) + print("Added group %s" % groupname) class cmd_group_delete(Command): @@ -115,6 +116,7 @@ class cmd_group_delete(Command): samdb.deletegroup(groupname) except Exception, e: raise CommandError('Failed to remove group "%s"' % groupname, e) + print("Deleted group %s" % groupname) class cmd_group_add_members(Command): @@ -146,6 +148,7 @@ class cmd_group_add_members(Command): samdb.add_remove_group_members(groupname, listofmembers, add_members_operation=True) except Exception, e: raise CommandError('Failed to add members "%s" to group "%s"' % (listofmembers, groupname), e) + print("Added members to group %s" % groupname) class cmd_group_remove_members(Command): @@ -177,6 +180,7 @@ class cmd_group_remove_members(Command): samdb.add_remove_group_members(groupname, listofmembers, add_members_operation=False) except Exception, e: raise CommandError('Failed to remove members "%s" from group "%s"' % (listofmembers, groupname), e) + print("Removed members from group %s" % groupname) class cmd_group(SuperCommand): diff --git a/source4/scripting/python/samba/netcmd/join.py b/source4/scripting/python/samba/netcmd/join.py index 507253ab81..820709c9e3 100644 --- a/source4/scripting/python/samba/netcmd/join.py +++ b/source4/scripting/python/samba/netcmd/join.py @@ -22,7 +22,7 @@ import samba.getopt as options from samba.net import Net, LIBNET_JOIN_AUTOMATIC from samba.netcmd import Command, CommandError, Option -from samba.dcerpc.misc import SEC_CHAN_WKSTA, SEC_CHAN_BDC +from samba.dcerpc.misc import SEC_CHAN_WKSTA from samba.join import join_RODC, join_DC class cmd_join(Command): @@ -39,12 +39,13 @@ class cmd_join(Command): takes_options = [ Option("--server", help="DC to join", type=str), Option("--site", help="site to join", type=str), + Option("--targetdir", help="where to store provision", type=str), ] takes_args = ["domain", "role?"] def run(self, domain, role=None, sambaopts=None, credopts=None, - versionopts=None, server=None, site=None): + versionopts=None, server=None, site=None, targetdir=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) net = Net(creds, lp, server=credopts.ipaddress) @@ -58,21 +59,20 @@ class cmd_join(Command): role = role.upper() if role is None or role == "MEMBER": - secure_channel_type = SEC_CHAN_WKSTA + (join_password, sid, domain_name) = net.join_member(domain, + netbios_name, + LIBNET_JOIN_AUTOMATIC) + + self.outf.write("Joined domain %s (%s)\n" % (domain_name, sid)) + return + elif role == "DC": join_DC(server=server, creds=creds, lp=lp, domain=domain, - site=site, netbios_name=netbios_name) + site=site, netbios_name=netbios_name, targetdir=targetdir) return elif role == "RODC": join_RODC(server=server, creds=creds, lp=lp, domain=domain, - site=site, netbios_name=netbios_name) + site=site, netbios_name=netbios_name, targetdir=targetdir) return else: raise CommandError("Invalid role %s (possible values: MEMBER, BDC, RODC)" % role) - - (join_password, sid, domain_name) = net.join(domain, - netbios_name, - secure_channel_type, - LIBNET_JOIN_AUTOMATIC) - - self.outf.write("Joined domain %s (%s)\n" % (domain_name, sid)) diff --git a/source4/scripting/python/samba/netcmd/setexpiry.py b/source4/scripting/python/samba/netcmd/setexpiry.py deleted file mode 100644 index bd8ea166fa..0000000000 --- a/source4/scripting/python/samba/netcmd/setexpiry.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python -# -# Sets the user password expiry on a Samba4 server -# Copyright Jelmer Vernooij 2008 -# -# Based on the original in EJS: -# Copyright 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 <http://www.gnu.org/licenses/>. -# - -from samba.netcmd import Command, CommandError, Option - -import samba.getopt as options - -from samba.auth import system_session -from samba.samdb import SamDB - -class cmd_setexpiry(Command): - """Sets the expiration of a user account""" - - synopsis = "setexpiry [username] [options]" - - takes_optiongroups = { - "sambaopts": options.SambaOptions, - "versionopts": options.VersionOptions, - "credopts": options.CredentialsOptions, - } - - takes_options = [ - Option("-H", help="LDB URL for database or target server", type=str), - Option("--filter", help="LDAP Filter to set password on", type=str), - Option("--days", help="Days to expiry", type=int), - Option("--noexpiry", help="Password does never expire", action="store_true"), - ] - - takes_args = ["username?"] - - def run(self, username=None, sambaopts=None, credopts=None, - versionopts=None, H=None, filter=None, days=None, noexpiry=None): - if username is None and filter is None: - raise CommandError("Either the username or '--filter' must be specified!") - - if filter is None: - filter = "(&(objectClass=user)(sAMAccountName=%s))" % (username) - - lp = sambaopts.get_loadparm() - creds = credopts.get_credentials(lp) - - if days is None: - days = 0 - - samdb = SamDB(url=H, session_info=system_session(), - credentials=creds, lp=lp) - - samdb.setexpiry(filter, days*24*3600, no_expiry_req=noexpiry) diff --git a/source4/scripting/python/samba/netcmd/user.py b/source4/scripting/python/samba/netcmd/user.py index a5750b5010..6acf52d790 100644 --- a/source4/scripting/python/samba/netcmd/user.py +++ b/source4/scripting/python/samba/netcmd/user.py @@ -3,6 +3,7 @@ # user management # # Copyright Jelmer Vernooij 2010 <jelmer@samba.org> +# Copyright Theresa Halloran 2011 <theresahalloran@gmail.com> # # 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 @@ -19,6 +20,10 @@ # import samba.getopt as options +import sys +from samba.auth import system_session +from samba.samdb import SamDB + from samba.net import Net @@ -26,6 +31,7 @@ from samba.netcmd import ( Command, CommandError, SuperCommand, + Option, ) class cmd_user_add(Command): @@ -70,6 +76,86 @@ class cmd_user_delete(Command): except RuntimeError, msg: raise CommandError("Failed to delete user %s: %s" % (name, msg)) +class cmd_user_enable(Command): + """Enables a user""" + + synopsis = "%prog user enable <username> [options]" + + + takes_optiongroups = { + "sambaopts": options.SambaOptions, + "versionopts": options.VersionOptions, + "credopts": options.CredentialsOptions, + } + + takes_options = [ + Option("-H", help="LDB URL for database or target server", type=str), + Option("--filter", help="LDAP Filter to set password on", type=str), + ] + + takes_args = ["username?"] + + def run(self, username=None, sambaopts=None, credopts=None, + versionopts=None, filter=None, H=None): + if username is None and filter is None: + raise CommandError("Either the username or '--filter' must be specified!") + + if filter is None: + filter = "(&(objectClass=user)(sAMAccountName=%s))" % (username) + + lp = sambaopts.get_loadparm() + creds = credopts.get_credentials(lp, fallback_machine=True) + + samdb = SamDB(url=H, session_info=system_session(), + credentials=creds, lp=lp) + try: + samdb.enable_account(filter) + except Exception, msg: + raise CommandError("Failed to enable user %s: %s" % (username or filter, msg)) + print("Enabled user %s" % (username or filter)) + + +class cmd_user_setexpiry(Command): + """Sets the expiration of a user account""" + + synopsis = "%prog user setexpiry <username> [options]" + + takes_optiongroups = { + "sambaopts": options.SambaOptions, + "versionopts": options.VersionOptions, + "credopts": options.CredentialsOptions, + } + + takes_options = [ + Option("-H", help="LDB URL for database or target server", type=str), + Option("--filter", help="LDAP Filter to set password on", type=str), + Option("--days", help="Days to expiry", type=int), + Option("--noexpiry", help="Password does never expire", action="store_true"), + ] + + takes_args = ["username?"] + def run(self, username=None, sambaopts=None, credopts=None, + versionopts=None, H=None, filter=None, days=None, noexpiry=None): + if username is None and filter is None: + raise CommandError("Either the username or '--filter' must be specified!") + + if filter is None: + filter = "(&(objectClass=user)(sAMAccountName=%s))" % (username) + + lp = sambaopts.get_loadparm() + creds = credopts.get_credentials(lp) + + if days is None: + days = 0 + + samdb = SamDB(url=H, session_info=system_session(), + credentials=creds, lp=lp) + + try: + samdb.setexpiry(filter, days*24*3600, no_expiry_req=noexpiry) + except Exception, msg: + raise CommandError("Failed to set expiry for user %s: %s" % (username or filter, msg)) + print("Set expiry for user %s to %u days" % (username or filter, days)) class cmd_user(SuperCommand): """User management [server connection needed]""" @@ -77,4 +163,5 @@ class cmd_user(SuperCommand): subcommands = {} subcommands["add"] = cmd_user_add() subcommands["delete"] = cmd_user_delete() - + subcommands["enable"] = cmd_user_enable() + subcommands["setexpiry"] = cmd_user_setexpiry() diff --git a/source4/scripting/python/samba/provision/__init__.py b/source4/scripting/python/samba/provision/__init__.py index ff9b00122d..5aabd36c1a 100644 --- a/source4/scripting/python/samba/provision/__init__.py +++ b/source4/scripting/python/samba/provision/__init__.py @@ -38,23 +38,23 @@ import uuid import socket import urllib import shutil +import string import ldb from samba.auth import system_session, admin_session import samba +from samba.dsdb import DS_DOMAIN_FUNCTION_2000 from samba import ( Ldb, check_all_substituted, - in_source_tree, - source_tree_topdir, read_and_sub_file, setup_file, substitute_var, valid_netbios_name, version, ) -from samba.dcerpc import security +from samba.dcerpc import security, misc from samba.dcerpc.misc import ( SEC_CHAN_BDC, SEC_CHAN_WKSTA, @@ -94,19 +94,6 @@ def setup_path(file): # "get_schema_descriptor" is located in "schema.py" -def get_sites_descriptor(domain_sid): - sddl = "D:(A;;RPLCLORC;;;AU)" \ - "(A;;RPWPCRCCLCLORCWOWDSW;;;EA)" \ - "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)" \ - "S:AI(AU;CISA;CCDCSDDT;;;WD)" \ - "(OU;CIIOSA;CR;;f0f8ffab-1191-11d0-a060-00aa006c33ed;WD)" \ - "(OU;CIIOSA;WP;f30e3bbe-9ff0-11d1-b603-0000f80367c1;bf967ab3-0de6-11d0-a285-00aa003049e2;WD)" \ - "(OU;CIIOSA;WP;f30e3bbf-9ff0-11d1-b603-0000f80367c1;bf967ab3-0de6-11d0-a285-00aa003049e2;WD)" \ - "(OU;CIIOSA;WP;3e10944c-c354-11d0-aff8-0000f80367c1;b7b13124-b82e-11d0-afee-0000f80367c1;WD)" - sec = security.descriptor.from_sddl(sddl, domain_sid) - return ndr_pack(sec) - - def get_config_descriptor(domain_sid): sddl = "O:EAG:EAD:(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \ "(OA;;CR;1131f6ab-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \ @@ -217,8 +204,112 @@ class ProvisionNames(object): self.sitename = None self.smbconf = None +def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf, lp): + """Get key provision parameters (realm, domain, ...) from a given provision + + :param samdb: An LDB object connected to the sam.ldb file + :param secretsdb: An LDB object connected to the secrets.ldb file + :param idmapdb: An LDB object connected to the idmap.ldb file + :param paths: A list of path to provision object + :param smbconf: Path to the smb.conf file + :param lp: A LoadParm object + :return: A list of key provision parameters + """ + names = ProvisionNames() + names.adminpass = None + + # NT domain, kerberos realm, root dn, domain dn, domain dns name + names.domain = string.upper(lp.get("workgroup")) + names.realm = lp.get("realm") + basedn = "DC=" + names.realm.replace(".",",DC=") + names.dnsdomain = names.realm.lower() + names.realm = string.upper(names.realm) + # netbiosname + # Get the netbiosname first (could be obtained from smb.conf in theory) + res = secretsdb.search(expression="(flatname=%s)" % + names.domain,base="CN=Primary Domains", + scope=ldb.SCOPE_SUBTREE, attrs=["sAMAccountName"]) + names.netbiosname = str(res[0]["sAMAccountName"]).replace("$","") + + names.smbconf = smbconf + + # That's a bit simplistic but it's ok as long as we have only 3 + # partitions + current = samdb.search(expression="(objectClass=*)", + base="", scope=ldb.SCOPE_BASE, + attrs=["defaultNamingContext", "schemaNamingContext", + "configurationNamingContext","rootDomainNamingContext"]) + + names.configdn = current[0]["configurationNamingContext"] + configdn = str(names.configdn) + names.schemadn = current[0]["schemaNamingContext"] + if not (ldb.Dn(samdb, basedn) == (ldb.Dn(samdb, + current[0]["defaultNamingContext"][0]))): + raise ProvisioningError(("basedn in %s (%s) and from %s (%s)" + "is not the same ..." % (paths.samdb, + str(current[0]["defaultNamingContext"][0]), + paths.smbconf, basedn))) + + names.domaindn=current[0]["defaultNamingContext"] + names.rootdn=current[0]["rootDomainNamingContext"] + # default site name + res3 = samdb.search(expression="(objectClass=site)", + base="CN=Sites," + configdn, scope=ldb.SCOPE_ONELEVEL, attrs=["cn"]) + names.sitename = str(res3[0]["cn"]) + + # dns hostname and server dn + res4 = samdb.search(expression="(CN=%s)" % names.netbiosname, + base="OU=Domain Controllers,%s" % basedn, + scope=ldb.SCOPE_ONELEVEL, attrs=["dNSHostName"]) + names.hostname = str(res4[0]["dNSHostName"]).replace("." + names.dnsdomain,"") + + server_res = samdb.search(expression="serverReference=%s" % res4[0].dn, + attrs=[], base=configdn) + names.serverdn = server_res[0].dn + + # invocation id/objectguid + res5 = samdb.search(expression="(objectClass=*)", + base="CN=NTDS Settings,%s" % str(names.serverdn), scope=ldb.SCOPE_BASE, + attrs=["invocationID", "objectGUID"]) + names.invocation = str(ndr_unpack(misc.GUID, res5[0]["invocationId"][0])) + names.ntdsguid = str(ndr_unpack(misc.GUID, res5[0]["objectGUID"][0])) + + # domain guid/sid + res6 = samdb.search(expression="(objectClass=*)", base=basedn, + scope=ldb.SCOPE_BASE, attrs=["objectGUID", + "objectSid","msDS-Behavior-Version" ]) + names.domainguid = str(ndr_unpack(misc.GUID, res6[0]["objectGUID"][0])) + names.domainsid = ndr_unpack( security.dom_sid, res6[0]["objectSid"][0]) + if res6[0].get("msDS-Behavior-Version") is None or \ + int(res6[0]["msDS-Behavior-Version"][0]) < DS_DOMAIN_FUNCTION_2000: + names.domainlevel = DS_DOMAIN_FUNCTION_2000 + else: + names.domainlevel = int(res6[0]["msDS-Behavior-Version"][0]) + + # policy guid + res7 = samdb.search(expression="(displayName=Default Domain Policy)", + base="CN=Policies,CN=System," + basedn, + scope=ldb.SCOPE_ONELEVEL, attrs=["cn","displayName"]) + names.policyid = str(res7[0]["cn"]).replace("{","").replace("}","") + # dc policy guid + res8 = samdb.search(expression="(displayName=Default Domain Controllers" + " Policy)", + base="CN=Policies,CN=System," + basedn, + scope=ldb.SCOPE_ONELEVEL, attrs=["cn","displayName"]) + if len(res8) == 1: + names.policyid_dc = str(res8[0]["cn"]).replace("{","").replace("}","") + else: + names.policyid_dc = None + res9 = idmapdb.search(expression="(cn=%s)" % + (security.SID_BUILTIN_ADMINISTRATORS), + attrs=["xidNumber"]) + if len(res9) == 1: + names.wheel_gid = res9[0]["xidNumber"] + else: + raise ProvisioningError("Unable to find uid/gid for Domain Admins rid") + return names -def update_provision_usn(samdb, low, high, replace=False): +def update_provision_usn(samdb, low, high, id, replace=False): """Update the field provisionUSN in sam.ldb This field is used to track range of USN modified by provision and @@ -229,6 +320,7 @@ def update_provision_usn(samdb, low, high, replace=False): :param samdb: An LDB object connect to sam.ldb :param low: The lowest USN modified by this upgrade :param high: The highest USN modified by this upgrade + :param id: The invocation id of the samba's dc :param replace: A boolean indicating if the range should replace any existing one or appended (default) """ @@ -240,17 +332,24 @@ def update_provision_usn(samdb, low, high, replace=False): scope=ldb.SCOPE_SUBTREE, attrs=[LAST_PROVISION_USN_ATTRIBUTE, "dn"]) for e in entry[0][LAST_PROVISION_USN_ATTRIBUTE]: + if not re.search(';', e): + e = "%s;%s" % (e, id) tab.append(str(e)) - tab.append("%s-%s" % (low, high)) + tab.append("%s-%s;%s" % (low, high, id)) delta = ldb.Message() delta.dn = ldb.Dn(samdb, "@PROVISION") delta[LAST_PROVISION_USN_ATTRIBUTE] = ldb.MessageElement(tab, ldb.FLAG_MOD_REPLACE, LAST_PROVISION_USN_ATTRIBUTE) + entry = samdb.search(expression="(&(dn=@PROVISION)(provisionnerID=*))", + base="", scope=ldb.SCOPE_SUBTREE, + attrs=["provisionnerID"]) + if len(entry) == 0 or len(entry[0]) == 0: + delta["provisionnerID"] = ldb.MessageElement(id, ldb.FLAG_MOD_ADD, "provisionnerID") samdb.modify(delta) -def set_provision_usn(samdb, low, high): +def set_provision_usn(samdb, low, high, id): """Set the field provisionUSN in sam.ldb This field is used to track range of USN modified by provision and upgradeprovision. @@ -259,9 +358,12 @@ def set_provision_usn(samdb, low, high): :param samdb: An LDB object connect to sam.ldb :param low: The lowest USN modified by this upgrade - :param high: The highest USN modified by this upgrade""" + :param high: The highest USN modified by this upgrade + :param id: The invocationId of the provision""" + tab = [] - tab.append("%s-%s" % (low, high)) + tab.append("%s-%s;%s" % (low, high, id)) + delta = ldb.Message() delta.dn = ldb.Dn(samdb, "@PROVISION") delta[LAST_PROVISION_USN_ATTRIBUTE] = ldb.MessageElement(tab, @@ -286,25 +388,36 @@ def get_max_usn(samdb,basedn): def get_last_provision_usn(sam): - """Get the lastest USN modified by a provision or an upgradeprovision + """Get USNs ranges modified by a provision or an upgradeprovision :param sam: An LDB object pointing to the sam.ldb - :return: an integer corresponding to the highest USN modified by - (upgrade)provision, 0 is this value is unknown + :return: a dictionnary which keys are invocation id and values are an array + of integer representing the different ranges """ entry = sam.search(expression="(&(dn=@PROVISION)(%s=*))" % LAST_PROVISION_USN_ATTRIBUTE, base="", scope=ldb.SCOPE_SUBTREE, - attrs=[LAST_PROVISION_USN_ATTRIBUTE]) + attrs=[LAST_PROVISION_USN_ATTRIBUTE, "provisionnerID"]) if len(entry): - range = [] - idx = 0 + myids = [] + range = {} p = re.compile(r'-') + if entry[0].get("provisionnerID"): + for e in entry[0]["provisionnerID"]: + myids.append(str(e)) for r in entry[0][LAST_PROVISION_USN_ATTRIBUTE]: - tab = p.split(str(r)) - range.append(tab[0]) - range.append(tab[1]) - idx = idx + 1 + tab1 = str(r).split(';') + if len(tab1) == 2: + id = tab1[1] + else: + id = "default" + if (len(myids) > 0 and id not in myids): + continue + tab2 = p.split(tab1[0]) + if range.get(id) == None: + range[id] = [] + range[id].append(tab2[0]) + range[id].append(tab2[1]) return range else: return None @@ -328,7 +441,7 @@ def check_install(lp, session_info, credentials): """ if lp.get("realm") == "": raise Exception("Realm empty") - samdb = Ldb(lp.get("sam database"), session_info=session_info, + samdb = Ldb(lp.samdb_url(), session_info=session_info, credentials=credentials, lp=lp) if len(samdb.search("(cn=Administrator)")) != 1: raise ProvisioningError("No administrator account found") @@ -413,12 +526,9 @@ def provision_paths_from_lp(lp, dnsdomain): paths.keytab = "secrets.keytab" paths.shareconf = os.path.join(paths.private_dir, "share.ldb") - paths.samdb = os.path.join(paths.private_dir, - lp.get("sam database") or "samdb.ldb") - paths.idmapdb = os.path.join(paths.private_dir, - lp.get("idmap database") or "idmap.ldb") - paths.secrets = os.path.join(paths.private_dir, - lp.get("secrets database") or "secrets.ldb") + paths.samdb = os.path.join(paths.private_dir, "sam.ldb") + paths.idmapdb = os.path.join(paths.private_dir, "idmap.ldb") + paths.secrets = os.path.join(paths.private_dir, "secrets.ldb") paths.privilege = os.path.join(paths.private_dir, "privilege.ldb") paths.dns = os.path.join(paths.private_dir, "dns", dnsdomain + ".zone") paths.dns_update_list = os.path.join(paths.private_dir, "dns_update_list") @@ -608,11 +718,6 @@ def make_smbconf(smbconf, hostname, domain, realm, serverrole, privatedir_line = "" lockdir_line = "" - if sid_generator == "internal": - sid_generator_line = "" - else: - sid_generator_line = "sid generator = " + sid_generator - sysvol = os.path.join(lp.get("lock dir"), "sysvol") netlogon = os.path.join(sysvol, realm.lower(), "scripts") @@ -624,7 +729,6 @@ def make_smbconf(smbconf, hostname, domain, realm, serverrole, "SERVERROLE": serverrole, "NETLOGONPATH": netlogon, "SYSVOLPATH": sysvol, - "SIDGENERATOR_LINE": sid_generator_line, "PRIVATEDIR_LINE": privatedir_line, "LOCKDIR_LINE": lockdir_line }) @@ -1166,6 +1270,11 @@ def setup_samdb(path, session_info, provision_backend, lp, names, "DESCRIPTOR": descr, }) + # Now register this container in the root of the forest + msg = ldb.Message(ldb.Dn(samdb, names.domaindn)) + msg["subRefs"] = ldb.MessageElement(names.configdn , ldb.FLAG_MOD_ADD, + "subRefs") + # The LDIF here was created when the Schema object was constructed logger.info("Setting up sam.ldb schema") samdb.add_ldif(schema.schema_dn_add, controls=["relax:0"]) @@ -1196,7 +1305,6 @@ def setup_samdb(path, session_info, provision_backend, lp, names, samdb.invocation_id = invocationid logger.info("Setting up sam.ldb configuration data") - descr = b64encode(get_sites_descriptor(domainsid)) setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), { "CONFIGDN": names.configdn, "NETBIOSNAME": names.netbiosname, @@ -1208,7 +1316,6 @@ def setup_samdb(path, session_info, provision_backend, lp, names, "SERVERDN": names.serverdn, "FOREST_FUNCTIONALITY": str(forestFunctionality), "DOMAIN_FUNCTIONALITY": str(domainFunctionality), - "SITES_DESCRIPTOR": descr }) logger.info("Setting up display specifiers") @@ -1365,6 +1472,25 @@ def setsysvolacl(samdb, netlogon, sysvol, gid, domainsid, dnsdomain, domaindn, set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp) +def interface_ips_v4(lp): + '''return only IPv4 IPs''' + ips = samba.interface_ips(lp, False) + ret = [] + for i in ips: + if i.find(':') == -1: + ret.append(i) + return ret + +def interface_ips_v6(lp, linklocal=False): + '''return only IPv6 IPs''' + ips = samba.interface_ips(lp, False) + ret = [] + for i in ips: + if i.find(':') != -1 and (linklocal or i.find('%') == -1): + ret.append(i) + return ret + + def provision(logger, session_info, credentials, smbconf=None, targetdir=None, samdb_fill=FILL_FULL, realm=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, serverdn=None, @@ -1465,15 +1591,26 @@ def provision(logger, session_info, credentials, smbconf=None, if hostip is None: logger.info("Looking up IPv4 addresses") - hostips = samba.interface_ips(lp, False) - if len(hostips) == 0: - logger.warning("No external IPv4 address has been found. Using loopback.") - hostip = '127.0.0.1' - else: + hostips = interface_ips_v4(lp) + if len(hostips) > 0: hostip = hostips[0] if len(hostips) > 1: - logger.warning("More than one IPv4 address found. Using %s.", + logger.warning("More than one IPv4 address found. Using %s", hostip) + if hostip == "127.0.0.1": + hostip = None + if hostip is None: + logger.warning("No IPv4 address will be assigned") + + if hostip6 is None: + logger.info("Looking up IPv6 addresses") + hostips = interface_ips_v6(lp, linklocal=False) + if hostips: + hostip6 = hostips[0] + if len(hostips) > 1: + logger.warning("More than one IPv6 address found. Using %s", hostip6) + if hostip6 is None: + logger.warning("No IPv6 address will be assigned") if serverrole is None: serverrole = lp.get("server role") @@ -1640,6 +1777,7 @@ def provision(logger, session_info, credentials, smbconf=None, create_named_txt(paths.namedtxt, realm=names.realm, dnsdomain=names.dnsdomain, + dnsname = "%s.%s" % (names.hostname, names.dnsdomain), private_dir=paths.private_dir, keytab_name=paths.dns_keytab) logger.info("See %s for an example configuration include file for BIND", paths.namedconf) @@ -1649,9 +1787,9 @@ def provision(logger, session_info, credentials, smbconf=None, lastProvisionUSNs = get_last_provision_usn(samdb) maxUSN = get_max_usn(samdb, str(names.rootdn)) if lastProvisionUSNs is not None: - update_provision_usn(samdb, 0, maxUSN, 1) + update_provision_usn(samdb, 0, maxUSN, invocationid, 1) else: - set_provision_usn(samdb, 0, maxUSN) + set_provision_usn(samdb, 0, maxUSN, invocationid) create_krb5_conf(paths.krb5conf, dnsdomain=names.dnsdomain, hostname=names.hostname, @@ -1740,7 +1878,7 @@ def provision_become_dc(smbconf=None, targetdir=None, smbconf=smbconf, targetdir=targetdir, samdb_fill=FILL_DRS, realm=realm, rootdn=rootdn, domaindn=domaindn, schemadn=schemadn, configdn=configdn, serverdn=serverdn, domain=domain, - hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, + hostname=hostname, hostip=None, domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename) res.lp.set("debuglevel", str(debuglevel)) @@ -1876,7 +2014,7 @@ def create_named_conf(paths, realm, dnsdomain, setup_file(setup_path("named.conf.update"), paths.namedconf_update) -def create_named_txt(path, realm, dnsdomain, private_dir, +def create_named_txt(path, realm, dnsdomain, dnsname, private_dir, keytab_name): """Write out a file containing zone statements suitable for inclusion in a named.conf file (including GSS-TSIG configuration). @@ -1889,6 +2027,7 @@ def create_named_txt(path, realm, dnsdomain, private_dir, """ setup_file(setup_path("named.txt"), path, { "DNSDOMAIN": dnsdomain, + "DNSNAME" : dnsname, "REALM": realm, "DNS_KEYTAB": keytab_name, "DNS_KEYTAB_ABS": os.path.join(private_dir, keytab_name), diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index 2c323bd0b4..ae5b20edd2 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -50,9 +50,12 @@ class TdbDatabase(object): def __init__(self, file): """Open a file. - :param file: Path of the file to open. + :param file: Path of the file to open (appending "2" if TDB2 enabled). """ - self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) + if tdb.__version__.startswith("2"): + self.tdb = tdb.Tdb(file + "2", flags=os.O_RDONLY) + else: + self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) self._check_version() def _check_version(self): diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 99f141e664..72ee472764 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -46,7 +46,7 @@ class SamDB(samba.Ldb): if not auto_connect: url = None elif url is None and lp is not None: - url = lp.get("sam database") + url = lp.samdb_url() super(SamDB, self).__init__(url=url, lp=lp, modules_dir=modules_dir, session_info=session_info, credentials=credentials, flags=flags, @@ -79,6 +79,8 @@ class SamDB(samba.Ldb): """ res = self.search(base=self.domain_dn(), scope=ldb.SCOPE_SUBTREE, expression=search_filter, attrs=["userAccountControl"]) + if len(res) == 0: + raise Exception('Unable to find user "%s"' % search_filter) assert(len(res) == 1) user_dn = res[0].dn @@ -106,6 +108,8 @@ userAccountControl: %u """ res = self.search(base=self.domain_dn(), scope=ldb.SCOPE_SUBTREE, expression=search_filter, attrs=[]) + if len(res) == 0: + raise Exception('Unable to find user "%s"' % search_filter) assert(len(res) == 1) user_dn = res[0].dn @@ -138,7 +142,7 @@ pwdLastSet: 0 "objectClass": "group"} if grouptype is not None: - ldbmessage["groupType"] = "%d" % grouptype + ldbmessage["groupType"] = self.normalise_int32(grouptype) if description is not None: ldbmessage["description"] = description @@ -409,6 +413,8 @@ unicodePwd:: %s res = self.search(base=self.domain_dn(), scope=ldb.SCOPE_SUBTREE, expression=search_filter, attrs=["userAccountControl", "accountExpires"]) + if len(res) == 0: + raise Exception('Unable to find user "%s"' % search_filter) assert(len(res) == 1) user_dn = res[0].dn @@ -470,9 +476,14 @@ accountExpires: %u def get_attid_from_lDAPDisplayName(self, ldap_display_name, is_schema_nc=False): + '''return the attribute ID for a LDAP attribute as an integer as found in DRSUAPI''' return dsdb._dsdb_get_attid_from_lDAPDisplayName(self, ldap_display_name, is_schema_nc) + def get_syntax_oid_from_lDAPDisplayName(self, ldap_display_name): + '''return the syntax OID for a LDAP attribute as a string''' + return dsdb._dsdb_get_syntax_oid_from_lDAPDisplayName(self, ldap_display_name) + def set_ntds_settings_dn(self, ntds_settings_dn): """Set the NTDS Settings DN, as would be returned on the dsServiceName rootDSE attribute. @@ -501,8 +512,13 @@ accountExpires: %u dsdb._dsdb_set_schema_from_ldb(self, ldb_conn) def dsdb_DsReplicaAttribute(self, ldb, ldap_display_name, ldif_elements): + '''convert a list of attribute values to a DRSUAPI DsReplicaAttribute''' return dsdb._dsdb_DsReplicaAttribute(ldb, ldap_display_name, ldif_elements) + def dsdb_normalise_attributes(self, ldb, ldap_display_name, ldif_elements): + '''normalise a list of attribute values''' + return dsdb._dsdb_normalise_attributes(ldb, ldap_display_name, ldif_elements) + def get_attribute_from_attid(self, attid): """ Get from an attid the associated attribute @@ -711,3 +727,9 @@ accountExpires: %u if sd: m["nTSecurityDescriptor"] = ndr_pack(sd) self.add(m) + + def normalise_int32(self, ivalue): + '''normalise a ldap integer to signed 32 bit''' + if int(ivalue) & 0x80000000: + return str(int(ivalue) - 0x100000000) + return str(ivalue) diff --git a/source4/scripting/python/samba/tests/samba3sam.py b/source4/scripting/python/samba/tests/samba3sam.py index a34f0f620c..7353391519 100644 --- a/source4/scripting/python/samba/tests/samba3sam.py +++ b/source4/scripting/python/samba/tests/samba3sam.py @@ -30,6 +30,7 @@ from samba.tests import TestCaseInTempDir, env_loadparm import samba.dcerpc.security import samba.ndr from samba.auth import system_session +from operator import attrgetter def read_datafile(filename): @@ -64,7 +65,6 @@ class MapBaseTestCase(TestCaseInTempDir): def setUp(self): self.lp = env_loadparm() - self.lp.set("sid generator", "backend") self.lp.set("workgroup", "TESTS") self.lp.set("netbios name", "TESTS") super(MapBaseTestCase, self).setUp() @@ -86,6 +86,7 @@ class MapBaseTestCase(TestCaseInTempDir): def __init__(self, basedn, dn, lp): self.db = Ldb(lp=lp, session_info=system_session()) + self.db.set_opaque("skip_allocate_sids", "true"); self.basedn = basedn self.basedn_casefold = ldb.Dn(self.db, basedn).get_casefold() self.substvars = {"BASEDN": self.basedn} @@ -135,12 +136,14 @@ class Samba3SamTestCase(MapBaseTestCase): def setUp(self): super(Samba3SamTestCase, self).setUp() ldb = Ldb(self.ldburl, lp=self.lp, session_info=system_session()) + ldb.set_opaque("skip_allocate_sids", "true"); self.samba3.setup_data("samba3.ldif") ldif = read_datafile("provision_samba3sam.ldif") ldb.add_ldif(self.samba4.subst(ldif)) self.setup_modules(ldb, self.samba3, self.samba4) del ldb self.ldb = Ldb(self.ldburl, lp=self.lp, session_info=system_session()) + self.ldb.set_opaque("skip_allocate_sids", "true"); def test_search_non_mapped(self): """Looking up by non-mapped attribute""" @@ -302,11 +305,13 @@ class MapTestCase(MapBaseTestCase): def setUp(self): super(MapTestCase, self).setUp() ldb = Ldb(self.ldburl, lp=self.lp, session_info=system_session()) + ldb.set_opaque("skip_allocate_sids", "true"); ldif = read_datafile("provision_samba3sam.ldif") ldb.add_ldif(self.samba4.subst(ldif)) self.setup_modules(ldb, self.samba3, self.samba4) del ldb self.ldb = Ldb(self.ldburl, lp=self.lp, session_info=system_session()) + self.ldb.set_opaque("skip_allocate_sids", "true"); def test_map_search(self): """Running search tests on mapped data.""" @@ -439,34 +444,37 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 res = self.ldb.search(expression="(revision=x)", scope=SCOPE_DEFAULT, attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 2) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y")) - self.assertEquals(str(res[0]["dnsHostName"]), "y") - self.assertEquals(str(res[0]["lastLogon"]), "y") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X")) - self.assertEquals(str(res[1]["dnsHostName"]), "x") - self.assertEquals(str(res[1]["lastLogon"]), "x") + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X")) + self.assertEquals(str(res[0]["dnsHostName"]), "x") + self.assertEquals(str(res[0]["lastLogon"]), "x") + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y")) + self.assertEquals(str(res[1]["dnsHostName"]), "y") + self.assertEquals(str(res[1]["lastLogon"]), "y") # Search by kept attribute res = self.ldb.search(expression="(description=y)", scope=SCOPE_DEFAULT, attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 2) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Z")) - self.assertEquals(str(res[0]["dnsHostName"]), "z") + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=C")) + self.assertTrue(not "dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "z") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=C")) - self.assertTrue(not "dnsHostName" in res[1]) + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Z")) + self.assertEquals(str(res[1]["dnsHostName"]), "z") self.assertEquals(str(res[1]["lastLogon"]), "z") # Search by renamed attribute res = self.ldb.search(expression="(badPwdCount=x)", scope=SCOPE_DEFAULT, attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 2) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) self.assertTrue(not "dnsHostName" in res[0]) - self.assertEquals(str(res[0]["lastLogon"]), "y") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=A")) + self.assertEquals(str(res[0]["lastLogon"]), "x") + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) self.assertTrue(not "dnsHostName" in res[1]) - self.assertEquals(str(res[1]["lastLogon"]), "x") + self.assertEquals(str(res[1]["lastLogon"]), "y") # Search by converted attribute # TODO: @@ -475,18 +483,19 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 #res = self.ldb.search("(objectSid=S-1-5-21-4231626423-2410014848-2360679739-552)", scope=SCOPE_DEFAULT, attrs) res = self.ldb.search(expression="(objectSid=*)", base=None, scope=SCOPE_DEFAULT, attrs=["dnsHostName", "lastLogon", "objectSid"]) self.assertEquals(len(res), 4) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X")) - self.assertEquals(str(res[0]["dnsHostName"]), "x") - self.assertEquals(str(res[0]["lastLogon"]), "x") - self.assertSidEquals("S-1-5-21-4231626423-2410014848-2360679739-552", - res[0]["objectSid"]) - self.assertTrue("objectSid" in res[0]) - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=A")) - self.assertTrue(not "dnsHostName" in res[1]) + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X")) + self.assertEquals(str(res[1]["dnsHostName"]), "x") self.assertEquals(str(res[1]["lastLogon"]), "x") self.assertSidEquals("S-1-5-21-4231626423-2410014848-2360679739-552", res[1]["objectSid"]) self.assertTrue("objectSid" in res[1]) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) + self.assertTrue(not "dnsHostName" in res[0]) + self.assertEquals(str(res[0]["lastLogon"]), "x") + self.assertSidEquals("S-1-5-21-4231626423-2410014848-2360679739-552", + res[0]["objectSid"]) + self.assertTrue("objectSid" in res[0]) # Search by generated attribute # In most cases, this even works when the mapping is missing @@ -519,12 +528,13 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 attrs = ["dnsHostName", "lastLogon", "objectClass"] res = self.ldb.search(expression="(objectClass=user)", attrs=attrs) self.assertEquals(len(res), 2) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X")) - self.assertEquals(str(res[0]["dnsHostName"]), "x") + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) + self.assertTrue(not "dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "x") self.assertEquals(str(res[0]["objectClass"][0]), "user") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=A")) - self.assertTrue(not "dnsHostName" in res[1]) + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X")) + self.assertEquals(str(res[1]["dnsHostName"]), "x") self.assertEquals(str(res[1]["lastLogon"]), "x") self.assertEquals(str(res[1]["objectClass"][0]), "user") @@ -532,18 +542,19 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 res = self.ldb.search(expression="(|(objectClass=user)(badPwdCount=x))", attrs=attrs) self.assertEquals(len(res), 3) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) self.assertTrue(not "dnsHostName" in res[0]) - self.assertEquals(str(res[0]["lastLogon"]), "y") - self.assertEquals(set(res[0]["objectClass"]), set(["top"])) - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X")) - self.assertEquals(str(res[1]["dnsHostName"]), "x") - self.assertEquals(str(res[1]["lastLogon"]), "x") - self.assertEquals(str(res[1]["objectClass"][0]), "user") - self.assertEquals(str(res[2].dn), self.samba4.dn("cn=A")) - self.assertTrue(not "dnsHostName" in res[2]) + self.assertEquals(str(res[0]["lastLogon"]), "x") + self.assertEquals(res[0]["objectClass"][0], "user") + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) + self.assertTrue(not "dnsHostName" in res[1]) + self.assertEquals(str(res[1]["lastLogon"]), "y") + self.assertEquals(set(res[1]["objectClass"]), set(["top"])) + self.assertEquals(str(res[2].dn), self.samba4.dn("cn=X")) + self.assertEquals(str(res[2]["dnsHostName"]), "x") self.assertEquals(str(res[2]["lastLogon"]), "x") - self.assertEquals(res[2]["objectClass"][0], "user") + self.assertEquals(str(res[2]["objectClass"][0]), "user") # Testing search by parse tree @@ -551,34 +562,37 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 res = self.ldb.search(expression="(&(codePage=x)(revision=x))", attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 2) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y")) - self.assertEquals(str(res[0]["dnsHostName"]), "y") - self.assertEquals(str(res[0]["lastLogon"]), "y") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X")) - self.assertEquals(str(res[1]["dnsHostName"]), "x") - self.assertEquals(str(res[1]["lastLogon"]), "x") + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X")) + self.assertEquals(str(res[0]["dnsHostName"]), "x") + self.assertEquals(str(res[0]["lastLogon"]), "x") + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y")) + self.assertEquals(str(res[1]["dnsHostName"]), "y") + self.assertEquals(str(res[1]["lastLogon"]), "y") # Search by conjunction of remote attributes res = self.ldb.search(expression="(&(lastLogon=x)(description=x))", attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 2) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X")) - self.assertEquals(str(res[0]["dnsHostName"]), "x") + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) + self.assertTrue(not "dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "x") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=A")) - self.assertTrue(not "dnsHostName" in res[1]) + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X")) + self.assertEquals(str(res[1]["dnsHostName"]), "x") self.assertEquals(str(res[1]["lastLogon"]), "x") # Search by conjunction of local and remote attribute res = self.ldb.search(expression="(&(codePage=x)(description=x))", attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 2) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y")) - self.assertEquals(str(res[0]["dnsHostName"]), "y") - self.assertEquals(str(res[0]["lastLogon"]), "y") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X")) - self.assertEquals(str(res[1]["dnsHostName"]), "x") - self.assertEquals(str(res[1]["lastLogon"]), "x") + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X")) + self.assertEquals(str(res[0]["dnsHostName"]), "x") + self.assertEquals(str(res[0]["lastLogon"]), "x") + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y")) + self.assertEquals(str(res[1]["dnsHostName"]), "y") + self.assertEquals(str(res[1]["lastLogon"]), "y") # Search by conjunction of local and remote attribute w/o match attrs = ["dnsHostName", "lastLogon"] @@ -593,40 +607,43 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 res = self.ldb.search(expression="(|(revision=x)(dnsHostName=x))", attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 2) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y")) - self.assertEquals(str(res[0]["dnsHostName"]), "y") - self.assertEquals(str(res[0]["lastLogon"]), "y") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X")) - self.assertEquals(str(res[1]["dnsHostName"]), "x") - self.assertEquals(str(res[1]["lastLogon"]), "x") + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X")) + self.assertEquals(str(res[0]["dnsHostName"]), "x") + self.assertEquals(str(res[0]["lastLogon"]), "x") + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y")) + self.assertEquals(str(res[1]["dnsHostName"]), "y") + self.assertEquals(str(res[1]["lastLogon"]), "y") # Search by disjunction of remote attributes res = self.ldb.search(expression="(|(badPwdCount=x)(lastLogon=x))", attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 3) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) self.assertFalse("dnsHostName" in res[0]) - self.assertEquals(str(res[0]["lastLogon"]), "y") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X")) - self.assertEquals(str(res[1]["dnsHostName"]), "x") - self.assertEquals(str(res[1]["lastLogon"]), "x") - self.assertEquals(str(res[2].dn), self.samba4.dn("cn=A")) - self.assertFalse("dnsHostName" in res[2]) + self.assertEquals(str(res[0]["lastLogon"]), "x") + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) + self.assertFalse("dnsHostName" in res[1]) + self.assertEquals(str(res[1]["lastLogon"]), "y") + self.assertEquals(str(res[2].dn), self.samba4.dn("cn=X")) + self.assertEquals(str(res[2]["dnsHostName"]), "x") self.assertEquals(str(res[2]["lastLogon"]), "x") # Search by disjunction of local and remote attribute res = self.ldb.search(expression="(|(revision=x)(lastLogon=y))", attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 3) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y")) - self.assertEquals(str(res[0]["dnsHostName"]), "y") + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) + self.assertFalse("dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "y") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) - self.assertFalse("dnsHostName" in res[1]) - self.assertEquals(str(res[1]["lastLogon"]), "y") - self.assertEquals(str(res[2].dn), self.samba4.dn("cn=X")) - self.assertEquals(str(res[2]["dnsHostName"]), "x") - self.assertEquals(str(res[2]["lastLogon"]), "x") + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X")) + self.assertEquals(str(res[1]["dnsHostName"]), "x") + self.assertEquals(str(res[1]["lastLogon"]), "x") + self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Y")) + self.assertEquals(str(res[2]["dnsHostName"]), "y") + self.assertEquals(str(res[2]["lastLogon"]), "y") # Search by disjunction of local and remote attribute w/o match res = self.ldb.search(expression="(|(codePage=y)(nextRid=z))", @@ -637,142 +654,151 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 res = self.ldb.search(expression="(!(revision=x))", attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 6) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) self.assertTrue(not "dnsHostName" in res[0]) - self.assertEquals(str(res[0]["lastLogon"]), "y") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=A")) + self.assertEquals(str(res[0]["lastLogon"]), "x") + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) self.assertTrue(not "dnsHostName" in res[1]) - self.assertEquals(str(res[1]["lastLogon"]), "x") - self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Z")) - self.assertEquals(str(res[2]["dnsHostName"]), "z") + self.assertEquals(str(res[1]["lastLogon"]), "y") + self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C")) + self.assertTrue(not "dnsHostName" in res[2]) self.assertEquals(str(res[2]["lastLogon"]), "z") - self.assertEquals(str(res[3].dn), self.samba4.dn("cn=C")) - self.assertTrue(not "dnsHostName" in res[3]) + self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z")) + self.assertEquals(str(res[3]["dnsHostName"]), "z") self.assertEquals(str(res[3]["lastLogon"]), "z") # Search by negated remote attribute res = self.ldb.search(expression="(!(description=x))", attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 4) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Z")) - self.assertEquals(str(res[0]["dnsHostName"]), "z") + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=C")) + self.assertTrue(not "dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "z") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=C")) - self.assertTrue(not "dnsHostName" in res[1]) + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Z")) + self.assertEquals(str(res[1]["dnsHostName"]), "z") self.assertEquals(str(res[1]["lastLogon"]), "z") # Search by negated conjunction of local attributes res = self.ldb.search(expression="(!(&(codePage=x)(revision=x)))", attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 6) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) self.assertTrue(not "dnsHostName" in res[0]) - self.assertEquals(str(res[0]["lastLogon"]), "y") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=A")) + self.assertEquals(str(res[0]["lastLogon"]), "x") + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) self.assertTrue(not "dnsHostName" in res[1]) - self.assertEquals(str(res[1]["lastLogon"]), "x") - self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Z")) - self.assertEquals(str(res[2]["dnsHostName"]), "z") + self.assertEquals(str(res[1]["lastLogon"]), "y") + self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C")) + self.assertTrue(not "dnsHostName" in res[2]) self.assertEquals(str(res[2]["lastLogon"]), "z") - self.assertEquals(str(res[3].dn), self.samba4.dn("cn=C")) - self.assertTrue(not "dnsHostName" in res[3]) + self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z")) + self.assertEquals(str(res[3]["dnsHostName"]), "z") self.assertEquals(str(res[3]["lastLogon"]), "z") # Search by negated conjunction of remote attributes res = self.ldb.search(expression="(!(&(lastLogon=x)(description=x)))", attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 6) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y")) - self.assertEquals(str(res[0]["dnsHostName"]), "y") + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) + self.assertTrue(not "dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "y") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=C")) self.assertTrue(not "dnsHostName" in res[1]) - self.assertEquals(str(res[1]["lastLogon"]), "y") - self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Z")) - self.assertEquals(str(res[2]["dnsHostName"]), "z") - self.assertEquals(str(res[2]["lastLogon"]), "z") - self.assertEquals(str(res[3].dn), self.samba4.dn("cn=C")) - self.assertTrue(not "dnsHostName" in res[3]) + self.assertEquals(str(res[1]["lastLogon"]), "z") + self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Y")) + self.assertEquals(str(res[2]["dnsHostName"]), "y") + self.assertEquals(str(res[2]["lastLogon"]), "y") + self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z")) + self.assertEquals(str(res[3]["dnsHostName"]), "z") self.assertEquals(str(res[3]["lastLogon"]), "z") # Search by negated conjunction of local and remote attribute res = self.ldb.search(expression="(!(&(codePage=x)(description=x)))", attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 6) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) self.assertTrue(not "dnsHostName" in res[0]) - self.assertEquals(str(res[0]["lastLogon"]), "y") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=A")) + self.assertEquals(str(res[0]["lastLogon"]), "x") + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) self.assertTrue(not "dnsHostName" in res[1]) - self.assertEquals(str(res[1]["lastLogon"]), "x") - self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Z")) - self.assertEquals(str(res[2]["dnsHostName"]), "z") + self.assertEquals(str(res[1]["lastLogon"]), "y") + self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C")) + self.assertTrue(not "dnsHostName" in res[2]) self.assertEquals(str(res[2]["lastLogon"]), "z") - self.assertEquals(str(res[3].dn), self.samba4.dn("cn=C")) - self.assertTrue(not "dnsHostName" in res[3]) + self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z")) + self.assertEquals(str(res[3]["dnsHostName"]), "z") self.assertEquals(str(res[3]["lastLogon"]), "z") # Search by negated disjunction of local attributes res = self.ldb.search(expression="(!(|(revision=x)(dnsHostName=x)))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) self.assertTrue(not "dnsHostName" in res[0]) - self.assertEquals(str(res[0]["lastLogon"]), "y") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=A")) + self.assertEquals(str(res[0]["lastLogon"]), "x") + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) self.assertTrue(not "dnsHostName" in res[1]) - self.assertEquals(str(res[1]["lastLogon"]), "x") - self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Z")) - self.assertEquals(str(res[2]["dnsHostName"]), "z") + self.assertEquals(str(res[1]["lastLogon"]), "y") + self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C")) + self.assertTrue(not "dnsHostName" in res[2]) self.assertEquals(str(res[2]["lastLogon"]), "z") - self.assertEquals(str(res[3].dn), self.samba4.dn("cn=C")) - self.assertTrue(not "dnsHostName" in res[3]) + self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z")) + self.assertEquals(str(res[3]["dnsHostName"]), "z") self.assertEquals(str(res[3]["lastLogon"]), "z") # Search by negated disjunction of remote attributes res = self.ldb.search(expression="(!(|(badPwdCount=x)(lastLogon=x)))", attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 5) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y")) - self.assertEquals(str(res[0]["dnsHostName"]), "y") - self.assertEquals(str(res[0]["lastLogon"]), "y") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Z")) - self.assertEquals(str(res[1]["dnsHostName"]), "z") - self.assertEquals(str(res[1]["lastLogon"]), "z") - self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C")) - self.assertTrue(not "dnsHostName" in res[2]) + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=C")) + self.assertTrue(not "dnsHostName" in res[0]) + self.assertEquals(str(res[0]["lastLogon"]), "z") + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y")) + self.assertEquals(str(res[1]["dnsHostName"]), "y") + self.assertEquals(str(res[1]["lastLogon"]), "y") + self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Z")) + self.assertEquals(str(res[2]["dnsHostName"]), "z") self.assertEquals(str(res[2]["lastLogon"]), "z") # Search by negated disjunction of local and remote attribute res = self.ldb.search(expression="(!(|(revision=x)(lastLogon=y)))", attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 5) + res = sorted(res, key=attrgetter('dn')) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) self.assertTrue(not "dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "x") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Z")) - self.assertEquals(str(res[1]["dnsHostName"]), "z") + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=C")) + self.assertTrue(not "dnsHostName" in res[1]) self.assertEquals(str(res[1]["lastLogon"]), "z") - self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C")) - self.assertTrue(not "dnsHostName" in res[2]) + self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Z")) + self.assertEquals(str(res[2]["dnsHostName"]), "z") self.assertEquals(str(res[2]["lastLogon"]), "z") # Search by complex parse tree res = self.ldb.search(expression="(|(&(revision=x)(dnsHostName=x))(!(&(description=x)(nextRid=y)))(badPwdCount=y))", attrs=["dnsHostName", "lastLogon"]) self.assertEquals(len(res), 7) - self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) + res = sorted(res, key=attrgetter('dn')) + self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) self.assertTrue(not "dnsHostName" in res[0]) - self.assertEquals(str(res[0]["lastLogon"]), "y") - self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X")) - self.assertEquals(str(res[1]["dnsHostName"]), "x") - self.assertEquals(str(res[1]["lastLogon"]), "x") - self.assertEquals(str(res[2].dn), self.samba4.dn("cn=A")) + self.assertEquals(str(res[0]["lastLogon"]), "x") + self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B")) + self.assertTrue(not "dnsHostName" in res[1]) + self.assertEquals(str(res[1]["lastLogon"]), "y") + self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C")) self.assertTrue(not "dnsHostName" in res[2]) - self.assertEquals(str(res[2]["lastLogon"]), "x") - self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z")) - self.assertEquals(str(res[3]["dnsHostName"]), "z") - self.assertEquals(str(res[3]["lastLogon"]), "z") - self.assertEquals(str(res[4].dn), self.samba4.dn("cn=C")) - self.assertTrue(not "dnsHostName" in res[4]) + self.assertEquals(str(res[2]["lastLogon"]), "z") + self.assertEquals(str(res[3].dn), self.samba4.dn("cn=X")) + self.assertEquals(str(res[3]["dnsHostName"]), "x") + self.assertEquals(str(res[3]["lastLogon"]), "x") + self.assertEquals(str(res[4].dn), self.samba4.dn("cn=Z")) + self.assertEquals(str(res[4]["dnsHostName"]), "z") self.assertEquals(str(res[4]["lastLogon"]), "z") # Clean up diff --git a/source4/scripting/python/samba/tests/strings.py b/source4/scripting/python/samba/tests/strings.py new file mode 100644 index 0000000000..5f3e5c5bb7 --- /dev/null +++ b/source4/scripting/python/samba/tests/strings.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python + +# subunit test cases for Samba string functions. + +# Copyright (C) 2003 by Martin Pool <mbp@samba.org> +# Copyright (C) 2011 Andrew Bartlett +# +# 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 <http://www.gnu.org/licenses/>. + +# XXX: All this code assumes that the Unix character set is UTF-8, +# which is the most common setting. I guess it would be better to +# force it to that value while running the tests. I'm not sure of the +# best way to do that yet. +# +# -- mbp + +import sys, re +from unicodenames import * + +import samba.tests +from samba import strcasecmp_m, strstr_m + +def signum(a): + if a < 0: + return -1 + elif a > 0: + return +1 + else: + return 0 + + +class strcasecmp_m_Tests(samba.tests.TestCase): + """String comparisons in simple ASCII and unicode""" + def test_strcasecmp_m(self): + # A, B, strcasecmp(A, B) + cases = [('hello', 'hello', 0), + ('hello', 'goodbye', +1), + ('goodbye', 'hello', -1), + ('hell', 'hello', -1), + ('', '', 0), + ('a', '', +1), + ('', 'a', -1), + ('a', 'A', 0), + ('aa', 'aA', 0), + ('Aa', 'aa', 0), + ('longstring ' * 100, 'longstring ' * 100, 0), + ('longstring ' * 100, 'longstring ' * 100 + 'a', -1), + ('longstring ' * 100 + 'a', 'longstring ' * 100, +1), + (KATAKANA_LETTER_A, KATAKANA_LETTER_A, 0), + (KATAKANA_LETTER_A, 'a', 1), + ] + for a, b, expect in cases: + self.assertEquals(signum(strcasecmp_m(a.encode('utf-8'), + b.encode('utf-8'))), + expect) + +class strstr_m_Tests(samba.tests.TestCase): + """strstr_m tests in simple ASCII and unicode strings""" + def test_strstr_m(self): + # A, B, strstr_m(A, B) + cases = [('hello', 'hello', 'hello'), + ('hello', 'goodbye', None), + ('goodbye', 'hello', None), + ('hell', 'hello', None), + ('hello', 'hell', 'hello'), + ('', '', ''), + ('a', '', 'a'), + ('', 'a', None), + ('a', 'A', None), + ('aa', 'aA', None), + ('Aa', 'aa', None), + ('%v foo', '%v', '%v foo'), + ('foo %v foo', '%v', '%v foo'), + ('foo %v', '%v', '%v'), + ('longstring ' * 100, 'longstring ' * 99, 'longstring ' * 100), + ('longstring ' * 99, 'longstring ' * 100, None), + ('longstring a' * 99, 'longstring ' * 100 + 'a', None), + ('longstring ' * 100 + 'a', 'longstring ' * 100, 'longstring ' * 100 + 'a'), + (KATAKANA_LETTER_A, KATAKANA_LETTER_A + 'bcd', None), + (KATAKANA_LETTER_A + 'bcde', KATAKANA_LETTER_A + 'bcd', KATAKANA_LETTER_A + 'bcde'), + ('d'+KATAKANA_LETTER_A + 'bcd', KATAKANA_LETTER_A + 'bcd', KATAKANA_LETTER_A + 'bcd'), + ('d'+KATAKANA_LETTER_A + 'bd', KATAKANA_LETTER_A + 'bcd', None), + + ('e'+KATAKANA_LETTER_A + 'bcdf', KATAKANA_LETTER_A + 'bcd', KATAKANA_LETTER_A + 'bcdf'), + (KATAKANA_LETTER_A, KATAKANA_LETTER_A + 'bcd', None), + (KATAKANA_LETTER_A*3, 'a', None), + ] + for a, b, expect in cases: + if expect is not None: + expect = expect.encode('utf-8') + self.assertEquals(strstr_m(a.encode('utf-8'), + b.encode('utf-8')), + expect) diff --git a/source4/scripting/python/samba/tests/unicodenames.py b/source4/scripting/python/samba/tests/unicodenames.py new file mode 100644 index 0000000000..fa5d0efc8c --- /dev/null +++ b/source4/scripting/python/samba/tests/unicodenames.py @@ -0,0 +1,31 @@ +#! /usr/bin/python + +# Copyright (C) 2003 by Martin Pool <mbp@samba.org> +# +# 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 <http://www.gnu.org/licenses/>. + + +""" +Defines symbolic names for a few UNICODE characters, to make test +source code more readable on machines that don't have all the +necessary fonts. + +You can do "import *" on this file safely. +""" + +LATIN_CAPITAL_LETTER_N_WITH_TILDE = u'\u004e' +LATIN_CAPITAL_LETTER_O_WITH_DIARESIS = u'\u00d6' +LATIN_SMALL_LETTER_O_WITH_DIARESIS = u'\u00f6' + +KATAKANA_LETTER_A = u'\u30a2' diff --git a/source4/scripting/python/samba/tests/upgradeprovisionneeddc.py b/source4/scripting/python/samba/tests/upgradeprovisionneeddc.py index 3a9c78e0dc..596cff6d3a 100644 --- a/source4/scripting/python/samba/tests/upgradeprovisionneeddc.py +++ b/source4/scripting/python/samba/tests/upgradeprovisionneeddc.py @@ -26,9 +26,9 @@ import shutil from samba import param from samba.credentials import Credentials from samba.auth import system_session -from samba.provision import getpolicypath +from samba.provision import getpolicypath,find_provision_key_parameters from samba.upgradehelpers import (get_paths, get_ldbs, - find_provision_key_parameters, identic_rename, + identic_rename, updateOEMInfo, getOEMInfo, update_gpo, delta_update_basesamdb, update_dns_account_password, diff --git a/source4/scripting/python/samba/upgradehelpers.py b/source4/scripting/python/samba/upgradehelpers.py index 48f492a7dc..e15523033f 100755 --- a/source4/scripting/python/samba/upgradehelpers.py +++ b/source4/scripting/python/samba/upgradehelpers.py @@ -24,22 +24,19 @@ """Helpers used for upgrading between different database formats.""" import os -import string import re import shutil import samba from samba import Ldb, version, ntacls -from samba.dsdb import DS_DOMAIN_FUNCTION_2000 from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE import ldb -from samba.provision import (ProvisionNames, provision_paths_from_lp, +from samba.provision import (provision_paths_from_lp, getpolicypath, set_gpos_acl, create_gpo_struct, FILL_FULL, provision, ProvisioningError, setsysvolacl, secretsdb_self_join) -from samba.dcerpc import misc, security, xattr +from samba.dcerpc import xattr from samba.dcerpc.misc import SEC_CHAN_BDC -from samba.ndr import ndr_unpack from samba.samdb import SamDB # All the ldb related to registry are commented because the path for them is @@ -242,112 +239,6 @@ def update_policyids(names, samdb): names.policyid_dc = None -def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf, lp): - """Get key provision parameters (realm, domain, ...) from a given provision - - :param samdb: An LDB object connected to the sam.ldb file - :param secretsdb: An LDB object connected to the secrets.ldb file - :param idmapdb: An LDB object connected to the idmap.ldb file - :param paths: A list of path to provision object - :param smbconf: Path to the smb.conf file - :param lp: A LoadParm object - :return: A list of key provision parameters - """ - names = ProvisionNames() - names.adminpass = None - - # NT domain, kerberos realm, root dn, domain dn, domain dns name - names.domain = string.upper(lp.get("workgroup")) - names.realm = lp.get("realm") - basedn = "DC=" + names.realm.replace(".",",DC=") - names.dnsdomain = names.realm.lower() - names.realm = string.upper(names.realm) - # netbiosname - # Get the netbiosname first (could be obtained from smb.conf in theory) - res = secretsdb.search(expression="(flatname=%s)" % - names.domain,base="CN=Primary Domains", - scope=SCOPE_SUBTREE, attrs=["sAMAccountName"]) - names.netbiosname = str(res[0]["sAMAccountName"]).replace("$","") - - names.smbconf = smbconf - - # That's a bit simplistic but it's ok as long as we have only 3 - # partitions - current = samdb.search(expression="(objectClass=*)", - base="", scope=SCOPE_BASE, - attrs=["defaultNamingContext", "schemaNamingContext", - "configurationNamingContext","rootDomainNamingContext"]) - - names.configdn = current[0]["configurationNamingContext"] - configdn = str(names.configdn) - names.schemadn = current[0]["schemaNamingContext"] - if not (ldb.Dn(samdb, basedn) == (ldb.Dn(samdb, - current[0]["defaultNamingContext"][0]))): - raise ProvisioningError(("basedn in %s (%s) and from %s (%s)" - "is not the same ..." % (paths.samdb, - str(current[0]["defaultNamingContext"][0]), - paths.smbconf, basedn))) - - names.domaindn=current[0]["defaultNamingContext"] - names.rootdn=current[0]["rootDomainNamingContext"] - # default site name - res3 = samdb.search(expression="(objectClass=*)", - base="CN=Sites," + configdn, scope=SCOPE_ONELEVEL, attrs=["cn"]) - names.sitename = str(res3[0]["cn"]) - - # dns hostname and server dn - res4 = samdb.search(expression="(CN=%s)" % names.netbiosname, - base="OU=Domain Controllers,%s" % basedn, - scope=SCOPE_ONELEVEL, attrs=["dNSHostName"]) - names.hostname = str(res4[0]["dNSHostName"]).replace("." + names.dnsdomain,"") - - server_res = samdb.search(expression="serverReference=%s" % res4[0].dn, - attrs=[], base=configdn) - names.serverdn = server_res[0].dn - - # invocation id/objectguid - res5 = samdb.search(expression="(objectClass=*)", - base="CN=NTDS Settings,%s" % str(names.serverdn), scope=SCOPE_BASE, - attrs=["invocationID", "objectGUID"]) - names.invocation = str(ndr_unpack(misc.GUID, res5[0]["invocationId"][0])) - names.ntdsguid = str(ndr_unpack(misc.GUID, res5[0]["objectGUID"][0])) - - # domain guid/sid - res6 = samdb.search(expression="(objectClass=*)", base=basedn, - scope=SCOPE_BASE, attrs=["objectGUID", - "objectSid","msDS-Behavior-Version" ]) - names.domainguid = str(ndr_unpack(misc.GUID, res6[0]["objectGUID"][0])) - names.domainsid = ndr_unpack( security.dom_sid, res6[0]["objectSid"][0]) - if res6[0].get("msDS-Behavior-Version") is None or \ - int(res6[0]["msDS-Behavior-Version"][0]) < DS_DOMAIN_FUNCTION_2000: - names.domainlevel = DS_DOMAIN_FUNCTION_2000 - else: - names.domainlevel = int(res6[0]["msDS-Behavior-Version"][0]) - - # policy guid - res7 = samdb.search(expression="(displayName=Default Domain Policy)", - base="CN=Policies,CN=System," + basedn, - scope=SCOPE_ONELEVEL, attrs=["cn","displayName"]) - names.policyid = str(res7[0]["cn"]).replace("{","").replace("}","") - # dc policy guid - res8 = samdb.search(expression="(displayName=Default Domain Controllers" - " Policy)", - base="CN=Policies,CN=System," + basedn, - scope=SCOPE_ONELEVEL, attrs=["cn","displayName"]) - if len(res8) == 1: - names.policyid_dc = str(res8[0]["cn"]).replace("{","").replace("}","") - else: - names.policyid_dc = None - res9 = idmapdb.search(expression="(cn=%s)" % - (security.SID_BUILTIN_ADMINISTRATORS), - attrs=["xidNumber"]) - if len(res9) == 1: - names.wheel_gid = res9[0]["xidNumber"] - else: - raise ProvisioningError("Unable to find uid/gid for Domain Admins rid") - return names - - def newprovision(names, creds, session, smbconf, provdir, logger): """Create a new provision. @@ -469,7 +360,7 @@ def chunck_sddl(sddl): return hash -def get_diff_sddls(refsddl, cursddl): +def get_diff_sddls(refsddl, cursddl, checkSacl = True): """Get the difference between 2 sddl This function split the textual representation of ACL into smaller @@ -477,46 +368,54 @@ def get_diff_sddls(refsddl, cursddl): :param refsddl: First sddl to compare :param cursddl: Second sddl to compare + :param checkSacl: If false we skip the sacl checks :return: A string that explain difference between sddls """ txt = "" - hash_new = chunck_sddl(cursddl) + hash_cur = chunck_sddl(cursddl) hash_ref = chunck_sddl(refsddl) - if hash_new["owner"] != hash_ref["owner"]: + if not hash_cur.has_key("owner"): + txt = "\tNo owner in current SD" + elif hash_cur["owner"] != hash_ref["owner"]: txt = "\tOwner mismatch: %s (in ref) %s" \ - "(in current)\n" % (hash_ref["owner"], hash_new["owner"]) + "(in current)\n" % (hash_ref["owner"], hash_cur["owner"]) - if hash_new["group"] != hash_ref["group"]: + if not hash_cur.has_key("group"): + txt = "%s\tNo group in current SD" % txt + elif hash_cur["group"] != hash_ref["group"]: txt = "%s\tGroup mismatch: %s (in ref) %s" \ - "(in current)\n" % (txt, hash_ref["group"], hash_new["group"]) + "(in current)\n" % (txt, hash_ref["group"], hash_cur["group"]) - for part in ["dacl", "sacl"]: - if hash_new.has_key(part) and hash_ref.has_key(part): + parts = [ "dacl" ] + if checkSacl: + parts.append("sacl") + for part in parts: + if hash_cur.has_key(part) and hash_ref.has_key(part): # both are present, check if they contain the same ACE - h_new = set() + h_cur = set() h_ref = set() - c_new = chunck_acl(hash_new[part]) + c_cur = chunck_acl(hash_cur[part]) c_ref = chunck_acl(hash_ref[part]) - for elem in c_new["aces"]: - h_new.add(elem) + for elem in c_cur["aces"]: + h_cur.add(elem) for elem in c_ref["aces"]: h_ref.add(elem) for k in set(h_ref): - if k in h_new: - h_new.remove(k) + if k in h_cur: + h_cur.remove(k) h_ref.remove(k) - if len(h_new) + len(h_ref) > 0: + if len(h_cur) + len(h_ref) > 0: txt = "%s\tPart %s is different between reference" \ " and current here is the detail:\n" % (txt, part) - for item in h_new: + for item in h_cur: txt = "%s\t\t%s ACE is not present in the" \ " reference\n" % (txt, item) @@ -524,9 +423,9 @@ def get_diff_sddls(refsddl, cursddl): txt = "%s\t\t%s ACE is not present in the" \ " current\n" % (txt, item) - elif hash_new.has_key(part) and not hash_ref.has_key(part): + elif hash_cur.has_key(part) and not hash_ref.has_key(part): txt = "%s\tReference ACL hasn't a %s part\n" % (txt, part) - elif not hash_new.has_key(part) and hash_ref.has_key(part): + elif not hash_cur.has_key(part) and hash_ref.has_key(part): txt = "%s\tCurrent ACL hasn't a %s part\n" % (txt, part) return txt @@ -541,7 +440,7 @@ def update_secrets(newsecrets_ldb, secrets_ldb, messagefunc): of the updated provision """ - messagefunc(SIMPLE, "update secrets.ldb") + messagefunc(SIMPLE, "Update of secrets.ldb") reference = newsecrets_ldb.search(expression="dn=@MODULES", base="", scope=SCOPE_SUBTREE) current = secrets_ldb.search(expression="dn=@MODULES", base="", @@ -649,7 +548,7 @@ def getOEMInfo(samdb, rootdn): """ res = samdb.search(expression="(objectClass=*)", base=str(rootdn), scope=SCOPE_BASE, attrs=["dn", "oEMInformation"]) - if len(res) > 0: + if len(res) > 0 and res[0].get("oEMInformation"): info = res[0]["oEMInformation"] return info else: @@ -666,7 +565,10 @@ def updateOEMInfo(samdb, rootdn): res = samdb.search(expression="(objectClass=*)", base=rootdn, scope=SCOPE_BASE, attrs=["dn", "oEMInformation"]) if len(res) > 0: - info = res[0]["oEMInformation"] + if res[0].get("oEMInformation"): + info = str(res[0]["oEMInformation"]) + else: + info = "" info = "%s, upgrade to %s" % (info, version) delta = ldb.Message() delta.dn = ldb.Dn(samdb, str(res[0]["dn"])) diff --git a/source4/scripting/wscript_build b/source4/scripting/wscript_build index 76ff739c9e..d94fc4fe9c 100644 --- a/source4/scripting/wscript_build +++ b/source4/scripting/wscript_build @@ -4,5 +4,5 @@ from samba_utils import MODE_755 bld.INSTALL_FILES('${SBINDIR}','bin/upgradeprovision bin/samba_dnsupdate bin/samba_spnupdate', chmod=MODE_755, python_fixup=True, flat=True) -bld.INSTALL_FILES('${BINDIR}','bin/testparm', - chmod=MODE_755, python_fixup=True, flat=True) + +bld.RECURSE('bin') diff --git a/source4/selftest/knownfail b/source4/selftest/knownfail index cdd7a2d306..266148b91f 100644 --- a/source4/selftest/knownfail +++ b/source4/selftest/knownfail @@ -3,82 +3,87 @@ # # "make test" will not report failures for tests listed here and will consider # a successful run for any of these tests an error. -samba4.local.resolve.*.async -samba4.local.iconv.*.next_codepoint() -samba4..*base.delete.*.deltest17 -samba4..*base.delete.*.deltest20a -samba4..*base.delete.*.deltest20b -samba4.raw.rename.*.osxrename -samba4.raw.rename.*.directory rename -samba4.rpc.winreg.*security -samba4.local.registry.(dir|ldb).check hive security -samba4.local.registry.local.security -samba4.rpc.wkssvc -samba4.rpc.handles.*.lsarpc-shared -samba4.rpc.handles.*.mixed-shared -samba4.rpc.epmapper -samba4.rpc.drsuapi.* -samba4.rpc.lsalookup -samba4.rpc.cracknames -samba4.rpc.netlogon.*.LogonUasLogon -samba4.rpc.netlogon.*.LogonUasLogoff -samba4.rpc.netlogon.*.DatabaseSync -samba4.rpc.netlogon.*.DatabaseSync2 -samba4.rpc.netlogon.*.LogonControl -samba4.rpc.netlogon.*.LogonControl2 -samba4.rpc.netlogon.*.DsrEnumerateDomainTrusts -samba4.rpc.netlogon.*.NetrEnumerateTrustedDomains -samba4.rpc.netlogon.*.NetrEnumerateTrustedDomainsEx -samba4.rpc.netlogon.*.GetPassword -samba4.rpc.netlogon.*.GetTrustPasswords -samba4.rpc.netlogon.*.DatabaseRedo -samba4.rpc.netlogon.*.ServerGetTrustInfo -samba4.rpc.netlogon.*.GetForestTrustInformation -samba4.rpc.samr.passwords.badpwdcount # Not provided by Samba 4 yet -samba4.rpc.samr.passwords.lockout -samba4.base.charset.*.Testing partial surrogate +^samba4.local.resolve.*.async +^samba4.local.iconv.*.next_codepoint() +^samba4..*base.delete.*.deltest17 +^samba4..*base.delete.*.deltest20a +^samba4..*base.delete.*.deltest20b +^samba4.raw.rename.*.osxrename +^samba4.raw.rename.*.directory rename +^samba4.rpc.winreg.*security +^samba4.local.registry.(dir|ldb).check hive security +^samba4.local.registry.local.security +^samba4.rpc.wkssvc +^samba4.rpc.handles.*.lsarpc-shared +^samba4.rpc.handles.*.mixed-shared +^samba4.rpc.epmapper +^samba4.rpc.drsuapi.* +^samba4.rpc.lsalookup +^samba4.rpc.cracknames +^samba4.rpc.netlogon.*.LogonUasLogon +^samba4.rpc.netlogon.*.LogonUasLogoff +^samba4.rpc.netlogon.*.DatabaseSync +^samba4.rpc.netlogon.*.DatabaseSync2 +^samba4.rpc.netlogon.*.LogonControl +^samba4.rpc.netlogon.*.LogonControl2 +^samba4.rpc.netlogon.*.DsrEnumerateDomainTrusts +^samba4.rpc.netlogon.*.NetrEnumerateTrustedDomains +^samba4.rpc.netlogon.*.NetrEnumerateTrustedDomainsEx +^samba4.rpc.netlogon.*.GetPassword +^samba4.rpc.netlogon.*.GetTrustPasswords +^samba4.rpc.netlogon.*.DatabaseRedo +^samba4.rpc.netlogon.*.ServerGetTrustInfo +^samba4.rpc.netlogon.*.GetForestTrustInformation +^samba4.rpc.samr.passwords.badpwdcount # Not provided by Samba 4 yet +^samba4.rpc.samr.passwords.lockout +^samba4.base.charset.*.Testing partial surrogate .*net.api.delshare.* # DelShare isn't implemented yet -samba4.rap.*netservergetinfo -samba4.rap.*netsessionenum -samba4.rap.*netsessiongetinfo -samba4.smb2.persistent.handles1 -samba4.winbind.struct.*.show_sequence # Not yet working in winbind -samba4.winbind.struct.*.getpwent # Not yet working in winbind -samba4.winbind.struct.*.setpwent # Not yet working in winbind -samba4.winbind.struct.*.lookup_name_sid # Not yet working in winbind -samba4.winbind.struct.*.list_groups -samba4.*base.delaywrite.*update of write time and SMBwrite truncate$ -samba4.*base.delaywrite.*update of write time and SMBwrite truncate expand$ -samba4.*base.delaywrite.*delayed update of write time 3a$ -samba4.*base.delaywrite.*delayed update of write time 3c$ -samba4.*base.delaywrite.*update of write time using SET_END_OF_FILE$ -samba4.*base.delaywrite.*update of write time using SET_ALLOCATION_SIZE$ -samba4.ldap.python \(dc\).Test add_ldif\(\) with BASE64 security descriptor input using WRONG domain SID$ +^samba4.rap.*netservergetinfo +^samba4.rap.*netsessionenum +^samba4.rap.*netsessiongetinfo +^samba4.rap.*netremotetod +^samba4.smb2.persistent.handles1 +^samba4.winbind.struct.*.show_sequence # Not yet working in winbind +^samba4.winbind.struct.*.getpwent # Not yet working in winbind +^samba4.winbind.struct.*.setpwent # Not yet working in winbind +^samba4.winbind.struct.*.lookup_name_sid # Not yet working in winbind +^samba4.winbind.struct.*.list_groups +^samba4.*base.delaywrite.*update of write time and SMBwrite truncate$ +^samba4.*base.delaywrite.*update of write time and SMBwrite truncate expand$ +^samba4.*base.delaywrite.*delayed update of write time 3a$ +^samba4.*base.delaywrite.*delayed update of write time 3c$ +^samba4.*base.delaywrite.*update of write time using SET_END_OF_FILE$ +^samba4.*base.delaywrite.*update of write time using SET_ALLOCATION_SIZE$ +^samba4.ldap.python \(dc\).Test add_ldif\(\) with BASE64 security descriptor input using WRONG domain SID$ # some operations don't work over the CIFS NTVFS backend yet (eg. root_fid) -samba4.ntvfs.cifs.base.createx_access -samba4.ntvfs.cifs.base.createx_sharemodes_dir -samba4.ntvfs.cifs.base.maximum_allowed -samba4.base.createx_access # this test is broken for non-administrator users -samba4.smb2.oplock # oplocks in the s4 SMB2 server are a mess -samba4.raw.lock.*.async # bug 6960 -samba4.smb2.lock.*.multiple-unlock # bug 6959 -samba4.raw.sfileinfo.*.end-of-file # bug 6962 -samba4.raw.oplock.*.batch22 # bug 6963 -samba4.raw.oplock.*.brl4 # bug 7928 -samba4.raw.lock.*.zerobyteread # bug 6974 -samba4.smb2.lock.*.zerobyteread # bug 6974 -samba4.raw.streams.*.delete -samba4.raw.streams.*.createdisp -samba4.raw.streams.*.sumtab -samba4.raw.acls.*.create_dir -samba4.raw.acls.*.create_file -samba4.smb2.create.*.acldir -samba4.smb2.acls.*.generic -samba4.smb2.acls.*.inheritflags -samba4.smb2.acls.*.owner -samba4.smb2.compound.*.related1 -samba4.smb2.compound.*.related2 -samba4.smb2.compound.*.invalid2 -samba4.ldap.acl.*.search.* # ACL search behaviour not enabled by default -samba4.ldap.acl.*.ntSecurityDescriptor.* # ACL extended checks on search not enabled by default -samba4.nbt.winsreplication.owned # fails sometimes, timing related +^samba4.ntvfs.cifs.base.createx_access +^samba4.ntvfs.cifs.base.createx_sharemodes_dir +^samba4.ntvfs.cifs.base.maximum_allowed +^samba4.base.createx_access # this test is broken for non-administrator users +^samba4.smb2.oplock # oplocks in the s4 SMB2 server are a mess +^samba4.raw.lock.*.async # bug 6960 +^samba4.smb2.lock.*.multiple-unlock # bug 6959 +^samba4.raw.sfileinfo.*.end-of-file # bug 6962 +^samba4.raw.oplock.*.batch22 # bug 6963 +^samba4.raw.oplock.*.brl4 # bug 7928 +^samba4.raw.lock.*.zerobyteread # bug 6974 +^samba4.smb2.lock.*.zerobyteread # bug 6974 +^samba4.raw.streams.*.delete +^samba4.raw.streams.*.createdisp +^samba4.raw.streams.*.sumtab +^samba4.raw.acls.*.create_dir +^samba4.raw.acls.*.create_file +^samba4.smb2.create.*.acldir +^samba4.smb2.acls.*.generic +^samba4.smb2.acls.*.inheritflags +^samba4.smb2.acls.*.owner +^samba4.smb2.compound.*.related1 +^samba4.smb2.compound.*.related2 +^samba4.smb2.compound.*.invalid2 +^samba4.ldap.acl.*.search.* # ACL search behaviour not enabled by default +^samba4.ldap.acl.*.ntSecurityDescriptor.* # ACL extended checks on search not enabled by default +^samba4.nbt.winsreplication.owned # fails sometimes, timing related +^samba4.ldap.dirsync.python.dc..__main__.ExtendedDirsyncTests.test_dirsync_deleted_items +#^samba4.ldap.dirsync.python.dc..__main__.ExtendedDirsyncTests.* +^samba4.drs.fsmo.python +^samba4.libsmbclient.opendir.opendir # This requires netbios browsing diff --git a/source4/selftest/skip b/source4/selftest/skip index 671269a8fd..c15375a709 100644 --- a/source4/selftest/skip +++ b/source4/selftest/skip @@ -18,69 +18,76 @@ # # Please add a comment for each testsuite you disable explaining why # it is being skipped. -raw.composite -base.iometer -base.casetable -base.nttrans -base.scan.maxfid -hold.oplock # Not a test, but a way to block other clients for a test -raw.ping.pong # Needs second server to test -rpc.samr.accessmask -raw.scan.eamax +^samba4.raw.composite +^samba4.base.iometer +^samba4.base.casetable +^samba4.base.nttrans +^samba4.base.scan.maxfid +^samba4.raw.hold-oplock # Not a test, but a way to block other clients for a test +^samba4.smb2.hold-oplock # Not a test, but a way to block other clients for a test +^samba4.raw.ping.pong # Needs second server to test +^samba4.rpc.samr.accessmask +^samba4.raw.scan.eamax samba4.ntvfs.cifs.raw.qfileinfo.ipc -smb2.notify -smb2.scan -smb2.lease -smb2.durable.open -smb2.dir -ntvfs.cifs.base.charset -ntvfs.cifs.base.iometer -ntvfs.cifs.base.casetable -ntvfs.cifs.base.nttrans -ntvfs.cifs.base.scan-maxfid -ntvfs.cifs.base.utable -ntvfs.cifs.base.smb -ntvfs.cifs.raw.composite -ntvfs.cifs.raw.notify -ntvfs.cifs.raw.scan-eamax -ntvfs.cifs.raw.context -ntvfs.cifs.raw.qfileinfo.ipc -rpc.samsync -rpc.remact # Not provided by Samba 4 -rpc.oxidresolve # Not provided by Samba 4 -rpc.eventlog # Not provided by Samba 4 -rpc.initshutdown # Not provided by Samba 4 -rpc.spoolss # Not provided by Samba 4 -rpc.svcctl # Not provided by Samba 4 -rpc.atsvc # Not provided by Samba 4 -rpc.frsapi # Not provided by Samba 4 -rpc.ntsvcs # Not provided by Samba 4 -rpc.dfs # Not provided by Samba 4 -rpc.lsa.forest # Not provided by Samba 4 +^samba4.smb2.notify +^samba4.smb2.scan +^samba4.smb2.lease +^samba4.smb2.durable.open +^samba4.smb2.dir +^samba4.ntvfs.cifs.base.charset +^samba4.ntvfs.cifs.base.iometer +^samba4.ntvfs.cifs.base.casetable +^samba4.ntvfs.cifs.base.nttrans +^samba4.ntvfs.cifs.base.scan-maxfid +^samba4.ntvfs.cifs.base.utable +^samba4.ntvfs.cifs.base.smb +^samba4.ntvfs.cifs.raw.composite +^samba4.ntvfs.cifs.raw.notify +^samba4.ntvfs.cifs.raw.scan-eamax +^samba4.ntvfs.cifs.raw.context +^samba4.ntvfs.cifs.raw.qfileinfo.ipc +^samba4.rpc.samsync +^samba4.rpc.remact # Not provided by Samba 4 +^samba4.rpc.oxidresolve # Not provided by Samba 4 +^samba4.rpc.eventlog # Not provided by Samba 4 +^samba4.rpc.initshutdown # Not provided by Samba 4 +^samba4.rpc.spoolss # Not provided by Samba 4 +^samba4.rpc.svcctl # Not provided by Samba 4 +^samba4.rpc.atsvc # Not provided by Samba 4 +^samba4.rpc.frsapi # Not provided by Samba 4 +^samba4.rpc.ntsvcs # Not provided by Samba 4 +^samba4.rpc.dfs # Not provided by Samba 4 +^samba4.rpc.lsa.forest # Not provided by Samba 4 ^samba4.base.samba3.* # Samba3-specific test ^samba4.ntvfs.cifs.base.samba3.* # Samba3-specific test ^samba4.raw.samba3.* # Samba3-specific test ^samba4.ntvfs.cifs.raw.samba3.* # Samba3-specific test -samba4.ntvfs.cifs.raw. +^samba4.ntvfs.cifs.raw. ^samba4.rpc..*samba3.* # Samba3-specific test ^samba4.samba-tool.domopen.*$ # Hangs for some reason -nss.test # Fails -raw.offline # Samba 4 doesn't have much offline support yet -rpc.autoidl # this one just generates a lot of noise, and is no longer useful -samba4.rpc.countcalls # this is not useful now we have full IDL -samba4.rap.scan # same thing here - we have docs now -samba4.rap.printing # Not provided by Samba 4 -samba4.rap.sam # Not provided by Samba 4 -samba4.gensec.python # not finished +^samba4.nss.test # Fails +^samba4.raw.offline # Samba 4 doesn't have much offline support yet +^samba4.rpc.autoidl # this one just generates a lot of noise, and is no longer useful +^samba4.rpc.countcalls # this is not useful now we have full IDL +^samba4.rap.scan # same thing here - we have docs now +^samba4.rap.printing # Not provided by Samba 4 +^samba4.rap.sam # Not provided by Samba 4 bench # don't run benchmarks in our selftest -trans2.scan # uses huge number of file descriptors -base.scan.ioctl # bad idea in make test -base.scan.pipe_number # bad idea in make test -base.secleak # no point on build farm -base.delaywrite # This is randomly failing, depending on timing and filesystem features -base.winattr -base.birthtime -smb2.acls # new test which doesn't pass yet +^samba4.ntvfs.cifs.trans2.scan +^samba4.trans2.scan # uses huge number of file descriptors +^samba4.ntvfs.cifs.base.scan.ioctl +^samba4.base.scan.ioctl # bad idea in make test +^samba4.ntvfs.cifs.base.scan.pipe_number +^samba4.base.scan.pipe_number # bad idea in make test +^samba4.ntvfs.cifs.base.secleak +^samba4.base.secleak # no point on build farm +^samba4.ntvfs.cifs.base.delaywrite +^samba4.base.delaywrite # This is randomly failing, depending on timing and filesystem features +^samba4.ntvfs.cifs.base.winattr +^samba4.base.winattr +^samba4.ntvfs.cifs.base.birthtime +^samba4.base.birthtime +^samba4.smb2.acls # new test which doesn't pass yet # ktutil might not be installed or from mit... # we should build a samba4ktutil and use that instead -samba4.blackbox.ktpass # this test isn't portable ... +^samba4.blackbox.ktpass # this test isn't portable ... diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 92ab28c2be..bf42c7c303 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -61,11 +61,20 @@ print "OPTIONS %s" % " ".join(torture_options) for options in ['-U"$USERNAME%$PASSWORD" --option=socket:testnonblock=true', '-U"$USERNAME%$PASSWORD"', '-U"$USERNAME%$PASSWORD" -k yes', '-U"$USERNAME%$PASSWORD" -k no', '-U"$USERNAME%$PASSWORD" -k no --sign', '-U"$USERNAME%$PASSWORD" -k no --encrypt', '-U"$USERNAME%$PASSWORD" -k yes --encrypt', '-U"$USERNAME%$PASSWORD" -k yes --sign']: plantestsuite("samba4.ldb.ldap with options %s(dc)" % options, "dc", "%s/test_ldb.sh ldap $SERVER %s" % (bbdir, options)) -# see if we support ldaps +# see if we support ADS on the Samba3 side try: config_h = os.environ["CONFIG_H"] except KeyError: - config_h = os.path.join(samba4bindir, "default/source4/include/config.h") + config_h = os.path.join(samba4bindir, "default/include/config.h") + +f = open(config_h, 'r') +try: + # The other parts of the HAVE_ADS test are always supplied by the top level build + have_ads_support = ("HAVE_LDAP 1" in f.read()) +finally: + f.close() + +# see if we support ldaps f = open(config_h, 'r') try: have_tls_support = ("ENABLE_GNUTLS 1" in f.read()) @@ -221,7 +230,11 @@ smb2 = smb4torture_testsuites("smb2.") raw = filter(lambda x: "raw.qfileinfo.ipc" not in x, smb4torture_testsuites("raw.")) base = smb4torture_testsuites("base.") -for t in base + raw + smb2: +netapi = smb4torture_testsuites("netapi.") + +libsmbclient = smb4torture_testsuites("libsmbclient.") + +for t in base + raw + smb2 + netapi + libsmbclient: plansmbtorturetestsuite(t, "dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD' + " " + " ".join(ntvfsargs)) plansmbtorturetestsuite("raw.qfileinfo.ipc", "dc", '//$SERVER/ipc\$ -U$USERNAME%$PASSWORD') @@ -306,11 +319,12 @@ for mech in [ "-k no", "-k no --option=usespnego=no", "-k no --option=gensec:spengo=no", - "-k yes", - "-k yes --option=gensec:fake_gssapi_krb5=yes --option=gensec:gssapi_krb5=no"]: + "-k yes"]: signoptions = "%s --signing=off" % mech - name = "smb.signing on with %s" % signoptions + name = "smb.signing disabled on with %s" % signoptions plantestsuite_loadlist("samba4.%s domain-creds" % name, "s4member", [valgrindify(smb4torture), "$LISTOPT", '//$NETBIOSNAME/tmp', signoptions, '-U$DC_USERNAME%$DC_PASSWORD', 'base.xcopy']) + if have_ads_support: + plantestsuite_loadlist("samba4.%s domain-creds" % name, "s3member", [valgrindify(smb4torture), "$LISTOPT", '//$NETBIOSNAME/tmp', signoptions, '-U$DC_USERNAME%$DC_PASSWORD', 'base.xcopy']) for mech in [ "-k no", @@ -319,6 +333,9 @@ for mech in [ signoptions = "%s --signing=off" % mech name = "smb.signing on with %s" % signoptions plantestsuite_loadlist("samba4.%s local-creds" % name, "s4member", [valgrindify(smb4torture), "$LISTOPT", '//$NETBIOSNAME/tmp', signoptions, '-U$NETBIOSNAME/$USERNAME%$PASSWORD', 'base.xcopy']) + if have_ads_support: + plantestsuite_loadlist("samba4.%s" % name, "plugin_s4_dc", [valgrindify(smb4torture), "$LISTOPT", '//$NETBIOSNAME/tmp', signoptions, '-U$USERNAME%$PASSWORD', 'base.xcopy']) + plantestsuite_loadlist("samba4.%s administrator" % name, "plugin_s4_dc", [valgrindify(smb4torture), "$LISTOPT", '//$NETBIOSNAME/tmp', signoptions, '-U$DC_USERNAME%$DC_PASSWORD', 'base.xcopy']) plantestsuite_loadlist("samba4.smb.signing --signing=yes anon", "dc", [valgrindify(smb4torture), "$LISTOPT", '//$NETBIOSNAME/tmp', '-k', 'no', '--signing=yes', '-U%', 'base.xcopy']) plantestsuite_loadlist("samba4.smb.signing --signing=required anon", "dc", [valgrindify(smb4torture), "$LISTOPT", '//$NETBIOSNAME/tmp', '-k', 'no', '--signing=required', '-U%', 'base.xcopy']) plantestsuite_loadlist("samba4.smb.signing --signing=no anon", "s4member", [valgrindify(smb4torture), "$LISTOPT", '//$NETBIOSNAME/tmp', '-k', 'no', '--signing=no', '-U%', 'base.xcopy']) @@ -367,6 +384,7 @@ planpythontestsuite("none", "samba.tests.upgrade") planpythontestsuite("none", "samba.tests.core") planpythontestsuite("none", "samba.tests.provision") planpythontestsuite("none", "samba.tests.samba3") +planpythontestsuite("none", "samba.tests.strings") planpythontestsuite("dc:local", "samba.tests.dcerpc.sam") planpythontestsuite("dc:local", "samba.tests.dsdb") planpythontestsuite("none", "samba.tests.netcmd") @@ -385,6 +403,7 @@ plantestsuite("samba4.tokengroups.python(dc)", "dc:local", [python, os.path.join plantestsuite("samba4.sam.python(dc)", "dc", [python, os.path.join(samba4srcdir, "dsdb/tests/python/sam.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '-W', '$DOMAIN']) plansambapythontestsuite("samba4.schemaInfo.python(dc)", "dc", os.path.join(samba4srcdir, 'dsdb/tests/python'), 'dsdb_schema_info', extra_args=['-U"$DOMAIN/$DC_USERNAME%$DC_PASSWORD"']) plantestsuite("samba4.urgent_replication.python(dc)", "dc", [python, os.path.join(samba4srcdir, "dsdb/tests/python/urgent_replication.py"), '$PREFIX_ABS/dc/private/sam.ldb'], allow_empty_output=True) +plantestsuite("samba4.ldap.dirsync.python(dc)", "dc", [python, os.path.join(samba4srcdir, "dsdb/tests/python/dirsync.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '-W', '$DOMAIN']) for env in ["dc", "fl2000dc", "fl2003dc", "fl2008r2dc"]: plantestsuite("samba4.ldap_schema.python(%s)" % env, env, [python, os.path.join(samba4srcdir, "dsdb/tests/python/ldap_schema.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '-W', '$DOMAIN']) plantestsuite("samba4.ldap.possibleInferiors.python(%s)" % env, env, [python, os.path.join(samba4srcdir, "dsdb/samdb/ldb_modules/tests/possibleinferiors.py"), "ldap://$SERVER", '-U"$USERNAME%$PASSWORD"', "-W", "$DOMAIN"]) @@ -429,3 +448,6 @@ plantestsuite_loadlist("samba4.%s.two" % t, "vampire_dc", [valgrindify(smb4tortu plantestsuite_loadlist("samba4.rpc.echo", "rodc", [smb4torture, "$LISTOPT", 'ncacn_np:$SERVER', "-k", "yes", '-U$USERNAME%$PASSWORD', '-W' '$DOMAIN', 'rpc.echo']) plantestsuite_loadlist("samba4.rpc.echo", "rodc:local", [smb4torture, "$LISTOPT", 'ncacn_np:$SERVER', "-k", "yes", '-P', '-W' '$DOMAIN', 'rpc.echo']) plantestsuite("samba4.blackbox.provision-backend.py", "none", ["PYTHON=%s" % python, os.path.join(samba4srcdir, "setup/tests/blackbox_provision-backend.sh"), '$PREFIX/provision']) + +# Test renaming the DC +plantestsuite("samba4.blackbox.renamedc.sh", "none", ["PYTHON=%s" % python, os.path.join(bbdir, "renamedc.sh"), '$PREFIX/provision']) diff --git a/source4/setup/dns_update_list b/source4/setup/dns_update_list index c69e155a80..91b182188b 100644 --- a/source4/setup/dns_update_list +++ b/source4/setup/dns_update_list @@ -2,6 +2,8 @@ # dynamic DNS update. It is processed by the samba_dnsupdate script A ${DNSDOMAIN} $IP A ${HOSTNAME} $IP +AAAA ${DNSDOMAIN} $IP +AAAA ${HOSTNAME} $IP CNAME ${NTDSGUID}._msdcs.${DNSDOMAIN} ${HOSTNAME} SRV _kerberos._tcp.${SITE}._sites.dc._msdcs.${DNSDOMAIN} ${HOSTNAME} 88 SRV _ldap._tcp.${SITE}._sites.dc._msdcs.${DNSDOMAIN} ${HOSTNAME} 389 diff --git a/source4/setup/named.txt b/source4/setup/named.txt index c1e6b3a9ee..97de69d8eb 100644 --- a/source4/setup/named.txt +++ b/source4/setup/named.txt @@ -5,7 +5,7 @@ # - Insert the following lines into the options {} section of your named.conf # file: -tkey-gssapi-credential "DNS/${DNSDOMAIN}"; +tkey-gssapi-credential "DNS/${DNSNAME}"; tkey-domain "${REALM}"; # - Modify BIND init scripts to pass the location of the generated keytab file. diff --git a/source4/setup/provision.smb.conf.dc b/source4/setup/provision.smb.conf.dc index a8e98ba4bc..f489f59ff9 100644 --- a/source4/setup/provision.smb.conf.dc +++ b/source4/setup/provision.smb.conf.dc @@ -3,7 +3,6 @@ workgroup = ${DOMAIN} realm = ${REALM} server role = ${SERVERROLE} - ${SIDGENERATOR_LINE} ${PRIVATEDIR_LINE} ${LOCKDIR_LINE} diff --git a/source4/setup/provision.smb.conf.member b/source4/setup/provision.smb.conf.member index 8241fc28f1..96e5d0c2e5 100644 --- a/source4/setup/provision.smb.conf.member +++ b/source4/setup/provision.smb.conf.member @@ -3,6 +3,5 @@ workgroup = ${DOMAIN} realm = ${REALM} server role = ${SERVERROLE} - ${SIDGENERATOR_LINE} ${PRIVATEDIR_LINE} ${LOCKDIR_LINE} diff --git a/source4/setup/provision.smb.conf.standalone b/source4/setup/provision.smb.conf.standalone index 8241fc28f1..96e5d0c2e5 100644 --- a/source4/setup/provision.smb.conf.standalone +++ b/source4/setup/provision.smb.conf.standalone @@ -3,6 +3,5 @@ workgroup = ${DOMAIN} realm = ${REALM} server role = ${SERVERROLE} - ${SIDGENERATOR_LINE} ${PRIVATEDIR_LINE} ${LOCKDIR_LINE} diff --git a/source4/setup/provision_basedn_modify.ldif b/source4/setup/provision_basedn_modify.ldif index d67d674319..a5e704769d 100644 --- a/source4/setup/provision_basedn_modify.ldif +++ b/source4/setup/provision_basedn_modify.ldif @@ -82,15 +82,9 @@ pwdProperties: 1 replace: pwdHistoryLength pwdHistoryLength: 24 - -replace: rIDManagerReference -rIDManagerReference: CN=RID Manager$,CN=System,${DOMAINDN} -- replace: serverState serverState: 1 - -replace: subRefs -subRefs: ${CONFIGDN} -- replace: systemFlags systemFlags: -1946157056 - diff --git a/source4/setup/provision_configuration.ldif b/source4/setup/provision_configuration.ldif index 2ccf6eded0..cb049b0c1e 100644 --- a/source4/setup/provision_configuration.ldif +++ b/source4/setup/provision_configuration.ldif @@ -1194,7 +1194,6 @@ dn: CN=Sites,${CONFIGDN} objectClass: top objectClass: sitesContainer systemFlags: -2113929216 -nTSecurityDescriptor:: ${SITES_DESCRIPTOR} dn: CN=${DEFAULTSITE},CN=Sites,${CONFIGDN} objectClass: top diff --git a/source4/setup/provision_self_join_modify.ldif b/source4/setup/provision_self_join_modify.ldif index 2fe5a43db6..aba1b862e1 100644 --- a/source4/setup/provision_self_join_modify.ldif +++ b/source4/setup/provision_self_join_modify.ldif @@ -2,6 +2,8 @@ dn: ${DOMAINDN} changetype: modify replace: fSMORoleOwner fSMORoleOwner: CN=NTDS Settings,${SERVERDN} +replace: rIDManagerReference +rIDManagerReference: CN=RID Manager$,CN=System,${DOMAINDN} dn: ${SCHEMADN} changetype: modify diff --git a/source4/setup/tests/blackbox_newuser.sh b/source4/setup/tests/blackbox_newuser.sh index fe5d051481..5ce634a70d 100755 --- a/source4/setup/tests/blackbox_newuser.sh +++ b/source4/setup/tests/blackbox_newuser.sh @@ -26,17 +26,17 @@ testit "newuser" $samba_tool newuser $CONFIG --given-name="User" --surname="Test testit "newuser" $samba_tool newuser $CONFIG --use-username-as-cn --given-name="User1" --surname="Tester1" --initials="UT1" --profile-path="\\\\myserver\\my\\profile" --script-path="\\\\myserver\\my\\script" --home-directory="\\\\myserver\\my\\homedir" --job-title="Tester" --department="Testing" --company="Samba.org" --description="Description" --mail-address="tester@samba.org" --internet-address="http://samba.org" --telephone-number="001122334455" --physical-delivery-office="101" --home-drive="H:" NewUser1 testp@ssw0Rd # check the enable account script -testit "enableaccount" $samba_tool enableaccount $CONFIG NewUser -testit "enableaccount" $samba_tool enableaccount $CONFIG NewUser1 +testit "enableaccount" $samba_tool user enable $CONFIG NewUser +testit "enableaccount" $samba_tool user enable $CONFIG NewUser1 # check the enable account script testit "setpassword" $samba_tool setpassword $CONFIG NewUser --newpassword=testp@ssw0Rd2 testit "setpassword" $samba_tool setpassword $CONFIG NewUser1 --newpassword=testp@ssw0Rd2 # check the setexpiry script -testit "noexpiry" $samba_tool setexpiry $CONFIG NewUser --noexpiry -testit "noexpiry" $samba_tool setexpiry $CONFIG NewUser1 --noexpiry -testit "expiry" $samba_tool setexpiry $CONFIG NewUser --days=7 -testit "expiry" $samba_tool setexpiry $CONFIG NewUser1 --days=7 +testit "noexpiry" $samba_tool user setexpiry $CONFIG NewUser --noexpiry +testit "noexpiry" $samba_tool user setexpiry $CONFIG NewUser1 --noexpiry +testit "expiry" $samba_tool user setexpiry $CONFIG NewUser --days=7 +testit "expiry" $samba_tool user setexpiry $CONFIG NewUser1 --days=7 exit $failed diff --git a/source4/setup/tests/blackbox_upgradeprovision.sh b/source4/setup/tests/blackbox_upgradeprovision.sh index 05b155d521..a3d1838f88 100755 --- a/source4/setup/tests/blackbox_upgradeprovision.sh +++ b/source4/setup/tests/blackbox_upgradeprovision.sh @@ -24,13 +24,10 @@ upgradeprovision_full() { if [ -d $PREFIX/upgradeprovision_full ]; then rm -fr $PREFIX/upgradeprovision_full fi - $PYTHON $SRCDIR/source4/setup/provision --domain=FOO --realm=foo.example.com --targetdir="$PREFIX/upgradeprovision_full" --server-role="dc" + $PYTHON $SRCDIR/source4/setup/provision --host-name=bar --domain=FOO --realm=foo.example.com --targetdir="$PREFIX/upgradeprovision_full" --server-role="dc" $PYTHON $SRCDIR/source4/scripting/bin/upgradeprovision -s "$PREFIX/upgradeprovision_full/etc/smb.conf" --full --debugchange } -testit "upgradeprovision" upgradeprovision -testit "upgradeprovision_full" upgradeprovision_full - if [ -d $PREFIX/upgradeprovision ]; then rm -fr $PREFIX/upgradeprovision fi @@ -39,4 +36,7 @@ if [ -d $PREFIX/upgradeprovision_full ]; then rm -fr $PREFIX/upgradeprovision_full fi +testit "upgradeprovision" upgradeprovision +testit "upgradeprovision_full" upgradeprovision_full + exit $failed diff --git a/source4/setup/wscript_build b/source4/setup/wscript_build index 241e8b8686..65cbfc9aeb 100644 --- a/source4/setup/wscript_build +++ b/source4/setup/wscript_build @@ -7,6 +7,8 @@ bld.INSTALL_WILDCARD('${SETUPDIR}', 'display-specifiers/*.txt') bld.INSTALL_FILES('${SBINDIR}', 'provision', chmod=MODE_755, python_fixup=True) +bld.SAMBA_SCRIPT('provision', pattern='provision', installdir='.') + bld.INSTALL_FILES('${SETUPDIR}', 'dns_update_list') bld.INSTALL_FILES('${SETUPDIR}', 'spn_update_list') diff --git a/source4/smb_server/service_smb.c b/source4/smb_server/service_smb.c index 583360bbe7..cbbd2cd95e 100644 --- a/source4/smb_server/service_smb.c +++ b/source4/smb_server/service_smb.c @@ -48,24 +48,32 @@ static void smbsrv_task_init(struct task_server *task) int i; struct interface *ifaces; - load_interfaces(task, lpcfg_interfaces(task->lp_ctx), &ifaces); + load_interface_list(task, task->lp_ctx, &ifaces); - num_interfaces = iface_count(ifaces); + num_interfaces = iface_list_count(ifaces); /* We have been given an interfaces line, and been told to only bind to those interfaces. Create a socket per interface and bind to only these. */ for(i = 0; i < num_interfaces; i++) { - const char *address = iface_n_ip(ifaces, i); + const char *address = iface_list_n_ip(ifaces, i); status = smbsrv_add_socket(task, task->event_ctx, task->lp_ctx, task->model_ops, address); if (!NT_STATUS_IS_OK(status)) goto failed; } } else { - /* Just bind to lpcfg_socket_address() (usually 0.0.0.0) */ - status = smbsrv_add_socket(task, task->event_ctx, task->lp_ctx, task->model_ops, - lpcfg_socket_address(task->lp_ctx)); - if (!NT_STATUS_IS_OK(status)) goto failed; + const char **wcard; + int i; + wcard = iface_list_wildcard(task, task->lp_ctx); + if (wcard == NULL) { + DEBUG(0,("No wildcard addresses available\n")); + goto failed; + } + for (i=0; wcard[i]; i++) { + status = smbsrv_add_socket(task, task->event_ctx, task->lp_ctx, task->model_ops, wcard[i]); + if (!NT_STATUS_IS_OK(status)) goto failed; + } + talloc_free(wcard); } return; diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c index 656da4df20..0a07ab93e2 100644 --- a/source4/smb_server/smb/negprot.c +++ b/source4/smb_server/smb/negprot.c @@ -145,7 +145,7 @@ static void reply_lanman1(struct smbsrv_request *req, uint16_t choice) SSVAL(req->out.vwv, VWV(3), lpcfg_maxmux(req->smb_conn->lp_ctx)); SSVAL(req->out.vwv, VWV(4), 1); SSVAL(req->out.vwv, VWV(5), raw); - SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id.id); + SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id.pid); srv_push_dos_date(req->smb_conn, req->out.vwv, VWV(8), t); SSVAL(req->out.vwv, VWV(10), req->smb_conn->negotiate.zone_offset/60); SIVAL(req->out.vwv, VWV(11), 0); /* reserved */ @@ -199,7 +199,7 @@ static void reply_lanman2(struct smbsrv_request *req, uint16_t choice) SSVAL(req->out.vwv, VWV(3), lpcfg_maxmux(req->smb_conn->lp_ctx)); SSVAL(req->out.vwv, VWV(4), 1); SSVAL(req->out.vwv, VWV(5), raw); - SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id.id); + SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id.pid); srv_push_dos_date(req->smb_conn, req->out.vwv, VWV(8), t); SSVAL(req->out.vwv, VWV(10), req->smb_conn->negotiate.zone_offset/60); SIVAL(req->out.vwv, VWV(11), 0); @@ -278,7 +278,7 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice) capabilities |= CAP_LARGE_READX | CAP_LARGE_WRITEX | CAP_W2K_SMBS; } - large_test_path = lock_path(req, req->smb_conn->lp_ctx, "large_test.dat"); + large_test_path = lpcfg_lock_path(req, req->smb_conn->lp_ctx, "large_test.dat"); if (large_file_support(large_test_path)) { capabilities |= CAP_LARGE_FILES; } @@ -332,7 +332,8 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice) SSVAL(req->out.vwv+1, VWV(2), 1); /* num vcs */ SIVAL(req->out.vwv+1, VWV(3), req->smb_conn->negotiate.max_recv); SIVAL(req->out.vwv+1, VWV(5), 0x10000); /* raw size. full 64k */ - SIVAL(req->out.vwv+1, VWV(7), req->smb_conn->connection->server_id.id); /* session key */ + SIVAL(req->out.vwv+1, VWV(7), req->smb_conn->connection->server_id.pid); /* session key */ + SIVAL(req->out.vwv+1, VWV(9), capabilities); push_nttime(req->out.vwv+1, VWV(11), nttime); SSVALS(req->out.vwv+1,VWV(15), req->smb_conn->negotiate.zone_offset/60); diff --git a/source4/smb_server/smb/receive.c b/source4/smb_server/smb/receive.c index c2503efabc..1379fe31cf 100644 --- a/source4/smb_server/smb/receive.c +++ b/source4/smb_server/smb/receive.c @@ -25,7 +25,7 @@ #include "smb_server/smb_server.h" #include "system/filesys.h" #include "param/param.h" - +#include "cluster/cluster.h" /* send an oplock break request to a client @@ -471,6 +471,7 @@ static void switch_message(int type, struct smbsrv_request *req) int flags; struct smbsrv_connection *smb_conn = req->smb_conn; NTSTATUS status; + char *task_id; type &= 0xff; @@ -501,8 +502,10 @@ static void switch_message(int type, struct smbsrv_request *req) } } - DEBUG(5,("switch message %s (task_id %u)\n", - smb_fn_name(type), (unsigned)req->smb_conn->connection->server_id.id)); + task_id = server_id_str(NULL, &req->smb_conn->connection->server_id); + DEBUG(5,("switch message %s (task_id %s)\n", + smb_fn_name(type), task_id)); + talloc_free(task_id); /* this must be called before we do any reply */ if (flags & SIGNING_NO_REPLY) { diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c index c4efe3919c..116f2cd958 100644 --- a/source4/smb_server/smb/sesssetup.c +++ b/source4/smb_server/smb/sesssetup.c @@ -34,7 +34,7 @@ #include "lib/stream/packet.h" struct sesssetup_context { - struct auth_context *auth_context; + struct auth4_context *auth_context; struct smbsrv_request *req; }; diff --git a/source4/smb_server/smb/trans2.c b/source4/smb_server/smb/trans2.c index 0a6c014e88..72babd533b 100644 --- a/source4/smb_server/smb/trans2.c +++ b/source4/smb_server/smb/trans2.c @@ -867,24 +867,14 @@ static NTSTATUS fill_normal_dfs_referraltype(struct dfs_referral_type *ref, const char *dfs_path, const char *server_path, int isfirstoffset) { - + ZERO_STRUCTP(ref); switch (version) { - case 3: - ZERO_STRUCTP(ref); - ref->version = version; - ref->referral.v3.data.server_type = DFS_SERVER_NON_ROOT; - /* "normal" referral seems to always include the GUID */ - ref->referral.v3.size = 34; - - ref->referral.v3.data.entry_flags = 0; - ref->referral.v3.data.ttl = 600; /* As w2k3 */ - ref->referral.v3.data.referrals.r1.DFS_path = dfs_path; - ref->referral.v3.data.referrals.r1.DFS_alt_path = dfs_path; - ref->referral.v3.data.referrals.r1.netw_address = server_path; - return NT_STATUS_OK; case 4: - ZERO_STRUCTP(ref); - ref->version = version; + version = 3; +# if 0 + /* For the moment there is a bug with XP that don't seems to appriciate much + * level4 so we return just level 3 for everyone + */ ref->referral.v4.server_type = DFS_SERVER_NON_ROOT; /* "normal" referral seems to always include the GUID */ ref->referral.v4.size = 34; @@ -892,11 +882,23 @@ static NTSTATUS fill_normal_dfs_referraltype(struct dfs_referral_type *ref, if (isfirstoffset) { ref->referral.v4.entry_flags = DFS_HEADER_FLAG_TARGET_BCK; } - ref->referral.v4.ttl = 600; /* As w2k3 */ - ref->referral.v4.r1.DFS_path = dfs_path; - ref->referral.v4.r1.DFS_alt_path = dfs_path; - ref->referral.v4.r1.netw_address = server_path; + ref->referral.v4.ttl = 900; /* As w2k8r2 */ + ref->referral.v4.referrals.r1.DFS_path = talloc_strdup(ref, dfs_path); + ref->referral.v4.referrals.r1.DFS_alt_path = talloc_strdup(ref, dfs_path); + ref->referral.v4.referrals.r1.netw_address = talloc_strdup(ref, server_path); + return NT_STATUS_OK; +#endif + case 3: + ref->version = version; + ref->referral.v3.server_type = DFS_SERVER_NON_ROOT; + /* "normal" referral seems to always include the GUID */ + ref->referral.v3.size = 34; + ref->referral.v3.entry_flags = 0; + ref->referral.v3.ttl = 600; /* As w2k3 */ + ref->referral.v3.referrals.r1.DFS_path = talloc_strdup(ref, dfs_path); + ref->referral.v3.referrals.r1.DFS_alt_path = talloc_strdup(ref, dfs_path); + ref->referral.v3.referrals.r1.netw_address = talloc_strdup(ref, server_path); return NT_STATUS_OK; } return NT_STATUS_INVALID_LEVEL; @@ -914,18 +916,25 @@ static NTSTATUS fill_domain_dfs_referraltype(struct dfs_referral_type *ref, switch (version) { case 3: ZERO_STRUCTP(ref); + DEBUG(8, ("Called fill_domain_dfs_referraltype\n")); ref->version = version; - ref->referral.v3.data.server_type = DFS_SERVER_NON_ROOT; + ref->referral.v3.server_type = DFS_SERVER_NON_ROOT; /* It's hard coded ... don't think it's a good way but the sizeof return not the * correct values * * We have 18 if the GUID is not included 34 otherwise */ - ref->referral.v3.size = 18; - ref->referral.v3.data.entry_flags = DFS_FLAG_REFERRAL_DOMAIN_RESP; - ref->referral.v3.data.ttl = 600; /* As w2k3 */ - ref->referral.v3.data.referrals.r2.special_name = domain; - ref->referral.v3.data.referrals.r2.nb_expanded_names = numnames; + if (numnames == 0) { + /* Windows return without the guid when returning domain list + */ + ref->referral.v3.size = 18; + } else { + ref->referral.v3.size = 34; + } + ref->referral.v3.entry_flags = DFS_FLAG_REFERRAL_DOMAIN_RESP; + ref->referral.v3.ttl = 600; /* As w2k3 */ + ref->referral.v3.referrals.r2.special_name = domain; + ref->referral.v3.referrals.r2.nb_expanded_names = numnames; /* Put the final terminator */ if (names) { const char **names2 = talloc_array(ref, const char *, numnames+1); @@ -935,8 +944,8 @@ static NTSTATUS fill_domain_dfs_referraltype(struct dfs_referral_type *ref, names2[i] = talloc_asprintf(names2, "\\%s", names[i]); NT_STATUS_HAVE_NO_MEMORY(names2[i]); } - names2[numnames] = 0; - ref->referral.v3.data.referrals.r2.expanded_names = names2; + names2[numnames] = NULL; + ref->referral.v3.referrals.r2.expanded_names = names2; } return NT_STATUS_OK; } @@ -1098,7 +1107,7 @@ static NTSTATUS get_dcs(TALLOC_CTX *ctx, struct ldb_context *ldb, } talloc_free(r); - if (searched_site != NULL) { + if (searched_site != NULL && searched_site[0] != '\0') { ret = ldb_search(ldb, subctx, &r, configdn, LDB_SCOPE_SUBTREE, attrs_none, "(&(name=%s)(objectClass=site))", searched_site); if (ret != LDB_SUCCESS) { @@ -1342,7 +1351,7 @@ static NTSTATUS dodomain_referral(TALLOC_CTX *ctx, } if (!ok && resp.nb_referrals == 2) { - DEBUG(0, (__location__ "; Not able to fit the domain and realm in DFS a " + DEBUG(8, (__location__ "; Not able to fit the domain and realm in DFS a " " 56K buffer, something must be broken")); talloc_free(context); return NT_STATUS_INTERNAL_ERROR; @@ -1363,6 +1372,8 @@ static NTSTATUS dodomain_referral(TALLOC_CTX *ctx, */ static NTSTATUS dodc_or_sysvol_referral(TALLOC_CTX *ctx, const struct dfs_GetDFSReferral_in dfsreq, + const char* requesteddomain, + const char* requestedshare, const char* requestedname, struct ldb_context *ldb, struct smb_trans2 *trans, @@ -1378,16 +1389,13 @@ static NTSTATUS dodc_or_sysvol_referral(TALLOC_CTX *ctx, NTSTATUS status; unsigned int num_domain = 1; enum ndr_err_code ndr_err; - const char *requesteddomain; const char *realm = lpcfg_realm(lp_ctx); const char *domain = lpcfg_workgroup(lp_ctx); const char *site_name = NULL; /* Name of the site where the client is */ - char *share = NULL; bool found = false; bool need_fqdn = false; bool dc_referral = true; unsigned int i; - char *tmp; struct dc_set **set; char const **domain_list; struct tsocket_address *remote_address; @@ -1407,24 +1415,13 @@ static NTSTATUS dodc_or_sysvol_referral(TALLOC_CTX *ctx, context = talloc_new(ctx); NT_STATUS_HAVE_NO_MEMORY(context); - if (requestedname[0] == '\\' && !strchr(requestedname+1,'\\')) { - requestedname++; - } - requesteddomain = requestedname; - - if (strchr(requestedname,'\\')) { - char *subpart; - /* we have a second part */ - requesteddomain = talloc_strdup(context, requestedname+1); - NT_STATUS_HAVE_NO_MEMORY_AND_FREE(requesteddomain, context); - subpart = strchr(requesteddomain,'\\'); - subpart[0] = '\0'; - } - tmp = strchr(requestedname + 1,'\\'); /* To get second \ if any */ + DEBUG(10, ("in this we have request for %s and share %s requested is %s\n", + requesteddomain, + requestedshare, + requestedname)); - if (tmp != NULL) { - /* There was a share */ - share = tmp+1; + if (requestedshare) { + DEBUG(10, ("Have a non DC domain referal\n")); dc_referral = false; } @@ -1464,7 +1461,7 @@ static NTSTATUS dodc_or_sysvol_referral(TALLOC_CTX *ctx, client_addr = tsocket_address_inet_addr_string(remote_address, context); NT_STATUS_HAVE_NO_MEMORY_AND_FREE(client_addr, context); } - + site_name = samdb_client_site_name(ldb, context, client_addr, NULL); status = get_dcs(context, ldb, site_name, need_fqdn, &set, 0); if (!NT_STATUS_IS_OK(status)) { DEBUG(3,("Unable to get list of DCs\n")); @@ -1508,8 +1505,13 @@ static NTSTATUS dodc_or_sysvol_referral(TALLOC_CTX *ctx, referral = talloc(context, struct dfs_referral_type); NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral, context); - referral_str = talloc_asprintf(referral, "\\%s", - requestedname); + if (requestedname[0] == '\\') { + referral_str = talloc_asprintf(referral, "%s", + requestedname); + } else { + referral_str = talloc_asprintf(referral, "\\%s", + requestedname); + } NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral_str, context); status = fill_domain_dfs_referraltype(referral, 3, @@ -1564,12 +1566,14 @@ static NTSTATUS dodc_or_sysvol_referral(TALLOC_CTX *ctx, NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral, context); referral_str = talloc_asprintf(referral, "\\%s\\%s", - set[i]->names[j], share); + set[i]->names[j], requestedshare); + DEBUG(8, ("Doing a dfs referral for %s with this value %s requested %s\n", set[i]->names[j], referral_str, requestedname)); NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral_str, context); status = fill_normal_dfs_referraltype(referral, dfsreq.max_referral_level, requestedname, referral_str, j==0); + if (!NT_STATUS_IS_OK(status)) { DEBUG(2, (__location__ ": Unable to fill a normal dfs referral object")); talloc_free(context); @@ -1616,7 +1620,7 @@ static NTSTATUS trans2_getdfsreferral(struct smbsrv_request *req, struct ldb_context *ldb; struct loadparm_context *lp_ctx; const char *realm, *nbname, *requestedname; - char *fqdn, *tmp; + char *fqdn, *share, *domain, *tmp; NTSTATUS status; lp_ctx = req->tcon->ntvfs->lp_ctx; @@ -1645,7 +1649,7 @@ static NTSTATUS trans2_getdfsreferral(struct smbsrv_request *req, return status; } - DEBUG(10, ("Requested DFS name: %s length: %u\n", + DEBUG(8, ("Requested DFS name: %s length: %u\n", dfsreq.servername, (unsigned int)strlen(dfsreq.servername))); /* @@ -1679,31 +1683,41 @@ static NTSTATUS trans2_getdfsreferral(struct smbsrv_request *req, } talloc_free(fqdn); - tmp = strchr(requestedname + 1,'\\'); /* To get second \ if any */ + domain = talloc_strdup(context, requestedname); + while(*domain && *domain == '\\') { + domain++; + } + tmp = strchr(domain,'\\'); /* To get second \ if any */ + share = NULL; + if (tmp) { + /* + * We are finishing properly the domain string + * and the share one will start after the \ + */ + tmp[0] = '\\'; + tmp++; + share = talloc_strdup(context, tmp); + } /* - * If we have no slash at the first position or (foo.bar.domain.net) - * a slash at the first position but no other slash (\foo.bar.domain.net) - * or a slash at the first position and another slash - * and netlogon or sysvol after the second slash - * (\foo.bar.domain.net\sysvol) then we will handle it because - * it's either a dc referral or a sysvol/netlogon referral + * Here we have filtered the thing the requested name don't contain our DNS name. + * So if the share == NULL or if share in ("sysvol", "netlogon") + * then we proceed. In the first case it will be a dc refereal in the second it will + * be just a sysvol/netlogon referral. */ - if (requestedname[0] != '\\' || - tmp == NULL || - strcasecmp(tmp+1, "sysvol") == 0 || - strcasecmp(tmp+1, "netlogon") == 0) { - status = dodc_or_sysvol_referral(op, dfsreq, requestedname, + if (share == NULL || + strcasecmp(share, "sysvol") == 0 || + strcasecmp(share, "netlogon") == 0) { + status = dodc_or_sysvol_referral(op, dfsreq, domain, share, requestedname, ldb, trans, req, lp_ctx); talloc_free(context); return status; } - if (requestedname[0] == '\\' && - tmp && - strchr(tmp+1, '\\') && - (strncasecmp(tmp+1, "sysvol", 6) == 0 || - strncasecmp(tmp+1, "netlogon", 8) == 0)) { + tmp = strchr(share, '\\'); + if (tmp && + (strncasecmp(share, "sysvol", 6) == 0 || + strncasecmp(share, "netlogon", 8) == 0)) { /* * We have more than two \ so it something like * \domain\sysvol\foobar diff --git a/source4/smb_server/smb_samba3.c b/source4/smb_server/smb_samba3.c index b0ed38cf6a..1a99be644a 100644 --- a/source4/smb_server/smb_samba3.c +++ b/source4/smb_server/smb_samba3.c @@ -135,16 +135,16 @@ static void samba3_smb_task_init(struct task_server *task) int i; struct interface *ifaces; - load_interfaces(task, lpcfg_interfaces(task->lp_ctx), &ifaces); + load_interface_list(task, task->lp_ctx, &ifaces); - num_interfaces = iface_count(ifaces); + num_interfaces = iface_list_count(ifaces); /* We have been given an interfaces line, and been told to only bind to those interfaces. Create a socket per interface and bind to only these. */ for(i = 0; i < num_interfaces; i++) { - const char *address = iface_n_ip(ifaces, i); + const char *address = iface_list_n_ip(ifaces, i); status = samba3_add_socket(task, task->event_ctx, task->lp_ctx, @@ -152,12 +152,21 @@ static void samba3_smb_task_init(struct task_server *task) if (!NT_STATUS_IS_OK(status)) goto failed; } } else { - /* Just bind to lpcfg_socket_address() (usually 0.0.0.0) */ - status = samba3_add_socket(task, - task->event_ctx, task->lp_ctx, - model_ops, - lpcfg_socket_address(task->lp_ctx)); - if (!NT_STATUS_IS_OK(status)) goto failed; + const char **wcard; + int i; + wcard = iface_list_wildcard(task, task->lp_ctx); + if (wcard == NULL) { + DEBUG(0,("No wildcard addresses available\n")); + goto failed; + } + for (i=0; wcard[i]; i++) { + status = samba3_add_socket(task, + task->event_ctx, task->lp_ctx, + model_ops, + wcard[i]); + if (!NT_STATUS_IS_OK(status)) goto failed; + } + talloc_free(wcard); } return; diff --git a/source4/smb_server/smb_server.c b/source4/smb_server/smb_server.c index d21e5fbdb0..d64a597d31 100644 --- a/source4/smb_server/smb_server.c +++ b/source4/smb_server/smb_server.c @@ -190,7 +190,7 @@ _PUBLIC_ NTSTATUS smbsrv_add_socket(TALLOC_CTX *mem_ctx, if (port == 0) continue; status = stream_setup_socket(mem_ctx, event_context, lp_ctx, model_ops, &smb_stream_ops, - "ipv4", address, &port, + "ip", address, &port, lpcfg_socket_options(lp_ctx), NULL); NT_STATUS_NOT_OK_RETURN(status); diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h index 6088853743..6fcd9787bb 100644 --- a/source4/smb_server/smb_server.h +++ b/source4/smb_server/smb_server.h @@ -22,6 +22,7 @@ #include "libcli/raw/request.h" #include "libcli/raw/interfaces.h" #include "lib/socket/socket.h" +#include "libds/common/roles.h" #include "../lib/util/dlinklist.h" #include "../librpc/gen_ndr/nbt.h" @@ -265,8 +266,6 @@ struct smbsrv_request { struct smb_request_buffer out; }; -enum security_types {SEC_SHARE,SEC_USER}; - /* smb server context structure. This should contain all the state * information associated with a SMB server connection */ @@ -300,7 +299,7 @@ struct smbsrv_connection { enum protocol_types protocol; /* authentication context for multi-part negprot */ - struct auth_context *auth_context; + struct auth4_context *auth_context; /* reference to the kerberos keytab, or machine trust account */ struct cli_credentials *server_credentials; diff --git a/source4/smbd/process_model.c b/source4/smbd/process_model.c index af12a7b8cb..3c4c03ebf2 100644 --- a/source4/smbd/process_model.c +++ b/source4/smbd/process_model.c @@ -111,7 +111,7 @@ _PUBLIC_ NTSTATUS process_model_init(struct loadparm_context *lp_ctx) } initialised = true; - shared_init = load_samba_modules(NULL, lp_ctx, "process_model"); + shared_init = load_samba_modules(NULL, "process_model"); run_init_functions(static_init); run_init_functions(shared_init); diff --git a/source4/smbd/server.c b/source4/smbd/server.c index 0f2f1bb1bb..1be3b2885f 100644 --- a/source4/smbd/server.c +++ b/source4/smbd/server.c @@ -178,13 +178,8 @@ _NORETURN_ static void max_runtime_handler(struct tevent_context *ev, struct timeval t, void *private_data) { const char *binary_name = (const char *)private_data; - struct timeval tv; - struct timezone tz; - if (gettimeofday(&tv, &tz) == 0) { - DEBUG(0,("%s: maximum runtime exceeded - terminating, current ts: %d\n", binary_name, (int)tv.tv_sec)); - } else { - DEBUG(0,("%s: maximum runtime exceeded - terminating\n", binary_name)); - } + DEBUG(0,("%s: maximum runtime exceeded - terminating, current ts: %llu\n", + binary_name, (unsigned long long) time(NULL))); exit(0); } @@ -221,11 +216,11 @@ static NTSTATUS samba_terminate(struct irpc_message *msg, static NTSTATUS setup_parent_messaging(struct tevent_context *event_ctx, struct loadparm_context *lp_ctx) { - struct messaging_context *msg; + struct imessaging_context *msg; NTSTATUS status; - msg = messaging_init(talloc_autofree_context(), - lpcfg_messaging_path(event_ctx, lp_ctx), + msg = imessaging_init(talloc_autofree_context(), + lpcfg_imessaging_path(event_ctx, lp_ctx), cluster_id(0, SAMBA_PARENT_TASKID), event_ctx); NT_STATUS_HAVE_NO_MEMORY(msg); @@ -388,10 +383,9 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[ pidfile_create(lpcfg_piddir(cmdline_lp_ctx), binary_name); - /* Do *not* remove this, until you have removed - * passdb/secrets.c, and proved that Samba still builds... */ - /* Setup the SECRETS subsystem */ - if (secrets_init(talloc_autofree_context(), cmdline_lp_ctx) == NULL) { + /* Set up a database to hold a random seed, in case we don't + * have /dev/urandom */ + if (!randseed_init(talloc_autofree_context(), cmdline_lp_ctx)) { return 1; } @@ -402,9 +396,9 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[ } } - gensec_init(cmdline_lp_ctx); /* FIXME: */ + gensec_init(); /* FIXME: */ - ntptr_init(cmdline_lp_ctx); /* FIXME: maybe run this in the initialization function + ntptr_init(); /* FIXME: maybe run this in the initialization function of the spoolss RPC server instead? */ ntvfs_init(cmdline_lp_ctx); /* FIXME: maybe run this in the initialization functions @@ -412,7 +406,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[ process_model_init(cmdline_lp_ctx); - shared_init = load_samba_modules(NULL, cmdline_lp_ctx, "service"); + shared_init = load_samba_modules(NULL, "service"); run_init_functions(static_init); run_init_functions(shared_init); @@ -445,14 +439,8 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[ discard_const(binary_name)); if (max_runtime) { - struct timeval tv; - struct timezone tz; - - if (gettimeofday(&tv, &tz) == 0) { - DEBUG(0,("Called with maxruntime %d - current ts %d\n", max_runtime, (int)tv.tv_sec)); - } else { - DEBUG(0,("Called with maxruntime %d\n", max_runtime)); - } + DEBUG(0,("Called with maxruntime %d - current ts %llu\n", + max_runtime, (unsigned long long) time(NULL))); tevent_add_timer(event_ctx, event_ctx, timeval_current_ofs(max_runtime, 0), max_runtime_handler, diff --git a/source4/smbd/service_named_pipe.c b/source4/smbd/service_named_pipe.c index 086a037b69..b000083eec 100644 --- a/source4/smbd/service_named_pipe.c +++ b/source4/smbd/service_named_pipe.c @@ -200,14 +200,21 @@ NTSTATUS tstream_setup_named_pipe(TALLOC_CTX *mem_ctx, goto fail; } + if (!directory_create_or_exist(lpcfg_ncalrpc_dir(lp_ctx), geteuid(), 0755)) { + status = map_nt_error_from_unix_common(errno); + DEBUG(0,(__location__ ": Failed to create ncalrpc pipe directory '%s' - %s\n", + lpcfg_ncalrpc_dir(lp_ctx), nt_errstr(status))); + goto fail; + } + dirname = talloc_asprintf(pipe_sock, "%s/np", lpcfg_ncalrpc_dir(lp_ctx)); if (dirname == NULL) { goto fail; } if (!directory_create_or_exist(dirname, geteuid(), 0700)) { - status = map_nt_error_from_unix(errno); - DEBUG(0,(__location__ ": Failed to create stream pipe directory %s - %s\n", + status = map_nt_error_from_unix_common(errno); + DEBUG(0,(__location__ ": Failed to create stream pipe directory '%s' - %s\n", dirname, nt_errstr(status))); goto fail; } diff --git a/source4/smbd/service_stream.c b/source4/smbd/service_stream.c index 916393253b..6e65122063 100644 --- a/source4/smbd/service_stream.c +++ b/source4/smbd/service_stream.c @@ -27,6 +27,7 @@ #include "cluster/cluster.h" #include "param/param.h" #include "../lib/tsocket/tsocket.h" +#include "lib/util/util_net.h" /* the range of ports to try for dcerpc over tcp endpoints */ #define SERVER_TCP_LOW_PORT 1024 @@ -122,7 +123,7 @@ NTSTATUS stream_new_connection_merge(struct tevent_context *ev, struct loadparm_context *lp_ctx, const struct model_ops *model_ops, const struct stream_server_ops *stream_ops, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, void *private_data, struct stream_connection **_srv_conn) { @@ -186,11 +187,11 @@ static void stream_new_connection(struct tevent_context *ev, } /* setup to receive internal messages on this connection */ - srv_conn->msg_ctx = messaging_init(srv_conn, - lpcfg_messaging_path(srv_conn, lp_ctx), + srv_conn->msg_ctx = imessaging_init(srv_conn, + lpcfg_imessaging_path(srv_conn, lp_ctx), srv_conn->server_id, ev); if (!srv_conn->msg_ctx) { - stream_terminate_connection(srv_conn, "messaging_init() failed"); + stream_terminate_connection(srv_conn, "imessaging_init() failed"); return; } @@ -216,7 +217,7 @@ static void stream_new_connection(struct tevent_context *ev, stream_socket->ops->name, tsocket_address_string(srv_conn->remote_address, tmp_ctx), tsocket_address_string(srv_conn->local_address, tmp_ctx), - cluster_id_string(tmp_ctx, server_id)); + server_id_str(tmp_ctx, &server_id)); if (title) { stream_connection_set_title(srv_conn, title); } @@ -271,12 +272,34 @@ NTSTATUS stream_setup_socket(TALLOC_CTX *mem_ctx, struct socket_address *socket_address; struct tevent_fd *fde; int i; + struct sockaddr_storage ss; stream_socket = talloc_zero(mem_ctx, struct stream_socket); NT_STATUS_HAVE_NO_MEMORY(stream_socket); - status = socket_create(family, SOCKET_TYPE_STREAM, &stream_socket->sock, 0); - NT_STATUS_NOT_OK_RETURN(status); + if (strcmp(family, "ip") == 0) { + /* we will get the real family from the address itself */ + if (!interpret_string_addr(&ss, sock_addr, 0)) { + talloc_free(stream_socket); + return NT_STATUS_INVALID_ADDRESS; + } + + socket_address = socket_address_from_sockaddr_storage(stream_socket, &ss, port?*port:0); + NT_STATUS_HAVE_NO_MEMORY_AND_FREE(socket_address, stream_socket); + + status = socket_create(socket_address->family, SOCKET_TYPE_STREAM, &stream_socket->sock, 0); + NT_STATUS_NOT_OK_RETURN(status); + } else { + status = socket_create(family, SOCKET_TYPE_STREAM, &stream_socket->sock, 0); + NT_STATUS_NOT_OK_RETURN(status); + + /* this is for non-IP sockets, eg. unix domain sockets */ + socket_address = socket_address_from_strings(stream_socket, + stream_socket->sock->backend_name, + sock_addr, port?*port:0); + NT_STATUS_HAVE_NO_MEMORY(socket_address); + } + talloc_steal(stream_socket, stream_socket->sock); @@ -297,34 +320,19 @@ NTSTATUS stream_setup_socket(TALLOC_CTX *mem_ctx, /* Some sockets don't have a port, or are just described from * the string. We are indicating this by having port == NULL */ if (!port) { - socket_address = socket_address_from_strings(stream_socket, - stream_socket->sock->backend_name, - sock_addr, 0); - NT_STATUS_HAVE_NO_MEMORY(socket_address); status = socket_listen(stream_socket->sock, socket_address, SERVER_LISTEN_BACKLOG, 0); - talloc_free(socket_address); - } else if (*port == 0) { for (i=SERVER_TCP_LOW_PORT;i<= SERVER_TCP_HIGH_PORT;i++) { - socket_address = socket_address_from_strings(stream_socket, - stream_socket->sock->backend_name, - sock_addr, i); - NT_STATUS_HAVE_NO_MEMORY(socket_address); + socket_address->port = i; status = socket_listen(stream_socket->sock, socket_address, SERVER_LISTEN_BACKLOG, 0); - talloc_free(socket_address); if (NT_STATUS_IS_OK(status)) { *port = i; break; } } } else { - socket_address = socket_address_from_strings(stream_socket, - stream_socket->sock->backend_name, - sock_addr, *port); - NT_STATUS_HAVE_NO_MEMORY(socket_address); status = socket_listen(stream_socket->sock, socket_address, SERVER_LISTEN_BACKLOG, 0); - talloc_free(socket_address); } if (!NT_STATUS_IS_OK(status)) { @@ -362,6 +370,7 @@ NTSTATUS stream_setup_socket(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } + /* setup a connection title */ diff --git a/source4/smbd/service_stream.h b/source4/smbd/service_stream.h index 02ade716d2..e098a690f1 100644 --- a/source4/smbd/service_stream.h +++ b/source4/smbd/service_stream.h @@ -23,7 +23,7 @@ #ifndef __SERVICE_STREAM_H__ #define __SERVICE_STREAM_H__ -#include "librpc/gen_ndr/server_id4.h" +#include "librpc/gen_ndr/server_id.h" /* modules can use the following to determine if the interface has changed * please increment the version number after each interface change @@ -47,7 +47,7 @@ struct stream_connection { } event; struct socket_context *socket; - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; struct loadparm_context *lp_ctx; struct tstream_context *tstream; diff --git a/source4/smbd/service_task.c b/source4/smbd/service_task.c index 1eb8403e3b..32c44cf660 100644 --- a/source4/smbd/service_task.c +++ b/source4/smbd/service_task.c @@ -78,12 +78,12 @@ static void task_server_callback(struct tevent_context *event_ctx, task->server_id = server_id; task->lp_ctx = lp_ctx; - task->msg_ctx = messaging_init(task, - lpcfg_messaging_path(task, task->lp_ctx), + task->msg_ctx = imessaging_init(task, + lpcfg_imessaging_path(task, task->lp_ctx), task->server_id, task->event_ctx); if (!task->msg_ctx) { - task_server_terminate(task, "messaging_init() failed", true); + task_server_terminate(task, "imessaging_init() failed", true); return; } diff --git a/source4/smbd/service_task.h b/source4/smbd/service_task.h index b8954073e5..ded4590daf 100644 --- a/source4/smbd/service_task.h +++ b/source4/smbd/service_task.h @@ -22,12 +22,12 @@ #ifndef __SERVICE_TASK_H__ #define __SERVICE_TASK_H__ -#include "librpc/gen_ndr/server_id4.h" +#include "librpc/gen_ndr/server_id.h" struct task_server { struct tevent_context *event_ctx; const struct model_ops *model_ops; - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; struct loadparm_context *lp_ctx; struct server_id server_id; void *private_data; diff --git a/source4/torture/basic/attr.c b/source4/torture/basic/attr.c index 09d1ae2968..2f0248e20f 100644 --- a/source4/torture/basic/attr.c +++ b/source4/torture/basic/attr.c @@ -374,7 +374,7 @@ error_exit_file: [0x%x], got attr 0x%x, should be 0x%x\n", open_attrs_table[j], (uint16_t)attr, - open_attrs_table[j]|FILE_ATTRIBUTE_DIRECTORY); + (unsigned int)(open_attrs_table[j]|FILE_ATTRIBUTE_DIRECTORY)); CHECK_MAX_FAILURES(error_exit_dir); } diff --git a/source4/torture/basic/mangle_test.c b/source4/torture/basic/mangle_test.c index 0b7d696e67..d549a0c1eb 100644 --- a/source4/torture/basic/mangle_test.c +++ b/source4/torture/basic/mangle_test.c @@ -20,7 +20,7 @@ #include "includes.h" #include "system/filesys.h" #include "system/dir.h" -#include <tdb.h> +#include "../lib/tdb_compat/tdb_compat.h" #include "../lib/util/util_tdb.h" #include "libcli/libcli.h" #include "torture/util.h" @@ -167,7 +167,7 @@ bool torture_mangle(struct torture_context *torture, int i; /* we will use an internal tdb to store the names we have used */ - tdb = tdb_open(NULL, 100000, TDB_INTERNAL, 0, 0); + tdb = tdb_open_compat(NULL, 100000, TDB_INTERNAL, 0, 0, NULL, NULL); if (!tdb) { printf("ERROR: Failed to open tdb\n"); return false; diff --git a/source4/torture/dfs/domaindfs.c b/source4/torture/dfs/domaindfs.c index 467e104e25..89e9cc1426 100644 --- a/source4/torture/dfs/domaindfs.c +++ b/source4/torture/dfs/domaindfs.c @@ -55,20 +55,24 @@ static bool test_getdomainreferral(struct torture_context *tctx, talloc_asprintf(tctx, "Not expected version for referral entry 0 got %d expected 3", resp.referral_entries[0].version)); - torture_assert_int_equal(tctx, resp.referral_entries[0].referral.v3.data.server_type, + torture_assert_int_equal(tctx, resp.referral_entries[0].referral.v3.server_type, DFS_SERVER_NON_ROOT, talloc_asprintf(tctx, "Wrong server type, expected non root server and got %d", - resp.referral_entries[0].referral.v3.data.server_type)); - torture_assert_int_equal(tctx, resp.referral_entries[0].referral.v3.data.entry_flags, + resp.referral_entries[0].referral.v3.server_type)); + torture_assert_int_equal(tctx, resp.referral_entries[0].referral.v3.entry_flags, DFS_FLAG_REFERRAL_DOMAIN_RESP, talloc_asprintf(tctx, "Wrong entry flag expected to have a domain response and got %d", - resp.referral_entries[0].referral.v3.data.entry_flags)); + resp.referral_entries[0].referral.v3.entry_flags)); torture_assert_int_equal(tctx, strlen( - resp.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0, + resp.referral_entries[0].referral.v3.referrals.r2.special_name) > 0, 1, "Length of domain is 0 or less"); + torture_assert_int_equal(tctx, + resp.referral_entries[0].referral.v3.referrals.r2.special_name[0] == '\\', + 1, + "domain didn't start with a \\"); return true; } @@ -88,9 +92,9 @@ static bool test_getdcreferral(struct torture_context *tctx, dfs_cli_do_call(cli->tree, &r), "Get Domain referral failed"); - str = resp.referral_entries[0].referral.v3.data.referrals.r2.special_name; + str = resp.referral_entries[0].referral.v3.referrals.r2.special_name; if( strchr(str, '.') == NULL ) { - str = resp.referral_entries[1].referral.v3.data.referrals.r2.special_name; + str = resp.referral_entries[1].referral.v3.referrals.r2.special_name; } r2.in.req.max_referral_level = 3; @@ -112,34 +116,38 @@ static bool test_getdcreferral(struct torture_context *tctx, talloc_asprintf(tctx, "Not expected version for referral entry 0 got %d expected 3", resp2.referral_entries[0].version)); - torture_assert_int_equal(tctx, resp2.referral_entries[0].referral.v3.data.server_type, + torture_assert_int_equal(tctx, resp2.referral_entries[0].referral.v3.server_type, DFS_SERVER_NON_ROOT, talloc_asprintf(tctx, "Wrong server type, expected non root server and got %d", - resp2.referral_entries[0].referral.v3.data.server_type)); - torture_assert_int_equal(tctx, resp2.referral_entries[0].referral.v3.data.entry_flags, + resp2.referral_entries[0].referral.v3.server_type)); + torture_assert_int_equal(tctx, resp2.referral_entries[0].referral.v3.entry_flags, DFS_FLAG_REFERRAL_DOMAIN_RESP, talloc_asprintf(tctx, "Wrong entry flag expected to have a domain response and got %d", - resp2.referral_entries[0].referral.v3.data.entry_flags)); + resp2.referral_entries[0].referral.v3.entry_flags)); torture_assert_int_equal(tctx, strlen( - resp2.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0, + resp2.referral_entries[0].referral.v3.referrals.r2.special_name) > 0, 1, "Length of domain is 0 or less"); torture_assert_int_equal(tctx, strlen( - resp2.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0]) > 0, + resp2.referral_entries[0].referral.v3.referrals.r2.expanded_names[0]) > 0, 1, "Length of first dc is less than 0"); - str = strchr(resp2.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0], '.'); - str2 = resp2.referral_entries[0].referral.v3.data.referrals.r2.special_name; + str = strchr(resp2.referral_entries[0].referral.v3.referrals.r2.expanded_names[0], '.'); + str2 = resp2.referral_entries[0].referral.v3.referrals.r2.special_name; if (str2[0] == '\\') { str2++; } torture_assert_int_equal(tctx, strlen(str) >0, 1 ,"Length of domain too short"); str++; torture_assert_int_equal(tctx, strcmp(str,str2), 0, - talloc_asprintf(tctx, "Pb domain of the dc is not"\ - "the same as the requested: domain = %s got =%s",str2 ,str)); + talloc_asprintf(tctx, "Pb domain of the dc is not "\ + "the same as the requested: domain was = %s got =%s",str2 ,str)); + torture_assert_int_equal(tctx, + resp.referral_entries[0].referral.v3.referrals.r2.special_name[0] == '\\', + 1, + "dc name didn't start with a \\"); r3.in.req.max_referral_level = 3; /* @@ -164,22 +172,22 @@ static bool test_getdcreferral(struct torture_context *tctx, talloc_asprintf(tctx, "Not expected version for referral entry 0 got %d expected 3", resp3.referral_entries[0].version)); - torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.server_type, + torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.server_type, DFS_SERVER_NON_ROOT, talloc_asprintf(tctx, "Wrong server type, expected non root server and got %d", - resp3.referral_entries[0].referral.v3.data.server_type)); - torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.entry_flags, + resp3.referral_entries[0].referral.v3.server_type)); + torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.entry_flags, DFS_FLAG_REFERRAL_DOMAIN_RESP, talloc_asprintf(tctx, "Wrong entry flag expected to have a domain response and got %d", - resp3.referral_entries[0].referral.v3.data.entry_flags)); + resp3.referral_entries[0].referral.v3.entry_flags)); torture_assert_int_equal(tctx, strlen( - resp3.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0, + resp3.referral_entries[0].referral.v3.referrals.r2.special_name) > 0, 1, "Length of domain is 0 or less"); torture_assert_int_equal(tctx, strlen( - resp3.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0]) > 0, + resp3.referral_entries[0].referral.v3.referrals.r2.expanded_names[0]) > 0, 1, "Length of first dc is less than 0"); return true; @@ -202,9 +210,9 @@ static bool test_getdcreferral_netbios(struct torture_context *tctx, r2.in.req.max_referral_level = 3; - str = resp.referral_entries[0].referral.v3.data.referrals.r2.special_name; + str = resp.referral_entries[0].referral.v3.referrals.r2.special_name; if( strchr(str, '.') != NULL ) { - str = resp.referral_entries[1].referral.v3.data.referrals.r2.special_name; + str = resp.referral_entries[1].referral.v3.referrals.r2.special_name; } r2.in.req.servername = str; @@ -224,26 +232,26 @@ static bool test_getdcreferral_netbios(struct torture_context *tctx, talloc_asprintf(tctx, "Not expected version for referral entry 0 got %d expected 3", resp2.referral_entries[0].version)); - torture_assert_int_equal(tctx, resp2.referral_entries[0].referral.v3.data.server_type, + torture_assert_int_equal(tctx, resp2.referral_entries[0].referral.v3.server_type, DFS_SERVER_NON_ROOT, talloc_asprintf(tctx, "Wrong server type, expected non root server and got %d", - resp2.referral_entries[0].referral.v3.data.server_type)); - torture_assert_int_equal(tctx, resp2.referral_entries[0].referral.v3.data.entry_flags, + resp2.referral_entries[0].referral.v3.server_type)); + torture_assert_int_equal(tctx, resp2.referral_entries[0].referral.v3.entry_flags, DFS_FLAG_REFERRAL_DOMAIN_RESP, talloc_asprintf(tctx, "Wrong entry flag expected to have a domain response and got %d", - resp2.referral_entries[0].referral.v3.data.entry_flags)); + resp2.referral_entries[0].referral.v3.entry_flags)); torture_assert_int_equal(tctx, strlen( - resp2.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0, + resp2.referral_entries[0].referral.v3.referrals.r2.special_name) > 0, 1, "Length of domain is 0 or less"); torture_assert_int_equal(tctx, strlen( - resp2.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0]) > 0, + resp2.referral_entries[0].referral.v3.referrals.r2.expanded_names[0]) > 0, 1, "Length of first dc is less than 0"); torture_assert(tctx, strchr( - resp2.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0],'.') == NULL, + resp2.referral_entries[0].referral.v3.referrals.r2.expanded_names[0],'.') == NULL, "referral contains dots it's not a netbios name"); r3.in.req.max_referral_level = 3; @@ -269,26 +277,26 @@ static bool test_getdcreferral_netbios(struct torture_context *tctx, talloc_asprintf(tctx, "Not expected version for referral entry 0 got %d expected 3", resp3.referral_entries[0].version)); - torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.server_type, + torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.server_type, DFS_SERVER_NON_ROOT, talloc_asprintf(tctx, "Wrong server type, expected non root server and got %d", - resp3.referral_entries[0].referral.v3.data.server_type)); - torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.entry_flags, + resp3.referral_entries[0].referral.v3.server_type)); + torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.entry_flags, DFS_FLAG_REFERRAL_DOMAIN_RESP, talloc_asprintf(tctx, "Wrong entry flag expected to have a domain response and got %d", - resp3.referral_entries[0].referral.v3.data.entry_flags)); + resp3.referral_entries[0].referral.v3.entry_flags)); torture_assert_int_equal(tctx, strlen( - resp3.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0, + resp3.referral_entries[0].referral.v3.referrals.r2.special_name) > 0, 1, "Length of domain is 0 or less"); torture_assert_int_equal(tctx, strlen( - resp3.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0]) > 0, + resp3.referral_entries[0].referral.v3.referrals.r2.expanded_names[0]) > 0, 1, "Length of first dc is less than 0"); torture_assert(tctx, strchr( - resp3.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0],'.') == NULL, + resp3.referral_entries[0].referral.v3.referrals.r2.expanded_names[0],'.') == NULL, "referral contains dots it's not a netbios name"); return true; } @@ -299,6 +307,9 @@ static bool test_getsysvolreferral(struct torture_context *tctx, const char* str; struct dfs_GetDFSReferral r, r2, r3; struct dfs_referral_resp resp, resp2, resp3; + uint8_t zeros[16]; + + memset(zeros, 0, sizeof(zeros)); r.in.req.max_referral_level = 3; r.in.req.servername = ""; @@ -308,9 +319,9 @@ static bool test_getsysvolreferral(struct torture_context *tctx, dfs_cli_do_call(cli->tree, &r), "Get Domain referral failed"); - str = resp.referral_entries[0].referral.v3.data.referrals.r2.special_name; + str = resp.referral_entries[0].referral.v3.referrals.r2.special_name; if( strchr(str, '.') == NULL ) { - str = resp.referral_entries[1].referral.v3.data.referrals.r2.special_name; + str = resp.referral_entries[1].referral.v3.referrals.r2.special_name; } r2.in.req.max_referral_level = 3; @@ -339,25 +350,41 @@ static bool test_getsysvolreferral(struct torture_context *tctx, talloc_asprintf(tctx, "Not expected version for referral entry 0 got %d expected 3", resp3.referral_entries[0].version)); - torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.server_type, + torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.server_type, DFS_SERVER_NON_ROOT, talloc_asprintf(tctx, "Wrong server type, expected non root server and got %d", - resp3.referral_entries[0].referral.v3.data.server_type)); - torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.entry_flags, + resp3.referral_entries[0].referral.v3.server_type)); + torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.entry_flags, 0, talloc_asprintf(tctx, "Wrong entry flag expected to have a non domain response and got %d", - resp3.referral_entries[0].referral.v3.data.entry_flags)); + resp3.referral_entries[0].referral.v3.entry_flags)); torture_assert_int_equal(tctx, strlen( - resp3.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0, + resp3.referral_entries[0].referral.v3.referrals.r1.DFS_path) > 0, 1, "Length of domain is 0 or less"); + torture_assert_int_equal(tctx, strstr(resp3.referral_entries[0].referral.v3.referrals.r1.DFS_path, + str+1) != NULL, 1, + talloc_asprintf(tctx, + "Wrong DFS_path %s unable to find substring %s in it", + resp3.referral_entries[0].referral.v3.referrals.r1.DFS_path, + str+1)); torture_assert_int_equal(tctx, strlen( - resp2.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0]) > 0, + resp3.referral_entries[0].referral.v3.referrals.r1.netw_address) > 0, 1, "Length of first referral is less than 0"); - + torture_assert_int_equal(tctx, strstr(resp3.referral_entries[0].referral.v3.referrals.r1.netw_address, + str+1) != NULL, 1, + talloc_asprintf(tctx, + "Wrong DFS_path %s unable to find substring %s in it", + resp3.referral_entries[0].referral.v3.referrals.r1.netw_address, + str+1)); +#if 0 + /* + * Due to strange behavior with XP and level 4 + * we are obliged to degrade to level 3 ... + */ r3.in.req.max_referral_level = 4; torture_assert_ntstatus_ok(tctx, @@ -368,6 +395,20 @@ static bool test_getsysvolreferral(struct torture_context *tctx, talloc_asprintf(tctx, "Not expected version for referral entry 0 got %d expected 4", resp3.referral_entries[0].version)); + torture_assert_int_equal(tctx, memcmp(resp3.referral_entries[0].referral.v3.service_site_guid.value, zeros, 16), 0, + talloc_asprintf(tctx, + "Service_site_guid is not NULL as expected")); +#endif + r3.in.req.max_referral_level = 4; + + torture_assert_ntstatus_ok(tctx, + dfs_cli_do_call(cli->tree, &r3), + "Get sysvol Domain referral failed"); + + torture_assert_int_equal(tctx, resp3.referral_entries[0].version, 3, + talloc_asprintf(tctx, + "Not expected version for referral entry 0 got %d expected 3 in degraded mode", + resp3.referral_entries[0].version)); #if 0 /* * We do not support fallback indication for the moment @@ -375,12 +416,12 @@ static bool test_getsysvolreferral(struct torture_context *tctx, torture_assert_int_equal(tctx, resp3.header_flags, DFS_HEADER_FLAG_STORAGE_SVR | DFS_HEADER_FLAG_TARGET_BCK, "Header flag different it's not a referral for a storage with fallback"); -#endif torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v4.entry_flags, DFS_FLAG_REFERRAL_FIRST_TARGET_SET, talloc_asprintf(tctx, "Wrong entry flag expected to have a non domain response and got %d", resp3.referral_entries[0].referral.v4.entry_flags)); +#endif return true; } @@ -426,14 +467,14 @@ static bool test_getsysvolplusreferral(struct torture_context *tctx, "Get Domain referral failed"); r2.in.req.max_referral_level = 3; - r2.in.req.servername = resp.referral_entries[0].referral.v3.data.referrals.r2.special_name; + r2.in.req.servername = resp.referral_entries[0].referral.v3.referrals.r2.special_name; r2.out.resp = &resp2; torture_assert_ntstatus_ok(tctx, dfs_cli_do_call(cli->tree, &r2), "Get DC Domain referral failed"); - str = resp2.referral_entries[0].referral.v3.data.referrals.r2.special_name; + str = resp2.referral_entries[0].referral.v3.referrals.r2.special_name; r3.in.req.max_referral_level = 3; r3.in.req.servername = talloc_asprintf(tctx, "%s\\sysvol\\foo", str); r3.out.resp = &resp3; diff --git a/source4/torture/drs/python/getnc_exop.py b/source4/torture/drs/python/getnc_exop.py new file mode 100644 index 0000000000..904c013333 --- /dev/null +++ b/source4/torture/drs/python/getnc_exop.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Tests various schema replication scenarios +# +# Copyright (C) Kamen Mazdrashki <kamenim@samba.org> 2011 +# +# 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 <http://www.gnu.org/licenses/>. +# + +# +# Usage: +# export DC1=dc1_dns_name +# export DC2=dc2_dns_name +# export SUBUNITRUN=$samba4srcdir/scripting/bin/subunitrun +# PYTHONPATH="$PYTHONPATH:$samba4srcdir/torture/drs/python" $SUBUNITRUN getnc_exop -U"$DOMAIN/$DC_USERNAME"%"$DC_PASSWORD" +# + +import drs_base +import samba.tests + +from ldb import SCOPE_BASE + +from samba.dcerpc import drsuapi, misc, drsblobs +from samba.drs_utils import drs_DsBind + + +class DrsReplicaSyncTestCase(drs_base.DrsBaseTestCase): + """Intended as a semi-black box test case for DsGetNCChanges + implementation for extended operations. It should be testing + how DsGetNCChanges handles different input params (mostly invalid). + Final goal is to make DsGetNCChanges as binary compatible to + Windows implementation as possible""" + + def setUp(self): + super(DrsReplicaSyncTestCase, self).setUp() + + def tearDown(self): + super(DrsReplicaSyncTestCase, self).tearDown() + + def _exop_req8(self, dest_dsa, invocation_id, nc_dn_str, exop): + req8 = drsuapi.DsGetNCChangesRequest8() + + req8.destination_dsa_guid = misc.GUID(dest_dsa) + req8.source_dsa_invocation_id = misc.GUID(invocation_id) + req8.naming_context = drsuapi.DsReplicaObjectIdentifier() + req8.naming_context.dn = unicode(nc_dn_str) + req8.highwatermark = drsuapi.DsReplicaHighWaterMark() + req8.highwatermark.tmp_highest_usn = 0 + req8.highwatermark.reserved_usn = 0 + req8.highwatermark.highest_usn = 0 + req8.uptodateness_vector = None + req8.replica_flags = 0 + req8.max_object_count = 0 + req8.max_ndr_size = 402116 + req8.extended_op = exop + req8.fsmo_info = 0 + req8.partial_attribute_set = None + req8.partial_attribute_set_ex = None + req8.mapping_ctr.num_mappings = 0 + req8.mapping_ctr.mappings = None + + return req8 + + def _ds_bind(self, server_name): + binding_str = "ncacn_ip_tcp:%s[print,seal]" % server_name + + drs = drsuapi.drsuapi(binding_str, self.get_loadparm(), self.get_credentials()) + (drs_handle, supported_extensions) = drs_DsBind(drs) + return (drs, drs_handle) + + def _determine_fSMORoleOwner(self, fsmo_obj_dn): + """Returns (owner, not_owner) pair where: + owner: dns name for FSMO owner + not_owner: dns name for DC not owning the FSMO""" + # collect info to return later + fsmo_info_1 = {"dns_name": self.dnsname_dc1, + "invocation_id": self.ldb_dc1.get_invocation_id(), + "ntds_guid": self.ldb_dc1.get_ntds_GUID()} + fsmo_info_2 = {"dns_name": self.dnsname_dc2, + "invocation_id": self.ldb_dc2.get_invocation_id(), + "ntds_guid": self.ldb_dc2.get_ntds_GUID()} + # determine the owner dc + res = self.ldb_dc1.search(fsmo_obj_dn, + scope=SCOPE_BASE, attrs=["fSMORoleOwner"]) + assert len(res) == 1, "Only one fSMORoleOwner value expected for %s!"%fsmo_obj_dn + fsmo_owner = res[0]["fSMORoleOwner"][0] + if fsmo_owner == self.info_dc1["dsServiceName"][0]: + return (fsmo_info_1, fsmo_info_2) + return (fsmo_info_2, fsmo_info_1) + + def _check_exop_failed(self, ctr6, expected_failure): + self.assertEqual(ctr6.extended_ret, expected_failure) + #self.assertEqual(ctr6.object_count, 0) + #self.assertEqual(ctr6.first_object, None) + self.assertEqual(ctr6.more_data, False) + self.assertEqual(ctr6.nc_object_count, 0) + self.assertEqual(ctr6.nc_linked_attributes_count, 0) + self.assertEqual(ctr6.linked_attributes_count, 0) + self.assertEqual(ctr6.linked_attributes, None) + self.assertEqual(ctr6.drs_error[0], 0) + + def test_FSMONotOwner(self): + """Test role transfer with against DC not owner of the role""" + fsmo_dn = self.ldb_dc1.get_schema_basedn() + (fsmo_owner, fsmo_not_owner) = self._determine_fSMORoleOwner(fsmo_dn) + + req8 = self._exop_req8(dest_dsa=fsmo_owner["ntds_guid"], + invocation_id=fsmo_not_owner["invocation_id"], + nc_dn_str=fsmo_dn, + exop=drsuapi.DRSUAPI_EXOP_FSMO_REQ_ROLE) + + (drs, drs_handle) = self._ds_bind(fsmo_not_owner["dns_name"]) + (level, ctr) = drs.DsGetNCChanges(drs_handle, 8, req8) + self.assertEqual(level, 6, "Expected level 6 response!") + self._check_exop_failed(ctr, drsuapi.DRSUAPI_EXOP_ERR_FSMO_NOT_OWNER) + self.assertEqual(ctr.source_dsa_guid, misc.GUID(fsmo_not_owner["ntds_guid"])) + self.assertEqual(ctr.source_dsa_invocation_id, misc.GUID(fsmo_not_owner["invocation_id"])) + + def test_InvalidDestDSA(self): + """Test role transfer with invalid destination DSA guid""" + fsmo_dn = self.ldb_dc1.get_schema_basedn() + (fsmo_owner, fsmo_not_owner) = self._determine_fSMORoleOwner(fsmo_dn) + + req8 = self._exop_req8(dest_dsa="9c637462-5b8c-4467-aef2-bdb1f57bc4ef", + invocation_id=fsmo_owner["invocation_id"], + nc_dn_str=fsmo_dn, + exop=drsuapi.DRSUAPI_EXOP_FSMO_REQ_ROLE) + + (drs, drs_handle) = self._ds_bind(fsmo_owner["dns_name"]) + (level, ctr) = drs.DsGetNCChanges(drs_handle, 8, req8) + self.assertEqual(level, 6, "Expected level 6 response!") + self._check_exop_failed(ctr, drsuapi.DRSUAPI_EXOP_ERR_UNKNOWN_CALLER) + self.assertEqual(ctr.source_dsa_guid, misc.GUID(fsmo_owner["ntds_guid"])) + self.assertEqual(ctr.source_dsa_invocation_id, misc.GUID(fsmo_owner["invocation_id"])) diff --git a/source4/torture/drs/rpc/dssync.c b/source4/torture/drs/rpc/dssync.c index 2ec3ded287..8279e736b1 100644 --- a/source4/torture/drs/rpc/dssync.c +++ b/source4/torture/drs/rpc/dssync.c @@ -105,8 +105,9 @@ static struct DsSyncTest *test_create_context(struct torture_context *tctx) make_nbt_name_server(&name, ctx->drsuapi_binding->host); /* do an initial name resolution to find its IP */ - status = resolve_name(lpcfg_resolve_context(tctx->lp_ctx), &name, tctx, - &ctx->dest_address, tctx->ev); + status = resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx), + 0, 0, &name, tctx, + &ctx->dest_address, tctx->ev); if (!NT_STATUS_IS_OK(status)) { printf("Failed to resolve %s - %s\n", name.name, nt_errstr(status)); @@ -270,10 +271,7 @@ static bool test_LDAPBind(struct torture_context *tctx, struct DsSyncTest *ctx, return NULL; } - ldb_set_modules_dir(ldb, - talloc_asprintf(ldb, - "%s/ldb", - lpcfg_modulesdir(tctx->lp_ctx))); + ldb_set_modules_dir(ldb, modules_path(ldb, "ldb")); if (ldb_set_opaque(ldb, "credentials", credentials)) { talloc_free(ldb); diff --git a/source4/torture/drs/rpc/msds_intid.c b/source4/torture/drs/rpc/msds_intid.c index 53f4992ba2..14c6454abe 100644 --- a/source4/torture/drs/rpc/msds_intid.c +++ b/source4/torture/drs/rpc/msds_intid.c @@ -283,10 +283,7 @@ static bool _test_LDAPBind(struct torture_context *tctx, return NULL; } - ldb_set_modules_dir(ldb, - talloc_asprintf(ldb, - "%s/ldb", - lpcfg_modulesdir(tctx->lp_ctx))); + ldb_set_modules_dir(ldb, modules_path(ldb, "ldb")); if (ldb_set_opaque(ldb, "credentials", credentials) != LDB_SUCCESS) { talloc_free(ldb); diff --git a/source4/torture/gentest.c b/source4/torture/gentest.c index 6f69460dc8..9b6e7fc0fd 100644 --- a/source4/torture/gentest.c +++ b/source4/torture/gentest.c @@ -2318,6 +2318,18 @@ static void gen_setfileinfo(int instance, union smb_setfileinfo *info) case RAW_SFILEINFO_UNIX_INFO2: case RAW_SFILEINFO_UNIX_LINK: case RAW_SFILEINFO_UNIX_HLINK: + case RAW_SFILEINFO_LINK_INFORMATION: + case RAW_SFILEINFO_PIPE_INFORMATION: + case RAW_SFILEINFO_VALID_DATA_INFORMATION: + case RAW_SFILEINFO_SHORT_NAME_INFORMATION: + case RAW_SFILEINFO_1027: + case RAW_SFILEINFO_1030: + case RAW_SFILEINFO_1031: + case RAW_SFILEINFO_1036: + case RAW_SFILEINFO_1041: + case RAW_SFILEINFO_1042: + case RAW_SFILEINFO_1043: + case RAW_SFILEINFO_1044: /* Untested */ break; } @@ -3247,7 +3259,7 @@ static bool split_unc_name(const char *unc, char **server, char **share) ev = s4_event_context_init(talloc_autofree_context()); - gensec_init(lp_ctx); + gensec_init(); ret = start_gentest(ev, lp_ctx); diff --git a/source4/torture/ldap/cldapbench.c b/source4/torture/ldap/cldapbench.c index 5c7e56f40b..7d02a2580b 100644 --- a/source4/torture/ldap/cldapbench.c +++ b/source4/torture/ldap/cldapbench.c @@ -215,7 +215,8 @@ bool torture_bench_cldap(struct torture_context *torture) make_nbt_name_server(&name, torture_setting_string(torture, "host", NULL)); /* do an initial name resolution to find its IP */ - status = resolve_name(lpcfg_resolve_context(torture->lp_ctx), &name, torture, &address, torture->ev); + status = resolve_name_ex(lpcfg_resolve_context(torture->lp_ctx), + 0, 0, &name, torture, &address, torture->ev); if (!NT_STATUS_IS_OK(status)) { printf("Failed to resolve %s - %s\n", name.name, nt_errstr(status)); diff --git a/source4/torture/libnet/libnet_BecomeDC.c b/source4/torture/libnet/libnet_BecomeDC.c index 0fbad00d7b..9f569e6a48 100644 --- a/source4/torture/libnet/libnet_BecomeDC.c +++ b/source4/torture/libnet/libnet_BecomeDC.c @@ -44,7 +44,7 @@ bool torture_net_become_dc(struct torture_context *torture) struct ldb_message *msg; int ldb_ret; uint32_t i; - char *sam_ldb_path; + char *private_dir; const char *address; struct nbt_name name; const char *netbios_name; @@ -67,8 +67,9 @@ bool torture_net_become_dc(struct torture_context *torture) make_nbt_name_server(&name, torture_setting_string(torture, "host", NULL)); /* do an initial name resolution to find its IP */ - status = resolve_name(lpcfg_resolve_context(torture->lp_ctx), - &name, torture, &address, torture->ev); + status = resolve_name_ex(lpcfg_resolve_context(torture->lp_ctx), + 0, 0, + &name, torture, &address, torture->ev); torture_assert_ntstatus_ok(torture, status, talloc_asprintf(torture, "Failed to resolve %s - %s\n", name.name, nt_errstr(status))); @@ -143,13 +144,13 @@ bool torture_net_become_dc(struct torture_context *torture) talloc_unlink(s, ldb); lp_ctx = libnet_vampire_cb_lp_ctx(s); - sam_ldb_path = talloc_asprintf(s, "%s/%s", location, "private/sam.ldb"); - lpcfg_set_cmdline(lp_ctx, "sam database", sam_ldb_path); - torture_comment(torture, "Reopen the SAM LDB with system credentials and all replicated data: %s\n", sam_ldb_path); + private_dir = talloc_asprintf(s, "%s/%s", location, "private"); + lpcfg_set_cmdline(lp_ctx, "private dir", private_dir); + torture_comment(torture, "Reopen the SAM LDB with system credentials and all replicated data: %s\n", private_dir); ldb = samdb_connect(s, torture->ev, lp_ctx, system_session(lp_ctx), 0); torture_assert_goto(torture, ldb != NULL, ret, cleanup, talloc_asprintf(torture, - "Failed to open '%s'\n", sam_ldb_path)); + "Failed to open '%s/sam.ldb'\n", private_dir)); torture_assert_goto(torture, dsdb_uses_global_schema(ldb), ret, cleanup, "Uses global schema"); diff --git a/source4/torture/libnetapi/libnetapi.c b/source4/torture/libnetapi/libnetapi.c index 633dc6cc3e..92c7b3a394 100644 --- a/source4/torture/libnetapi/libnetapi.c +++ b/source4/torture/libnetapi/libnetapi.c @@ -17,11 +17,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "includes.h" +#include "source3/include/includes.h" #include "torture/smbtorture.h" #include "auth/credentials/credentials.h" #include "lib/cmdline/popt_common.h" -#include <netapi.h> +#include "source3/lib/netapi/netapi.h" +#include "source3/lib/netapi/netapi_private.h" +#include "source4/param/param.h" #include "torture/libnetapi/proto.h" bool torture_libnetapi_init_context(struct torture_context *tctx, @@ -30,13 +32,19 @@ bool torture_libnetapi_init_context(struct torture_context *tctx, NET_API_STATUS status; struct libnetapi_ctx *ctx; - status = libnetapi_init(&ctx); + if (!lp_load(lpcfg_configfile(tctx->lp_ctx), true, false, false, true)) { + fprintf(stderr, "error loading %s\n", lpcfg_configfile(tctx->lp_ctx)); + return W_ERROR_V(WERR_GENERAL_FAILURE); + } + + init_names(); + load_interfaces(); + + status = libnetapi_net_init(&ctx); if (status != 0) { return false; } - libnetapi_set_debuglevel(ctx, - talloc_asprintf(ctx, "%d", DEBUGLEVEL)); libnetapi_set_username(ctx, cli_credentials_get_username(cmdline_credentials)); libnetapi_set_password(ctx, @@ -52,10 +60,16 @@ static bool torture_libnetapi_initialize(struct torture_context *tctx) NET_API_STATUS status; struct libnetapi_ctx *ctx; + /* We must do this first, as otherwise we fail if we don't + * have an smb.conf in the default path (we need to use the + * torture smb.conf */ + torture_assert(tctx, torture_libnetapi_init_context(tctx, &ctx), + "failed to initialize libnetapi"); + status = libnetapi_init(&ctx); - if (status != 0) { - return false; - } + + torture_assert(tctx, ctx != NULL, "Failed to get a libnetapi_ctx"); + torture_assert_int_equal(tctx, status, 0, "libnetapi_init failed despite alredy being set up"); libnetapi_free(ctx); diff --git a/source4/torture/libnetapi/wscript_build b/source4/torture/libnetapi/wscript_build index a087c96662..4f579c9820 100644 --- a/source4/torture/libnetapi/wscript_build +++ b/source4/torture/libnetapi/wscript_build @@ -5,8 +5,7 @@ bld.SAMBA_MODULE('TORTURE_LIBNETAPI', autoproto='proto.h', subsystem='smbtorture', init_function='torture_libnetapi_init', - deps='POPT_CREDENTIALS NETAPI', + deps='POPT_CREDENTIALS netapi', internal_module=True, - enabled=False ) diff --git a/source4/torture/libsmbclient/wscript_build b/source4/torture/libsmbclient/wscript_build index 8f93487389..8b2c516dbf 100644 --- a/source4/torture/libsmbclient/wscript_build +++ b/source4/torture/libsmbclient/wscript_build @@ -6,9 +6,8 @@ bld.SAMBA_MODULE('TORTURE_LIBSMBCLIENT', autoproto='proto.h', subsystem='smbtorture', init_function='torture_libsmbclient_init', - deps='POPT_CREDENTIALS SMBCLIENT', - internal_module=True, - enabled=False + deps='POPT_CREDENTIALS libsmb/smbclient', + internal_module=True ) diff --git a/source4/torture/local/dbspeed.c b/source4/torture/local/dbspeed.c index 8768b349ef..614a9b52ae 100644 --- a/source4/torture/local/dbspeed.c +++ b/source4/torture/local/dbspeed.c @@ -21,11 +21,11 @@ #include "includes.h" #include "system/filesys.h" -#include <tdb.h> +#include "tdb_compat.h" #include <ldb.h> #include <ldb_errors.h> #include "ldb_wrap.h" -#include "lib/tdb_wrap.h" +#include "lib/util/tdb_wrap.h" #include "torture/smbtorture.h" #include "param/param.h" @@ -97,7 +97,7 @@ static bool test_tdb_speed(struct torture_context *torture, const void *_data) i = random() % torture_entries; key.dptr = (uint8_t *)talloc_asprintf(tmp_ctx, "S-1-5-21-53173311-3623041448-2049097239-%u", i); key.dsize = strlen((char *)key.dptr)+1; - data = tdb_fetch(tdbw->tdb, key); + data = tdb_fetch_compat(tdbw->tdb, key); talloc_free(key.dptr); if (data.dptr == NULL) { torture_result(torture, TORTURE_FAIL, "Failed to find SID %d!", i); @@ -106,7 +106,7 @@ static bool test_tdb_speed(struct torture_context *torture, const void *_data) free(data.dptr); key.dptr = (uint8_t *)talloc_asprintf(tmp_ctx, "UID %u", i); key.dsize = strlen((char *)key.dptr)+1; - data = tdb_fetch(tdbw->tdb, key); + data = tdb_fetch_compat(tdbw->tdb, key); talloc_free(key.dptr); if (data.dptr == NULL) { torture_result(torture, TORTURE_FAIL, "Failed to find UID %d!", i); diff --git a/source4/torture/locktest.c b/source4/torture/locktest.c index 445a626e7b..77fcb69eaf 100644 --- a/source4/torture/locktest.c +++ b/source4/torture/locktest.c @@ -644,7 +644,7 @@ static void usage(poptContext pc) ev = s4_event_context_init(talloc_autofree_context()); - gensec_init(lp_ctx); + gensec_init(); DEBUG(0,("seed=%u base=%d range=%d min_length=%d\n", seed, lock_base, lock_range, min_length)); diff --git a/source4/torture/masktest.c b/source4/torture/masktest.c index 9c66291087..a711634b24 100644 --- a/source4/torture/masktest.c +++ b/source4/torture/masktest.c @@ -49,7 +49,7 @@ static bool reg_match_one(struct smbcli_state *cli, const char *pattern, const c if (ISDOTDOT(file)) file = "."; - return ms_fnmatch(pattern, file, cli->transport->negotiate.protocol)==0; + return ms_fnmatch_protocol(pattern, file, cli->transport->negotiate.protocol)==0; } static char *reg_test(struct smbcli_state *cli, TALLOC_CTX *mem_ctx, const char *pattern, const char *long_name, const char *short_name) @@ -153,10 +153,8 @@ static void get_real_name(TALLOC_CTX *mem_ctx, struct smbcli_state *cli, listfn, &state); if (f_info_hit) { - *short_name = talloc_strdup(mem_ctx, last_hit.short_name); - strlower(*short_name); - *long_name = talloc_strdup(mem_ctx, last_hit.long_name); - strlower(*long_name); + *short_name = strlower_talloc(mem_ctx, last_hit.short_name); + *long_name = strlower_talloc(mem_ctx, last_hit.long_name); } if (*short_name == '\0') { @@ -177,7 +175,7 @@ static void testpair(TALLOC_CTX *mem_ctx, struct smbcli_state *cli, char *mask, count++; - safe_strcpy(res1, "---", sizeof(res1)); + strlcpy(res1, "---", sizeof(res1)); state.mem_ctx = mem_ctx; @@ -191,7 +189,7 @@ static void testpair(TALLOC_CTX *mem_ctx, struct smbcli_state *cli, char *mask, resultp = res1; short_name = talloc_strdup(mem_ctx, ""); get_real_name(mem_ctx, cli, &long_name, &short_name); - safe_strcpy(res1, "---", sizeof(res1)); + strlcpy(res1, "---", sizeof(res1)); smbcli_list_new(cli->tree, mask, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, @@ -362,7 +360,7 @@ static void usage(poptContext pc) ev = s4_event_context_init(mem_ctx); - gensec_init(lp_ctx); + gensec_init(); lpcfg_smbcli_options(lp_ctx, &options); lpcfg_smbcli_session_options(lp_ctx, &session_options); diff --git a/source4/torture/nbt/browse.c b/source4/torture/nbt/browse.c deleted file mode 100644 index dcf96ba3ef..0000000000 --- a/source4/torture/nbt/browse.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Browse service - - (C) Jelmer Vernooij 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 <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "librpc/gen_ndr/nbt.h" -#include "libcli/resolve/resolve.h" -#include "torture/torture.h" - -/* - test nbt dgram operations -*/ -bool torture_nbt_browse(struct torture_context *torture) -{ - const char *address; - struct nbt_name name; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - NTSTATUS status; - bool ret = true; - - name.name = lpcfg_workgroup(); - name.type = NBT_NAME_BROWSER; - name.scope = NULL; - - /* do an initial name resolution to find its IP */ - status = resolve_name(&name, mem_ctx, &address, torture->ev); - if (!NT_STATUS_IS_OK(status)) { - printf("Failed to resolve %s - %s\n", - name.name, nt_errstr(status)); - talloc_free(mem_ctx); - return false; - } - - talloc_free(mem_ctx); - - return ret; -} diff --git a/source4/torture/nbt/dgram.c b/source4/torture/nbt/dgram.c index 36914bdcc3..aa4759edaf 100644 --- a/source4/torture/nbt/dgram.c +++ b/source4/torture/nbt/dgram.c @@ -86,11 +86,13 @@ static bool nbt_test_netlogon(struct torture_context *tctx) /* do an initial name resolution to find its IP */ torture_assert_ntstatus_ok(tctx, - resolve_name(lpcfg_resolve_context(tctx->lp_ctx), &name, tctx, &address, tctx->ev), + resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx), + 0, 0, + &name, tctx, &address, tctx->ev), talloc_asprintf(tctx, "Failed to resolve %s", name.name)); - load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces); - myaddress = talloc_strdup(dgmsock, iface_best_ip(ifaces, address)); + load_interface_list(tctx, tctx->lp_ctx, &ifaces); + myaddress = talloc_strdup(dgmsock, iface_list_best_ip(ifaces, address)); socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, @@ -180,11 +182,13 @@ static bool nbt_test_netlogon2(struct torture_context *tctx) /* do an initial name resolution to find its IP */ torture_assert_ntstatus_ok(tctx, - resolve_name(lpcfg_resolve_context(tctx->lp_ctx), &name, tctx, &address, tctx->ev), + resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx), + 0, 0, + &name, tctx, &address, tctx->ev), talloc_asprintf(tctx, "Failed to resolve %s", name.name)); - load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces); - myaddress = talloc_strdup(dgmsock, iface_best_ip(ifaces, address)); + load_interface_list(tctx, tctx->lp_ctx, &ifaces); + myaddress = talloc_strdup(dgmsock, iface_list_best_ip(ifaces, address)); socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, myaddress, lpcfg_dgram_port(tctx->lp_ctx)); @@ -450,11 +454,12 @@ static bool nbt_test_ntlogon(struct torture_context *tctx) /* do an initial name resolution to find its IP */ torture_assert_ntstatus_ok(tctx, - resolve_name(lpcfg_resolve_context(tctx->lp_ctx), &name, tctx, &address, tctx->ev), + resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx), + 0, 0, &name, tctx, &address, tctx->ev), talloc_asprintf(tctx, "Failed to resolve %s", name.name)); - load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces); - myaddress = talloc_strdup(dgmsock, iface_best_ip(ifaces, address)); + load_interface_list(tctx, tctx->lp_ctx, &ifaces); + myaddress = talloc_strdup(dgmsock, iface_list_best_ip(ifaces, address)); socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, myaddress, lpcfg_dgram_port(tctx->lp_ctx)); diff --git a/source4/torture/nbt/nbt.c b/source4/torture/nbt/nbt.c index 7c45f867e7..1b7fe49cf8 100644 --- a/source4/torture/nbt/nbt.c +++ b/source4/torture/nbt/nbt.c @@ -39,7 +39,9 @@ bool torture_nbt_get_name(struct torture_context *tctx, /* do an initial name resolution to find its IP */ torture_assert_ntstatus_ok(tctx, - resolve_name(lpcfg_resolve_context(tctx->lp_ctx), name, tctx, address, tctx->ev), + resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx), + 0, 0, + name, tctx, address, tctx->ev), talloc_asprintf(tctx, "Failed to resolve %s", name->name)); diff --git a/source4/torture/nbt/register.c b/source4/torture/nbt/register.c index d52ae4181e..24ca328b30 100644 --- a/source4/torture/nbt/register.c +++ b/source4/torture/nbt/register.c @@ -54,9 +54,9 @@ static bool nbt_register_own(struct torture_context *tctx) if (!torture_nbt_get_name(tctx, &name, &address)) return false; - load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces); + load_interface_list(tctx, tctx->lp_ctx, &ifaces); - myaddress = iface_best_ip(ifaces, address); + myaddress = iface_list_best_ip(ifaces, address); socket_address = socket_address_from_strings(tctx, nbtsock->sock->backend_name, myaddress, 0); @@ -123,9 +123,9 @@ static bool nbt_refresh_own(struct torture_context *tctx) if (!torture_nbt_get_name(tctx, &name, &address)) return false; - load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces); + load_interface_list(tctx, tctx->lp_ctx, &ifaces); - myaddress = iface_best_ip(ifaces, address); + myaddress = iface_list_best_ip(ifaces, address); socket_address = socket_address_from_strings(tctx, nbtsock->sock->backend_name, myaddress, 0); diff --git a/source4/torture/nbt/wins.c b/source4/torture/nbt/wins.c index 0ddaa8a05a..571249f562 100644 --- a/source4/torture/nbt/wins.c +++ b/source4/torture/nbt/wins.c @@ -65,9 +65,9 @@ static bool nbt_test_wins_name(struct torture_context *tctx, const char *address struct interface *ifaces; bool low_port = try_low_port; - load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces); + load_interface_list(tctx, tctx->lp_ctx, &ifaces); - myaddress = talloc_strdup(tctx, iface_best_ip(ifaces, address)); + myaddress = talloc_strdup(tctx, iface_list_best_ip(ifaces, address)); socket_address = socket_address_from_strings(tctx, nbtsock->sock->backend_name, diff --git a/source4/torture/nbt/winsbench.c b/source4/torture/nbt/winsbench.c index aff620878c..cb71d8755d 100644 --- a/source4/torture/nbt/winsbench.c +++ b/source4/torture/nbt/winsbench.c @@ -246,8 +246,8 @@ static bool bench_wins(struct torture_context *tctx) state->registered = talloc_zero_array(state, bool, state->num_names); state->wins_server = address; state->wins_port = lpcfg_nbt_port(tctx->lp_ctx); - load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces); - state->my_ip = talloc_strdup(tctx, iface_best_ip(ifaces, address)); + load_interface_list(tctx, tctx->lp_ctx, &ifaces); + state->my_ip = talloc_strdup(tctx, iface_list_best_ip(ifaces, address)); state->ttl = timelimit; my_ip = socket_address_from_strings(nbtsock, nbtsock->sock->backend_name, diff --git a/source4/torture/nbt/winsreplication.c b/source4/torture/nbt/winsreplication.c index cf8db494ca..7165f10dbb 100644 --- a/source4/torture/nbt/winsreplication.c +++ b/source4/torture/nbt/winsreplication.c @@ -615,14 +615,14 @@ static struct test_wrepl_conflict_conn *test_create_conflict_ctx( ctx->nbtsock = nbt_name_socket_init(ctx, tctx->ev); if (!ctx->nbtsock) return NULL; - load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces); + load_interface_list(tctx, tctx->lp_ctx, &ifaces); - ctx->myaddr = socket_address_from_strings(tctx, ctx->nbtsock->sock->backend_name, iface_best_ip(ifaces, address), 0); + ctx->myaddr = socket_address_from_strings(tctx, ctx->nbtsock->sock->backend_name, iface_list_best_ip(ifaces, address), 0); if (!ctx->myaddr) return NULL; - for (i = 0; i < iface_count(ifaces); i++) { - if (strcmp(ctx->myaddr->addr, iface_n_ip(ifaces, i)) == 0) continue; - ctx->myaddr2 = socket_address_from_strings(tctx, ctx->nbtsock->sock->backend_name, iface_n_ip(ifaces, i), 0); + for (i = 0; i < iface_list_count(ifaces); i++) { + if (strcmp(ctx->myaddr->addr, iface_list_n_ip(ifaces, i)) == 0) continue; + ctx->myaddr2 = socket_address_from_strings(tctx, ctx->nbtsock->sock->backend_name, iface_list_n_ip(ifaces, i), 0); if (!ctx->myaddr2) return NULL; break; } @@ -679,12 +679,12 @@ static struct test_wrepl_conflict_conn *test_create_conflict_ctx( ctx->addresses_best[0].owner = ctx->b.address; ctx->addresses_best[0].ip = ctx->myaddr->addr; - ctx->addresses_all_num = iface_count(ifaces); + ctx->addresses_all_num = iface_list_count(ifaces); ctx->addresses_all = talloc_array(ctx, struct wrepl_ip, ctx->addresses_all_num); if (!ctx->addresses_all) return NULL; for (i=0; i < ctx->addresses_all_num; i++) { ctx->addresses_all[i].owner = ctx->b.address; - ctx->addresses_all[i].ip = talloc_strdup(ctx->addresses_all, iface_n_ip(ifaces, i)); + ctx->addresses_all[i].ip = talloc_strdup(ctx->addresses_all, iface_list_n_ip(ifaces, i)); if (!ctx->addresses_all[i].ip) return NULL; } @@ -6701,6 +6701,7 @@ static bool test_conflict_owned_released_vs_replica(struct torture_context *tctx } struct test_conflict_owned_active_vs_replica_struct { + struct torture_context *tctx; const char *line; /* just better debugging */ const char *section; /* just better debugging */ struct nbt_name name; @@ -6760,6 +6761,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. unique,active with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_UA_SI_U", 0x00, NULL), .wins = { @@ -6786,6 +6788,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. unique,active with different ip(s), positive response */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_UA_DI_P", 0x00, NULL), .wins = { @@ -6813,6 +6816,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. unique,active with different ip(s), positive response other ips */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_UA_DI_O", 0x00, NULL), .wins = { @@ -6842,6 +6846,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. unique,active with different ip(s), negative response */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_UA_DI_N", 0x00, NULL), .wins = { @@ -6869,6 +6874,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. unique,tombstone with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_UT_SI_U", 0x00, NULL), .wins = { @@ -6895,6 +6901,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. unique,tombstone with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_UT_DI_U", 0x00, NULL), .wins = { @@ -6924,6 +6931,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. group,active with same ip(s), release expected */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_GA_SI_R", 0x00, NULL), .wins = { @@ -6951,6 +6959,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. group,active with different ip(s), release expected */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_GA_DI_R", 0x00, NULL), .wins = { @@ -6978,6 +6987,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. group,tombstone with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_GT_SI_U", 0x00, NULL), .wins = { @@ -7004,6 +7014,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. group,tombstone with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_GT_DI_U", 0x00, NULL), .wins = { @@ -7033,6 +7044,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. sgroup,active with same ip(s), release expected */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_SA_SI_R", 0x00, NULL), .wins = { @@ -7060,6 +7072,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. group,active with different ip(s), release expected */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_SA_DI_R", 0x00, NULL), .wins = { @@ -7087,6 +7100,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. sgroup,tombstone with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_ST_SI_U", 0x00, NULL), .wins = { @@ -7113,6 +7127,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. sgroup,tombstone with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_ST_DI_U", 0x00, NULL), .wins = { @@ -7142,6 +7157,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. mhomed,active with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_MA_SI_U", 0x00, NULL), .wins = { @@ -7168,6 +7184,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. mhomed,active with superset ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_MA_SP_U", 0x00, NULL), .wins = { @@ -7194,6 +7211,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. mhomed,active with different ip(s), positive response */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_MA_DI_P", 0x00, NULL), .wins = { @@ -7221,6 +7239,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. mhomed,active with different ip(s), positive response other ips */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_MA_DI_O", 0x00, NULL), .wins = { @@ -7250,6 +7269,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. mhomed,active with different ip(s), negative response */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_MA_DI_N", 0x00, NULL), .wins = { @@ -7277,6 +7297,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. mhomed,tombstone with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_MT_SI_U", 0x00, NULL), .wins = { @@ -7303,6 +7324,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. mhomed,tombstone with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_MT_DI_U", 0x00, NULL), .wins = { @@ -7332,6 +7354,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * group,active vs. unique,active with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_GA_UA_SI_U", 0x00, NULL), .wins = { @@ -7358,6 +7381,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * group,active vs. unique,active with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_GA_UA_DI_U", 0x00, NULL), .wins = { @@ -7384,6 +7408,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * group,active vs. unique,tombstone with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_GA_UT_SI_U", 0x00, NULL), .wins = { @@ -7410,6 +7435,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * group,active vs. unique,tombstone with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_GA_UT_DI_U", 0x00, NULL), .wins = { @@ -7439,6 +7465,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * group,active vs. group,active with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_GA_GA_SI_U", 0x00, NULL), .wins = { @@ -7465,6 +7492,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * group,active vs. group,active with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_GA_GA_DI_U", 0x00, NULL), .wins = { @@ -7491,6 +7519,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * group,active vs. group,tombstone with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_GA_GT_SI_U", 0x00, NULL), .wins = { @@ -7517,6 +7546,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * group,active vs. group,tombstone with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_GA_GT_DI_U", 0x00, NULL), .wins = { @@ -7546,6 +7576,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * group,active vs. sgroup,active with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_GA_SA_SI_U", 0x00, NULL), .wins = { @@ -7572,6 +7603,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * group,active vs. sgroup,active with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_GA_SA_DI_U", 0x00, NULL), .wins = { @@ -7598,6 +7630,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * group,active vs. sgroup,tombstone with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_GA_ST_SI_U", 0x00, NULL), .wins = { @@ -7624,6 +7657,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * group,active vs. sgroup,tombstone with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_GA_ST_DI_U", 0x00, NULL), .wins = { @@ -7653,6 +7687,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * group,active vs. mhomed,active with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_GA_MA_SI_U", 0x00, NULL), .wins = { @@ -7679,6 +7714,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * group,active vs. mhomed,active with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_GA_MA_DI_U", 0x00, NULL), .wins = { @@ -7705,6 +7741,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * group,active vs. mhomed,tombstone with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_GA_MT_SI_U", 0x00, NULL), .wins = { @@ -7731,6 +7768,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * group,active vs. mhomed,tombstone with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_GA_MT_DI_U", 0x00, NULL), .wins = { @@ -7760,6 +7798,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. unique,active with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_UA_SI_U", 0x1C, NULL), .wins = { @@ -7786,6 +7825,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. unique,active with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_UA_DI_U", 0x1C, NULL), .wins = { @@ -7812,6 +7852,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. unique,tombstone with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_UT_SI_U", 0x1C, NULL), .wins = { @@ -7838,6 +7879,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. unique,tombstone with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_UT_DI_U", 0x1C, NULL), .wins = { @@ -7867,6 +7909,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. group,active with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_GA_SI_U", 0x1C, NULL), .wins = { @@ -7893,6 +7936,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. group,active with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_GA_DI_U", 0x1C, NULL), .wins = { @@ -7919,6 +7963,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. group,tombstone with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_GT_SI_U", 0x1C, NULL), .wins = { @@ -7945,6 +7990,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. group,tombstone with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_GT_DI_U", 0x1C, NULL), .wins = { @@ -7974,6 +8020,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. mhomed,active with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_MA_SI_U", 0x1C, NULL), .wins = { @@ -8000,6 +8047,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. mhomed,active with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_MA_DI_U", 0x1C, NULL), .wins = { @@ -8026,6 +8074,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. mhomed,tombstone with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_MT_SI_U", 0x1C, NULL), .wins = { @@ -8052,6 +8101,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. mhomed,tombstone with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_MT_DI_U", 0x1C, NULL), .wins = { @@ -8081,6 +8131,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. unique,active with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_UA_SI_U", 0x00, NULL), .wins = { @@ -8107,6 +8158,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. unique,active with different ip(s), positive response */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_UA_DI_P", 0x00, NULL), .wins = { @@ -8134,6 +8186,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. unique,active with different ip(s), positive response other ips */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_UA_DI_O", 0x00, NULL), .wins = { @@ -8163,6 +8216,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. unique,active with different ip(s), negative response */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_UA_DI_N", 0x00, NULL), .wins = { @@ -8190,6 +8244,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. unique,tombstone with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_UT_SI_U", 0x00, NULL), .wins = { @@ -8216,6 +8271,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. unique,tombstone with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_UT_DI_U", 0x00, NULL), .wins = { @@ -8245,6 +8301,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. group,active with same ip(s), release expected */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_GA_SI_R", 0x00, NULL), .wins = { @@ -8272,6 +8329,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. group,active with different ip(s), release expected */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_GA_DI_R", 0x00, NULL), .wins = { @@ -8299,6 +8357,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. group,tombstone with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_GT_SI_U", 0x00, NULL), .wins = { @@ -8325,6 +8384,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. group,tombstone with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_GT_DI_U", 0x00, NULL), .wins = { @@ -8354,6 +8414,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. sgroup,active with same ip(s), release expected */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_SA_SI_R", 0x00, NULL), .wins = { @@ -8381,6 +8442,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. group,active with different ip(s), release expected */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_SA_DI_R", 0x00, NULL), .wins = { @@ -8408,6 +8470,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. sgroup,tombstone with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_ST_SI_U", 0x00, NULL), .wins = { @@ -8434,6 +8497,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. sgroup,tombstone with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_ST_DI_U", 0x00, NULL), .wins = { @@ -8463,6 +8527,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. mhomed,active with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_MA_SI_U", 0x00, NULL), .wins = { @@ -8489,6 +8554,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. mhomed,active with superset ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_MA_SP_U", 0x00, NULL), .wins = { @@ -8515,6 +8581,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. mhomed,active with different ip(s), positive response */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_MA_DI_P", 0x00, NULL), .wins = { @@ -8542,6 +8609,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. mhomed,active with different ip(s), positive response other ips */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_MA_DI_O", 0x00, NULL), .wins = { @@ -8571,6 +8639,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. mhomed,active with different ip(s), negative response */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_MA_DI_N", 0x00, NULL), .wins = { @@ -8598,6 +8667,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. mhomed,tombstone with same ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_MT_SI_U", 0x00, NULL), .wins = { @@ -8624,6 +8694,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. mhomed,tombstone with different ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_MT_DI_U", 0x00, NULL), .wins = { @@ -8653,6 +8724,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. mhomed,active with superset ip(s), unchecked */ { + .tctx = tctx, .line = __location__, .section= "Test Replica vs. owned active: some more MHOMED combinations", .name = _NBT_NAME("_MA_MA_SP_U", 0x00, NULL), @@ -8682,6 +8754,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. mhomed,active with same ips, unchecked */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_MA_SM_U", 0x00, NULL), .comment= "C:MHOMED vs. B:MHOMED => B:MHOMED", @@ -8710,6 +8783,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. mhomed,active with subset ip(s), positive response */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_MA_SB_P", 0x00, NULL), .comment= "C:MHOMED vs. B:BEST (C:MHOMED) => B:MHOMED", @@ -8739,6 +8813,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. mhomed,active with subset ip(s), positive response, with all addresses */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_MA_SB_A", 0x00, NULL), .comment= "C:MHOMED vs. B:BEST (C:ALL) => B:MHOMED", @@ -8772,6 +8847,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * the release demand has no effect to the database record... */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_MA_SB_PRA", 0x00, NULL), .comment= "C:MHOMED vs. B:BEST (C:BEST) => C:MHOMED", @@ -8804,6 +8880,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. mhomed,active with subset ip(s), positive response, with other addresses */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_MA_SB_O", 0x00, NULL), .comment= "C:MHOMED vs. B:BEST (B:B_3_4) =>C:MHOMED", @@ -8835,6 +8912,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. mhomed,active with subset ip(s), negative response */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_MA_MA_SB_N", 0x00, NULL), .comment= "C:MHOMED vs. B:BEST (NEGATIVE) => B:BEST", @@ -8867,6 +8945,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * mhomed,active vs. unique,active with subset ip(s), positive response */ { + .tctx = tctx, .line = __location__, .section= "Test Replica vs. owned active: some more UNIQUE,MHOMED combinations", .name = _NBT_NAME("_MA_UA_SB_P", 0x00, NULL), @@ -8899,6 +8978,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * the release demand has no effect to the database record... */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_UA_DI_PRA", 0x00, NULL), .comment= "C:BEST vs. B:BEST2 (C:BEST2,LR:BEST2) => C:BEST", @@ -8931,6 +9011,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. unique,active with different ip(s), positive response, with all addresses */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_UA_DI_A", 0x00, NULL), .comment= "C:BEST vs. B:BEST2 (C:ALL) => B:MHOMED", @@ -8962,6 +9043,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * unique,active vs. mhomed,active with different ip(s), positive response, with all addresses */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_UA_MA_DI_A", 0x00, NULL), .comment= "C:BEST vs. B:BEST2 (C:ALL) => B:MHOMED", @@ -8996,6 +9078,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. sgroup,active with different ip(s) */ { + .tctx = tctx, .line = __location__, .section= "Test Replica vs. owned active: SGROUP vs. SGROUP tests", .name = _NBT_NAME("_SA_SA_DI_U", 0x1C, NULL), @@ -9024,6 +9107,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. sgroup,active with same ip(s) */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_SA_SI_U", 0x1C, NULL), .skip = (ctx->addresses_all_num < 3), @@ -9051,6 +9135,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. sgroup,active with superset ip(s) */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_SA_SP_U", 0x1C, NULL), .skip = (ctx->addresses_all_num < 3), @@ -9078,6 +9163,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. sgroup,active with subset ip(s) */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_SA_SB_U", 0x1C, NULL), .skip = (ctx->addresses_all_num < 3), @@ -9105,6 +9191,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. sgroup,tombstone with different ip(s) */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_ST_DI_U", 0x1C, NULL), .skip = (ctx->addresses_all_num < 3), @@ -9132,6 +9219,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. sgroup,tombstone with same ip(s) */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_ST_SI_U", 0x1C, NULL), .skip = (ctx->addresses_all_num < 3), @@ -9159,6 +9247,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. sgroup,tombstone with superset ip(s) */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_ST_SP_U", 0x1C, NULL), .skip = (ctx->addresses_all_num < 3), @@ -9186,6 +9275,7 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, * sgroup,active vs. sgroup,tombstone with subset ip(s) */ { + .tctx = tctx, .line = __location__, .name = _NBT_NAME("_SA_ST_SB_U", 0x1C, NULL), .skip = (ctx->addresses_all_num < 3), @@ -9489,20 +9579,26 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, return ret; } +#define __NBT_LABEL_CAT1__(a,b) a##b +#define __NBT_LABEL_CAT2__(a,b) __NBT_LABEL_CAT1__(a,b) +#define _NBT_LABEL __NBT_LABEL_CAT2__(_label_, __LINE__) + #define _NBT_ASSERT(v, correct) do { \ - if ((v) != (correct)) { \ - printf("(%s) Incorrect value %s=%d - should be %s (%d)\n", \ - __location__, #v, v, #correct, correct); \ + bool _ret = true; \ + torture_assert_int_equal_goto(rec->tctx, v, correct, \ + _ret, _NBT_LABEL, "Invalid int value"); \ +_NBT_LABEL: \ + if (!_ret) { \ return; \ } \ } while (0) #define _NBT_ASSERT_STRING(v, correct) do { \ - if ( ((!v) && (correct)) || \ - ((v) && (!correct)) || \ - ((v) && (correct) && strcmp(v,correct) != 0)) { \ - printf("(%s) Incorrect value %s=%s - should be %s\n", \ - __location__, #v, v, correct); \ + bool _ret = true; \ + torture_assert_str_equal_goto(rec->tctx, v, correct, \ + _ret, _NBT_LABEL, "Invalid string value"); \ +_NBT_LABEL: \ + if (!_ret) { \ return; \ } \ } while (0) @@ -9522,8 +9618,8 @@ static void test_conflict_owned_active_vs_replica_handler_query(struct nbt_name_ name = &req_packet->questions[0].name; - _NBT_ASSERT(name->type, rec->name.type); _NBT_ASSERT_STRING(name->name, rec->name.name); + _NBT_ASSERT(name->type, rec->name.type); _NBT_ASSERT_STRING(name->scope, rec->name.scope); _NBT_ASSERT(rec->defend.expect_release, false); @@ -9621,8 +9717,8 @@ static void test_conflict_owned_active_vs_replica_handler_release( name = &req_packet->questions[0].name; - _NBT_ASSERT(name->type, rec->name.type); _NBT_ASSERT_STRING(name->name, rec->name.name); + _NBT_ASSERT(name->type, rec->name.type); _NBT_ASSERT_STRING(name->scope, rec->name.scope); _NBT_ASSERT(rec->defend.expect_release, true); @@ -9668,6 +9764,17 @@ static void test_conflict_owned_active_vs_replica_handler(struct nbt_name_socket { struct test_conflict_owned_active_vs_replica_struct *rec = (struct test_conflict_owned_active_vs_replica_struct *)nbtsock->incoming.private_data; + struct nbt_name *name = &req_packet->questions[0].name; + + if (req_packet->operation & NBT_FLAG_BROADCAST) { + torture_comment(rec->tctx, + "%s: incoming packet name[%s] flags[0x%08X] from[%s]\n", + __location__, + nbt_name_string(rec->tctx, name), + req_packet->operation, + src->addr); + return; + } rec->defend.ret = false; @@ -9679,8 +9786,14 @@ static void test_conflict_owned_active_vs_replica_handler(struct nbt_name_socket test_conflict_owned_active_vs_replica_handler_release(nbtsock, req_packet, src); break; default: - printf("%s: unexpected incoming packet\n", __location__); - return; + torture_comment(rec->tctx, + "%s: unexpected packet name[%s] flags[0x%08X] from[%s]\n", + __location__, + nbt_name_string(rec->tctx, name), + req_packet->operation, + src->addr); + _NBT_ASSERT((req_packet->operation & NBT_OPCODE), NBT_OPCODE_QUERY); + break; } } diff --git a/source4/torture/ndr/dfsblob.c b/source4/torture/ndr/dfsblob.c index 3c95928a5c..27ad5e40bf 100644 --- a/source4/torture/ndr/dfsblob.c +++ b/source4/torture/ndr/dfsblob.c @@ -63,7 +63,7 @@ static const uint8_t dfs_get_ref_out2[] = { static bool dfs_referral_out_check(struct torture_context *tctx, struct dfs_referral_resp *r) { torture_assert_str_equal(tctx, - r->referral_entries[0].referral.v3.data.referrals.r2.special_name, + r->referral_entries[0].referral.v3.referrals.r2.special_name, "\\msw2k3.tst", "Special name"); ndr_push_struct_blob(&blob, tctx, r, (ndr_push_flags_fn_t)ndr_push_dfs_referral_resp); torture_assert_int_equal(tctx, blob.data[blob.length-2], 0, "expanded names not null terminated"); diff --git a/source4/torture/ndr/ndr.c b/source4/torture/ndr/ndr.c index 36b2b5540c..6c564d3310 100644 --- a/source4/torture/ndr/ndr.c +++ b/source4/torture/ndr/ndr.c @@ -355,6 +355,7 @@ struct torture_suite *torture_local_ndr(TALLOC_CTX *mem_ctx) torture_suite_add_suite(suite, ndr_nbt_suite(suite)); torture_suite_add_suite(suite, ndr_ntlmssp_suite(suite)); torture_suite_add_suite(suite, ndr_backupkey_suite(suite)); + torture_suite_add_suite(suite, ndr_string_suite(suite)); torture_suite_add_simple_test(suite, "string terminator", test_check_string_terminator); diff --git a/source4/torture/ndr/string.c b/source4/torture/ndr/string.c new file mode 100644 index 0000000000..30ed1e4d1a --- /dev/null +++ b/source4/torture/ndr/string.c @@ -0,0 +1,198 @@ +#include "includes.h" +#include "torture/ndr/ndr.h" +#include "torture/ndr/proto.h" +#include "../lib/util/dlinklist.h" +#include "param/param.h" + +static const char const *ascii = "ascii"; +/* the following is equivalent to "kamelåså öäüÿéèóò" in latin1 */ +static const char const latin1[] = { 0x6b, 0x61, 0x6d, 0x65, 0x6c, 0xe5, 0x73, + 0xe5, 0x20, 0xF6, 0xE4, 0xFC, 0xFF, 0xE9, + 0xE8, 0xF3, 0xF2, 0x00 }; +/* the following is equivalent to "kamelåså ☺☺☺ öäüÿéèóò" in utf8 */ +static const char const utf8[] = { 0x6b, 0x61, 0x6d, 0x65, 0x6c, 0xc3, 0xa5, + 0x73, 0xc3, 0xa5, 0x20, 0xE2, 0x98, 0xBA, + 0xE2, 0x98, 0xBA, 0xE2, 0x98, 0xBA, 0x20, + 0xc3, 0xb6, 0xc3, 0xa4, 0xc3, 0xbc, 0xc3, + 0xbf, 0xc3, 0xa9, 0xc3, 0xa8, 0xc3, 0xb3, + 0xc3, 0xb2, 0x00 }; + +/* purely for convenience */ +static int fl_ascii_null = LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM; +static int fl_utf8_null = LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM; +static int fl_raw8_null = LIBNDR_FLAG_STR_RAW8|LIBNDR_FLAG_STR_NULLTERM; + +static bool +test_ndr_push_string (struct torture_context *tctx, const char *string, + int flags, enum ndr_err_code exp_ndr_err, + bool strcmp_pass) +{ + TALLOC_CTX *mem_ctx; + struct ndr_push *ndr; + enum ndr_err_code err; + + torture_comment(tctx, + "test_ndr_push_string %s flags 0x%x expecting " + "err 0x%x and strcmp %s\n", string, flags, exp_ndr_err, + strcmp_pass?"pass":"fail"); + if (exp_ndr_err != NDR_ERR_SUCCESS) { + torture_comment(tctx, "(ignore any Conversion error) "); + } + + mem_ctx = talloc_named (NULL, 0, "test_ndr_push_string"); + ndr = talloc_zero (mem_ctx, struct ndr_push); + ndr_set_flags (&ndr->flags, flags); + + err = ndr_push_string (ndr, NDR_SCALARS, string); + torture_assert(tctx, err == exp_ndr_err, + "ndr_push_string: unexpected return code"); + + if (exp_ndr_err == NDR_ERR_SUCCESS) { + torture_assert(tctx, ndr->data != NULL, + "ndr_push_string: succeeded but NULL data"); + + torture_assert(tctx, + strcmp_pass == !strcmp(string, (char *)ndr->data), + "ndr_push_string: post-push strcmp"); + } + + talloc_free(mem_ctx); + return true; +} + +static bool +test_ndr_pull_string (struct torture_context *tctx, const char *string, + int flags, enum ndr_err_code exp_ndr_err, + bool strcmp_pass) +{ + TALLOC_CTX *mem_ctx; + DATA_BLOB blob; + struct ndr_pull *ndr; + enum ndr_err_code err; + const char *result = NULL; + + torture_comment(tctx, + "test_ndr_pull_string '%s' flags 0x%x expecting " + "err 0x%x and strcmp %s\n", string, flags, exp_ndr_err, + strcmp_pass?"pass":"fail"); + if (exp_ndr_err != NDR_ERR_SUCCESS) { + torture_comment(tctx, "(ignore any Conversion error) "); + } + + mem_ctx = talloc_named (NULL, 0, "test_ndr_pull_string"); + + blob = data_blob_string_const(string); + ndr = ndr_pull_init_blob(&blob, mem_ctx); + ndr_set_flags (&ndr->flags, flags); + + err = ndr_pull_string (ndr, NDR_SCALARS, &result); + torture_assert(tctx, err == exp_ndr_err, + "ndr_pull_string: unexpected return code"); + + if (exp_ndr_err == NDR_ERR_SUCCESS) { + torture_assert(tctx, result != NULL, + "ndr_pull_string: NULL data"); + torture_assert(tctx, strcmp_pass == !strcmp(string, result), + "ndr_pull_string: post-pull strcmp"); + torture_assert(tctx, result != NULL, + "ndr_pull_string succeeded but result NULL"); + } + + talloc_free(mem_ctx); + return true; +} + +static bool +torture_ndr_string(struct torture_context *torture) +{ + const char *saved_dos_cp = lpcfg_dos_charset(torture->lp_ctx); + + torture_assert(torture, + test_ndr_push_string (torture, ascii, fl_ascii_null, + NDR_ERR_SUCCESS, true), + "test_ndr_push_string(ASCII, STR_ASCII|STR_NULL)"); + torture_assert(torture, + test_ndr_push_string (torture, utf8, fl_utf8_null, + NDR_ERR_SUCCESS, true), + "test_ndr_push_string(UTF8, STR_UTF8|STR_NULL)"); + torture_assert(torture, + test_ndr_push_string (torture, utf8, fl_raw8_null, + NDR_ERR_SUCCESS, true), + "test_ndr_push_string(UTF8, STR_RAW8|STR_NULL)"); + torture_assert(torture, + test_ndr_push_string (torture, latin1, fl_raw8_null, + NDR_ERR_SUCCESS, true), + "test_ndr_push_string(LATIN1, STR_RAW8|STR_NULL)"); + torture_assert(torture, + test_ndr_push_string (torture, utf8, fl_ascii_null, + NDR_ERR_CHARCNV, false), + "test_ndr_push_string(UTF8, STR_ASCII|STR_NULL)"); + torture_assert(torture, + test_ndr_push_string (torture, latin1, fl_ascii_null, + NDR_ERR_CHARCNV, false), + "test_ndr_push_string(LATIN1, STR_ASCII|STR_NULL)"); + + + torture_assert(torture, + test_ndr_pull_string (torture, ascii, fl_ascii_null, + NDR_ERR_SUCCESS, true), + "test_ndr_pull_string(ASCII, STR_ASCII|STR_NULL)"); + torture_assert(torture, + test_ndr_pull_string (torture, utf8, fl_utf8_null, + NDR_ERR_SUCCESS, true), + "test_ndr_pull_string(UTF8, STR_UTF8|STR_NULL)"); + torture_assert(torture, + test_ndr_pull_string (torture, utf8, fl_raw8_null, + NDR_ERR_SUCCESS, true), + "test_ndr_pull_string(UTF8, STR_RAW8|STR_NULL)"); + torture_assert(torture, + test_ndr_pull_string (torture, latin1, fl_raw8_null, + NDR_ERR_SUCCESS, true), + "test_ndr_pull_string(LATIN1, STR_RAW8|STR_NULL)"); + + /* Depending on runtime config, the behavior of ndr_pull_string on + * incorrect combinations of strings and flags (latin1 with ASCII + * flags, for example) may differ; it may return NDR_ERR_CHARCNV, or + * it may return NDR_ERR_SUCCESS but with a string that has been + * mutilated, depending on the value of "dos charset". We test for + * both cases here. */ + + lpcfg_do_global_parameter(torture->lp_ctx, "dos charset", "ASCII"); + reload_charcnv(torture->lp_ctx); + + torture_assert(torture, + test_ndr_pull_string (torture, latin1, fl_ascii_null, + NDR_ERR_CHARCNV, false), + "test_ndr_pull_string(LATIN1, STR_ASCII|STR_NULL)"); + torture_assert(torture, + test_ndr_pull_string (torture, utf8, fl_ascii_null, + NDR_ERR_CHARCNV, false), + "test_ndr_pull_string(UTF8, STR_ASCII|STR_NULL)"); + + lpcfg_do_global_parameter(torture->lp_ctx, "dos charset", "CP850"); + reload_charcnv(torture->lp_ctx); + + torture_assert(torture, + test_ndr_pull_string (torture, latin1, fl_ascii_null, + NDR_ERR_SUCCESS, false), + "test_ndr_pull_string(LATIN1, STR_ASCII|STR_NULL)"); + torture_assert(torture, + test_ndr_pull_string (torture, utf8, fl_ascii_null, + NDR_ERR_SUCCESS, false), + "test_ndr_pull_string(UTF8, STR_ASCII|STR_NULL)"); + + lpcfg_do_global_parameter(torture->lp_ctx, "dos charset", saved_dos_cp); + reload_charcnv(torture->lp_ctx); + + return true; +} + +struct torture_suite *ndr_string_suite(TALLOC_CTX *ctx) +{ + struct torture_suite *suite = torture_suite_create(ctx, "ndr_string"); + + torture_suite_add_simple_test(suite, "ndr_string", torture_ndr_string); + suite->description = talloc_strdup(suite, "NDR - string-conversion focused push/pull tests"); + + return suite; +} diff --git a/source4/torture/rap/rap.c b/source4/torture/rap/rap.c index 5c1c5e196c..ee37158a43 100644 --- a/source4/torture/rap/rap.c +++ b/source4/torture/rap/rap.c @@ -206,6 +206,21 @@ static bool test_netsessiongetinfo(struct torture_context *tctx, return true; } +static bool test_netremotetod(struct torture_context *tctx, + struct smbcli_state *cli) +{ + struct rap_NetRemoteTOD r; + + r.in.bufsize = 8192; + + torture_assert_ntstatus_ok(tctx, + smbcli_rap_netremotetod(cli->tree, tctx, &r), + "smbcli_rap_netremotetod failed"); + torture_assert_werr_ok(tctx, W_ERROR(r.out.status), + "smbcli_rap_netremotetod failed"); + + return true; +} bool torture_rap_scan(struct torture_context *torture, struct smbcli_state *cli) { @@ -246,6 +261,8 @@ NTSTATUS torture_rap_init(void) test_netsessionenum); torture_suite_add_1smb_test(suite_basic, "netsessiongetinfo", test_netsessiongetinfo); + torture_suite_add_1smb_test(suite_basic, "netremotetod", + test_netremotetod); torture_suite_add_1smb_test(suite, "scan", torture_rap_scan); diff --git a/source4/torture/raw/acls.c b/source4/torture/raw/acls.c index 666d164c96..01ee8be6a9 100644 --- a/source4/torture/raw/acls.c +++ b/source4/torture/raw/acls.c @@ -1846,6 +1846,7 @@ done: return ret; } +#if 0 static bool test_inheritance_flags(struct torture_context *tctx, struct smbcli_state *cli) { @@ -2073,6 +2074,7 @@ done: smbcli_deltree(cli->tree, BASEDIR); return ret; } +#endif /* test dynamic acl inheritance @@ -2201,13 +2203,14 @@ static bool test_inheritance_dynamic(struct torture_context *tctx, smbcli_unlink(cli->tree, fname1); done: - torture_comment(tctx, "put back original sd\n"); - set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC; - set.set_secdesc.in.file.fnum = fnum; - set.set_secdesc.in.secinfo_flags = SECINFO_DACL; - set.set_secdesc.in.sd = sd_orig; - status = smb_raw_setfileinfo(cli->tree, &set); - + if (sd_orig != NULL) { + torture_comment(tctx, "put back original sd\n"); + set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC; + set.set_secdesc.in.file.fnum = fnum; + set.set_secdesc.in.secinfo_flags = SECINFO_DACL; + set.set_secdesc.in.sd = sd_orig; + status = smb_raw_setfileinfo(cli->tree, &set); + } smbcli_close(cli->tree, fnum); smbcli_rmdir(cli->tree, dname); smb_raw_exit(cli->session); @@ -2244,6 +2247,8 @@ done: CHECK_STATUS_FOR_BIT_ACTION(status, bits, do {} while (0)); \ } while (0) +#if 0 + /* test what access mask is needed for getting and setting security_descriptors Test copied to smb2/acls.c for SMB2. */ static bool test_sd_get_set(struct torture_context *tctx, @@ -2433,6 +2438,7 @@ done: return ret; } +#endif /* basic testing of security descriptor calls @@ -2450,11 +2456,14 @@ struct torture_suite *torture_raw_acls(TALLOC_CTX *mem_ctx) torture_suite_add_1smb_test(suite, "owner", test_owner_bits); torture_suite_add_1smb_test(suite, "inheritance", test_inheritance); - /* torture_suite_add_1smb_test(suite, "INHERITFLAGS", test_inheritance_flags); */ +#if 0 + torture_suite_add_1smb_test(suite, "INHERITFLAGS", test_inheritance_flags); +#endif torture_suite_add_1smb_test(suite, "dynamic", test_inheritance_dynamic); - /* XXX This test does not work against XP or Vista. +#if 0 + /* XXX This test does not work against XP or Vista. */ torture_suite_add_1smb_test(suite, "GETSET", test_sd_get_set); - */ +#endif return suite; } diff --git a/source4/torture/raw/open.c b/source4/torture/raw/open.c index 89042d77dc..8a66a12cd5 100644 --- a/source4/torture/raw/open.c +++ b/source4/torture/raw/open.c @@ -130,7 +130,7 @@ static const char *rdwr_string(enum rdwr_mode m) if ((v) != (finfo.all_info.out.field)) { \ torture_result(tctx, TORTURE_FAIL, \ "(%s) wrong value for field %s 0x%x - 0x%x\n", \ - __location__, #field, (int)v, (int)(finfo.all_info.out.field)); \ + __location__, #field, (unsigned int)(v), (unsigned int)(finfo.all_info.out.field)); \ dump_all_info(tctx, &finfo); \ ret = false; \ }} while (0) @@ -139,7 +139,7 @@ static const char *rdwr_string(enum rdwr_mode m) if ((v) != (correct)) { \ torture_result(tctx, TORTURE_FAIL, \ "(%s) wrong value for %s 0x%x - should be 0x%x\n", \ - __location__, #v, (int)(v), (int)correct); \ + __location__, #v, (unsigned int)(v), (unsigned int)(correct)); \ ret = false; \ }} while (0) @@ -152,7 +152,7 @@ static const char *rdwr_string(enum rdwr_mode m) status = smb_raw_setpathinfo(cli->tree, &sfinfo); \ if (!NT_STATUS_IS_OK(status)) { \ torture_warning(tctx, "(%s) Failed to set attrib 0x%x on %s\n", \ - __location__, sattrib, fname); \ + __location__, (unsigned int)(sattrib), fname); \ }} while (0) /* @@ -337,7 +337,7 @@ static bool test_openx(struct torture_context *tctx, struct smbcli_state *cli) __location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status), i, (int)open_funcs[i].with_file, - (int)open_funcs[i].open_func); + open_funcs[i].open_func); ret = false; } if (NT_STATUS_IS_OK(status)) { @@ -602,7 +602,7 @@ static bool test_t2open(struct torture_context *tctx, struct smbcli_state *cli) __location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status), i, (int)open_funcs[i].with_file, - (int)open_funcs[i].open_func); + open_funcs[i].open_func); ret = false; } if (NT_STATUS_IS_OK(status)) { diff --git a/source4/torture/raw/qfileinfo.c b/source4/torture/raw/qfileinfo.c index 414084080b..ca5f66795e 100644 --- a/source4/torture/raw/qfileinfo.c +++ b/source4/torture/raw/qfileinfo.c @@ -779,7 +779,7 @@ static bool torture_raw_qfileinfo_internals(struct torture_context *torture, s1 = fnum_find("BASIC_INFO"); if (s1 && is_ipc) { if (s1->basic_info.out.attrib != FILE_ATTRIBUTE_NORMAL) { - printf("(%d) attrib basic_info/nlink incorrect - %d should be %d\n", __LINE__, s1->basic_info.out.attrib, FILE_ATTRIBUTE_NORMAL); + printf("(%d) attrib basic_info/nlink incorrect - %d should be %d\n", __LINE__, s1->basic_info.out.attrib, (int)FILE_ATTRIBUTE_NORMAL); ret = false; } } diff --git a/source4/torture/raw/streams.c b/source4/torture/raw/streams.c index 5ce9b756ef..ae3bc2a713 100644 --- a/source4/torture/raw/streams.c +++ b/source4/torture/raw/streams.c @@ -1629,6 +1629,7 @@ static bool test_stream_create_disposition(struct torture_context *tctx, return ret; } +#if 0 /* Test streaminfo with enough streams on a file to fill up the buffer. */ static bool test_stream_large_streaminfo(struct torture_context *tctx, struct smbcli_state *cli) @@ -1674,6 +1675,7 @@ static bool test_stream_large_streaminfo(struct torture_context *tctx, smbcli_deltree(cli->tree, BASEDIR); return ret; } +#endif /* Test the effect of setting attributes on a stream. */ static bool test_stream_attributes(struct torture_context *tctx, @@ -1913,8 +1915,10 @@ struct torture_suite *torture_raw_streams(TALLOC_CTX *tctx) torture_suite_add_1smb_test(suite, "attr", test_stream_attributes); torture_suite_add_1smb_test(suite, "sumtab", test_stream_summary_tab); - /* torture_suite_add_1smb_test(suite, "LARGESTREAMINFO", */ - /* test_stream_large_streaminfo); */ +#if 0 + torture_suite_add_1smb_test(suite, "LARGESTREAMINFO", + test_stream_large_streaminfo); +#endif return suite; } diff --git a/source4/torture/rpc/dsgetinfo.c b/source4/torture/rpc/dsgetinfo.c index 6122ff0603..a0360e8404 100644 --- a/source4/torture/rpc/dsgetinfo.c +++ b/source4/torture/rpc/dsgetinfo.c @@ -88,7 +88,7 @@ static const char *torture_get_ldap_base_dn(struct torture_context *tctx, struct } ldb_set_modules_dir(ldb, - talloc_asprintf(ldb, "%s/ldb", lpcfg_modulesdir(tctx->lp_ctx))); + modules_path(ldb, "ldb")); ret = ldb_connect(ldb, ldap_url, 0, NULL); if (ret != LDB_SUCCESS) { diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c index c4efabcebc..70912781a8 100644 --- a/source4/torture/rpc/remote_pac.c +++ b/source4/torture/rpc/remote_pac.c @@ -476,8 +476,9 @@ static bool test_S2U4Self(struct torture_context *tctx, /* Wipe out any existing ccache */ cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED); - cli_credentials_set_target_service(credentials, talloc_asprintf(tmp_ctx, "host/%s", test_machine_name)); - cli_credentials_set_impersonate_principal(credentials, cli_credentials_get_principal(cmdline_credentials, tmp_ctx)); + cli_credentials_set_impersonate_principal(credentials, + cli_credentials_get_principal(cmdline_credentials, tmp_ctx), + talloc_asprintf(tmp_ctx, "host/%s", test_machine_name)); status = gensec_client_start(tctx, &gensec_client_context, tctx->ev, lpcfg_gensec_settings(tctx, tctx->lp_ctx)); @@ -525,7 +526,7 @@ static bool test_S2U4Self(struct torture_context *tctx, /* Don't pollute the remaining tests with the changed credentials */ cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED); cli_credentials_set_target_service(credentials, NULL); - cli_credentials_set_impersonate_principal(credentials, NULL); + cli_credentials_set_impersonate_principal(credentials, NULL, NULL); /* Extract the PAC using Samba's code */ diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c index 03936f22ff..01ce93f373 100644 --- a/source4/torture/rpc/rpc.c +++ b/source4/torture/rpc/rpc.c @@ -75,7 +75,7 @@ _PUBLIC_ NTSTATUS torture_rpc_connection(struct torture_context *tctx, NTSTATUS status; struct dcerpc_binding *binding; - dcerpc_init(tctx->lp_ctx); + dcerpc_init(); status = torture_rpc_binding(tctx, &binding); if (NT_STATUS_IS_ERR(status)) diff --git a/source4/torture/rpc/spoolss_notify.c b/source4/torture/rpc/spoolss_notify.c index ec29c3944f..ea05d9bd1c 100644 --- a/source4/torture/rpc/spoolss_notify.c +++ b/source4/torture/rpc/spoolss_notify.c @@ -247,20 +247,13 @@ static NTSTATUS spoolss__op_init_server(struct dcesrv_context *dce_ctx, const st static bool test_OpenPrinter(struct torture_context *tctx, struct dcerpc_pipe *p, struct policy_handle *handle, - const char *name) + const char *printername) { struct spoolss_OpenPrinter r; - const char *printername; struct dcerpc_binding_handle *b = p->binding_handle; ZERO_STRUCT(r); - if (name) { - printername = talloc_asprintf(tctx, "\\\\%s\\%s", dcerpc_server_name(p), name); - } else { - printername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); - } - r.in.printername = printername; r.in.datatype = NULL; r.in.devmode_ctr.devmode= NULL; @@ -352,17 +345,17 @@ static bool test_RemoteFindFirstPrinterChangeNotifyEx(struct torture_context *tc static bool test_RouterRefreshPrinterChangeNotify(struct torture_context *tctx, struct dcerpc_binding_handle *b, struct policy_handle *handle, - struct spoolss_NotifyOption *options) + struct spoolss_NotifyOption *options, + struct spoolss_NotifyInfo **info) { struct spoolss_RouterRefreshPrinterChangeNotify r; - struct spoolss_NotifyInfo *info; torture_comment(tctx, "Testing RouterRefreshPrinterChangeNotify\n"); r.in.handle = handle; r.in.change_low = 0; r.in.options = options; - r.out.info = &info; + r.out.info = info; torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_RouterRefreshPrinterChangeNotify_r(b, tctx, &r), "RouterRefreshPrinterChangeNotify failed"); @@ -455,8 +448,8 @@ static bool test_start_dcerpc_server(struct torture_context *tctx, lpcfg_set_cmdline(tctx->lp_ctx, "dcerpc endpoint servers", "spoolss"); - load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces); - address = iface_n_ip(ifaces, 0); + load_interface_list(tctx, tctx->lp_ctx, &ifaces); + address = iface_list_first_v4(ifaces); torture_comment(tctx, "Listening for callbacks on %s\n", address); @@ -503,31 +496,37 @@ static bool test_RFFPCNEx(struct torture_context *tctx, struct spoolss_NotifyOption *printer_option = setup_printer_NotifyOption(tctx); #endif struct dcerpc_binding_handle *b = p->binding_handle; + const char *printername = NULL; + struct spoolss_NotifyInfo *info = NULL; received_packets = NULL; /* Start DCE/RPC server */ torture_assert(tctx, test_start_dcerpc_server(tctx, p->conn->event_ctx, &dce_ctx, &address), ""); - torture_assert(tctx, test_OpenPrinter(tctx, p, &handle, NULL), ""); + printername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); + + torture_assert(tctx, test_OpenPrinter(tctx, p, &handle, printername), ""); torture_assert(tctx, test_RemoteFindFirstPrinterChangeNotifyEx(tctx, b, &handle, address, server_option), ""); torture_assert(tctx, received_packets, "no packets received"); torture_assert_int_equal(tctx, received_packets->opnum, NDR_SPOOLSS_REPLYOPENPRINTER, "no ReplyOpenPrinter packet after RemoteFindFirstPrinterChangeNotifyEx"); - torture_assert(tctx, test_RouterRefreshPrinterChangeNotify(tctx, b, &handle, NULL), ""); - torture_assert(tctx, test_RouterRefreshPrinterChangeNotify(tctx, b, &handle, server_option), ""); + torture_assert(tctx, test_RouterRefreshPrinterChangeNotify(tctx, b, &handle, NULL, &info), ""); + torture_assert(tctx, test_RouterRefreshPrinterChangeNotify(tctx, b, &handle, server_option, &info), ""); torture_assert(tctx, test_ClosePrinter(tctx, b, &handle), ""); tmp = last_packet(received_packets); torture_assert_int_equal(tctx, tmp->opnum, NDR_SPOOLSS_REPLYCLOSEPRINTER, "no ReplyClosePrinter packet after ClosePrinter"); #if 0 + printername = talloc_asprintf(tctx, "\\\\%s\\%s", dcerpc_server_name(p), name); + torture_assert(tctx, test_OpenPrinter(tctx, p, &handle, "Epson AL-2600"), ""); torture_assert(tctx, test_RemoteFindFirstPrinterChangeNotifyEx(tctx, p, &handle, address, printer_option), ""); tmp = last_packet(received_packets); torture_assert_int_equal(tctx, tmp->opnum, NDR_SPOOLSS_REPLYOPENPRINTER, "no ReplyOpenPrinter packet after RemoteFindFirstPrinterChangeNotifyEx"); - torture_assert(tctx, test_RouterRefreshPrinterChangeNotify(tctx, p, &handle, NULL), ""); - torture_assert(tctx, test_RouterRefreshPrinterChangeNotify(tctx, p, &handle, printer_option), ""); + torture_assert(tctx, test_RouterRefreshPrinterChangeNotify(tctx, p, &handle, NULL, &info), ""); + torture_assert(tctx, test_RouterRefreshPrinterChangeNotify(tctx, p, &handle, printer_option, &info), ""); torture_assert(tctx, test_SetPrinter(tctx, p, &handle), ""); tmp = last_packet(received_packets); torture_assert_int_equal(tctx, tmp->opnum, NDR_SPOOLSS_ROUTERREPLYPRINTEREX, diff --git a/source4/torture/rpc/testjoin.c b/source4/torture/rpc/testjoin.c index c4ab0e43ad..76344e0ddf 100644 --- a/source4/torture/rpc/testjoin.c +++ b/source4/torture/rpc/testjoin.c @@ -583,14 +583,14 @@ static NTSTATUS torture_leave_ads_domain(struct torture_context *torture, ldb_set_opaque(ldb_ctx, "loadparm", cmdline_lp_ctx); rtn = ldb_connect(ldb_ctx, remote_ldb_url, 0, NULL); - if (rtn != 0) { + if (rtn != LDB_SUCCESS) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); return NT_STATUS_UNSUCCESSFUL; } rtn = ldb_delete(ldb_ctx, server_dn); - if (rtn != 0) { + if (rtn != LDB_SUCCESS) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); return NT_STATUS_UNSUCCESSFUL; diff --git a/source4/torture/smb2/acls.c b/source4/torture/smb2/acls.c index 3883ae5055..fa6c002da7 100644 --- a/source4/torture/smb2/acls.c +++ b/source4/torture/smb2/acls.c @@ -1662,6 +1662,7 @@ done: CHECK_STATUS_FOR_BIT_ACTION(status, bits, do {} while (0)); \ } while (0) +#if 0 /* test what access mask is needed for getting and setting security_descriptors */ /* Note: This test was copied from raw/acls.c. */ static bool test_sd_get_set(struct torture_context *tctx, struct smb2_tree *tree) @@ -1849,6 +1850,7 @@ done: return ret; } +#endif /* basic testing of SMB2 ACLs @@ -1863,9 +1865,10 @@ struct torture_suite *torture_smb2_acls_init(void) torture_suite_add_1smb2_test(suite, "INHERITANCE", test_inheritance); torture_suite_add_1smb2_test(suite, "INHERITFLAGS", test_inheritance_flags); torture_suite_add_1smb2_test(suite, "DYNAMIC", test_inheritance_dynamic); - /* XXX This test does not work against XP or Vista. +#if 0 + /* XXX This test does not work against XP or Vista. */ torture_suite_add_1smb2_test(suite, "GETSET", test_sd_get_set); - */ +#endif suite->description = talloc_strdup(suite, "SMB2-ACLS tests"); diff --git a/source4/torture/smbtorture.c b/source4/torture/smbtorture.c index 62cf0abfb7..83816e8be5 100644 --- a/source4/torture/smbtorture.c +++ b/source4/torture/smbtorture.c @@ -686,7 +686,7 @@ int main(int argc,char *argv[]) torture->lp_ctx = cmdline_lp_ctx; - gensec_init(cmdline_lp_ctx); + gensec_init(); if (shell) { /* In shell mode, just ignore any remaining test names. */ diff --git a/source4/torture/torture.c b/source4/torture/torture.c index ffd884a38d..9b1719ed7d 100644 --- a/source4/torture/torture.c +++ b/source4/torture/torture.c @@ -43,26 +43,12 @@ bool torture_register_suite(struct torture_suite *suite) return torture_suite_add_suite(torture_root, suite); } -#ifndef ENABLE_LIBNETAPI -NTSTATUS torture_libnetapi_init(void) -{ - return NT_STATUS_OK; -} -#endif - -#ifndef ENABLE_LIBSMBCLIENT -NTSTATUS torture_libsmbclient_init(void) -{ - return NT_STATUS_OK; -} -#endif - _PUBLIC_ int torture_init(void) { #define _MODULE_PROTO(init) extern NTSTATUS init(void); STATIC_smbtorture_MODULES_PROTO; init_module_fn static_init[] = { STATIC_smbtorture_MODULES }; - init_module_fn *shared_init = load_samba_modules(NULL, cmdline_lp_ctx, "smbtorture"); + init_module_fn *shared_init = load_samba_modules(NULL, "smbtorture"); run_init_functions(static_init); run_init_functions(shared_init); diff --git a/source4/torture/unix/whoami.c b/source4/torture/unix/whoami.c index 45b2775646..1e79d7eeb2 100644 --- a/source4/torture/unix/whoami.c +++ b/source4/torture/unix/whoami.c @@ -29,10 +29,6 @@ /* Size (in bytes) of the required fields in the SMBwhoami response. */ #define WHOAMI_REQUIRED_SIZE 40 -enum smb_whoami_flags { - SMB_WHOAMI_GUEST = 0x1 /* Logged in as (or squashed to) guest */ -}; - /* SMBWhoami - Query the user mapping performed by the server for the connected tree. This is a subcommand of the TRANS2_QFSINFO. diff --git a/source4/torture/winbind/struct_based.c b/source4/torture/winbind/struct_based.c index aeb81c972c..2bab94088a 100644 --- a/source4/torture/winbind/struct_based.c +++ b/source4/torture/winbind/struct_based.c @@ -914,7 +914,6 @@ static bool parse_domain_user(struct torture_context *torture, fstrcpy(user, p+1); fstrcpy(domain, domuser); domain[PTR_DIFF(p, domuser)] = 0; - strupper_m(domain); return true; } diff --git a/source4/torture/wscript_build b/source4/torture/wscript_build index 68ec4e6220..106cc64280 100644 --- a/source4/torture/wscript_build +++ b/source4/torture/wscript_build @@ -33,7 +33,7 @@ bld.RECURSE('libnetapi') bld.RECURSE('libsmbclient') bld.SAMBA_SUBSYSTEM('TORTURE_NDR', - source='ndr/ndr.c ndr/winreg.c ndr/atsvc.c ndr/lsa.c ndr/epmap.c ndr/dfs.c ndr/netlogon.c ndr/drsuapi.c ndr/spoolss.c ndr/samr.c ndr/dfsblob.c ndr/drsblobs.c ndr/nbt.c ndr/ntlmssp.c ndr/backupkey.c', + source='ndr/ndr.c ndr/winreg.c ndr/atsvc.c ndr/lsa.c ndr/epmap.c ndr/dfs.c ndr/netlogon.c ndr/drsuapi.c ndr/spoolss.c ndr/samr.c ndr/dfsblob.c ndr/drsblobs.c ndr/nbt.c ndr/ntlmssp.c ndr/backupkey.c ndr/string.c', autoproto='ndr/proto.h', deps='torture' ) diff --git a/source4/utils/ntlm_auth.c b/source4/utils/ntlm_auth.c index a3701f8822..d5c385cbc6 100644 --- a/source4/utils/ntlm_auth.c +++ b/source4/utils/ntlm_auth.c @@ -366,7 +366,7 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, }; struct gensec_ntlm_state *state; struct tevent_context *ev; - struct messaging_context *msg; + struct imessaging_context *msg; NTSTATUS nt_status; bool first = false; @@ -461,9 +461,9 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, case SQUID_2_5_NTLMSSP: { const char *winbind_method[] = { "winbind", NULL }; - struct auth_context *auth_context; + struct auth4_context *auth_context; - msg = messaging_client_init(state, lpcfg_messaging_path(state, lp_ctx), ev); + msg = imessaging_client_init(state, lpcfg_imessaging_path(state, lp_ctx), ev); if (!msg) { talloc_free(mem_ctx); exit(1); @@ -1103,7 +1103,7 @@ int main(int argc, const char **argv) return 1; } - gensec_init(cmdline_lp_ctx); + gensec_init(); if (opt_domain == NULL) { opt_domain = lpcfg_workgroup(cmdline_lp_ctx); diff --git a/source4/web_server/web_server.c b/source4/web_server/web_server.c index 338cc2b57a..cdf6f9b7d0 100644 --- a/source4/web_server/web_server.c +++ b/source4/web_server/web_server.c @@ -248,15 +248,14 @@ static void websrv_send(struct stream_connection *conn, uint16_t flags) */ static void websrv_accept(struct stream_connection *conn) { - struct task_server *task = talloc_get_type(conn->private_data, struct task_server); - struct web_server_data *wdata = talloc_get_type(task->private_data, struct web_server_data); + struct web_server_data *wdata = talloc_get_type(conn->private_data, struct web_server_data); struct websrv_context *web; struct socket_context *tls_socket; web = talloc_zero(conn, struct websrv_context); if (web == NULL) goto failed; - web->task = task; + web->task = wdata->task; web->conn = conn; conn->private_data = web; talloc_set_destructor(web, websrv_destructor); @@ -312,6 +311,7 @@ static void websrv_task_init(struct task_server *task) wdata = talloc_zero(task, struct web_server_data); if (wdata == NULL) goto failed; + wdata->task = task; task->private_data = wdata; if (lpcfg_interfaces(task->lp_ctx) && lpcfg_bind_interfaces_only(task->lp_ctx)) { @@ -319,16 +319,16 @@ static void websrv_task_init(struct task_server *task) int i; struct interface *ifaces; - load_interfaces(NULL, lpcfg_interfaces(task->lp_ctx), &ifaces); + load_interface_list(NULL, task->lp_ctx, &ifaces); - num_interfaces = iface_count(ifaces); + num_interfaces = iface_list_count(ifaces); for(i = 0; i < num_interfaces; i++) { - const char *address = iface_n_ip(ifaces, i); + const char *address = iface_list_n_ip(ifaces, i); status = stream_setup_socket(task, task->event_ctx, task->lp_ctx, model_ops, &web_stream_ops, - "ipv4", address, + "ip", address, &port, lpcfg_socket_options(task->lp_ctx), task); if (!NT_STATUS_IS_OK(status)) goto failed; @@ -336,13 +336,23 @@ static void websrv_task_init(struct task_server *task) talloc_free(ifaces); } else { - status = stream_setup_socket(task, task->event_ctx, - task->lp_ctx, model_ops, - &web_stream_ops, - "ipv4", lpcfg_socket_address(task->lp_ctx), - &port, lpcfg_socket_options(task->lp_ctx), - task); - if (!NT_STATUS_IS_OK(status)) goto failed; + const char **wcard; + int i; + wcard = iface_list_wildcard(task, task->lp_ctx); + if (wcard == NULL) { + DEBUG(0,("No wildcard addresses available\n")); + goto failed; + } + for (i=0; wcard[i]; i++) { + status = stream_setup_socket(task, task->event_ctx, + task->lp_ctx, model_ops, + &web_stream_ops, + "ip", wcard[i], + &port, lpcfg_socket_options(task->lp_ctx), + wdata); + if (!NT_STATUS_IS_OK(status)) goto failed; + } + talloc_free(wcard); } wdata->tls_params = tls_initialise(wdata, task->lp_ctx); diff --git a/source4/web_server/web_server.h b/source4/web_server/web_server.h index aa4d83c17b..274a54a5c3 100644 --- a/source4/web_server/web_server.h +++ b/source4/web_server/web_server.h @@ -29,6 +29,7 @@ struct web_server_data { void (*http_process_input)(struct web_server_data *wdata, struct websrv_context *web); void *private_data; + struct task_server *task; }; struct http_header { diff --git a/source4/winbind/idmap.c b/source4/winbind/idmap.c index ff57064d48..4f2a54384c 100644 --- a/source4/winbind/idmap.c +++ b/source4/winbind/idmap.c @@ -164,7 +164,7 @@ struct idmap_context *idmap_init(TALLOC_CTX *mem_ctx, idmap_ctx->lp_ctx = lp_ctx; idmap_ctx->ldb_ctx = ldb_wrap_connect(mem_ctx, ev_ctx, lp_ctx, - lpcfg_idmap_url(lp_ctx), + "idmap.ldb", system_session(lp_ctx), NULL, 0); if (idmap_ctx->ldb_ctx == NULL) { diff --git a/source4/winbind/wb_init_domain.c b/source4/winbind/wb_init_domain.c index 50a6af05fd..9847afbba0 100644 --- a/source4/winbind/wb_init_domain.c +++ b/source4/winbind/wb_init_domain.c @@ -154,7 +154,7 @@ struct composite_context *wb_init_domain_send(TALLOC_CTX *mem_ctx, (lpcfg_server_role(service->task->lp_ctx) == ROLE_DOMAIN_CONTROLLER)) && (dom_sid_equal(state->domain->info->sid, state->service->primary_sid))) { - state->domain->netlogon_binding->flags |= DCERPC_SCHANNEL; + state->domain->netlogon_binding->flags |= DCERPC_SCHANNEL | DCERPC_SCHANNEL_128; /* For debugging, it can be a real pain if all the traffic is encrypted */ if (lpcfg_winbind_sealed_pipes(service->task->lp_ctx)) { diff --git a/source4/winbind/wb_samba3_protocol.c b/source4/winbind/wb_samba3_protocol.c index 4bb0582cd2..f0f803dac5 100644 --- a/source4/winbind/wb_samba3_protocol.c +++ b/source4/winbind/wb_samba3_protocol.c @@ -183,6 +183,7 @@ NTSTATUS wbsrv_samba3_handle_call(struct wbsrv_samba3_call *s3call) case WINBINDD_PAM_CHAUTHTOK: case WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP: case WINBINDD_LOOKUPRIDS: + case WINBINDD_LOOKUPSIDS: case WINBINDD_SIDS_TO_XIDS: case WINBINDD_ALLOCATE_UID: case WINBINDD_ALLOCATE_GID: @@ -199,7 +200,11 @@ NTSTATUS wbsrv_samba3_handle_call(struct wbsrv_samba3_call *s3call) case WINBINDD_DUAL_NDRCMD: case WINBINDD_CCACHE_NTLMAUTH: case WINBINDD_NUM_CMDS: - DEBUG(10, ("Unimplemented winbind samba3 request %d\n", + case WINBINDD_CHANGE_MACHACC: + case WINBINDD_PING_DC: + case WINBINDD_DC_INFO: + case WINBINDD_CCACHE_SAVE: + DEBUG(10, ("Unimplemented winbind samba3 request %d\n", s3call->request->cmd)); break; } diff --git a/source4/winbind/wb_server.h b/source4/winbind/wb_server.h index f20bc0aa51..12dd1888ed 100644 --- a/source4/winbind/wb_server.h +++ b/source4/winbind/wb_server.h @@ -104,7 +104,7 @@ struct wbsrv_connection { #define WBSRV_SAMBA3_SET_STRING(dest, src) do { \ memset(dest, 0, sizeof(dest));\ - safe_strcpy(dest, src, sizeof(dest)-1);\ + strlcpy((dest), (src) ? (src) : "", sizeof(dest));\ } while(0) /* diff --git a/source4/wrepl_server/wrepl_in_connection.c b/source4/wrepl_server/wrepl_in_connection.c index 9d3ddbf0da..962a1cb7fa 100644 --- a/source4/wrepl_server/wrepl_in_connection.c +++ b/source4/wrepl_server/wrepl_in_connection.c @@ -441,16 +441,19 @@ NTSTATUS wreplsrv_setup_sockets(struct wreplsrv_service *service, struct loadpar int i; struct interface *ifaces; - load_interfaces(task, lpcfg_interfaces(lp_ctx), &ifaces); + load_interface_list(task, lp_ctx, &ifaces); - num_interfaces = iface_count(ifaces); + num_interfaces = iface_list_count(ifaces); /* We have been given an interfaces line, and been told to only bind to those interfaces. Create a socket per interface and bind to only these. */ for(i = 0; i < num_interfaces; i++) { - address = iface_n_ip(ifaces, i); + if (!iface_list_n_is_v4(ifaces, i)) { + continue; + } + address = iface_list_n_ip(ifaces, i); status = stream_setup_socket(task, task->event_ctx, task->lp_ctx, model_ops, &wreplsrv_stream_ops, @@ -465,6 +468,9 @@ NTSTATUS wreplsrv_setup_sockets(struct wreplsrv_service *service, struct loadpar } } else { address = lpcfg_socket_address(lp_ctx); + if (strcmp(address, "") == 0) { + address = "0.0.0.0"; + } status = stream_setup_socket(task, task->event_ctx, task->lp_ctx, model_ops, &wreplsrv_stream_ops, "ipv4", address, &port, lpcfg_socket_options(task->lp_ctx), diff --git a/source4/wrepl_server/wrepl_scavenging.c b/source4/wrepl_server/wrepl_scavenging.c index 18d4780c0b..d04064970c 100644 --- a/source4/wrepl_server/wrepl_scavenging.c +++ b/source4/wrepl_server/wrepl_scavenging.c @@ -306,7 +306,7 @@ static NTSTATUS wreplsrv_scavenging_replica_non_active_records(struct wreplsrv_s } struct verify_state { - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; struct wreplsrv_service *service; struct winsdb_record *rec; struct nbtd_proxy_wins_challenge r; diff --git a/source4/wrepl_server/wrepl_server.c b/source4/wrepl_server/wrepl_server.c index 83510c73a8..79e0cfc24d 100644 --- a/source4/wrepl_server/wrepl_server.c +++ b/source4/wrepl_server/wrepl_server.c @@ -38,7 +38,7 @@ static struct ldb_context *wins_config_db_connect(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, struct loadparm_context *lp_ctx) { - return ldb_wrap_connect(mem_ctx, ev_ctx, lp_ctx, private_path(mem_ctx, + return ldb_wrap_connect(mem_ctx, ev_ctx, lp_ctx, lpcfg_private_path(mem_ctx, lp_ctx, lpcfg_wins_config_url(lp_ctx)), system_session(lp_ctx), NULL, 0); } @@ -78,8 +78,8 @@ static NTSTATUS wreplsrv_open_winsdb(struct wreplsrv_service *service, if (owner == NULL) { struct interface *ifaces; - load_interfaces(service, lpcfg_interfaces(lp_ctx), &ifaces); - owner = iface_n_ip(ifaces, 0); + load_interface_list(service, lp_ctx, &ifaces); + owner = iface_list_first_v4(ifaces); } service->wins_db = winsdb_connect(service, service->task->event_ctx, lp_ctx, owner, WINSDB_HANDLE_CALLER_WREPL); |