diff options
Diffstat (limited to 'source3')
77 files changed, 2627 insertions, 3466 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index b1f1658c68..1376f4c07a 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -482,7 +482,7 @@ LIBSMB_OBJ0 = \ libsmb/ntlmssp.o \ libsmb/ntlmssp_sign.o \ $(LIBNDR_NTLMSSP_OBJ) \ - libsmb/ntlmssp_ndr.o + ../libcli/auth/ntlmssp_ndr.o LIBSAMBA_OBJ = $(LIBSMB_OBJ0) \ $(LIBSMB_ERR_OBJ) @@ -862,10 +862,8 @@ STATUS_OBJ = utils/status.o utils/status_profile.o \ $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \ $(LIBSAMBA_OBJ) $(FNAME_UTIL_OBJ) -SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \ - $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \ - $(LIBSAMBA_OBJ) $(FNAME_UTIL_OBJ) \ - $(PRINTBASE_OBJ) +SMBCONTROL_OBJ = utils/smbcontrol.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \ + $(LIBSMB_ERR_OBJ) $(POPT_LIB_OBJ) $(PRINTBASE_OBJ) SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \ $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) \ @@ -1148,7 +1146,6 @@ IDMAP_ADEX_OBJ = \ WINBINDD_OBJ1 = \ winbindd/winbindd.o \ - winbindd/winbindd_user.o \ winbindd/winbindd_group.o \ winbindd/winbindd_util.o \ winbindd/winbindd_cache.o \ @@ -1226,6 +1223,7 @@ WINBINDD_OBJ1 = \ winbindd/winbindd_list_groups.o \ winbindd/winbindd_check_machine_acct.o \ winbindd/winbindd_change_machine_acct.o \ + winbindd/winbindd_ping_dc.o \ winbindd/winbindd_set_mapping.o \ winbindd/winbindd_remove_mapping.o \ winbindd/winbindd_set_hwm.o \ diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c index 034d354a33..4243a24ca7 100644 --- a/source3/auth/auth_ntlmssp.c +++ b/source3/auth/auth_ntlmssp.c @@ -21,19 +21,21 @@ */ #include "includes.h" +#include "ntlmssp.h" /** * Return the challenge as determined by the authentication subsystem * @return an 8 byte random challenge */ -static void auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state, - uint8_t chal[8]) +static NTSTATUS auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state, + uint8_t chal[8]) { AUTH_NTLMSSP_STATE *auth_ntlmssp_state = (AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context; auth_ntlmssp_state->auth_context->get_ntlm_challenge( auth_ntlmssp_state->auth_context, chal); + return NT_STATUS_OK; } /** diff --git a/source3/include/async_smb.h b/source3/include/async_smb.h index 03dd274539..47fed92739 100644 --- a/source3/include/async_smb.h +++ b/source3/include/async_smb.h @@ -22,11 +22,6 @@ #include "includes.h" -bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command, - uint8_t wct, const uint16_t *vwv, - size_t bytes_alignment, - uint32_t num_bytes, const uint8_t *bytes); - /* * Fetch an error out of a NBT packet */ diff --git a/source3/include/client.h b/source3/include/client.h index 82d94b055f..d5030c1cb2 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -56,7 +56,7 @@ struct cli_pipe_auth_data { union { struct schannel_state *schannel_auth; - NTLMSSP_STATE *ntlmssp_state; + struct ntlmssp_state *ntlmssp_state; struct kerberos_auth_struct *kerberos_auth; } a_u; }; @@ -172,7 +172,7 @@ struct smb_trans_enc_state { uint16 enc_ctx_num; bool enc_on; union { - NTLMSSP_STATE *ntlmssp_state; + struct ntlmssp_state *ntlmssp_state; #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) struct smb_tran_enc_state_gss *gss_state; #endif diff --git a/source3/include/includes.h b/source3/include/includes.h index cf0979592c..d9d51a8a99 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -659,7 +659,9 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx); #include "../lib/crypto/arcfour.h" #include "../lib/crypto/crc32.h" #include "../lib/crypto/hmacmd5.h" -#include "ntlmssp.h" + +struct ntlmssp_state; + #include "auth.h" #include "ntdomain.h" #include "reg_objects.h" diff --git a/source3/include/ntlmssp.h b/source3/include/ntlmssp.h index 9f47c9c555..d3de59835f 100644 --- a/source3/include/ntlmssp.h +++ b/source3/include/ntlmssp.h @@ -20,14 +20,14 @@ */ /* NTLMSSP mode */ -enum NTLMSSP_ROLE +enum ntlmssp_role { NTLMSSP_SERVER, NTLMSSP_CLIENT }; /* NTLMSSP message types */ -enum NTLM_MESSAGE_TYPE +enum ntlmssp_message_type { NTLMSSP_INITIAL = 0 /* samba internal state */, NTLMSSP_NEGOTIATE = 1, @@ -41,12 +41,11 @@ enum NTLM_MESSAGE_TYPE #define NTLMSSP_FEATURE_SIGN 0x00000002 #define NTLMSSP_FEATURE_SEAL 0x00000004 -typedef struct ntlmssp_state +struct ntlmssp_state { - unsigned int ref_count; - enum NTLMSSP_ROLE role; + enum ntlmssp_role role; enum server_types server_role; - uint32 expected_state; + uint32_t expected_state; bool unicode; bool use_ntlmv2; @@ -60,11 +59,11 @@ typedef struct ntlmssp_state DATA_BLOB internal_chal; /* Random challenge as supplied to the client for NTLM authentication */ DATA_BLOB chal; /* Random challenge as input into the actual NTLM (or NTLM2) authentication */ - DATA_BLOB lm_resp; + DATA_BLOB lm_resp; DATA_BLOB nt_resp; DATA_BLOB session_key; - uint32 neg_flags; /* the current state of negotiation with the NTLMSSP partner */ + uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */ void *auth_context; @@ -72,11 +71,11 @@ typedef struct ntlmssp_state * Callback to get the 'challenge' used for NTLM authentication. * * @param ntlmssp_state This structure - * @return 8 bytes of challnege data, determined by the server to be the challenge for NTLM authentication + * @return 8 bytes of challenge data, determined by the server to be the challenge for NTLM authentication * */ - void (*get_challenge)(const struct ntlmssp_state *ntlmssp_state, - uint8_t challenge[8]); + NTSTATUS (*get_challenge)(const struct ntlmssp_state *ntlmssp_state, + uint8_t challenge[8]); /** * Callback to find if the challenge used by NTLM authentication may be modified @@ -126,15 +125,10 @@ typedef struct ntlmssp_state struct arcfour_state send_seal_arc4_state; struct arcfour_state recv_seal_arc4_state; - uint32 ntlm2_send_seq_num; - uint32 ntlm2_recv_seq_num; + uint32_t ntlm2_send_seq_num; + uint32_t ntlm2_recv_seq_num; /* ntlmv1 */ struct arcfour_state ntlmv1_arc4_state; - uint32 ntlmv1_seq_num; - - /* it turns out that we don't always get the - response in at the time we want to process it. - Store it here, until we need it */ - DATA_BLOB stored_response; -} NTLMSSP_STATE; + uint32_t ntlmv1_seq_num; +}; diff --git a/source3/include/proto.h b/source3/include/proto.h index ab74c9cb95..b3921c468e 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2165,7 +2165,11 @@ struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct cli_state *cli); NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req); -bool cli_ulogoff(struct cli_state *cli); +struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli); +NTSTATUS cli_ulogoff_recv(struct tevent_req *req); +NTSTATUS cli_ulogoff(struct cli_state *cli); struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx, struct event_context *ev, struct cli_state *cli, @@ -2180,7 +2184,11 @@ struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx, NTSTATUS cli_tcon_andx_recv(struct tevent_req *req); NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share, const char *dev, const char *pass, int passlen); -bool cli_tdis(struct cli_state *cli); +struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli); +NTSTATUS cli_tdis_recv(struct tevent_req *req); +NTSTATUS cli_tdis(struct cli_state *cli); void cli_negprot_sendsync(struct cli_state *cli); NTSTATUS cli_negprot(struct cli_state *cli); struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx, @@ -3057,8 +3065,6 @@ NTSTATUS cli_trans(TALLOC_CTX *mem_ctx, struct cli_state *cli, NTSTATUS check_negative_conn_cache_timeout( const char *domain, const char *server, unsigned int failed_cache_timeout ); NTSTATUS check_negative_conn_cache( const char *domain, const char *server); void add_failed_connection_entry(const char *domain, const char *server, NTSTATUS result) ; -void delete_negative_conn_cache(const char *domain, const char *server); -void flush_negative_conn_cache( void ); void flush_negative_conn_cache_for_domain(const char *domain); /* The following definitions come from ../librpc/rpc/dcerpc_error.c */ @@ -3213,43 +3219,41 @@ NTSTATUS nt_status_squash(NTSTATUS nt_status); /* The following definitions come from libsmb/ntlmssp.c */ void debug_ntlmssp_flags(uint32 neg_flags); -NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user) ; -NTSTATUS ntlmssp_set_hashes(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user) ; +NTSTATUS ntlmssp_set_hashes(struct ntlmssp_state *ntlmssp_state, const unsigned char lm_hash[16], const unsigned char nt_hash[16]) ; -NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password) ; -NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) ; -NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation) ; -NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state, - DATA_BLOB response) ; -void ntlmssp_want_feature_list(NTLMSSP_STATE *ntlmssp_state, char *feature_list); -void ntlmssp_want_feature(NTLMSSP_STATE *ntlmssp_state, uint32 feature); -NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password) ; +NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) ; +NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation) ; +void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *feature_list); +void ntlmssp_want_feature(struct ntlmssp_state *ntlmssp_state, uint32 feature); +NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, const DATA_BLOB in, DATA_BLOB *out) ; -void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state); -DATA_BLOB ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state, TALLOC_CTX *mem_ctx); -NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state); -NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state); +void ntlmssp_end(struct ntlmssp_state **ntlmssp_state); +DATA_BLOB ntlmssp_weaken_keys(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *mem_ctx); +NTSTATUS ntlmssp_server_start(struct ntlmssp_state **ntlmssp_state); +NTSTATUS ntlmssp_client_start(struct ntlmssp_state **ntlmssp_state); /* The following definitions come from libsmb/ntlmssp_sign.c */ -NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_sign_packet(struct ntlmssp_state *ntlmssp_state, const uchar *data, size_t length, const uchar *whole_pdu, size_t pdu_length, DATA_BLOB *sig) ; -NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state, const uchar *data, size_t length, const uchar *whole_pdu, size_t pdu_length, const DATA_BLOB *sig) ; -NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, uchar *data, size_t length, uchar *whole_pdu, size_t pdu_length, DATA_BLOB *sig); -NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_unseal_packet(struct ntlmssp_state *ntlmssp_state, uchar *data, size_t length, uchar *whole_pdu, size_t pdu_length, DATA_BLOB *sig); -NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state); +NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state); /* The following definitions come from libsmb/passchange.c */ @@ -3270,8 +3274,8 @@ bool netsamlogon_cache_have(const DOM_SID *user_sid); NTSTATUS get_enc_ctx_num(const uint8_t *buf, uint16 *p_enc_ctx_num); bool common_encryption_on(struct smb_trans_enc_state *es); -NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf); -NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS common_ntlm_decrypt_buffer(struct ntlmssp_state *ntlmssp_state, char *buf); +NTSTATUS common_ntlm_encrypt_buffer(struct ntlmssp_state *ntlmssp_state, uint16 enc_ctx_num, char *buf, char **ppbuf_out); @@ -6277,9 +6281,7 @@ void error_packet_set(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatu int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file); void reply_nt_error(struct smb_request *req, NTSTATUS ntstatus, int line, const char *file); -void reply_force_nt_error(struct smb_request *req, NTSTATUS ntstatus, - int line, const char *file); -void reply_dos_error(struct smb_request *req, uint8 eclass, uint32 ecode, +void reply_force_dos_error(struct smb_request *req, uint8 eclass, uint32 ecode, int line, const char *file); void reply_both_error(struct smb_request *req, uint8 eclass, uint32 ecode, NTSTATUS status, int line, const char *file); @@ -6737,6 +6739,10 @@ void reply_pipe_close(connection_struct *conn, struct smb_request *req); void create_file_sids(const SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid); bool nt4_compatible_acls(void); +uint32_t map_canon_ace_perms(int snum, + enum security_ace_type *pacl_type, + mode_t perms, + bool directory_ace); NTSTATUS unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_sent, const SEC_DESC *psd); SMB_ACL_T free_empty_sys_acl(connection_struct *conn, SMB_ACL_T the_acl); NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, diff --git a/source3/include/smb.h b/source3/include/smb.h index 4affd4a8cf..b23ea647ec 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -27,7 +27,7 @@ #define _SMB_H /* logged when starting the various Samba daemons */ -#define COPYRIGHT_STARTUP_MESSAGE "Copyright Andrew Tridgell and the Samba Team 1992-2009" +#define COPYRIGHT_STARTUP_MESSAGE "Copyright Andrew Tridgell and the Samba Team 1992-2010" #if defined(LARGE_SMB_OFF_T) diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h index 10ee78b394..bc5d9a7fe1 100644 --- a/source3/include/smb_macros.h +++ b/source3/include/smb_macros.h @@ -112,8 +112,7 @@ #define ERROR_BOTH(status,class,code) error_packet(outbuf,class,code,status,__LINE__,__FILE__) #define reply_nterror(req,status) reply_nt_error(req,status,__LINE__,__FILE__) -#define reply_force_nterror(req,status) reply_force_nt_error(req,status,__LINE__,__FILE__) -#define reply_doserror(req,eclass,ecode) reply_dos_error(req,eclass,ecode,__LINE__,__FILE__) +#define reply_force_doserror(req,eclass,ecode) reply_force_dos_error(req,eclass,ecode,__LINE__,__FILE__) #define reply_botherror(req,status,eclass,ecode) reply_both_error(req,eclass,ecode,status,__LINE__,__FILE__) #if 0 diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index 639269cac2..1f47bf35f0 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -557,17 +557,18 @@ char *sid_binstring_hex(const DOM_SID *sid) Tallocs a duplicate SID. ********************************************************************/ -DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, const DOM_SID *src) +struct dom_sid *sid_dup_talloc(TALLOC_CTX *ctx, const struct dom_sid *src) { - DOM_SID *dst; - - if(!src) + struct dom_sid *dst; + + if (src == NULL) { return NULL; - - if((dst = TALLOC_ZERO_P(ctx, DOM_SID)) != NULL) { - sid_copy( dst, src); } - + dst = talloc_zero(ctx, struct dom_sid); + if (dst == NULL) { + return NULL; + } + sid_copy(dst, src); return dst; } diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 9b4d8bd2d4..6a0a1ae3d2 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -19,6 +19,7 @@ #include "includes.h" #include "../libcli/auth/spnego.h" +#include "ntlmssp.h" #ifdef HAVE_LDAP diff --git a/source3/librpc/gen_ndr/cli_wbint.c b/source3/librpc/gen_ndr/cli_wbint.c index 3115a20d9d..592b27b50d 100644 --- a/source3/librpc/gen_ndr/cli_wbint.c +++ b/source3/librpc/gen_ndr/cli_wbint.c @@ -2901,6 +2901,136 @@ NTSTATUS rpccli_wbint_ChangeMachineAccount(struct rpc_pipe_client *cli, return r.out.result; } +struct rpccli_wbint_PingDc_state { + struct wbint_PingDc orig; + struct wbint_PingDc tmp; + TALLOC_CTX *out_mem_ctx; + NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx); +}; + +static void rpccli_wbint_PingDc_done(struct tevent_req *subreq); + +struct tevent_req *rpccli_wbint_PingDc_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct rpc_pipe_client *cli) +{ + struct tevent_req *req; + struct rpccli_wbint_PingDc_state *state; + struct tevent_req *subreq; + + req = tevent_req_create(mem_ctx, &state, + struct rpccli_wbint_PingDc_state); + if (req == NULL) { + return NULL; + } + state->out_mem_ctx = NULL; + state->dispatch_recv = cli->dispatch_recv; + + /* In parameters */ + + /* Out parameters */ + + /* Result */ + ZERO_STRUCT(state->orig.out.result); + + /* make a temporary copy, that we pass to the dispatch function */ + state->tmp = state->orig; + + subreq = cli->dispatch_send(state, ev, cli, + &ndr_table_wbint, + NDR_WBINT_PINGDC, + &state->tmp); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, rpccli_wbint_PingDc_done, req); + return req; +} + +static void rpccli_wbint_PingDc_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpccli_wbint_PingDc_state *state = tevent_req_data( + req, struct rpccli_wbint_PingDc_state); + NTSTATUS status; + TALLOC_CTX *mem_ctx; + + if (state->out_mem_ctx) { + mem_ctx = state->out_mem_ctx; + } else { + mem_ctx = state; + } + + status = state->dispatch_recv(subreq, mem_ctx); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + + /* Copy out parameters */ + + /* Copy result */ + state->orig.out.result = state->tmp.out.result; + + /* Reset temporary structure */ + ZERO_STRUCT(state->tmp); + + tevent_req_done(req); +} + +NTSTATUS rpccli_wbint_PingDc_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + NTSTATUS *result) +{ + struct rpccli_wbint_PingDc_state *state = tevent_req_data( + req, struct rpccli_wbint_PingDc_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; + } + + /* Steal possbile out parameters to the callers context */ + talloc_steal(mem_ctx, state->out_mem_ctx); + + /* Return result */ + *result = state->orig.out.result; + + tevent_req_received(req); + return NT_STATUS_OK; +} + +NTSTATUS rpccli_wbint_PingDc(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx) +{ + struct wbint_PingDc r; + NTSTATUS status; + + /* In parameters */ + + status = cli->dispatch(cli, + mem_ctx, + &ndr_table_wbint, + NDR_WBINT_PINGDC, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + return r.out.result; +} + struct rpccli_wbint_SetMapping_state { struct wbint_SetMapping orig; struct wbint_SetMapping tmp; diff --git a/source3/librpc/gen_ndr/cli_wbint.h b/source3/librpc/gen_ndr/cli_wbint.h index b08ef3fef1..4528d43efc 100644 --- a/source3/librpc/gen_ndr/cli_wbint.h +++ b/source3/librpc/gen_ndr/cli_wbint.h @@ -248,6 +248,14 @@ NTSTATUS rpccli_wbint_ChangeMachineAccount_recv(struct tevent_req *req, NTSTATUS *result); NTSTATUS rpccli_wbint_ChangeMachineAccount(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx); +struct tevent_req *rpccli_wbint_PingDc_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct rpc_pipe_client *cli); +NTSTATUS rpccli_wbint_PingDc_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + NTSTATUS *result); +NTSTATUS rpccli_wbint_PingDc(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx); struct tevent_req *rpccli_wbint_SetMapping_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct rpc_pipe_client *cli, diff --git a/source3/librpc/gen_ndr/ndr_wbint.c b/source3/librpc/gen_ndr/ndr_wbint.c index 97b29761ee..50f781cc20 100644 --- a/source3/librpc/gen_ndr/ndr_wbint.c +++ b/source3/librpc/gen_ndr/ndr_wbint.c @@ -2232,6 +2232,47 @@ _PUBLIC_ void ndr_print_wbint_ChangeMachineAccount(struct ndr_print *ndr, const ndr->depth--; } +static enum ndr_err_code ndr_push_wbint_PingDc(struct ndr_push *ndr, int flags, const struct wbint_PingDc *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_wbint_PingDc(struct ndr_pull *ndr, int flags, struct wbint_PingDc *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_wbint_PingDc(struct ndr_print *ndr, const char *name, int flags, const struct wbint_PingDc *r) +{ + ndr_print_struct(ndr, name, "wbint_PingDc"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "wbint_PingDc"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "wbint_PingDc"); + ndr->depth++; + ndr_print_NTSTATUS(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + static enum ndr_err_code ndr_push_wbint_SetMapping(struct ndr_push *ndr, int flags, const struct wbint_SetMapping *r) { if (flags & NDR_IN) { @@ -2567,6 +2608,14 @@ static const struct ndr_interface_call wbint_calls[] = { false, }, { + "wbint_PingDc", + sizeof(struct wbint_PingDc), + (ndr_push_flags_fn_t) ndr_push_wbint_PingDc, + (ndr_pull_flags_fn_t) ndr_pull_wbint_PingDc, + (ndr_print_function_t) ndr_print_wbint_PingDc, + false, + }, + { "wbint_SetMapping", sizeof(struct wbint_SetMapping), (ndr_push_flags_fn_t) ndr_push_wbint_SetMapping, @@ -2619,7 +2668,7 @@ const struct ndr_interface_table ndr_table_wbint = { NDR_WBINT_VERSION }, .helpstring = NDR_WBINT_HELPSTRING, - .num_calls = 23, + .num_calls = 24, .calls = wbint_calls, .endpoints = &wbint_endpoints, .authservices = &wbint_authservices diff --git a/source3/librpc/gen_ndr/ndr_wbint.h b/source3/librpc/gen_ndr/ndr_wbint.h index e163ff3674..4a381ccfb2 100644 --- a/source3/librpc/gen_ndr/ndr_wbint.h +++ b/source3/librpc/gen_ndr/ndr_wbint.h @@ -51,13 +51,15 @@ extern const struct ndr_interface_table ndr_table_wbint; #define NDR_WBINT_CHANGEMACHINEACCOUNT (0x13) -#define NDR_WBINT_SETMAPPING (0x14) +#define NDR_WBINT_PINGDC (0x14) -#define NDR_WBINT_REMOVEMAPPING (0x15) +#define NDR_WBINT_SETMAPPING (0x15) -#define NDR_WBINT_SETHWM (0x16) +#define NDR_WBINT_REMOVEMAPPING (0x16) -#define NDR_WBINT_CALL_COUNT (23) +#define NDR_WBINT_SETHWM (0x17) + +#define NDR_WBINT_CALL_COUNT (24) enum ndr_err_code ndr_push_wbint_userinfo(struct ndr_push *ndr, int ndr_flags, const struct wbint_userinfo *r); enum ndr_err_code ndr_pull_wbint_userinfo(struct ndr_pull *ndr, int ndr_flags, struct wbint_userinfo *r); void ndr_print_wbint_userinfo(struct ndr_print *ndr, const char *name, const struct wbint_userinfo *r); @@ -99,6 +101,7 @@ void ndr_print_wbint_DsGetDcName(struct ndr_print *ndr, const char *name, int fl void ndr_print_wbint_LookupRids(struct ndr_print *ndr, const char *name, int flags, const struct wbint_LookupRids *r); void ndr_print_wbint_CheckMachineAccount(struct ndr_print *ndr, const char *name, int flags, const struct wbint_CheckMachineAccount *r); void ndr_print_wbint_ChangeMachineAccount(struct ndr_print *ndr, const char *name, int flags, const struct wbint_ChangeMachineAccount *r); +void ndr_print_wbint_PingDc(struct ndr_print *ndr, const char *name, int flags, const struct wbint_PingDc *r); void ndr_print_wbint_SetMapping(struct ndr_print *ndr, const char *name, int flags, const struct wbint_SetMapping *r); void ndr_print_wbint_RemoveMapping(struct ndr_print *ndr, const char *name, int flags, const struct wbint_RemoveMapping *r); void ndr_print_wbint_SetHWM(struct ndr_print *ndr, const char *name, int flags, const struct wbint_SetHWM *r); diff --git a/source3/librpc/gen_ndr/srv_wbint.c b/source3/librpc/gen_ndr/srv_wbint.c index 0f39cd93e1..efd9be6b7a 100644 --- a/source3/librpc/gen_ndr/srv_wbint.c +++ b/source3/librpc/gen_ndr/srv_wbint.c @@ -1610,6 +1610,79 @@ static bool api_wbint_ChangeMachineAccount(pipes_struct *p) return true; } +static bool api_wbint_PingDc(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct wbint_PingDc *r; + + call = &ndr_table_wbint.calls[NDR_WBINT_PINGDC]; + + r = talloc(talloc_tos(), struct wbint_PingDc); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r, NULL); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(wbint_PingDc, r); + } + + r->out.result = _wbint_PingDc(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(wbint_PingDc, r); + } + + push = ndr_push_init_ctx(r, NULL); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + static bool api_wbint_SetMapping(pipes_struct *p) { const struct ndr_interface_call *call; @@ -1853,6 +1926,7 @@ static struct api_struct api_wbint_cmds[] = {"WBINT_LOOKUPRIDS", NDR_WBINT_LOOKUPRIDS, api_wbint_LookupRids}, {"WBINT_CHECKMACHINEACCOUNT", NDR_WBINT_CHECKMACHINEACCOUNT, api_wbint_CheckMachineAccount}, {"WBINT_CHANGEMACHINEACCOUNT", NDR_WBINT_CHANGEMACHINEACCOUNT, api_wbint_ChangeMachineAccount}, + {"WBINT_PINGDC", NDR_WBINT_PINGDC, api_wbint_PingDc}, {"WBINT_SETMAPPING", NDR_WBINT_SETMAPPING, api_wbint_SetMapping}, {"WBINT_REMOVEMAPPING", NDR_WBINT_REMOVEMAPPING, api_wbint_RemoveMapping}, {"WBINT_SETHWM", NDR_WBINT_SETHWM, api_wbint_SetHWM}, @@ -2115,6 +2189,12 @@ NTSTATUS rpc_wbint_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, co return NT_STATUS_OK; } + case NDR_WBINT_PINGDC: { + struct wbint_PingDc *r = (struct wbint_PingDc *)_r; + r->out.result = _wbint_PingDc(cli->pipes_struct, r); + return NT_STATUS_OK; + } + case NDR_WBINT_SETMAPPING: { struct wbint_SetMapping *r = (struct wbint_SetMapping *)_r; r->out.result = _wbint_SetMapping(cli->pipes_struct, r); diff --git a/source3/librpc/gen_ndr/srv_wbint.h b/source3/librpc/gen_ndr/srv_wbint.h index c8c04fb3cc..716f1ac9d1 100644 --- a/source3/librpc/gen_ndr/srv_wbint.h +++ b/source3/librpc/gen_ndr/srv_wbint.h @@ -21,6 +21,7 @@ NTSTATUS _wbint_DsGetDcName(pipes_struct *p, struct wbint_DsGetDcName *r); NTSTATUS _wbint_LookupRids(pipes_struct *p, struct wbint_LookupRids *r); NTSTATUS _wbint_CheckMachineAccount(pipes_struct *p, struct wbint_CheckMachineAccount *r); NTSTATUS _wbint_ChangeMachineAccount(pipes_struct *p, struct wbint_ChangeMachineAccount *r); +NTSTATUS _wbint_PingDc(pipes_struct *p, struct wbint_PingDc *r); NTSTATUS _wbint_SetMapping(pipes_struct *p, struct wbint_SetMapping *r); NTSTATUS _wbint_RemoveMapping(pipes_struct *p, struct wbint_RemoveMapping *r); NTSTATUS _wbint_SetHWM(pipes_struct *p, struct wbint_SetHWM *r); @@ -46,6 +47,7 @@ NTSTATUS _wbint_DsGetDcName(pipes_struct *p, struct wbint_DsGetDcName *r); NTSTATUS _wbint_LookupRids(pipes_struct *p, struct wbint_LookupRids *r); NTSTATUS _wbint_CheckMachineAccount(pipes_struct *p, struct wbint_CheckMachineAccount *r); NTSTATUS _wbint_ChangeMachineAccount(pipes_struct *p, struct wbint_ChangeMachineAccount *r); +NTSTATUS _wbint_PingDc(pipes_struct *p, struct wbint_PingDc *r); NTSTATUS _wbint_SetMapping(pipes_struct *p, struct wbint_SetMapping *r); NTSTATUS _wbint_RemoveMapping(pipes_struct *p, struct wbint_RemoveMapping *r); NTSTATUS _wbint_SetHWM(pipes_struct *p, struct wbint_SetHWM *r); diff --git a/source3/librpc/gen_ndr/wbint.h b/source3/librpc/gen_ndr/wbint.h index 962a87ea26..96b7800624 100644 --- a/source3/librpc/gen_ndr/wbint.h +++ b/source3/librpc/gen_ndr/wbint.h @@ -303,6 +303,14 @@ struct wbint_ChangeMachineAccount { }; +struct wbint_PingDc { + struct { + NTSTATUS result; + } out; + +}; + + struct wbint_SetMapping { struct { struct dom_sid *sid;/* [ref] */ diff --git a/source3/librpc/idl/wbint.idl b/source3/librpc/idl/wbint.idl index e44f179723..432d59e086 100644 --- a/source3/librpc/idl/wbint.idl +++ b/source3/librpc/idl/wbint.idl @@ -150,6 +150,9 @@ interface wbint NTSTATUS wbint_ChangeMachineAccount( ); + NTSTATUS wbint_PingDc( + ); + typedef [public] enum { WBINT_ID_TYPE_NOT_SPECIFIED, WBINT_ID_TYPE_UID, diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 6edfe514b8..f5000e4730 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -153,180 +153,6 @@ void cli_set_error(struct cli_state *cli, NTSTATUS status) } /** - * @brief Find the smb_cmd offset of the last command pushed - * @param[in] buf The buffer we're building up - * @retval Where can we put our next andx cmd? - * - * While chaining requests, the "next" request we're looking at needs to put - * its SMB_Command before the data the previous request already built up added - * to the chain. Find the offset to the place where we have to put our cmd. - */ - -static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs) -{ - uint8_t cmd; - size_t ofs; - - cmd = CVAL(buf, smb_com); - - SMB_ASSERT(is_andx_req(cmd)); - - ofs = smb_vwv0; - - while (CVAL(buf, ofs) != 0xff) { - - if (!is_andx_req(CVAL(buf, ofs))) { - return false; - } - - /* - * ofs is from start of smb header, so add the 4 length - * bytes. The next cmd is right after the wct field. - */ - ofs = SVAL(buf, ofs+2) + 4 + 1; - - SMB_ASSERT(ofs+4 < talloc_get_size(buf)); - } - - *pofs = ofs; - return true; -} - -/** - * @brief Do the smb chaining at a buffer level - * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified - * @param[in] smb_command The command that we want to issue - * @param[in] wct How many words? - * @param[in] vwv The words, already in network order - * @param[in] bytes_alignment How shall we align "bytes"? - * @param[in] num_bytes How many bytes? - * @param[in] bytes The data the request ships - * - * smb_splice_chain() adds the vwv and bytes to the request already present in - * *poutbuf. - */ - -bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command, - uint8_t wct, const uint16_t *vwv, - size_t bytes_alignment, - uint32_t num_bytes, const uint8_t *bytes) -{ - uint8_t *outbuf; - size_t old_size, new_size; - size_t ofs; - size_t chain_padding = 0; - size_t bytes_padding = 0; - bool first_request; - - old_size = talloc_get_size(*poutbuf); - - /* - * old_size == smb_wct means we're pushing the first request in for - * libsmb/ - */ - - first_request = (old_size == smb_wct); - - if (!first_request && ((old_size % 4) != 0)) { - /* - * Align the wct field of subsequent requests to a 4-byte - * boundary - */ - chain_padding = 4 - (old_size % 4); - } - - /* - * After the old request comes the new wct field (1 byte), the vwv's - * and the num_bytes field. After at we might need to align the bytes - * given to us to "bytes_alignment", increasing the num_bytes value. - */ - - new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2; - - if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) { - bytes_padding = bytes_alignment - (new_size % bytes_alignment); - } - - new_size += bytes_padding + num_bytes; - - if ((smb_command != SMBwriteX) && (new_size > 0xffff)) { - DEBUG(1, ("splice_chain: %u bytes won't fit\n", - (unsigned)new_size)); - return false; - } - - outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size); - if (outbuf == NULL) { - DEBUG(0, ("talloc failed\n")); - return false; - } - *poutbuf = outbuf; - - if (first_request) { - SCVAL(outbuf, smb_com, smb_command); - } else { - size_t andx_cmd_ofs; - - if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) { - DEBUG(1, ("invalid command chain\n")); - *poutbuf = TALLOC_REALLOC_ARRAY( - NULL, *poutbuf, uint8_t, old_size); - return false; - } - - if (chain_padding != 0) { - memset(outbuf + old_size, 0, chain_padding); - old_size += chain_padding; - } - - SCVAL(outbuf, andx_cmd_ofs, smb_command); - SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4); - } - - ofs = old_size; - - /* - * Push the chained request: - * - * wct field - */ - - SCVAL(outbuf, ofs, wct); - ofs += 1; - - /* - * vwv array - */ - - memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct); - ofs += sizeof(uint16_t) * wct; - - /* - * bcc (byte count) - */ - - SSVAL(outbuf, ofs, num_bytes + bytes_padding); - ofs += sizeof(uint16_t); - - /* - * padding - */ - - if (bytes_padding != 0) { - memset(outbuf + ofs, 0, bytes_padding); - ofs += bytes_padding; - } - - /* - * The bytes field - */ - - memcpy(outbuf + ofs, bytes, num_bytes); - - return true; -} - -/** * Figure out if there is an andx command behind the current one * @param[in] buf The smb buffer to look at * @param[in] ofs The offset to the wct field that is followed by the cmd @@ -556,6 +382,7 @@ struct tevent_req *cli_smb_req_create(TALLOC_CTX *mem_ctx, { struct tevent_req *result; struct cli_smb_state *state; + struct timeval endtime; if (iov_count > MAX_SMB_IOV) { /* @@ -596,6 +423,10 @@ struct tevent_req *cli_smb_req_create(TALLOC_CTX *mem_ctx, } state->iov_count = iov_count + 3; + endtime = timeval_current_ofs(0, cli->timeout * 1000); + if (!tevent_req_set_endtime(result, ev, endtime)) { + tevent_req_nomem(NULL, result); + } return result; } @@ -679,12 +510,10 @@ static NTSTATUS cli_smb_req_iov_send(struct tevent_req *req, } iov[0].iov_base = (void *)buf; iov[0].iov_len = talloc_get_size(buf); - subreq = writev_send(state, state->ev, state->cli->outgoing, - state->cli->fd, false, iov, 1); - } else { - subreq = writev_send(state, state->ev, state->cli->outgoing, - state->cli->fd, false, iov, iov_count); + iov_count = 1; } + subreq = writev_send(state, state->ev, state->cli->outgoing, + state->cli->fd, false, iov, iov_count); if (subreq == NULL) { return NT_STATUS_NO_MEMORY; } @@ -986,16 +815,30 @@ NTSTATUS cli_smb_recv(struct tevent_req *req, uint8_t min_wct, status = cli_pull_error((char *)state->inbuf); - if (!have_andx_command((char *)state->inbuf, wct_ofs) - && NT_STATUS_IS_ERR(status)) { - /* - * The last command takes the error code. All further commands - * down the requested chain will get a - * NT_STATUS_REQUEST_ABORTED. - */ - return status; + if (!have_andx_command((char *)state->inbuf, wct_ofs)) { + + if ((cmd == SMBsesssetupX) + && NT_STATUS_EQUAL( + status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + /* + * NT_STATUS_MORE_PROCESSING_REQUIRED is a + * valid return code for session setup + */ + goto no_err; + } + + if (NT_STATUS_IS_ERR(status)) { + /* + * The last command takes the error code. All + * further commands down the requested chain + * will get a NT_STATUS_REQUEST_ABORTED. + */ + return status; + } } +no_err: + wct = CVAL(state->inbuf, wct_ofs); bytes_offset = wct_ofs + 1 + wct * sizeof(uint16_t); num_bytes = SVAL(state->inbuf, bytes_offset); @@ -1027,7 +870,7 @@ NTSTATUS cli_smb_recv(struct tevent_req *req, uint8_t min_wct, *pbytes = (uint8_t *)state->inbuf + bytes_offset + 2; } - return NT_STATUS_OK; + return status; } size_t cli_smb_wct_ofs(struct tevent_req **reqs, int num_reqs) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 112143ca96..31216b8240 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -3,17 +3,17 @@ client connect/disconnect routines Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) Andrew Bartlett 2001-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/>. */ @@ -22,6 +22,7 @@ #include "../libcli/auth/libcli_auth.h" #include "../libcli/auth/spnego.h" #include "smb_krb5.h" +#include "ntlmssp.h" static const struct { int prot; @@ -104,7 +105,7 @@ static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, cli_set_message(cli->outbuf,10, 0, True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); - + SCVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit); SSVAL(cli->outbuf,smb_vwv3,2); @@ -130,7 +131,7 @@ static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, if (cli_is_error(cli)) { return cli_nt_error(cli); } - + /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); status = cli_set_username(cli, user); @@ -359,14 +360,14 @@ static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, char *p; NTSTATUS status; fstring lanman; - + fstr_sprintf( lanman, "Samba %s", samba_version_string()); memset(cli->outbuf, '\0', smb_size); cli_set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); - + SCVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); SSVAL(cli->outbuf,smb_vwv3,2); @@ -375,9 +376,9 @@ static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, SSVAL(cli->outbuf,smb_vwv8,0); SIVAL(cli->outbuf,smb_vwv11,capabilities); p = smb_buf(cli->outbuf); - + /* check wether to send the ASCII or UNICODE version of the password */ - + if ( (capabilities & CAP_UNICODE) == 0 ) { p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */ SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf))); @@ -393,7 +394,7 @@ static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, p += clistr_push(cli, p, pass, -1, STR_UNICODE|STR_TERMINATE); /* unicode password */ SSVAL(cli->outbuf,smb_vwv8,PTR_DIFF(p, smb_buf(cli->outbuf))-1); } - + p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */ p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */ p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); @@ -403,9 +404,9 @@ static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { return cli_nt_error(cli); } - + show_msg(cli->inbuf); - + if (cli_is_error(cli)) { return cli_nt_error(cli); } @@ -524,7 +525,7 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, cli_set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); - + SCVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); SSVAL(cli->outbuf,smb_vwv3,2); @@ -574,7 +575,7 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); - + p = smb_buf(cli->inbuf); p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE); @@ -605,172 +606,212 @@ end: return result; } -/**************************************************************************** - Send a extended security session setup blob -****************************************************************************/ +/* The following is calculated from : + * (smb_size-4) = 35 + * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() ) + * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at + * end of packet. + */ -static bool cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob) -{ - uint32 capabilities = cli_session_setup_capabilities(cli); - char *p; +#define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22) - capabilities |= CAP_EXTENDED_SECURITY; +struct cli_sesssetup_blob_state { + struct tevent_context *ev; + struct cli_state *cli; + DATA_BLOB blob; + uint16_t max_blob_size; + uint16_t vwv[12]; + uint8_t *buf; - /* send a session setup command */ - memset(cli->outbuf,'\0',smb_size); + NTSTATUS status; + char *inbuf; + DATA_BLOB ret_blob; +}; - cli_set_message(cli->outbuf,12,0,True); - SCVAL(cli->outbuf,smb_com,SMBsesssetupX); +static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state, + struct tevent_req **psubreq); +static void cli_sesssetup_blob_done(struct tevent_req *subreq); - cli_setup_packet(cli); +static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + DATA_BLOB blob) +{ + struct tevent_req *req, *subreq; + struct cli_sesssetup_blob_state *state; - SCVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); - SSVAL(cli->outbuf,smb_vwv3,2); - SSVAL(cli->outbuf,smb_vwv4,1); - SIVAL(cli->outbuf,smb_vwv5,0); - SSVAL(cli->outbuf,smb_vwv7,blob.length); - SIVAL(cli->outbuf,smb_vwv10,capabilities); - p = smb_buf(cli->outbuf); - memcpy(p, blob.data, blob.length); - p += blob.length; - p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); - p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); - cli_setup_bcc(cli, p); - return cli_send_smb(cli); -} + req = tevent_req_create(mem_ctx, &state, + struct cli_sesssetup_blob_state); + if (req == NULL) { + return NULL; + } + state->ev = ev; + state->blob = blob; + state->cli = cli; -/**************************************************************************** - Send a extended security session setup blob, returning a reply blob. -****************************************************************************/ + if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) { + DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small " + "(was %u, need minimum %u)\n", + (unsigned int)cli->max_xmit, + BASE_SESSSETUP_BLOB_PACKET_SIZE)); + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + state->max_blob_size = + MIN(cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE, 0xFFFF); -static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli) + if (!cli_sesssetup_blob_next(state, &subreq)) { + tevent_req_nomem(NULL, req); + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req); + return req; +} + +static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state, + struct tevent_req **psubreq) { - DATA_BLOB blob2 = data_blob_null; - char *p; - size_t len; + struct tevent_req *subreq; + uint16_t thistime; + + SCVAL(state->vwv+0, 0, 0xFF); + SCVAL(state->vwv+0, 1, 0); + SSVAL(state->vwv+1, 0, 0); + SSVAL(state->vwv+2, 0, CLI_BUFFER_SIZE); + SSVAL(state->vwv+3, 0, 2); + SSVAL(state->vwv+4, 0, 1); + SIVAL(state->vwv+5, 0, 0); + + thistime = MIN(state->blob.length, state->max_blob_size); + SSVAL(state->vwv+7, 0, thistime); + + SSVAL(state->vwv+8, 0, 0); + SSVAL(state->vwv+9, 0, 0); + SIVAL(state->vwv+10, 0, + cli_session_setup_capabilities(state->cli) + | CAP_EXTENDED_SECURITY); + + state->buf = (uint8_t *)talloc_memdup(state, state->blob.data, + thistime); + if (state->buf == NULL) { + return false; + } + state->blob.data += thistime; + state->blob.length -= thistime; - if (!cli_receive_smb(cli)) - return blob2; + state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli), + "Unix", 5, NULL); + state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli), + "Samba", 6, NULL); + if (state->buf == NULL) { + return false; + } + subreq = cli_smb_send(state, state->ev, state->cli, SMBsesssetupX, 0, + 12, state->vwv, + talloc_get_size(state->buf), state->buf); + if (subreq == NULL) { + return false; + } + *psubreq = subreq; + return true; +} - show_msg(cli->inbuf); +static void cli_sesssetup_blob_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_sesssetup_blob_state *state = tevent_req_data( + req, struct cli_sesssetup_blob_state); + struct cli_state *cli = state->cli; + uint8_t wct; + uint16_t *vwv; + uint32_t num_bytes; + uint8_t *bytes; + NTSTATUS status; + uint8_t *p; + uint16_t blob_length; - if (cli_is_error(cli) && !NT_STATUS_EQUAL(cli_nt_error(cli), - NT_STATUS_MORE_PROCESSING_REQUIRED)) { - return blob2; + status = cli_smb_recv(subreq, 1, &wct, &vwv, &num_bytes, &bytes); + if (!NT_STATUS_IS_OK(status) + && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + TALLOC_FREE(subreq); + tevent_req_nterror(req, status); + return; } - /* use the returned vuid from now on */ - cli->vuid = SVAL(cli->inbuf,smb_uid); + state->status = status; + TALLOC_FREE(state->buf); - p = smb_buf(cli->inbuf); + state->inbuf = (char *)cli_smb_inbuf(subreq); + cli->vuid = SVAL(state->inbuf, smb_uid); + + blob_length = SVAL(vwv+3, 0); + if (blob_length > num_bytes) { + TALLOC_FREE(subreq); + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } + state->ret_blob = data_blob_const(bytes, blob_length); - blob2 = data_blob(p, SVAL(cli->inbuf, smb_vwv3)); + p = bytes + blob_length; - p += blob2.length; - p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring), - -1, STR_TERMINATE); + p += clistr_pull(state->inbuf, cli->server_os, + (char *)p, sizeof(fstring), + bytes+num_bytes-p, STR_TERMINATE); + p += clistr_pull(state->inbuf, cli->server_type, + (char *)p, sizeof(fstring), + bytes+num_bytes-p, STR_TERMINATE); + p += clistr_pull(state->inbuf, cli->server_domain, + (char *)p, sizeof(fstring), + bytes+num_bytes-p, STR_TERMINATE); - /* w2k with kerberos doesn't properly null terminate this field */ - len = smb_bufrem(cli->inbuf, p); - if (p + len < cli->inbuf + cli->bufsize+SAFETY_MARGIN - 2) { - char *end_of_buf = p + len; + if (strstr(cli->server_type, "Samba")) { + cli->is_samba = True; + } - SSVAL(p, len, 0); - /* Now it's null terminated. */ - p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring), - -1, STR_TERMINATE); + if (state->blob.length != 0) { + TALLOC_FREE(subreq); /* - * See if there's another string. If so it's the - * server domain (part of the 'standard' Samba - * server signature). + * More to send */ - if (p < end_of_buf) { - p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring), - -1, STR_TERMINATE); + if (!cli_sesssetup_blob_next(state, &subreq)) { + tevent_req_nomem(NULL, req); + return; } - } else { - /* - * No room to null terminate so we can't see if there - * is another string (server_domain) afterwards. - */ - p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring), - len, 0); + tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req); + return; } - return blob2; + tevent_req_done(req); } -#ifdef HAVE_KRB5 -/**************************************************************************** - Send a extended security session setup blob, returning a reply blob. -****************************************************************************/ - -/* The following is calculated from : - * (smb_size-4) = 35 - * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() ) - * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at - * end of packet. - */ - -#define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22) - -static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) +static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + DATA_BLOB *pblob, + char **pinbuf) { - int32 remaining = blob.length; - int32 cur = 0; - DATA_BLOB send_blob = data_blob_null; - int32 max_blob_size = 0; - DATA_BLOB receive_blob = data_blob_null; + struct cli_sesssetup_blob_state *state = tevent_req_data( + req, struct cli_sesssetup_blob_state); + NTSTATUS status; + char *inbuf; - if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) { - DEBUG(0,("cli_session_setup_blob: cli->max_xmit too small " - "(was %u, need minimum %u)\n", - (unsigned int)cli->max_xmit, - BASE_SESSSETUP_BLOB_PACKET_SIZE)); - cli_set_nt_error(cli, NT_STATUS_INVALID_PARAMETER); - return False; + if (tevent_req_is_nterror(req, &status)) { + state->cli->vuid = 0; + return status; } - max_blob_size = cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE; - - while ( remaining > 0) { - if (remaining >= max_blob_size) { - send_blob.length = max_blob_size; - remaining -= max_blob_size; - } else { - send_blob.length = remaining; - remaining = 0; - } - - send_blob.data = &blob.data[cur]; - cur += send_blob.length; - - DEBUG(10, ("cli_session_setup_blob: Remaining (%u) sending (%u) current (%u)\n", - (unsigned int)remaining, - (unsigned int)send_blob.length, - (unsigned int)cur )); - - if (!cli_session_setup_blob_send(cli, send_blob)) { - DEBUG(0, ("cli_session_setup_blob: send failed\n")); - return False; - } - - receive_blob = cli_session_setup_blob_receive(cli); - data_blob_free(&receive_blob); - - if (cli_is_error(cli) && - !NT_STATUS_EQUAL( cli_get_nt_error(cli), - NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DEBUG(0, ("cli_session_setup_blob: receive failed " - "(%s)\n", nt_errstr(cli_get_nt_error(cli)))); - cli->vuid = 0; - return False; - } + inbuf = talloc_move(mem_ctx, &state->inbuf); + if (pblob != NULL) { + *pblob = state->ret_blob; } - - return True; + if (pinbuf != NULL) { + *pinbuf = inbuf; + } + /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */ + return state->status; } +#ifdef HAVE_KRB5 + /**************************************************************************** Use in-memory credentials cache ****************************************************************************/ @@ -783,187 +824,358 @@ static void use_in_memory_ccache(void) { Do a spnego/kerberos encrypted session setup. ****************************************************************************/ -static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup) -{ +struct cli_session_setup_kerberos_state { + struct cli_state *cli; DATA_BLOB negTokenTarg; DATA_BLOB session_key_krb5; - NTSTATUS nt_status; - int rc; + ADS_STATUS ads_status; +}; - cli_temp_set_signing(cli); +static void cli_session_setup_kerberos_done(struct tevent_req *subreq); + +static struct tevent_req *cli_session_setup_kerberos_send( + TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, + const char *principal, const char *workgroup) +{ + struct tevent_req *req, *subreq; + struct cli_session_setup_kerberos_state *state; + int rc; DEBUG(2,("Doing kerberos session setup\n")); - /* generate the encapsulated kerberos5 ticket */ - rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0, NULL); + req = tevent_req_create(mem_ctx, &state, + struct cli_session_setup_kerberos_state); + if (req == NULL) { + return NULL; + } + state->cli = cli; + state->ads_status = ADS_SUCCESS; + + cli_temp_set_signing(cli); + /* + * Ok, this is cheated: spnego_gen_negTokenTarg can block if + * we have to acquire a ticket. To be fixed later :-) + */ + rc = spnego_gen_negTokenTarg(principal, 0, &state->negTokenTarg, + &state->session_key_krb5, 0, NULL); if (rc) { - DEBUG(1, ("cli_session_setup_kerberos: spnego_gen_negTokenTarg failed: %s\n", - error_message(rc))); - return ADS_ERROR_KRB5(rc); + DEBUG(1, ("cli_session_setup_kerberos: " + "spnego_gen_negTokenTarg failed: %s\n", + error_message(rc))); + state->ads_status = ADS_ERROR_KRB5(rc); + tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL); + return tevent_req_post(req, ev); } #if 0 - file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); + file_save("negTokenTarg.dat", state->negTokenTarg.data, + state->negTokenTarg.length); #endif - if (!cli_session_setup_blob(cli, negTokenTarg)) { - nt_status = cli_nt_error(cli); - goto nt_error; + subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); } + tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req); + return req; +} - if (cli_is_error(cli)) { - nt_status = cli_nt_error(cli); - if (NT_STATUS_IS_OK(nt_status)) { - nt_status = NT_STATUS_UNSUCCESSFUL; - } - goto nt_error; - } +static void cli_session_setup_kerberos_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_session_setup_kerberos_state *state = tevent_req_data( + req, struct cli_session_setup_kerberos_state); + char *inbuf = NULL; + NTSTATUS status; - cli_set_session_key(cli, session_key_krb5); + status = cli_sesssetup_blob_recv(subreq, talloc_tos(), NULL, &inbuf); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(subreq); + tevent_req_nterror(req, status); + return; + } - if (cli_simple_set_signing( - cli, session_key_krb5, data_blob_null)) { + cli_set_session_key(state->cli, state->session_key_krb5); - if (!cli_check_sign_mac(cli, cli->inbuf, 1)) { - nt_status = NT_STATUS_ACCESS_DENIED; - goto nt_error; - } + if (cli_simple_set_signing(state->cli, state->session_key_krb5, + data_blob_null) + && !cli_check_sign_mac(state->cli, inbuf, 1)) { + TALLOC_FREE(subreq); + tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); + return; } + TALLOC_FREE(subreq); + tevent_req_done(req); +} + +static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req) +{ + struct cli_session_setup_kerberos_state *state = tevent_req_data( + req, struct cli_session_setup_kerberos_state); + NTSTATUS status; - data_blob_free(&negTokenTarg); - data_blob_free(&session_key_krb5); + if (tevent_req_is_nterror(req, &status)) { + return ADS_ERROR_NT(status); + } + return state->ads_status; +} - return ADS_ERROR_NT(NT_STATUS_OK); +static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, + const char *principal, + const char *workgroup) +{ + struct tevent_context *ev; + struct tevent_req *req; + ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); -nt_error: - data_blob_free(&negTokenTarg); - data_blob_free(&session_key_krb5); - cli->vuid = 0; - return ADS_ERROR_NT(nt_status); + if (cli_has_async_calls(cli)) { + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + ev = tevent_context_init(talloc_tos()); + if (ev == NULL) { + goto fail; + } + req = cli_session_setup_kerberos_send(ev, ev, cli, principal, + workgroup); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll(req, ev)) { + status = ADS_ERROR_SYSTEM(errno); + goto fail; + } + status = cli_session_setup_kerberos_recv(req); +fail: + TALLOC_FREE(ev); + return status; } #endif /* HAVE_KRB5 */ - /**************************************************************************** Do a spnego/NTLMSSP encrypted session setup. ****************************************************************************/ -static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, - const char *pass, const char *domain) -{ +struct cli_session_setup_ntlmssp_state { + struct tevent_context *ev; + struct cli_state *cli; struct ntlmssp_state *ntlmssp_state; - NTSTATUS nt_status; - int turn = 1; - DATA_BLOB msg1; - DATA_BLOB blob = data_blob_null; - DATA_BLOB blob_in = data_blob_null; - DATA_BLOB blob_out = data_blob_null; + int turn; + DATA_BLOB blob_out; +}; - cli_temp_set_signing(cli); +static int cli_session_setup_ntlmssp_state_destructor( + struct cli_session_setup_ntlmssp_state *state) +{ + if (state->ntlmssp_state != NULL) { + ntlmssp_end(&state->ntlmssp_state); + } + return 0; +} - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { - return nt_status; +static void cli_session_setup_ntlmssp_done(struct tevent_req *req); + +static struct tevent_req *cli_session_setup_ntlmssp_send( + TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, + const char *user, const char *pass, const char *domain) +{ + struct tevent_req *req, *subreq; + struct cli_session_setup_ntlmssp_state *state; + NTSTATUS status; + DATA_BLOB blob_out; + + req = tevent_req_create(mem_ctx, &state, + struct cli_session_setup_ntlmssp_state); + if (req == NULL) { + return NULL; } - ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); + state->ev = ev; + state->cli = cli; + state->turn = 1; - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { - return nt_status; + state->ntlmssp_state = NULL; + talloc_set_destructor( + state, cli_session_setup_ntlmssp_state_destructor); + + cli_temp_set_signing(cli); + + status = ntlmssp_client_start(&state->ntlmssp_state); + if (!NT_STATUS_IS_OK(status)) { + goto fail; } - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { - return nt_status; + ntlmssp_want_feature(state->ntlmssp_state, + NTLMSSP_FEATURE_SESSION_KEY); + status = ntlmssp_set_username(state->ntlmssp_state, user); + if (!NT_STATUS_IS_OK(status)) { + goto fail; } - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) { - return nt_status; + status = ntlmssp_set_domain(state->ntlmssp_state, domain); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + status = ntlmssp_set_password(state->ntlmssp_state, pass); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + status = ntlmssp_update(state->ntlmssp_state, data_blob_null, + &blob_out); + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + goto fail; } - do { - nt_status = ntlmssp_update(ntlmssp_state, - blob_in, &blob_out); - data_blob_free(&blob_in); - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(nt_status)) { - if (turn == 1) { - /* and wrap it in a SPNEGO wrapper */ - msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out); - } else { - /* wrap it in SPNEGO */ - msg1 = spnego_gen_auth(blob_out); - } - - /* now send that blob on its way */ - if (!cli_session_setup_blob_send(cli, msg1)) { - DEBUG(3, ("Failed to send NTLMSSP/SPNEGO blob to server!\n")); - nt_status = NT_STATUS_UNSUCCESSFUL; - } else { - blob = cli_session_setup_blob_receive(cli); - - nt_status = cli_nt_error(cli); - if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) { - if (cli->smb_rw_error == SMB_READ_BAD_SIG) { - nt_status = NT_STATUS_ACCESS_DENIED; - } else { - nt_status = NT_STATUS_UNSUCCESSFUL; - } - } - } - data_blob_free(&msg1); - } + state->blob_out = gen_negTokenInit(OID_NTLMSSP, blob_out); + data_blob_free(&blob_out); - if (!blob.length) { - if (NT_STATUS_IS_OK(nt_status)) { - nt_status = NT_STATUS_UNSUCCESSFUL; - } - } else if ((turn == 1) && - NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DATA_BLOB tmp_blob = data_blob_null; - /* the server might give us back two challenges */ - if (!spnego_parse_challenge(blob, &blob_in, - &tmp_blob)) { - DEBUG(3,("Failed to parse challenges\n")); - nt_status = NT_STATUS_INVALID_PARAMETER; - } - data_blob_free(&tmp_blob); - } else { - if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP, - &blob_in)) { - DEBUG(3,("Failed to parse auth response\n")); - if (NT_STATUS_IS_OK(nt_status) - || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) - nt_status = NT_STATUS_INVALID_PARAMETER; - } - } - data_blob_free(&blob); - data_blob_free(&blob_out); - turn++; - } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)); + subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req); + return req; +fail: + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); +} - data_blob_free(&blob_in); +static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_session_setup_ntlmssp_state *state = tevent_req_data( + req, struct cli_session_setup_ntlmssp_state); + DATA_BLOB blob_in, msg_in, blob_out; + char *inbuf = NULL; + bool parse_ret; + NTSTATUS status; - if (NT_STATUS_IS_OK(nt_status)) { + status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in, + &inbuf); + TALLOC_FREE(subreq); + data_blob_free(&state->blob_out); - if (cli->server_domain[0] == '\0') { - fstrcpy(cli->server_domain, ntlmssp_state->server_domain); + if (NT_STATUS_IS_OK(status)) { + if (state->cli->server_domain[0] == '\0') { + fstrcpy(state->cli->server_domain, + state->ntlmssp_state->server_domain); } - cli_set_session_key(cli, ntlmssp_state->session_key); + cli_set_session_key( + state->cli, state->ntlmssp_state->session_key); if (cli_simple_set_signing( - cli, ntlmssp_state->session_key, data_blob_null)) { + state->cli, state->ntlmssp_state->session_key, + data_blob_null) + && !cli_check_sign_mac(state->cli, inbuf, 1)) { + TALLOC_FREE(subreq); + tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); + return; + } + TALLOC_FREE(subreq); + ntlmssp_end(&state->ntlmssp_state); + tevent_req_done(req); + return; + } + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + tevent_req_nterror(req, status); + return; + } - if (!cli_check_sign_mac(cli, cli->inbuf, 1)) { - nt_status = NT_STATUS_ACCESS_DENIED; - } + if (blob_in.length == 0) { + tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL); + return; + } + + if ((state->turn == 1) + && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DATA_BLOB tmp_blob = data_blob_null; + /* the server might give us back two challenges */ + parse_ret = spnego_parse_challenge(blob_in, &msg_in, + &tmp_blob); + data_blob_free(&tmp_blob); + } else { + parse_ret = spnego_parse_auth_response(blob_in, status, + OID_NTLMSSP, &msg_in); + } + state->turn += 1; + + if (!parse_ret) { + DEBUG(3,("Failed to parse auth response\n")); + if (NT_STATUS_IS_OK(status) + || NT_STATUS_EQUAL(status, + NT_STATUS_MORE_PROCESSING_REQUIRED)) { + tevent_req_nterror( + req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; } } - /* we have a reference conter on ntlmssp_state, if we are signing - then the state will be kept by the signing engine */ + status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out); - ntlmssp_end(&ntlmssp_state); + if (!NT_STATUS_IS_OK(status) + && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + TALLOC_FREE(subreq); + ntlmssp_end(&state->ntlmssp_state); + tevent_req_nterror(req, status); + return; + } - if (!NT_STATUS_IS_OK(nt_status)) { - cli->vuid = 0; + state->blob_out = spnego_gen_auth(blob_out); + TALLOC_FREE(subreq); + if (tevent_req_nomem(state->blob_out.data, req)) { + return; + } + + subreq = cli_sesssetup_blob_send(state, state->ev, state->cli, + state->blob_out); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req); +} + +static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req) +{ + struct cli_session_setup_ntlmssp_state *state = tevent_req_data( + req, struct cli_session_setup_ntlmssp_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + state->cli->vuid = 0; + return status; + } + return NT_STATUS_OK; +} + +static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, + const char *user, + const char *pass, + const char *domain) +{ + struct tevent_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + if (cli_has_async_calls(cli)) { + return NT_STATUS_INVALID_PARAMETER; + } + ev = tevent_context_init(talloc_tos()); + if (ev == NULL) { + goto fail; + } + req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain); + if (req == NULL) { + goto fail; } - return nt_status; + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = cli_session_setup_ntlmssp_recv(req); +fail: + TALLOC_FREE(ev); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** @@ -1251,25 +1463,88 @@ NTSTATUS cli_session_setup(struct cli_state *cli, Send a uloggoff. *****************************************************************************/ -bool cli_ulogoff(struct cli_state *cli) +struct cli_ulogoff_state { + struct cli_state *cli; + uint16_t vwv[2]; +}; + +static void cli_ulogoff_done(struct tevent_req *subreq); + +struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli) { - memset(cli->outbuf,'\0',smb_size); - cli_set_message(cli->outbuf,2,0,True); - SCVAL(cli->outbuf,smb_com,SMBulogoffX); - cli_setup_packet(cli); - SSVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ + struct tevent_req *req, *subreq; + struct cli_ulogoff_state *state; - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state); + if (req == NULL) { + return NULL; + } + state->cli = cli; - if (cli_is_error(cli)) { - return False; + SCVAL(state->vwv+0, 0, 0xFF); + SCVAL(state->vwv+1, 0, 0); + SSVAL(state->vwv+2, 0, 0); + + subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv, + 0, NULL); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_ulogoff_done, req); + return req; +} + +static void cli_ulogoff_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_ulogoff_state *state = tevent_req_data( + req, struct cli_ulogoff_state); + NTSTATUS status; + + status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; } + state->cli->vuid = -1; + tevent_req_done(req); +} + +NTSTATUS cli_ulogoff_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +NTSTATUS cli_ulogoff(struct cli_state *cli) +{ + struct tevent_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; - cli->vuid = -1; - return True; + if (cli_has_async_calls(cli)) { + return NT_STATUS_INVALID_PARAMETER; + } + ev = tevent_context_init(talloc_tos()); + if (ev == NULL) { + goto fail; + } + req = cli_ulogoff_send(ev, ev, cli); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = cli_ulogoff_recv(req); +fail: + TALLOC_FREE(ev); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** @@ -1536,24 +1811,83 @@ NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share, Send a tree disconnect. ****************************************************************************/ -bool cli_tdis(struct cli_state *cli) +struct cli_tdis_state { + struct cli_state *cli; +}; + +static void cli_tdis_done(struct tevent_req *subreq); + +struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli) { - memset(cli->outbuf,'\0',smb_size); - cli_set_message(cli->outbuf,0,0,True); - SCVAL(cli->outbuf,smb_com,SMBtdis); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); + struct tevent_req *req, *subreq; + struct cli_tdis_state *state; - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state); + if (req == NULL) { + return NULL; + } + state->cli = cli; - if (cli_is_error(cli)) { - return False; + subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); } + tevent_req_set_callback(subreq, cli_tdis_done, req); + return req; +} - cli->cnum = -1; - return True; +static void cli_tdis_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_tdis_state *state = tevent_req_data( + req, struct cli_tdis_state); + NTSTATUS status; + + status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + state->cli->cnum = -1; + tevent_req_done(req); +} + +NTSTATUS cli_tdis_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +NTSTATUS cli_tdis(struct cli_state *cli) +{ + struct tevent_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + if (cli_has_async_calls(cli)) { + return NT_STATUS_INVALID_PARAMETER; + } + ev = tevent_context_init(talloc_tos()); + if (ev == NULL) { + goto fail; + } + req = cli_tdis_send(ev, ev, cli); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = cli_tdis_recv(req); +fail: + TALLOC_FREE(ev); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** @@ -1671,6 +2005,7 @@ static void cli_negprot_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, 1, &wct, &vwv, &num_bytes, &bytes); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(subreq); + tevent_req_nterror(req, status); return; } diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index afae4ff2ab..99f52f4ca7 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -993,6 +993,7 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, bool res; uint16 cnum; char *newextrapath = NULL; + NTSTATUS status; if (!cli || !sharename) { return false; @@ -1020,7 +1021,7 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, } if (force_encrypt) { - NTSTATUS status = cli_cm_force_encryption(cli, + status = cli_cm_force_encryption(cli, username, password, lp_workgroup(), @@ -1032,7 +1033,8 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, res = cli_dfs_get_referral(ctx, cli, fullpath, &refs, &num_refs, &consumed); - if (!cli_tdis(cli)) { + status = cli_tdis(cli); + if (!NT_STATUS_IS_OK(status)) { return false; } diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index ec690b4d82..38382e4af7 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -20,6 +20,7 @@ #include "includes.h" #include "../libcli/auth/spnego.h" +#include "ntlmssp.h" /**************************************************************************** Get UNIX extensions version info. diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c index b440d61048..85a09cc9ce 100644 --- a/source3/libsmb/conncache.c +++ b/source3/libsmb/conncache.c @@ -7,17 +7,18 @@ Copyright (C) Andrew Bartlett 2002 Copyright (C) Gerald (Jerry) Carter 2003 Copyright (C) Marc VanHeyningen 2008 - + Copyright (C) Volker Lendecke 2009 + 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/>. */ @@ -37,11 +38,6 @@ /** - * prefix used for all entries put into the general cache - */ -static const char NEGATIVE_CONN_CACHE_PREFIX[] = "NEG_CONN_CACHE"; - -/** * Marshalls the domain and server name into the key for the gencache * record * @@ -53,15 +49,16 @@ static const char NEGATIVE_CONN_CACHE_PREFIX[] = "NEG_CONN_CACHE"; */ static char *negative_conn_cache_keystr(const char *domain, const char *server) { - const char NEGATIVE_CONN_CACHE_KEY_FMT[] = "%s/%s,%s"; char *keystr = NULL; - SMB_ASSERT(domain != NULL); + if (domain == NULL) { + return NULL; + } if (server == NULL) server = ""; - keystr = talloc_asprintf(talloc_tos(),NEGATIVE_CONN_CACHE_KEY_FMT, - NEGATIVE_CONN_CACHE_PREFIX, domain, server); + keystr = talloc_asprintf(talloc_tos(), "NEG_CONN_CACHE/%s,%s", + domain, server); if (keystr == NULL) { DEBUG(0, ("negative_conn_cache_keystr: malloc error\n")); } @@ -100,13 +97,16 @@ static char *negative_conn_cache_valuestr(NTSTATUS status) */ static NTSTATUS negative_conn_cache_valuedecode(const char *value) { - NTSTATUS result = NT_STATUS_OK; + unsigned int v = NT_STATUS_V(NT_STATUS_INTERNAL_ERROR);; - SMB_ASSERT(value != NULL); - if (sscanf(value, "%x", &(NT_STATUS_V(result))) != 1) - DEBUG(0, ("negative_conn_cache_valuestr: unable to parse " + if (value != NULL) { + return NT_STATUS_INTERNAL_ERROR; + } + if (sscanf(value, "%x", &v) != 1) { + DEBUG(0, ("negative_conn_cache_valuedecode: unable to parse " "value field '%s'\n", value)); - return result; + } + return NT_STATUS(v); } /** @@ -143,7 +143,7 @@ NTSTATUS check_negative_conn_cache( const char *domain, const char *server) if (key == NULL) goto done; - if (gencache_get(key, &value, (time_t *) NULL)) + if (gencache_get(key, &value, NULL)) result = negative_conn_cache_valuedecode(value); done: DEBUG(9,("check_negative_conn_cache returning result %d for domain %s " @@ -154,29 +154,6 @@ NTSTATUS check_negative_conn_cache( const char *domain, const char *server) } /** - * Delete any negative cache entry for the given domain/server - * - * @param[in] domain - * @param[in] server may be either a FQDN or an IP address - */ -void delete_negative_conn_cache(const char *domain, const char *server) -{ - char *key = NULL; - - key = negative_conn_cache_keystr(domain, server); - if (key == NULL) - goto done; - - gencache_del(key); - DEBUG(9,("delete_negative_conn_cache removing domain %s server %s\n", - domain, server)); - done: - TALLOC_FREE(key); - return; -} - - -/** * Add an entry to the failed connection cache * * @param[in] domain @@ -189,7 +166,10 @@ void add_failed_connection_entry(const char *domain, const char *server, char *key = NULL; char *value = NULL; - SMB_ASSERT(!NT_STATUS_IS_OK(result)); + if (NT_STATUS_IS_OK(result)) { + /* Nothing failed here */ + return; + } key = negative_conn_cache_keystr(domain, server); if (key == NULL) { @@ -204,15 +184,14 @@ void add_failed_connection_entry(const char *domain, const char *server, } if (gencache_set(key, value, - time((time_t *) NULL) - + FAILED_CONNECTION_CACHE_TIMEOUT)) + time(NULL) + FAILED_CONNECTION_CACHE_TIMEOUT)) DEBUG(9,("add_failed_connection_entry: added domain %s (%s) " "to failed conn cache\n", domain, server )); else DEBUG(1,("add_failed_connection_entry: failed to add " "domain %s (%s) to failed conn cache\n", domain, server)); - + done: TALLOC_FREE(key); TALLOC_FREE(value); @@ -220,15 +199,6 @@ void add_failed_connection_entry(const char *domain, const char *server, } /** - * Deletes all records from the negative connection cache in all domains - */ -void flush_negative_conn_cache( void ) -{ - flush_negative_conn_cache_for_domain("*"); -} - - -/** * Deletes all records for a specified domain from the negative connection * cache * @@ -246,10 +216,10 @@ void flush_negative_conn_cache_for_domain(const char *domain) goto done; } - gencache_iterate(delete_matches, (void *) NULL, key_pattern); + gencache_iterate(delete_matches, NULL, key_pattern); DEBUG(8, ("flush_negative_conn_cache_for_domain: flushed domain %s\n", domain)); - + done: TALLOC_FREE(key_pattern); return; diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 0285f22be4..48b3eb32d9 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -146,7 +146,7 @@ static const struct { {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, ERReasnotsupported, 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}, @@ -708,7 +708,7 @@ static const struct { {ERRDOS, 276, NT_STATUS_NONEXISTENT_EA_ENTRY}, {ERRDOS, 277, NT_STATUS_NONEXISTENT_EA_ENTRY}, {ERRDOS, 278, NT_STATUS_NONEXISTENT_EA_ENTRY}, - {ERRDOS, 282, NT_STATUS_EAS_NOT_SUPPORTED}, + {ERRDOS, ERReasnotsupported, NT_STATUS_EAS_NOT_SUPPORTED}, {ERRDOS, 288, NT_STATUS_MUTANT_NOT_OWNED}, {ERRDOS, 298, NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, {ERRDOS, 299, NT_STATUS(0x8000000d)}, @@ -841,7 +841,7 @@ static const struct { {ERRHRD, 276, NT_STATUS_NONEXISTENT_EA_ENTRY}, {ERRHRD, 277, NT_STATUS_NONEXISTENT_EA_ENTRY}, {ERRHRD, 278, NT_STATUS_NONEXISTENT_EA_ENTRY}, - {ERRHRD, 282, NT_STATUS_EAS_NOT_SUPPORTED}, + {ERRHRD, ERReasnotsupported, NT_STATUS_EAS_NOT_SUPPORTED}, {ERRHRD, 288, NT_STATUS_MUTANT_NOT_OWNED}, {ERRHRD, 298, NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, {ERRHRD, 299, NT_STATUS(0x8000000d)}, diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index 53cd3d5a77..f9770d363c 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -151,12 +151,14 @@ SMBC_get_cached_server(SMBCCTX * context, * attribute server connection) is cool. */ if (smbc_getOptionOneSharePerServer(context)) { + NTSTATUS status; /* * The currently connected share name * doesn't match the requested share, so * disconnect from the current share. */ - if (! cli_tdis(srv->server->cli)) { + status = cli_tdis(srv->server->cli); + if (!NT_STATUS_IS_OK(status)) { /* Sigh. Couldn't disconnect. */ cli_shutdown(srv->server->cli); srv->server->cli = NULL; diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 60c1d49bb0..7fffe7cea3 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -22,9 +22,10 @@ */ #include "includes.h" +#include "ntlmssp.h" #include "../libcli/auth/libcli_auth.h" #include "../librpc/gen_ndr/ndr_ntlmssp.h" -#include "libsmb/ntlmssp_ndr.h" +#include "../libcli/auth/ntlmssp_ndr.h" static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, DATA_BLOB reply, DATA_BLOB *next_request); @@ -41,8 +42,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, */ static const struct ntlmssp_callbacks { - enum NTLMSSP_ROLE role; - enum NTLM_MESSAGE_TYPE ntlmssp_command; + enum ntlmssp_role role; + enum ntlmssp_message_type ntlmssp_command; NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB in, DATA_BLOB *out); } ntlmssp_callbacks[] = { @@ -111,10 +112,11 @@ void debug_ntlmssp_flags(uint32 neg_flags) * */ -static void get_challenge(const struct ntlmssp_state *ntlmssp_state, - uint8_t chal[8]) +static NTSTATUS get_challenge(const struct ntlmssp_state *ntlmssp_state, + uint8_t chal[8]) { generate_random_buffer(chal, 8); + return NT_STATUS_OK; } /** @@ -145,7 +147,7 @@ static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *ch * */ -NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user) +NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user) { ntlmssp_state->user = talloc_strdup(ntlmssp_state, user ? user : "" ); if (!ntlmssp_state->user) { @@ -158,7 +160,7 @@ NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user) * Store NT and LM hashes on an NTLMSSP context - ensures they are talloc()ed * */ -NTSTATUS ntlmssp_set_hashes(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_set_hashes(struct ntlmssp_state *ntlmssp_state, const unsigned char lm_hash[16], const unsigned char nt_hash[16]) { @@ -178,7 +180,7 @@ NTSTATUS ntlmssp_set_hashes(NTLMSSP_STATE *ntlmssp_state, * Converts a password to the hashes on an NTLMSSP context. * */ -NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password) +NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password) { if (!password) { ntlmssp_state->lm_hash = NULL; @@ -198,7 +200,7 @@ NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password * Set a domain on an NTLMSSP context - ensures it is talloc()ed * */ -NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) +NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) { ntlmssp_state->domain = talloc_strdup(ntlmssp_state, domain ? domain : "" ); @@ -212,7 +214,7 @@ NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) * Set a workstation on an NTLMSSP context - ensures it is talloc()ed * */ -NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation) +NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation) { ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation); if (!ntlmssp_state->workstation) { @@ -222,26 +224,12 @@ NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *works } /** - * Store a DATA_BLOB containing an NTLMSSP response, for use later. - * This copies the data blob - */ - -NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state, - DATA_BLOB response) -{ - ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state, - response.data, - response.length); - return NT_STATUS_OK; -} - -/** * Request features for the NTLMSSP negotiation * * @param ntlmssp_state NTLMSSP state * @param feature_list List of space seperated features requested from NTLMSSP. */ -void ntlmssp_want_feature_list(NTLMSSP_STATE *ntlmssp_state, char *feature_list) +void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *feature_list) { /* * We need to set this to allow a later SetPassword @@ -265,7 +253,7 @@ void ntlmssp_want_feature_list(NTLMSSP_STATE *ntlmssp_state, char *feature_list) * @param ntlmssp_state NTLMSSP state * @param feature Bit flag specifying the requested feature */ -void ntlmssp_want_feature(NTLMSSP_STATE *ntlmssp_state, uint32 feature) +void ntlmssp_want_feature(struct ntlmssp_state *ntlmssp_state, uint32 feature) { /* As per JRA's comment above */ if (feature & NTLMSSP_FEATURE_SESSION_KEY) { @@ -288,10 +276,9 @@ void ntlmssp_want_feature(NTLMSSP_STATE *ntlmssp_state, uint32 feature) * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. */ -NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, - const DATA_BLOB in, DATA_BLOB *out) +NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB input, DATA_BLOB *out) { - DATA_BLOB input; uint32 ntlmssp_command; int i; @@ -303,15 +290,6 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, *out = data_blob_null; - if (!in.length && ntlmssp_state->stored_response.length) { - input = ntlmssp_state->stored_response; - - /* we only want to read the stored response once - overwrite it */ - ntlmssp_state->stored_response = data_blob_null; - } else { - input = in; - } - if (!input.length) { switch (ntlmssp_state->role) { case NTLMSSP_CLIENT: @@ -356,16 +334,12 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, * @param ntlmssp_state NTLMSSP State, free()ed by this function */ -void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state) +void ntlmssp_end(struct ntlmssp_state **ntlmssp_state) { - (*ntlmssp_state)->ref_count--; - - if ((*ntlmssp_state)->ref_count == 0) { - data_blob_free(&(*ntlmssp_state)->chal); - data_blob_free(&(*ntlmssp_state)->lm_resp); - data_blob_free(&(*ntlmssp_state)->nt_resp); - TALLOC_FREE(*ntlmssp_state); - } + data_blob_free(&(*ntlmssp_state)->chal); + data_blob_free(&(*ntlmssp_state)->lm_resp); + data_blob_free(&(*ntlmssp_state)->nt_resp); + TALLOC_FREE(*ntlmssp_state); *ntlmssp_state = NULL; return; @@ -466,7 +440,7 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, by the client lanman auth/lanman auth parameters, it isn't too bad. */ -DATA_BLOB ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state, TALLOC_CTX *mem_ctx) +DATA_BLOB ntlmssp_weaken_keys(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *mem_ctx) { DATA_BLOB weakened_key = data_blob_talloc(mem_ctx, ntlmssp_state->session_key.data, @@ -520,6 +494,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, const char *target_name; struct NEGOTIATE_MESSAGE negotiate; struct CHALLENGE_MESSAGE challenge; + NTSTATUS status; /* parse the NTLMSSP packet */ #if 0 @@ -552,7 +527,10 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth()); /* Ask our caller what challenge they would like in the packet */ - ntlmssp_state->get_challenge(ntlmssp_state, cryptkey); + status = ntlmssp_state->get_challenge(ntlmssp_state, cryptkey); + if (!NT_STATUS_IS_OK(status)) { + return status; + } /* Check if we may set the challenge */ if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) { @@ -902,9 +880,9 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, * @param ntlmssp_state NTLMSSP State, allocated by this function */ -NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) +NTSTATUS ntlmssp_server_start(struct ntlmssp_state **ntlmssp_state) { - *ntlmssp_state = TALLOC_ZERO_P(NULL, NTLMSSP_STATE); + *ntlmssp_state = TALLOC_ZERO_P(NULL, struct ntlmssp_state); if (!*ntlmssp_state) { DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); talloc_destroy(*ntlmssp_state); @@ -923,8 +901,6 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE; - (*ntlmssp_state)->ref_count = 1; - (*ntlmssp_state)->neg_flags = NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_56 | @@ -1239,9 +1215,9 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, return nt_status; } -NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) +NTSTATUS ntlmssp_client_start(struct ntlmssp_state **ntlmssp_state) { - *ntlmssp_state = TALLOC_ZERO_P(NULL, NTLMSSP_STATE); + *ntlmssp_state = TALLOC_ZERO_P(NULL, struct ntlmssp_state); if (!*ntlmssp_state) { DEBUG(0,("ntlmssp_client_start: talloc failed!\n")); talloc_destroy(*ntlmssp_state); @@ -1259,8 +1235,6 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL; - (*ntlmssp_state)->ref_count = 1; - (*ntlmssp_state)->neg_flags = NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_ALWAYS_SIGN | diff --git a/source3/libsmb/ntlmssp_ndr.c b/source3/libsmb/ntlmssp_ndr.c deleted file mode 100644 index 92cd677572..0000000000 --- a/source3/libsmb/ntlmssp_ndr.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - Unix SMB/Netbios implementation. - NTLMSSP ndr functions - - Copyright (C) Guenther Deschner 2009 - - 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/ndr_ntlmssp.h" -#include "libsmb/ntlmssp_ndr.h" - -#define NTLMSSP_PULL_MESSAGE(type, blob, mem_ctx, ic, r) \ -do { \ - enum ndr_err_code __ndr_err; \ - __ndr_err = ndr_pull_struct_blob(blob, mem_ctx, ic, r, \ - (ndr_pull_flags_fn_t)ndr_pull_ ##type); \ - if (!NDR_ERR_CODE_IS_SUCCESS(__ndr_err)) { \ - return ndr_map_error2ntstatus(__ndr_err); \ - } \ - if (memcmp(r->Signature, "NTLMSSP\0", 8)) {\ - return NT_STATUS_INVALID_PARAMETER; \ - } \ - return NT_STATUS_OK; \ -} while(0); - -#define NTLMSSP_PUSH_MESSAGE(type, blob, mem_ctx, ic, r) \ -do { \ - enum ndr_err_code __ndr_err; \ - __ndr_err = ndr_push_struct_blob(blob, mem_ctx, ic, r, \ - (ndr_push_flags_fn_t)ndr_push_ ##type); \ - if (!NDR_ERR_CODE_IS_SUCCESS(__ndr_err)) { \ - return ndr_map_error2ntstatus(__ndr_err); \ - } \ - return NT_STATUS_OK; \ -} while(0); - - -/** - * Pull NTLMSSP NEGOTIATE_MESSAGE struct from a blob - * @param blob The plain packet blob - * @param mem_ctx A talloc context - * @param ic Iconv convenience structure - * @param r Pointer to a NTLMSSP NEGOTIATE_MESSAGE structure - */ - -NTSTATUS ntlmssp_pull_NEGOTIATE_MESSAGE(const DATA_BLOB *blob, - TALLOC_CTX *mem_ctx, - struct smb_iconv_convenience *ic, - struct NEGOTIATE_MESSAGE *r) -{ - NTLMSSP_PULL_MESSAGE(NEGOTIATE_MESSAGE, blob, mem_ctx, ic, r); -} - -/** - * Pull NTLMSSP CHALLENGE_MESSAGE struct from a blob - * @param blob The plain packet blob - * @param mem_ctx A talloc context - * @param ic Iconv convenience structure - * @param r Pointer to a NTLMSSP CHALLENGE_MESSAGE structure - */ - -NTSTATUS ntlmssp_pull_CHALLENGE_MESSAGE(const DATA_BLOB *blob, - TALLOC_CTX *mem_ctx, - struct smb_iconv_convenience *ic, - struct CHALLENGE_MESSAGE *r) -{ - NTLMSSP_PULL_MESSAGE(CHALLENGE_MESSAGE, blob, mem_ctx, ic, r); -} - -/** - * Pull NTLMSSP AUTHENTICATE_MESSAGE struct from a blob - * @param blob The plain packet blob - * @param mem_ctx A talloc context - * @param ic Iconv convenience structure - * @param r Pointer to a NTLMSSP AUTHENTICATE_MESSAGE structure - */ - -NTSTATUS ntlmssp_pull_AUTHENTICATE_MESSAGE(const DATA_BLOB *blob, - TALLOC_CTX *mem_ctx, - struct smb_iconv_convenience *ic, - struct AUTHENTICATE_MESSAGE *r) -{ - NTLMSSP_PULL_MESSAGE(AUTHENTICATE_MESSAGE, blob, mem_ctx, ic, r); -} - -/** - * Push NTLMSSP NEGOTIATE_MESSAGE struct into a blob - * @param blob The plain packet blob - * @param mem_ctx A talloc context - * @param ic Iconv convenience structure - * @param r Pointer to a NTLMSSP NEGOTIATE_MESSAGE structure - */ - -NTSTATUS ntlmssp_push_NEGOTIATE_MESSAGE(DATA_BLOB *blob, - TALLOC_CTX *mem_ctx, - struct smb_iconv_convenience *ic, - const struct NEGOTIATE_MESSAGE *r) -{ - NTLMSSP_PUSH_MESSAGE(NEGOTIATE_MESSAGE, blob, mem_ctx, ic, r); -} - -/** - * Push NTLMSSP CHALLENGE_MESSAGE struct into a blob - * @param blob The plain packet blob - * @param mem_ctx A talloc context - * @param ic Iconv convenience structure - * @param r Pointer to a NTLMSSP CHALLENGE_MESSAGE structure - */ - -NTSTATUS ntlmssp_push_CHALLENGE_MESSAGE(DATA_BLOB *blob, - TALLOC_CTX *mem_ctx, - struct smb_iconv_convenience *ic, - const struct CHALLENGE_MESSAGE *r) -{ - NTLMSSP_PUSH_MESSAGE(CHALLENGE_MESSAGE, blob, mem_ctx, ic, r); -} - -/** - * Push NTLMSSP AUTHENTICATE_MESSAGE struct into a blob - * @param blob The plain packet blob - * @param mem_ctx A talloc context - * @param ic Iconv convenience structure - * @param r Pointer to a NTLMSSP AUTHENTICATE_MESSAGE structure - */ - -NTSTATUS ntlmssp_push_AUTHENTICATE_MESSAGE(DATA_BLOB *blob, - TALLOC_CTX *mem_ctx, - struct smb_iconv_convenience *ic, - const struct AUTHENTICATE_MESSAGE *r) -{ - NTLMSSP_PUSH_MESSAGE(AUTHENTICATE_MESSAGE, blob, mem_ctx, ic, r); -} diff --git a/source3/libsmb/ntlmssp_ndr.h b/source3/libsmb/ntlmssp_ndr.h deleted file mode 100644 index 52990b2a56..0000000000 --- a/source3/libsmb/ntlmssp_ndr.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Unix SMB/Netbios implementation. - NTLMSSP ndr functions - - Copyright (C) Guenther Deschner 2009 - - 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/>. -*/ - -NTSTATUS ntlmssp_pull_NEGOTIATE_MESSAGE(const DATA_BLOB *blob, - TALLOC_CTX *mem_ctx, - struct smb_iconv_convenience *ic, - struct NEGOTIATE_MESSAGE *r); -NTSTATUS ntlmssp_pull_CHALLENGE_MESSAGE(const DATA_BLOB *blob, - TALLOC_CTX *mem_ctx, - struct smb_iconv_convenience *ic, - struct CHALLENGE_MESSAGE *r); -NTSTATUS ntlmssp_pull_AUTHENTICATE_MESSAGE(const DATA_BLOB *blob, - TALLOC_CTX *mem_ctx, - struct smb_iconv_convenience *ic, - struct AUTHENTICATE_MESSAGE *r); -NTSTATUS ntlmssp_push_NEGOTIATE_MESSAGE(DATA_BLOB *blob, - TALLOC_CTX *mem_ctx, - struct smb_iconv_convenience *ic, - const struct NEGOTIATE_MESSAGE *r); -NTSTATUS ntlmssp_push_CHALLENGE_MESSAGE(DATA_BLOB *blob, - TALLOC_CTX *mem_ctx, - struct smb_iconv_convenience *ic, - const struct CHALLENGE_MESSAGE *r); -NTSTATUS ntlmssp_push_AUTHENTICATE_MESSAGE(DATA_BLOB *blob, - TALLOC_CTX *mem_ctx, - struct smb_iconv_convenience *ic, - const struct AUTHENTICATE_MESSAGE *r); diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 752749cdd8..3fd22ce73f 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "ntlmssp.h" #include "../libcli/auth/libcli_auth.h" #define CLI_SIGN "session key to client-to-server signing key magic constant" @@ -58,7 +59,7 @@ enum ntlmssp_direction { NTLMSSP_RECEIVE }; -static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, +static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_state, const uchar *data, size_t length, const uchar *whole_pdu, size_t pdu_length, enum ntlmssp_direction direction, @@ -76,27 +77,27 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, } switch (direction) { - case NTLMSSP_SEND: - DEBUG(100,("ntlmssp_make_packet_signature: SEND seq = %u, len = %u, pdu_len = %u\n", - ntlmssp_state->ntlm2_send_seq_num, - (unsigned int)length, - (unsigned int)pdu_length)); - - SIVAL(seq_num, 0, ntlmssp_state->ntlm2_send_seq_num); - ntlmssp_state->ntlm2_send_seq_num++; - hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key, 16, &ctx); - break; - case NTLMSSP_RECEIVE: + case NTLMSSP_SEND: + DEBUG(100,("ntlmssp_make_packet_signature: SEND seq = %u, len = %u, pdu_len = %u\n", + ntlmssp_state->ntlm2_send_seq_num, + (unsigned int)length, + (unsigned int)pdu_length)); + + SIVAL(seq_num, 0, ntlmssp_state->ntlm2_send_seq_num); + ntlmssp_state->ntlm2_send_seq_num++; + hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key, 16, &ctx); + break; + case NTLMSSP_RECEIVE: - DEBUG(100,("ntlmssp_make_packet_signature: RECV seq = %u, len = %u, pdu_len = %u\n", - ntlmssp_state->ntlm2_recv_seq_num, - (unsigned int)length, - (unsigned int)pdu_length)); + DEBUG(100,("ntlmssp_make_packet_signature: RECV seq = %u, len = %u, pdu_len = %u\n", + ntlmssp_state->ntlm2_recv_seq_num, + (unsigned int)length, + (unsigned int)pdu_length)); - SIVAL(seq_num, 0, ntlmssp_state->ntlm2_recv_seq_num); - ntlmssp_state->ntlm2_recv_seq_num++; - hmac_md5_init_limK_to_64(ntlmssp_state->recv_sign_key, 16, &ctx); - break; + SIVAL(seq_num, 0, ntlmssp_state->ntlm2_recv_seq_num); + ntlmssp_state->ntlm2_recv_seq_num++; + hmac_md5_init_limK_to_64(ntlmssp_state->recv_sign_key, 16, &ctx); + break; } dump_data_pw("pdu data ", whole_pdu, pdu_length); @@ -137,7 +138,7 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, return NT_STATUS_OK; } -NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_sign_packet(struct ntlmssp_state *ntlmssp_state, const uchar *data, size_t length, const uchar *whole_pdu, size_t pdu_length, DATA_BLOB *sig) @@ -168,7 +169,7 @@ NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, * */ -NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state, const uchar *data, size_t length, const uchar *whole_pdu, size_t pdu_length, const DATA_BLOB *sig) @@ -236,7 +237,7 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, * */ -NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, uchar *data, size_t length, uchar *whole_pdu, size_t pdu_length, DATA_BLOB *sig) @@ -302,7 +303,7 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, * */ -NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_unseal_packet(struct ntlmssp_state *ntlmssp_state, uchar *data, size_t length, uchar *whole_pdu, size_t pdu_length, DATA_BLOB *sig) @@ -329,11 +330,9 @@ NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, /** Initialise the state for NTLMSSP signing. */ -NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) +NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) { - unsigned char p24[24]; TALLOC_CTX *mem_ctx; - ZERO_STRUCT(p24); mem_ctx = talloc_init("weak_keys"); if (!mem_ctx) { diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 2f7305c5b6..ec879db5b4 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "ntlmssp.h" /****************************************************************************** Pull out the encryption context for this packet. 0 means global context. @@ -59,7 +60,7 @@ bool common_encryption_on(struct smb_trans_enc_state *es) output, so cope with the same for compatibility. ******************************************************************************/ -NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) +NTSTATUS common_ntlm_decrypt_buffer(struct ntlmssp_state *ntlmssp_state, char *buf) { NTSTATUS status; size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ @@ -107,7 +108,7 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) output, so do the same for compatibility. ******************************************************************************/ -NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS common_ntlm_encrypt_buffer(struct ntlmssp_state *ntlmssp_state, uint16 enc_ctx_num, char *buf, char **ppbuf_out) diff --git a/source3/locale/net/de.po b/source3/locale/net/de.po index a336936343..0e18172a58 100644 --- a/source3/locale/net/de.po +++ b/source3/locale/net/de.po @@ -1,5 +1,6 @@ # net message translation (german). # Copyright (C) 2009 Kai Blin <kai@samba.org> +# Copyright (C) 2009 André Hentschel <nerv@dawncrow.de> # This file is distributed under the same license as the samba package. # #, fuzzy @@ -8,11 +9,12 @@ msgstr "" "Project-Id-Version: @PACKAGE@\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2009-08-11 09:01+0200\n" -"PO-Revision-Date: 2009-08-06 20:45+0200\n" -"Last-Translator: Kai Blin <kai@samba.org>\n" +"PO-Revision-Date: 2009-12-26 19:20+0100\n" +"Last-Translator: André Hentschel <nerv@dawncrow.de>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language-Team: \n" #: ../../utils/net.c:103 msgid "Enter machine password: " @@ -33,12 +35,14 @@ msgid "" "This function will change the ADS Domain member machine account password in the secrets.tdb file!\n" msgstr "" -#: ../../utils/net.c:150 ../../utils/net.c:228 +#: ../../utils/net.c:150 +#: ../../utils/net.c:228 #, c-format msgid "Unable to open secrets.tdb. Can't fetch domain SID for name: %s\n" msgstr "" -#: ../../utils/net.c:163 ../../utils/net.c:251 +#: ../../utils/net.c:163 +#: ../../utils/net.c:251 #, c-format msgid "SID for domain %s is: %s\n" msgstr "" @@ -88,7 +92,7 @@ msgstr "" #: ../../utils/net.c:317 msgid "Run functions using RPC transport" -msgstr "" +msgstr "RPC Protokoll nutzen" #: ../../utils/net.c:318 msgid " Use 'net help rpc' to get more extensive information about 'net rpc' commands." @@ -96,7 +100,7 @@ msgstr "" #: ../../utils/net.c:325 msgid "Run functions using RAP transport" -msgstr "" +msgstr "RAP Protokoll nutzen" #: ../../utils/net.c:326 msgid " Use 'net help rap' to get more extensive information about 'net rap' commands." @@ -104,7 +108,7 @@ msgstr "" #: ../../utils/net.c:333 msgid "Run functions using ADS transport" -msgstr "" +msgstr "ADS Protokoll nutzen" #: ../../utils/net.c:334 msgid " Use 'net help ads' to get more extensive information about 'net ads' commands." @@ -112,7 +116,7 @@ msgstr "" #: ../../utils/net.c:343 msgid "Functions on remote opened files" -msgstr "" +msgstr "Freigegebene Dateien verwalten" #: ../../utils/net.c:344 msgid " Use 'net help file' to get more information about 'net file' commands." @@ -120,7 +124,7 @@ msgstr "" #: ../../utils/net.c:351 msgid "Functions on shares" -msgstr "" +msgstr "Freigaben verwalten" #: ../../utils/net.c:352 msgid " Use 'net help share' to get more information about 'net share' commands." @@ -128,15 +132,16 @@ msgstr "" #: ../../utils/net.c:359 msgid "Manage sessions" -msgstr "" +msgstr "Sitzungen verwalten" #: ../../utils/net.c:360 msgid " Use 'net help session' to get more information about 'net session' commands." msgstr "" -#: ../../utils/net.c:367 ../../utils/net_rap.c:1291 +#: ../../utils/net.c:367 +#: ../../utils/net_rap.c:1291 msgid "List servers in workgroup" -msgstr "" +msgstr "Server der Arbeitsgruppe auflisten" #: ../../utils/net.c:368 msgid " Use 'net help server' to get more information about 'net server' commands." @@ -144,7 +149,7 @@ msgstr "" #: ../../utils/net.c:375 msgid "List domains/workgroups on network" -msgstr "" +msgstr "Domänen/Arbeitsgruppen im Netzwerk auflisten" #: ../../utils/net.c:376 msgid " Use 'net help domain' to get more information about 'net domain' commands." @@ -160,7 +165,7 @@ msgstr "" #: ../../utils/net.c:391 msgid "Manage users" -msgstr "" +msgstr "Benutzer verwalten" #: ../../utils/net.c:392 msgid " Use 'net help user' to get more information about 'net user' commands." @@ -168,7 +173,7 @@ msgstr "" #: ../../utils/net.c:399 msgid "Manage groups" -msgstr "" +msgstr "Gruppen verwalten" #: ../../utils/net.c:400 msgid " Use 'net help group' to get more information about 'net group' commands." @@ -176,7 +181,7 @@ msgstr "" #: ../../utils/net.c:407 msgid "Manage group mappings" -msgstr "" +msgstr "Gruppenzuweisungen verwalten" #: ../../utils/net.c:408 msgid " Use 'net help groupmap' to get more information about 'net groupmap' commands." @@ -200,7 +205,7 @@ msgstr "" #: ../../utils/net.c:431 msgid "Modify group memberships" -msgstr "" +msgstr "Gruppenzugehörigkeiten verwalten" #: ../../utils/net.c:432 msgid " Use 'net help groupmember' to get more information about 'net groupmember' commands." @@ -208,7 +213,7 @@ msgstr "" #: ../../utils/net.c:438 msgid "Execute remote command on a remote OS/2 server" -msgstr "" +msgstr "Befehl auf einem entfernten OS/2 Server ausführen" #: ../../utils/net.c:439 msgid " Use 'net help admin' to get more information about 'net admin' commands." @@ -216,7 +221,7 @@ msgstr "" #: ../../utils/net.c:445 msgid "List/modify running services" -msgstr "" +msgstr "Zeige/Ändere laufende Dienste" #: ../../utils/net.c:446 msgid " Use 'net help service' to get more information about 'net service' commands." @@ -240,7 +245,7 @@ msgstr "" #: ../../utils/net.c:467 msgid "Change the secret password" -msgstr "" +msgstr "Das geheime Passwort ändern" #: ../../utils/net.c:468 msgid "" @@ -252,7 +257,7 @@ msgstr "" #: ../../utils/net.c:477 msgid "Show/set time" -msgstr "" +msgstr "Zeigt/Setzt die Systemzeit" #: ../../utils/net.c:478 msgid " Use 'net help time' to get more information about 'net time' commands." @@ -268,7 +273,7 @@ msgstr "" #: ../../utils/net.c:491 msgid "Join a domain/AD" -msgstr "" +msgstr "Einer Domäne/AD beitreten" #: ../../utils/net.c:492 msgid " Use 'net help join' to get more information about 'net join'." @@ -340,7 +345,7 @@ msgstr "" #: ../../utils/net.c:549 msgid "Display server status" -msgstr "" +msgstr "Zeigt den Server Status" #: ../../utils/net.c:550 msgid " Use 'net help status' to get more information about 'net status' commands." @@ -348,7 +353,7 @@ msgstr "" #: ../../utils/net.c:556 msgid "Manage user-modifiable shares" -msgstr "" +msgstr "Benutzerfreigaben verwalten" #: ../../utils/net.c:557 msgid " Use 'net help usershare to get more information about 'net usershare' commands." @@ -356,7 +361,7 @@ msgstr "" #: ../../utils/net.c:563 msgid "Display list of all users with SID" -msgstr "" +msgstr "Zeigt eine Liste aller SID-Benutzer" #: ../../utils/net.c:564 msgid " Use 'net help usersidlist' to get more information about 'net usersidlist'." @@ -364,7 +369,7 @@ msgstr "" #: ../../utils/net.c:570 msgid "Manage Samba registry based configuration" -msgstr "" +msgstr "Konfiguration ändern" #: ../../utils/net.c:571 msgid " Use 'net help conf' to get more information about 'net conf' commands." @@ -380,7 +385,7 @@ msgstr "" #: ../../utils/net.c:591 msgid "Process Win32 *.evt eventlog files" -msgstr "" +msgstr "Arbeitet mit Win32 *.evt Eventlog Dateien" #: ../../utils/net.c:592 msgid " Use 'net help eventlog' to get more information about 'net eventlog' commands." @@ -396,7 +401,7 @@ msgstr "" #: ../../utils/net.c:609 msgid "Print usage information" -msgstr "" +msgstr "Zeigt die Hilfe an" #: ../../utils/net.c:610 msgid " Use 'net help help' to list usage information for 'net' commands." @@ -421,7 +426,8 @@ msgstr "" "\n" "Ungültige Option %s: %s\n" -#: ../../utils/net_ads.c:52 ../../utils/net_ads.c:392 +#: ../../utils/net_ads.c:52 +#: ../../utils/net_ads.c:392 msgid "CLDAP query failed!\n" msgstr "" @@ -459,15 +465,41 @@ msgid "" "\tIs NT6 DC that has all secrets: %s\n" msgstr "" -#: ../../utils/net_ads.c:87 ../../utils/net_ads.c:88 ../../utils/net_ads.c:89 ../../utils/net_ads.c:90 ../../utils/net_ads.c:91 ../../utils/net_ads.c:92 ../../utils/net_ads.c:93 ../../utils/net_ads.c:94 ../../utils/net_ads.c:95 ../../utils/net_ads.c:96 -#: ../../utils/net_ads.c:97 ../../utils/net_ads.c:98 ../../utils/net_rap.c:376 ../../utils/net_rpc_sh_acct.c:203 ../../utils/net_rpc_sh_acct.c:206 +#: ../../utils/net_ads.c:87 +#: ../../utils/net_ads.c:88 +#: ../../utils/net_ads.c:89 +#: ../../utils/net_ads.c:90 +#: ../../utils/net_ads.c:91 +#: ../../utils/net_ads.c:92 +#: ../../utils/net_ads.c:93 +#: ../../utils/net_ads.c:94 +#: ../../utils/net_ads.c:95 +#: ../../utils/net_ads.c:96 +#: ../../utils/net_ads.c:97 +#: ../../utils/net_ads.c:98 +#: ../../utils/net_rap.c:376 +#: ../../utils/net_rpc_sh_acct.c:203 +#: ../../utils/net_rpc_sh_acct.c:206 msgid "yes" -msgstr "" - -#: ../../utils/net_ads.c:87 ../../utils/net_ads.c:88 ../../utils/net_ads.c:89 ../../utils/net_ads.c:90 ../../utils/net_ads.c:91 ../../utils/net_ads.c:92 ../../utils/net_ads.c:93 ../../utils/net_ads.c:94 ../../utils/net_ads.c:95 ../../utils/net_ads.c:96 -#: ../../utils/net_ads.c:97 ../../utils/net_ads.c:98 ../../utils/net_rap.c:376 ../../utils/net_rpc_sh_acct.c:203 ../../utils/net_rpc_sh_acct.c:206 +msgstr "Ja" + +#: ../../utils/net_ads.c:87 +#: ../../utils/net_ads.c:88 +#: ../../utils/net_ads.c:89 +#: ../../utils/net_ads.c:90 +#: ../../utils/net_ads.c:91 +#: ../../utils/net_ads.c:92 +#: ../../utils/net_ads.c:93 +#: ../../utils/net_ads.c:94 +#: ../../utils/net_ads.c:95 +#: ../../utils/net_ads.c:96 +#: ../../utils/net_ads.c:97 +#: ../../utils/net_ads.c:98 +#: ../../utils/net_rap.c:376 +#: ../../utils/net_rpc_sh_acct.c:203 +#: ../../utils/net_rpc_sh_acct.c:206 msgid "no" -msgstr "" +msgstr "Nein" #: ../../utils/net_ads.c:101 #, c-format @@ -477,7 +509,7 @@ msgstr "" #: ../../utils/net_ads.c:102 #, c-format msgid "Domain:\t\t\t%s\n" -msgstr "" +msgstr "Domäne:\t\t\t%s\n" #: ../../utils/net_ads.c:103 #, c-format @@ -512,7 +544,7 @@ msgstr "" #: ../../utils/net_ads.c:113 #, c-format msgid "NT Version: %d\n" -msgstr "" +msgstr "NT Version: %d\n" #: ../../utils/net_ads.c:114 #, c-format @@ -531,7 +563,8 @@ msgid "" " Find the ADS DC using CLDAP lookup.\n" msgstr "" -#: ../../utils/net_ads.c:137 ../../utils/net_ads.c:381 +#: ../../utils/net_ads.c:137 +#: ../../utils/net_ads.c:381 msgid "Didn't find the cldap server!\n" msgstr "" @@ -542,7 +575,8 @@ msgid "" " Display information about an Active Directory server.\n" msgstr "" -#: ../../utils/net_ads.c:168 ../../utils/net_ads.c:173 +#: ../../utils/net_ads.c:168 +#: ../../utils/net_ads.c:173 msgid "Didn't find the ldap server!\n" msgstr "" @@ -617,7 +651,8 @@ msgstr "" msgid "Could not add user %s: %s\n" msgstr "" -#: ../../utils/net_ads.c:484 ../../utils/net_ads.c:497 +#: ../../utils/net_ads.c:484 +#: ../../utils/net_ads.c:497 #, c-format msgid "User %s added\n" msgstr "" @@ -699,7 +734,9 @@ msgid "" " List AD users\n" msgstr "" -#: ../../utils/net_ads.c:711 ../../utils/net_rap.c:901 ../../utils/net_rpc.c:852 +#: ../../utils/net_ads.c:711 +#: ../../utils/net_rap.c:901 +#: ../../utils/net_rpc.c:852 msgid "" "\n" "User name Comment\n" @@ -743,23 +780,27 @@ msgstr "" #: ../../utils/net_ads.c:828 msgid "Add an AD group" -msgstr "" +msgstr "AD Gruppe hinzufügen" #: ../../utils/net_ads.c:829 msgid "" "net ads group add\n" " Add an AD group" msgstr "" +"net ads group add\n" +" AD Gruppe hinzufügen" #: ../../utils/net_ads.c:836 msgid "Delete an AD group" -msgstr "" +msgstr "AD Gruppe entfernen" #: ../../utils/net_ads.c:837 msgid "" "net ads group delete\n" " Delete an AD group" msgstr "" +"net ads group delete\n" +" AD Gruppe entfernen" #: ../../utils/net_ads.c:850 msgid "" @@ -768,12 +809,16 @@ msgid "" " List AD groups\n" msgstr "" -#: ../../utils/net_ads.c:862 ../../utils/net_rpc.c:2230 +#: ../../utils/net_ads.c:862 +#: ../../utils/net_rpc.c:2230 msgid "" "\n" "Group name Comment\n" "-----------------------------\n" msgstr "" +"\n" +"Gruppenname Kommentar\n" +"-----------------------------\n" #: ../../utils/net_ads.c:884 msgid "" @@ -803,7 +848,8 @@ msgstr "" msgid "No realm set, are we joined ?\n" msgstr "" -#: ../../utils/net_ads.c:938 ../../utils/net_ads.c:1260 +#: ../../utils/net_ads.c:938 +#: ../../utils/net_ads.c:1260 msgid "Could not initialise talloc context.\n" msgstr "" @@ -847,15 +893,16 @@ msgid "Join to domain is not valid: %s\n" msgstr "" #: ../../utils/net_ads.c:1049 -#, c-format +#, fuzzy, c-format msgid "Join is OK\n" -msgstr "" +msgstr "Beitritt ist OK\n" #: ../../utils/net_ads.c:1060 msgid "Host is not configured as a member server.\n" msgstr "" -#: ../../utils/net_ads.c:1065 ../../utils/net_rpc.c:436 +#: ../../utils/net_ads.c:1065 +#: ../../utils/net_rpc.c:436 #, c-format msgid "Our netbios name can be at most 15 chars long, \"%s\" is %u chars long\n" msgstr "" @@ -947,12 +994,14 @@ msgstr "" msgid "Joined '%s' to domain '%s'\n" msgstr "" -#: ../../utils/net_ads.c:1377 ../../utils/net_ads.c:1433 +#: ../../utils/net_ads.c:1377 +#: ../../utils/net_ads.c:1433 msgid "DNS update failed!\n" msgstr "" #. issue an overall failure message at the end. -#: ../../utils/net_ads.c:1391 ../../utils/net_dom.c:198 +#: ../../utils/net_ads.c:1391 +#: ../../utils/net_dom.c:198 #, c-format msgid "Failed to join domain: %s\n" msgstr "" @@ -1059,7 +1108,8 @@ msgstr "" msgid "Server '%s' not found: %s\n" msgstr "" -#: ../../utils/net_ads.c:1611 ../../utils/net_ads.c:1794 +#: ../../utils/net_ads.c:1611 +#: ../../utils/net_ads.c:1794 #, c-format msgid "Printer '%s' not found\n" msgstr "" @@ -1083,7 +1133,8 @@ msgstr "" msgid "Could not find machine account for server %s\n" msgstr "" -#: ../../utils/net_ads.c:1704 ../../utils/net_ads.c:1713 +#: ../../utils/net_ads.c:1704 +#: ../../utils/net_ads.c:1713 msgid "Internal error, out of memory!" msgstr "" @@ -1171,12 +1222,14 @@ msgstr "" msgid "Didn't find the kerberos server!\n" msgstr "" -#: ../../utils/net_ads.c:1923 ../../utils/net_rpc.c:756 +#: ../../utils/net_ads.c:1923 +#: ../../utils/net_rpc.c:756 #, c-format msgid "Enter new password for %s:" msgstr "Bitte neues Passwort für %s eingeben: " -#: ../../utils/net_ads.c:1933 ../../utils/net_ads.c:1982 +#: ../../utils/net_ads.c:1933 +#: ../../utils/net_ads.c:1982 #, c-format msgid "Password change failed: %s\n" msgstr "" @@ -1224,12 +1277,17 @@ msgid "" "\n" msgstr "" -#: ../../utils/net_ads.c:2046 ../../utils/net_ads.c:2107 ../../utils/net_ads.c:2171 ../../utils/net_ads_gpo.c:250 +#: ../../utils/net_ads.c:2046 +#: ../../utils/net_ads.c:2107 +#: ../../utils/net_ads.c:2171 +#: ../../utils/net_ads_gpo.c:250 #, c-format msgid "search failed: %s\n" -msgstr "" +msgstr "Suche fehlgeschlagen: %s\n" -#: ../../utils/net_ads.c:2051 ../../utils/net_ads.c:2176 ../../utils/net_ads_gpo.c:256 +#: ../../utils/net_ads.c:2051 +#: ../../utils/net_ads.c:2176 +#: ../../utils/net_ads_gpo.c:256 #, c-format msgid "" "Got %d replies\n" @@ -1469,7 +1527,8 @@ msgid "" " Display machine account details" msgstr "" -#: ../../utils/net_ads.c:2509 ../../utils/net_rpc.c:7110 +#: ../../utils/net_ads.c:2509 +#: ../../utils/net_rpc.c:7110 msgid "List/modify users" msgstr "" @@ -1479,7 +1538,8 @@ msgid "" " List/modify users" msgstr "" -#: ../../utils/net_ads.c:2517 ../../utils/net_rpc.c:7127 +#: ../../utils/net_ads.c:2517 +#: ../../utils/net_rpc.c:7127 msgid "List/modify groups" msgstr "" @@ -1509,7 +1569,8 @@ msgid "" " Change user passwords" msgstr "" -#: ../../utils/net_ads.c:2541 ../../utils/net_rpc.c:7159 +#: ../../utils/net_ads.c:2541 +#: ../../utils/net_rpc.c:7159 msgid "Change trust account password" msgstr "Trust account Passwort ändern" @@ -1640,11 +1701,13 @@ msgid "" "\n" msgstr "" -#: ../../utils/net_ads_gpo.c:71 ../../utils/net_ads_gpo.c:328 +#: ../../utils/net_ads_gpo.c:71 +#: ../../utils/net_ads_gpo.c:328 msgid "machine" msgstr "" -#: ../../utils/net_ads_gpo.c:71 ../../utils/net_ads_gpo.c:328 +#: ../../utils/net_ads_gpo.c:71 +#: ../../utils/net_ads_gpo.c:328 msgid "user" msgstr "" @@ -1652,12 +1715,20 @@ msgstr "" msgid "* fetching token " msgstr "" -#: ../../utils/net_ads_gpo.c:82 ../../utils/net_ads_gpo.c:90 ../../utils/net_ads_gpo.c:102 ../../utils/net_ads_gpo.c:113 ../../utils/net_ads_gpo.c:158 +#: ../../utils/net_ads_gpo.c:82 +#: ../../utils/net_ads_gpo.c:90 +#: ../../utils/net_ads_gpo.c:102 +#: ../../utils/net_ads_gpo.c:113 +#: ../../utils/net_ads_gpo.c:158 #, c-format msgid "failed: %s\n" msgstr "" -#: ../../utils/net_ads_gpo.c:85 ../../utils/net_ads_gpo.c:94 ../../utils/net_ads_gpo.c:105 ../../utils/net_ads_gpo.c:118 ../../utils/net_ads_gpo.c:163 +#: ../../utils/net_ads_gpo.c:85 +#: ../../utils/net_ads_gpo.c:94 +#: ../../utils/net_ads_gpo.c:105 +#: ../../utils/net_ads_gpo.c:118 +#: ../../utils/net_ads_gpo.c:163 msgid "finished\n" msgstr "" @@ -1842,7 +1913,7 @@ msgstr "" #: ../../utils/net_afs.c:48 #, c-format msgid "Could not open %s\n" -msgstr "" +msgstr "Konnte %s nicht öffnen\n" #: ../../utils/net_afs.c:53 msgid "Could not read keyfile\n" @@ -1960,7 +2031,8 @@ msgid "" " List all cache entries.\n" msgstr "" -#: ../../utils/net_cache.c:293 ../../utils/net_cache.c:306 +#: ../../utils/net_cache.c:293 +#: ../../utils/net_cache.c:306 msgid "" "Usage:\n" "net cache flush\n" @@ -2109,8 +2181,18 @@ msgstr "" msgid "Error getting config: %s\n" msgstr "" -#: ../../utils/net_conf.c:305 ../../utils/net_conf.c:318 ../../utils/net_conf.c:614 ../../utils/net_conf.c:742 ../../utils/net_conf.c:780 ../../utils/net_conf.c:786 ../../utils/net_conf.c:860 ../../utils/net_conf.c:866 ../../utils/net_conf.c:916 -#: ../../utils/net_conf.c:970 ../../utils/net_conf.c:1010 ../../utils/net_conf.c:1050 +#: ../../utils/net_conf.c:305 +#: ../../utils/net_conf.c:318 +#: ../../utils/net_conf.c:614 +#: ../../utils/net_conf.c:742 +#: ../../utils/net_conf.c:780 +#: ../../utils/net_conf.c:786 +#: ../../utils/net_conf.c:860 +#: ../../utils/net_conf.c:866 +#: ../../utils/net_conf.c:916 +#: ../../utils/net_conf.c:970 +#: ../../utils/net_conf.c:1010 +#: ../../utils/net_conf.c:1050 msgid "error: out of memory!\n" msgstr "" @@ -2126,17 +2208,23 @@ msgid "" "\n" msgstr "" -#: ../../utils/net_conf.c:346 ../../utils/net_conf.c:382 ../../utils/net_conf.c:407 ../../utils/net_conf.c:793 +#: ../../utils/net_conf.c:346 +#: ../../utils/net_conf.c:382 +#: ../../utils/net_conf.c:407 +#: ../../utils/net_conf.c:793 #, c-format msgid "error starting transaction: %s\n" msgstr "" -#: ../../utils/net_conf.c:400 ../../utils/net_conf.c:416 ../../utils/net_conf.c:817 +#: ../../utils/net_conf.c:400 +#: ../../utils/net_conf.c:416 +#: ../../utils/net_conf.c:817 #, c-format msgid "error committing transaction: %s\n" msgstr "" -#: ../../utils/net_conf.c:427 ../../utils/net_conf.c:828 +#: ../../utils/net_conf.c:427 +#: ../../utils/net_conf.c:828 #, c-format msgid "error cancelling transaction: %s\n" msgstr "" @@ -2187,7 +2275,10 @@ msgstr "" msgid "Error creating share %s: %s\n" msgstr "" -#: ../../utils/net_conf.c:690 ../../utils/net_conf.c:699 ../../utils/net_conf.c:707 ../../utils/net_conf.c:715 +#: ../../utils/net_conf.c:690 +#: ../../utils/net_conf.c:699 +#: ../../utils/net_conf.c:707 +#: ../../utils/net_conf.c:715 #, c-format msgid "Error setting parameter %s: %s\n" msgstr "" @@ -2207,12 +2298,14 @@ msgstr "" msgid "Error setting value '%s': %s\n" msgstr "" -#: ../../utils/net_conf.c:874 ../../utils/net_conf.c:930 +#: ../../utils/net_conf.c:874 +#: ../../utils/net_conf.c:930 #, c-format msgid "Error: given service '%s' does not exist.\n" msgstr "" -#: ../../utils/net_conf.c:879 ../../utils/net_conf.c:935 +#: ../../utils/net_conf.c:879 +#: ../../utils/net_conf.c:935 #, c-format msgid "Error: given parameter '%s' is not set.\n" msgstr "" @@ -2242,8 +2335,20 @@ msgstr "" msgid "error deleting includes: %s\n" msgstr "" -#: ../../utils/net_conf.c:1136 ../../utils/net_help.c:36 ../../utils/net_rap.c:161 ../../utils/net_rap.c:302 ../../utils/net_rap.c:467 ../../utils/net_rap.c:750 ../../utils/net_rap.c:891 ../../utils/net_rap.c:1002 ../../utils/net_rap.c:1193 -#: ../../utils/net_rpc.c:960 ../../utils/net_rpc.c:2801 ../../utils/net_rpc.c:4897 ../../utils/net_rpc.c:6933 ../../utils/net_rpc.c:7038 +#: ../../utils/net_conf.c:1136 +#: ../../utils/net_help.c:36 +#: ../../utils/net_rap.c:161 +#: ../../utils/net_rap.c:302 +#: ../../utils/net_rap.c:467 +#: ../../utils/net_rap.c:750 +#: ../../utils/net_rap.c:891 +#: ../../utils/net_rap.c:1002 +#: ../../utils/net_rap.c:1193 +#: ../../utils/net_rpc.c:960 +#: ../../utils/net_rpc.c:2801 +#: ../../utils/net_rpc.c:4897 +#: ../../utils/net_rpc.c:6933 +#: ../../utils/net_rpc.c:7038 msgid "Usage:\n" msgstr "" @@ -2400,7 +2505,8 @@ msgstr "" msgid "Failed to unjoin domain: %s\n" msgstr "" -#: ../../utils/net_dom.c:97 ../../utils/net_dom.c:204 +#: ../../utils/net_dom.c:97 +#: ../../utils/net_dom.c:204 msgid "Shutting down due to a domain membership change" msgstr "" @@ -2452,12 +2558,14 @@ msgstr "" msgid "usage: net eventlog dump <file.evt>\n" msgstr "" -#: ../../utils/net_eventlog.c:52 ../../utils/net_eventlog.c:108 +#: ../../utils/net_eventlog.c:52 +#: ../../utils/net_eventlog.c:108 #, c-format msgid "failed to load evt file: %s\n" msgstr "" -#: ../../utils/net_eventlog.c:59 ../../utils/net_eventlog.c:129 +#: ../../utils/net_eventlog.c:59 +#: ../../utils/net_eventlog.c:129 #, c-format msgid "evt pull failed: %s\n" msgstr "" @@ -2475,7 +2583,8 @@ msgstr "" msgid "input file is wrapped, cannot proceed\n" msgstr "" -#: ../../utils/net_eventlog.c:138 ../../utils/net_eventlog.c:203 +#: ../../utils/net_eventlog.c:138 +#: ../../utils/net_eventlog.c:203 #, c-format msgid "can't open the eventlog TDB (%s)\n" msgstr "" @@ -2604,11 +2713,13 @@ msgid "" "\n" msgstr "" -#: ../../utils/net_group.c:44 ../../utils/net_user.c:41 +#: ../../utils/net_group.c:44 +#: ../../utils/net_user.c:41 msgid "\t-C or --comment=<comment>\tdescriptive comment (for add only)\n" msgstr "" -#: ../../utils/net_group.c:46 ../../utils/net_user.c:43 +#: ../../utils/net_group.c:46 +#: ../../utils/net_user.c:43 msgid "\t-c or --container=<container>\tLDAP container, defaults to cn=Users (for add in ADS only)\n" msgstr "" @@ -2659,22 +2770,37 @@ msgid "" " sid\tSID of group to list" msgstr "" -#: ../../utils/net_groupmap.c:91 ../../utils/net_groupmap.c:271 ../../utils/net_groupmap.c:356 ../../utils/net_groupmap.c:412 ../../utils/net_groupmap.c:495 ../../utils/net_groupmap.c:522 +#: ../../utils/net_groupmap.c:91 +#: ../../utils/net_groupmap.c:271 +#: ../../utils/net_groupmap.c:356 +#: ../../utils/net_groupmap.c:412 +#: ../../utils/net_groupmap.c:495 +#: ../../utils/net_groupmap.c:522 #, c-format msgid "" "Usage:\n" "%s\n" msgstr "" -#: ../../utils/net_groupmap.c:106 ../../utils/net_groupmap.c:213 ../../utils/net_groupmap.c:220 ../../utils/net_groupmap.c:365 ../../utils/net_groupmap.c:372 ../../utils/net_groupmap.c:504 +#: ../../utils/net_groupmap.c:106 +#: ../../utils/net_groupmap.c:213 +#: ../../utils/net_groupmap.c:220 +#: ../../utils/net_groupmap.c:365 +#: ../../utils/net_groupmap.c:372 +#: ../../utils/net_groupmap.c:504 msgid "must supply a name\n" msgstr "" -#: ../../utils/net_groupmap.c:113 ../../utils/net_groupmap.c:227 ../../utils/net_groupmap.c:511 +#: ../../utils/net_groupmap.c:113 +#: ../../utils/net_groupmap.c:227 +#: ../../utils/net_groupmap.c:511 msgid "must supply a SID\n" msgstr "" -#: ../../utils/net_groupmap.c:118 ../../utils/net_groupmap.c:265 ../../utils/net_groupmap.c:406 ../../utils/net_groupmap.c:516 +#: ../../utils/net_groupmap.c:118 +#: ../../utils/net_groupmap.c:265 +#: ../../utils/net_groupmap.c:406 +#: ../../utils/net_groupmap.c:516 #, c-format msgid "Bad option: %s\n" msgstr "Ungültige Option: %s\n" @@ -2699,7 +2825,8 @@ msgstr "" msgid "RID must be greater than %d\n" msgstr "" -#: ../../utils/net_groupmap.c:235 ../../utils/net_groupmap.c:380 +#: ../../utils/net_groupmap.c:235 +#: ../../utils/net_groupmap.c:380 msgid "must supply a comment string\n" msgstr "" @@ -2888,7 +3015,8 @@ msgstr "" msgid "Usage: net groupmap memberof sid\n" msgstr "" -#: ../../utils/net_groupmap.c:820 ../../utils/net_idmap.c:345 +#: ../../utils/net_groupmap.c:820 +#: ../../utils/net_idmap.c:345 msgid "talloc_init failed\n" msgstr "" @@ -3001,15 +3129,18 @@ msgstr "" msgid "net %s usage:\n" msgstr "" -#: ../../utils/net_help_common.c:25 ../../utils/net_join.c:28 +#: ../../utils/net_help_common.c:25 +#: ../../utils/net_join.c:28 msgid "Valid methods: (auto-detected if not specified)\n" msgstr "" -#: ../../utils/net_help_common.c:26 ../../utils/net_join.c:29 +#: ../../utils/net_help_common.c:26 +#: ../../utils/net_join.c:29 msgid "\tads\t\t\t\tActive Directory (LDAP/Kerberos)\n" msgstr "" -#: ../../utils/net_help_common.c:27 ../../utils/net_join.c:30 +#: ../../utils/net_help_common.c:27 +#: ../../utils/net_join.c:30 msgid "\trpc\t\t\t\tDCE-RPC\n" msgstr "" @@ -3146,7 +3277,8 @@ msgstr "ignoriere ungültige sid [%s]: %s\n" msgid "Could not set mapping of %s %lu to sid %s: %s\n" msgstr "" -#: ../../utils/net_idmap.c:196 ../../utils/net_idmap.c:202 +#: ../../utils/net_idmap.c:196 +#: ../../utils/net_idmap.c:202 msgid "Not Implemented yet\n" msgstr "" @@ -3209,7 +3341,8 @@ msgstr "" msgid "db_open failed: %s\n" msgstr "" -#: ../../utils/net_idmap.c:356 ../../utils/net_idmap.c:361 +#: ../../utils/net_idmap.c:356 +#: ../../utils/net_idmap.c:361 #, c-format msgid "%s is not a valid sid\n" msgstr "" @@ -3247,7 +3380,8 @@ msgid "" " Restore entries from stdin" msgstr "" -#: ../../utils/net_idmap.c:418 ../../utils/net_idmap.c:426 +#: ../../utils/net_idmap.c:418 +#: ../../utils/net_idmap.c:426 msgid "Not implemented yet" msgstr "" @@ -3332,7 +3466,8 @@ msgstr "" msgid "usage: net lookup name <name>\n" msgstr "" -#: ../../utils/net_lookup.c:331 ../../utils/net_lookup.c:358 +#: ../../utils/net_lookup.c:331 +#: ../../utils/net_lookup.c:358 #, c-format msgid "Could not lookup name %s\n" msgstr "" @@ -3388,7 +3523,8 @@ msgid "" "------ --------- ----- ----- ---- \n" msgstr "" -#: ../../utils/net_rap.c:120 ../../utils/net_rap.c:180 +#: ../../utils/net_rap.c:120 +#: ../../utils/net_rap.c:180 msgid "" "\n" "Operation not supported by server!\n" @@ -3446,7 +3582,8 @@ msgstr "" msgid "Server path not specified\n" msgstr "" -#: ../../utils/net_rap.c:273 ../../utils/net_rap.c:281 +#: ../../utils/net_rap.c:273 +#: ../../utils/net_rap.c:281 msgid "Delete a share from server" msgstr "" @@ -3479,7 +3616,8 @@ msgid "" " List all shares on remote server\n" msgstr "" -#: ../../utils/net_rap.c:314 ../../utils/net_rpc.c:3046 +#: ../../utils/net_rap.c:314 +#: ../../utils/net_rpc.c:3046 msgid "" "\n" "Enumerating shared resources (exports) on remote server:\n" @@ -3539,7 +3677,8 @@ msgid "" " Display information about session" msgstr "" -#: ../../utils/net_rap.c:446 ../../utils/net_rap.c:455 +#: ../../utils/net_rap.c:446 +#: ../../utils/net_rap.c:455 msgid "Close specified session" msgstr "" @@ -3673,7 +3812,8 @@ msgstr "" msgid "*Delete Pending*\n" msgstr "" -#: ../../utils/net_rap.c:652 ../../utils/net_rap.c:678 +#: ../../utils/net_rap.c:652 +#: ../../utils/net_rap.c:678 msgid "**UNKNOWN STATUS**\n" msgstr "" @@ -3730,7 +3870,8 @@ msgid "" " List the print queue\n" msgstr "" -#: ../../utils/net_rap.c:864 ../../utils/net_rpc.c:909 +#: ../../utils/net_rap.c:864 +#: ../../utils/net_rpc.c:909 msgid "Add specified user" msgstr "" @@ -3750,7 +3891,8 @@ msgid "" " List domain groups of specified user" msgstr "" -#: ../../utils/net_rap.c:881 ../../utils/net_rpc.c:925 +#: ../../utils/net_rap.c:881 +#: ../../utils/net_rpc.c:925 msgid "Remove specified user" msgstr "" @@ -3781,7 +3923,8 @@ msgid "" " Add specified group" msgstr "" -#: ../../utils/net_rap.c:991 ../../utils/net_rpc.c:2742 +#: ../../utils/net_rap.c:991 +#: ../../utils/net_rpc.c:2742 msgid "Delete specified group" msgstr "" @@ -3916,7 +4059,8 @@ msgid "" "\texecutes a remote command on an os/2 target server\n" msgstr "" -#: ../../utils/net_rap.c:1267 ../../utils/net_rpc.c:7143 +#: ../../utils/net_rap.c:1267 +#: ../../utils/net_rpc.c:7143 msgid "List open files" msgstr "" @@ -4032,7 +4176,8 @@ msgid "" " Start/stop remote service" msgstr "" -#: ../../utils/net_rap.c:1363 ../../utils/net_rpc.c:933 +#: ../../utils/net_rap.c:1363 +#: ../../utils/net_rpc.c:933 msgid "Change user password" msgstr "" @@ -4042,7 +4187,9 @@ msgid "" " Change user password" msgstr "" -#: ../../utils/net_registry.c:94 ../../utils/net_registry.c:197 ../../utils/net_registry.c:250 +#: ../../utils/net_registry.c:94 +#: ../../utils/net_registry.c:197 +#: ../../utils/net_registry.c:250 #, c-format msgid "open_hive failed: %s\n" msgstr "" @@ -4060,7 +4207,11 @@ msgstr "" msgid "Example: net registry enumerate 'HKLM\\Software\\Samba'\n" msgstr "" -#: ../../utils/net_registry.c:141 ../../utils/net_registry.c:286 ../../utils/net_registry.c:356 ../../utils/net_registry.c:390 ../../utils/net_registry.c:439 +#: ../../utils/net_registry.c:141 +#: ../../utils/net_registry.c:286 +#: ../../utils/net_registry.c:356 +#: ../../utils/net_registry.c:390 +#: ../../utils/net_registry.c:439 #, c-format msgid "open_key failed: %s\n" msgstr "" @@ -4073,7 +4224,8 @@ msgstr "" msgid "Example: net registry createkey 'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n" msgstr "" -#: ../../utils/net_registry.c:191 ../../utils/net_registry.c:244 +#: ../../utils/net_registry.c:191 +#: ../../utils/net_registry.c:244 msgid "error: zero length key name given\n" msgstr "" @@ -4082,16 +4234,19 @@ msgstr "" msgid "reg_createkey failed: %s\n" msgstr "" -#: ../../utils/net_registry.c:211 ../../utils/net_rpc_registry.c:681 +#: ../../utils/net_registry.c:211 +#: ../../utils/net_rpc_registry.c:681 msgid "createkey did nothing -- huh?\n" msgstr "" -#: ../../utils/net_registry.c:214 ../../utils/net_rpc_registry.c:684 +#: ../../utils/net_registry.c:214 +#: ../../utils/net_rpc_registry.c:684 #, c-format msgid "createkey created %s\n" msgstr "" -#: ../../utils/net_registry.c:217 ../../utils/net_rpc_registry.c:687 +#: ../../utils/net_registry.c:217 +#: ../../utils/net_rpc_registry.c:687 #, c-format msgid "createkey opened existing %s\n" msgstr "" @@ -4104,12 +4259,15 @@ msgstr "" msgid "Example: net registry deletekey 'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n" msgstr "" -#: ../../utils/net_registry.c:257 ../../utils/net_registry.c:396 +#: ../../utils/net_registry.c:257 +#: ../../utils/net_registry.c:396 #, c-format msgid "reg_deletekey failed: %s\n" msgstr "" -#: ../../utils/net_registry.c:279 ../../utils/net_rpc_registry.c:601 ../../utils/net_rpc_registry.c:628 +#: ../../utils/net_registry.c:279 +#: ../../utils/net_rpc_registry.c:601 +#: ../../utils/net_rpc_registry.c:628 msgid "usage: net rpc registry getvalue <key> <valuename>\n" msgstr "" @@ -4118,16 +4276,19 @@ msgstr "" msgid "reg_queryvalue failed: %s\n" msgstr "" -#: ../../utils/net_registry.c:328 ../../utils/net_rpc_registry.c:433 +#: ../../utils/net_registry.c:328 +#: ../../utils/net_rpc_registry.c:433 msgid "usage: net rpc registry setvalue <key> <valuename> <type> [<val>]+\n" msgstr "" -#: ../../utils/net_registry.c:334 ../../utils/net_rpc_registry.c:395 +#: ../../utils/net_registry.c:334 +#: ../../utils/net_rpc_registry.c:395 #, c-format msgid "Too many args for type %s\n" msgstr "" -#: ../../utils/net_registry.c:350 ../../utils/net_rpc_registry.c:409 +#: ../../utils/net_registry.c:350 +#: ../../utils/net_rpc_registry.c:409 #, c-format msgid "type \"%s\" not implemented\n" msgstr "" @@ -4137,7 +4298,8 @@ msgstr "" msgid "reg_setvalue failed: %s\n" msgstr "" -#: ../../utils/net_registry.c:383 ../../utils/net_rpc_registry.c:486 +#: ../../utils/net_registry.c:383 +#: ../../utils/net_rpc_registry.c:486 msgid "usage: net rpc registry deletevalue <key> <valuename>\n" msgstr "" @@ -4154,7 +4316,8 @@ msgstr "" msgid "reg_getkeysecurity failed: %s\n" msgstr "" -#: ../../utils/net_registry.c:468 ../../utils/net_rpc_registry.c:1234 +#: ../../utils/net_registry.c:468 +#: ../../utils/net_rpc_registry.c:1234 msgid "Enumerate registry keys and values" msgstr "" @@ -4164,7 +4327,8 @@ msgid "" " Enumerate registry keys and values" msgstr "" -#: ../../utils/net_registry.c:476 ../../utils/net_rpc_registry.c:1242 +#: ../../utils/net_registry.c:476 +#: ../../utils/net_rpc_registry.c:1242 msgid "Create a new registry key" msgstr "" @@ -4174,7 +4338,8 @@ msgid "" " Create a new registry key" msgstr "" -#: ../../utils/net_registry.c:484 ../../utils/net_rpc_registry.c:1250 +#: ../../utils/net_registry.c:484 +#: ../../utils/net_rpc_registry.c:1250 msgid "Delete a registry key" msgstr "" @@ -4184,7 +4349,9 @@ msgid "" " Delete a registry key" msgstr "" -#: ../../utils/net_registry.c:492 ../../utils/net_rpc_registry.c:1258 ../../utils/net_rpc_registry.c:1266 +#: ../../utils/net_registry.c:492 +#: ../../utils/net_rpc_registry.c:1258 +#: ../../utils/net_rpc_registry.c:1266 msgid "Print a registry value" msgstr "" @@ -4204,7 +4371,8 @@ msgid "" " Print a registry value (raw format)" msgstr "" -#: ../../utils/net_registry.c:508 ../../utils/net_rpc_registry.c:1274 +#: ../../utils/net_registry.c:508 +#: ../../utils/net_rpc_registry.c:1274 msgid "Set a new registry value" msgstr "" @@ -4214,7 +4382,8 @@ msgid "" " Set a new registry value" msgstr "" -#: ../../utils/net_registry.c:516 ../../utils/net_rpc_registry.c:1282 +#: ../../utils/net_registry.c:516 +#: ../../utils/net_rpc_registry.c:1282 msgid "Delete a registry value" msgstr "" @@ -4224,7 +4393,8 @@ msgid "" " Delete a registry value" msgstr "" -#: ../../utils/net_registry.c:524 ../../utils/net_rpc_registry.c:1314 +#: ../../utils/net_registry.c:524 +#: ../../utils/net_rpc_registry.c:1314 msgid "Get security descriptor" msgstr "" @@ -4253,7 +4423,9 @@ msgstr "" msgid "Type = %s\n" msgstr "" -#: ../../utils/net_registry_util.c:45 ../../utils/net_registry_util.c:76 ../../utils/net_registry_util.c:82 +#: ../../utils/net_registry_util.c:45 +#: ../../utils/net_registry_util.c:76 +#: ../../utils/net_registry_util.c:82 msgid "Value = " msgstr "" @@ -4280,11 +4452,13 @@ msgstr "" msgid "Valuename = %s\n" msgstr "" -#: ../../utils/net_rpc.c:66 ../../utils/net_util.c:43 +#: ../../utils/net_rpc.c:66 +#: ../../utils/net_util.c:43 msgid "Could not initialise lsa pipe\n" msgstr "" -#: ../../utils/net_rpc.c:74 ../../utils/net_util.c:51 +#: ../../utils/net_rpc.c:74 +#: ../../utils/net_util.c:51 #, c-format msgid "open_policy failed: %s\n" msgstr "" @@ -4301,7 +4475,8 @@ msgid "" " Change the machine trust password\n" msgstr "" -#: ../../utils/net_rpc.c:341 ../../utils/net_rpc_join.c:470 +#: ../../utils/net_rpc.c:341 +#: ../../utils/net_rpc_join.c:470 #, c-format msgid "Joined domain %s.\n" msgstr "" @@ -4487,7 +4662,10 @@ msgstr "" msgid "Could not lookup %s: %s\n" msgstr "" -#: ../../utils/net_rpc.c:1028 ../../utils/net_sam.c:52 ../../utils/net_sam.c:157 ../../utils/net_sam.c:249 +#: ../../utils/net_rpc.c:1028 +#: ../../utils/net_sam.c:52 +#: ../../utils/net_sam.c:157 +#: ../../utils/net_sam.c:249 #, c-format msgid "%s is a %s, not a user\n" msgstr "" @@ -4646,7 +4824,13 @@ msgstr "" msgid "Remove group member %d..." msgstr "" -#: ../../utils/net_rpc.c:1546 ../../utils/net_rpc_registry.c:1053 ../../utils/net_rpc_registry.c:1073 ../../utils/net_rpc_registry.c:1098 ../../utils/net_rpc_registry.c:1105 ../../utils/net_rpc_registry.c:1125 ../../utils/net_rpc_registry.c:1131 +#: ../../utils/net_rpc.c:1546 +#: ../../utils/net_rpc_registry.c:1053 +#: ../../utils/net_rpc_registry.c:1073 +#: ../../utils/net_rpc_registry.c:1098 +#: ../../utils/net_rpc_registry.c:1105 +#: ../../utils/net_rpc_registry.c:1125 +#: ../../utils/net_rpc_registry.c:1131 msgid "ok\n" msgstr "" @@ -4693,7 +4877,10 @@ msgstr "" msgid "Added alias '%s'.\n" msgstr "" -#: ../../utils/net_rpc.c:1782 ../../utils/net_rpc.c:1832 ../../utils/net_rpc.c:1989 ../../utils/net_rpc.c:2036 +#: ../../utils/net_rpc.c:1782 +#: ../../utils/net_rpc.c:1832 +#: ../../utils/net_rpc.c:1989 +#: ../../utils/net_rpc.c:2036 #, c-format msgid "Could not lookup up group member %s\n" msgstr "" @@ -4707,12 +4894,14 @@ msgid "" " member\tMember to add to group\n" msgstr "" -#: ../../utils/net_rpc.c:1902 ../../utils/net_rpc.c:2104 +#: ../../utils/net_rpc.c:1902 +#: ../../utils/net_rpc.c:2104 #, c-format msgid "Could not lookup group name %s\n" msgstr "" -#: ../../utils/net_rpc.c:1912 ../../utils/net_rpc.c:1923 +#: ../../utils/net_rpc.c:1912 +#: ../../utils/net_rpc.c:1923 #, c-format msgid "Could not add %s to %s: %s\n" msgstr "" @@ -4731,7 +4920,8 @@ msgid "" " member\tMember to delete from group\n" msgstr "" -#: ../../utils/net_rpc.c:2114 ../../utils/net_rpc.c:2125 +#: ../../utils/net_rpc.c:2114 +#: ../../utils/net_rpc.c:2125 #, c-format msgid "Could not del %s from %s: %s\n" msgstr "" @@ -4773,11 +4963,14 @@ msgstr "" msgid "Couldn't lookup SIDs\n" msgstr "" -#: ../../utils/net_rpc.c:2555 ../../utils/net_rpc.c:2556 +#: ../../utils/net_rpc.c:2555 +#: ../../utils/net_rpc.c:2556 msgid "*unknown*" msgstr "" -#: ../../utils/net_rpc.c:2630 ../../utils/net_rpc.c:2643 ../../utils/net_rpc.c:2650 +#: ../../utils/net_rpc.c:2630 +#: ../../utils/net_rpc.c:2643 +#: ../../utils/net_rpc.c:2650 #, c-format msgid "Couldn't find group %s\n" msgstr "" @@ -4837,7 +5030,8 @@ msgid "" " List groups" msgstr "" -#: ../../utils/net_rpc.c:2774 ../../utils/net_sam.c:2053 +#: ../../utils/net_rpc.c:2774 +#: ../../utils/net_sam.c:2053 msgid "List group members" msgstr "" @@ -4913,13 +5107,23 @@ msgid "" " Migrate shares to local server\n" msgstr "" -#: ../../utils/net_rpc.c:3210 ../../utils/net_rpc.c:3543 ../../utils/net_rpc.c:3668 ../../utils/net_rpc.c:3701 ../../utils/net_rpc.c:6476 ../../utils/net_rpc.c:6530 ../../utils/net_rpc.c:6560 ../../utils/net_rpc.c:6590 ../../utils/net_rpc.c:6620 +#: ../../utils/net_rpc.c:3210 +#: ../../utils/net_rpc.c:3543 +#: ../../utils/net_rpc.c:3668 +#: ../../utils/net_rpc.c:3701 +#: ../../utils/net_rpc.c:6476 +#: ../../utils/net_rpc.c:6530 +#: ../../utils/net_rpc.c:6560 +#: ../../utils/net_rpc.c:6590 +#: ../../utils/net_rpc.c:6620 #: ../../utils/net_rpc.c:6651 #, c-format msgid "no server to migrate\n" msgstr "" -#: ../../utils/net_rpc.c:3270 ../../utils/net_rpc.c:3382 ../../utils/net_rpc.c:3465 +#: ../../utils/net_rpc.c:3270 +#: ../../utils/net_rpc.c:3382 +#: ../../utils/net_rpc.c:3465 #, c-format msgid "Unsupported mode %d\n" msgstr "" @@ -4969,15 +5173,20 @@ msgstr "" msgid " [%s] files and directories %s ACLs, %s DOS Attributes %s\n" msgstr "" -#: ../../utils/net_rpc.c:3472 ../../utils/net_rpc.c:3473 +#: ../../utils/net_rpc.c:3472 +#: ../../utils/net_rpc.c:3473 msgid "including" msgstr "" -#: ../../utils/net_rpc.c:3472 ../../utils/net_rpc.c:3473 ../../utils/net_rpc_printer.c:371 ../../utils/net_rpc_printer.c:372 +#: ../../utils/net_rpc.c:3472 +#: ../../utils/net_rpc.c:3473 +#: ../../utils/net_rpc_printer.c:371 +#: ../../utils/net_rpc_printer.c:372 msgid "without" msgstr "" -#: ../../utils/net_rpc.c:3474 ../../utils/net_rpc_printer.c:373 +#: ../../utils/net_rpc.c:3474 +#: ../../utils/net_rpc_printer.c:373 msgid "(preserving timestamps)" msgstr "" @@ -5022,7 +5231,8 @@ msgid "" " Migrates shares including all share settings\n" msgstr "" -#: ../../utils/net_rpc.c:3738 ../../utils/net_rpc.c:3762 +#: ../../utils/net_rpc.c:3738 +#: ../../utils/net_rpc.c:3762 msgid "Migrate shares from remote to local server" msgstr "" @@ -5150,7 +5360,8 @@ msgstr "" msgid "usage: %s <share> <path> [comment]\n" msgstr "" -#: ../../utils/net_rpc.c:4686 ../../utils/net_rpc.c:4704 +#: ../../utils/net_rpc.c:4686 +#: ../../utils/net_rpc.c:4704 #, c-format msgid "usage: %s <share>\n" msgstr "" @@ -5237,7 +5448,8 @@ msgid "" " List opened files\n" msgstr "" -#: ../../utils/net_rpc.c:4941 ../../utils/net_rpc.c:4980 +#: ../../utils/net_rpc.c:4941 +#: ../../utils/net_rpc.c:4980 msgid "" "\n" "Shutdown successfully aborted\n" @@ -5250,11 +5462,13 @@ msgid "" " Abort a scheduled shutdown\n" msgstr "" -#: ../../utils/net_rpc.c:5050 ../../utils/net_rpc.c:5103 +#: ../../utils/net_rpc.c:5050 +#: ../../utils/net_rpc.c:5103 msgid "This machine will be shutdown shortly" msgstr "" -#: ../../utils/net_rpc.c:5069 ../../utils/net_rpc.c:5124 +#: ../../utils/net_rpc.c:5069 +#: ../../utils/net_rpc.c:5124 msgid "" "\n" "Shutdown of remote machine succeeded\n" @@ -5357,7 +5571,8 @@ msgstr "" #. * in case of no trusted domains say something rather #. * than just display blank line #. -#: ../../utils/net_rpc.c:5974 ../../utils/net_rpc.c:6121 +#: ../../utils/net_rpc.c:5974 +#: ../../utils/net_rpc.c:6121 msgid "none\n" msgstr "" @@ -5645,7 +5860,8 @@ msgid "" " List published printers via MSRPC\n" msgstr "" -#: ../../utils/net_rpc.c:6900 ../../utils/net_rpc.c:7029 +#: ../../utils/net_rpc.c:6900 +#: ../../utils/net_rpc.c:7029 msgid "Publish printer in AD" msgstr "" @@ -5908,7 +6124,8 @@ msgstr "" msgid "" "net rpc changetrustpw\n" " Change trust account password" -msgstr "net rpc changetrustpw\n" +msgstr "" +"net rpc changetrustpw\n" " trust account Passwort ändern" #: ../../utils/net_rpc.c:7167 @@ -6043,7 +6260,8 @@ msgid "" "\n" msgstr "" -#: ../../utils/net_rpc_audit.c:47 ../../utils/net_util.c:611 +#: ../../utils/net_rpc_audit.c:47 +#: ../../utils/net_util.c:611 msgid "Unknown" msgstr "" @@ -6056,11 +6274,13 @@ msgstr "" msgid "\t%s%s%s\n" msgstr "" -#: ../../utils/net_rpc_audit.c:80 ../../utils/net_rpc_audit.c:147 +#: ../../utils/net_rpc_audit.c:80 +#: ../../utils/net_rpc_audit.c:147 msgid "insufficient arguments\n" msgstr "" -#: ../../utils/net_rpc_audit.c:86 ../../utils/net_rpc_audit.c:153 +#: ../../utils/net_rpc_audit.c:86 +#: ../../utils/net_rpc_audit.c:153 #, c-format msgid "invalid auditing category: %s\n" msgstr "Ungültige Audit-Kategorie: %s\n" @@ -6221,7 +6441,8 @@ msgstr "" msgid "User specified does not have administrator privileges\n" msgstr "" -#: ../../utils/net_rpc_join.c:403 ../../utils/net_rpc_join.c:431 +#: ../../utils/net_rpc_join.c:403 +#: ../../utils/net_rpc_join.c:431 #, c-format msgid "" "Please make sure that no computer account\n" @@ -6355,7 +6576,8 @@ msgstr "" msgid "copying [\\\\%s\\%s%s] => [\\\\%s\\%s%s] %s ACLs and %s DOS Attributes %s\n" msgstr "" -#: ../../utils/net_rpc_printer.c:371 ../../utils/net_rpc_printer.c:372 +#: ../../utils/net_rpc_printer.c:371 +#: ../../utils/net_rpc_printer.c:372 msgid "with" msgstr "" @@ -6409,7 +6631,8 @@ msgstr "" msgid "cannot get printer-info: %s\n" msgstr "" -#: ../../utils/net_rpc_printer.c:823 ../../utils/net_rpc_printer.c:1318 +#: ../../utils/net_rpc_printer.c:823 +#: ../../utils/net_rpc_printer.c:1318 #, c-format msgid "cannot set printer-info: %s\n" msgstr "" @@ -6535,7 +6758,11 @@ msgstr "" msgid "unkown state: %d\n" msgstr "" -#: ../../utils/net_rpc_printer.c:1520 ../../utils/net_rpc_printer.c:1667 ../../utils/net_rpc_printer.c:1850 ../../utils/net_rpc_printer.c:2039 ../../utils/net_rpc_printer.c:2206 +#: ../../utils/net_rpc_printer.c:1520 +#: ../../utils/net_rpc_printer.c:1667 +#: ../../utils/net_rpc_printer.c:1850 +#: ../../utils/net_rpc_printer.c:2039 +#: ../../utils/net_rpc_printer.c:2206 #, c-format msgid "no printers found on server.\n" msgstr "" @@ -6607,7 +6834,12 @@ msgstr "" msgid "got no key-data\n" msgstr "" -#: ../../utils/net_rpc_registry.c:389 ../../utils/net_rpc_registry.c:461 ../../utils/net_rpc_registry.c:522 ../../utils/net_rpc_registry.c:791 ../../utils/net_rpc_registry.c:862 ../../utils/net_rpc_registry.c:1171 +#: ../../utils/net_rpc_registry.c:389 +#: ../../utils/net_rpc_registry.c:461 +#: ../../utils/net_rpc_registry.c:522 +#: ../../utils/net_rpc_registry.c:791 +#: ../../utils/net_rpc_registry.c:862 +#: ../../utils/net_rpc_registry.c:1171 #, c-format msgid "registry_openkey failed: %s\n" msgstr "" @@ -6622,7 +6854,8 @@ msgstr "" msgid "registry_deletevalue failed: %s\n" msgstr "" -#: ../../utils/net_rpc_registry.c:543 ../../utils/net_rpc_registry.c:560 +#: ../../utils/net_rpc_registry.c:543 +#: ../../utils/net_rpc_registry.c:560 #, c-format msgid "registry_queryvalue failed: %s\n" msgstr "" @@ -6680,17 +6913,21 @@ msgstr "" msgid "Usage: net rpc registry dump <file> \n" msgstr "" -#: ../../utils/net_rpc_registry.c:1048 ../../utils/net_rpc_registry.c:1093 ../../utils/net_rpc_registry.c:1100 +#: ../../utils/net_rpc_registry.c:1048 +#: ../../utils/net_rpc_registry.c:1093 +#: ../../utils/net_rpc_registry.c:1100 #, c-format msgid "Opening %s...." msgstr "" -#: ../../utils/net_rpc_registry.c:1050 ../../utils/net_rpc_registry.c:1095 +#: ../../utils/net_rpc_registry.c:1050 +#: ../../utils/net_rpc_registry.c:1095 #, c-format msgid "Failed to open %s for reading\n" msgstr "" -#: ../../utils/net_rpc_registry.c:1058 ../../utils/net_rpc_registry.c:1110 +#: ../../utils/net_rpc_registry.c:1058 +#: ../../utils/net_rpc_registry.c:1110 msgid "Could not get rootkey\n" msgstr "" @@ -6712,7 +6949,8 @@ msgstr "" msgid "RootKey: [%s]\n" msgstr "" -#: ../../utils/net_rpc_registry.c:1121 ../../utils/net_rpc_registry.c:1127 +#: ../../utils/net_rpc_registry.c:1121 +#: ../../utils/net_rpc_registry.c:1127 #, c-format msgid "Closing %s..." msgstr "" @@ -6902,7 +7140,8 @@ msgid "" " View available/assigned privileges" msgstr "" -#: ../../utils/net_rpc_rights.c:650 ../../utils/net_rpc_rights.c:709 +#: ../../utils/net_rpc_rights.c:650 +#: ../../utils/net_rpc_rights.c:709 msgid "Assign privilege[s]" msgstr "" @@ -6912,7 +7151,8 @@ msgid "" " Assign privilege[s]" msgstr "" -#: ../../utils/net_rpc_rights.c:658 ../../utils/net_rpc_rights.c:712 +#: ../../utils/net_rpc_rights.c:658 +#: ../../utils/net_rpc_rights.c:712 msgid "Revoke privilege[s]" msgstr "" @@ -7014,7 +7254,11 @@ msgstr "" msgid "Unknown State [%d]" msgstr "" -#: ../../utils/net_rpc_service.c:82 ../../utils/net_rpc_service.c:162 ../../utils/net_rpc_service.c:355 ../../utils/net_rpc_service.c:625 ../../utils/net_rpc_service.c:705 +#: ../../utils/net_rpc_service.c:82 +#: ../../utils/net_rpc_service.c:162 +#: ../../utils/net_rpc_service.c:355 +#: ../../utils/net_rpc_service.c:625 +#: ../../utils/net_rpc_service.c:705 #, c-format msgid "Failed to open service. [%s]\n" msgstr "" @@ -7024,7 +7268,8 @@ msgstr "" msgid "Control service request failed. [%s]\n" msgstr "" -#: ../../utils/net_rpc_service.c:185 ../../utils/net_rpc_service.c:373 +#: ../../utils/net_rpc_service.c:185 +#: ../../utils/net_rpc_service.c:373 #, c-format msgid "%s service is %s.\n" msgstr "" @@ -7033,7 +7278,8 @@ msgstr "" msgid "Usage: net rpc service list\n" msgstr "" -#: ../../utils/net_rpc_service.c:230 ../../utils/net_rpc_service.c:340 +#: ../../utils/net_rpc_service.c:230 +#: ../../utils/net_rpc_service.c:340 #, c-format msgid "Failed to open Service Control Manager. [%s]\n" msgstr "" @@ -7047,11 +7293,16 @@ msgstr "" msgid "No services returned\n" msgstr "" -#: ../../utils/net_rpc_service.c:327 ../../utils/net_rpc_service.c:459 ../../utils/net_rpc_service.c:505 ../../utils/net_rpc_service.c:551 ../../utils/net_rpc_service.c:597 +#: ../../utils/net_rpc_service.c:327 +#: ../../utils/net_rpc_service.c:459 +#: ../../utils/net_rpc_service.c:505 +#: ../../utils/net_rpc_service.c:551 +#: ../../utils/net_rpc_service.c:597 msgid "Usage: net rpc service status <service>\n" msgstr "" -#: ../../utils/net_rpc_service.c:368 ../../utils/net_rpc_service.c:639 +#: ../../utils/net_rpc_service.c:368 +#: ../../utils/net_rpc_service.c:639 #, c-format msgid "Query status request failed. [%s]\n" msgstr "" @@ -7116,7 +7367,12 @@ msgstr "" msgid "\tDisplay Name = %s\n" msgstr "" -#: ../../utils/net_rpc_service.c:474 ../../utils/net_rpc_service.c:520 ../../utils/net_rpc_service.c:566 ../../utils/net_rpc_service.c:610 ../../utils/net_rpc_service.c:690 ../../utils/net_rpc_service.c:769 +#: ../../utils/net_rpc_service.c:474 +#: ../../utils/net_rpc_service.c:520 +#: ../../utils/net_rpc_service.c:566 +#: ../../utils/net_rpc_service.c:610 +#: ../../utils/net_rpc_service.c:690 +#: ../../utils/net_rpc_service.c:769 #, c-format msgid "Failed to open Service Control Manager. [%s]\n" msgstr "" @@ -7334,12 +7590,18 @@ msgstr "" msgid "Minimum password age: " msgstr "" -#: ../../utils/net_rpc_sh_acct.c:168 ../../utils/net_rpc_sh_acct.c:176 ../../utils/net_rpc_sh_acct.c:188 ../../utils/net_rpc_sh_acct.c:196 +#: ../../utils/net_rpc_sh_acct.c:168 +#: ../../utils/net_rpc_sh_acct.c:176 +#: ../../utils/net_rpc_sh_acct.c:188 +#: ../../utils/net_rpc_sh_acct.c:196 #, c-format msgid "%d seconds\n" msgstr "" -#: ../../utils/net_rpc_sh_acct.c:170 ../../utils/net_rpc_sh_acct.c:178 ../../utils/net_rpc_sh_acct.c:190 ../../utils/net_rpc_sh_acct.c:198 +#: ../../utils/net_rpc_sh_acct.c:170 +#: ../../utils/net_rpc_sh_acct.c:178 +#: ../../utils/net_rpc_sh_acct.c:190 +#: ../../utils/net_rpc_sh_acct.c:198 msgid "not set\n" msgstr "" @@ -7370,7 +7632,13 @@ msgstr "" msgid "User must logon to change password: %s\n" msgstr "Benutzer muss sich anmelden um Passwort zu ändern: %s\n" -#: ../../utils/net_rpc_sh_acct.c:228 ../../utils/net_rpc_sh_acct.c:258 ../../utils/net_rpc_sh_acct.c:288 ../../utils/net_rpc_sh_acct.c:318 ../../utils/net_rpc_sh_acct.c:348 ../../utils/net_rpc_sh_acct.c:378 ../../utils/net_rpc_sh_acct.c:408 +#: ../../utils/net_rpc_sh_acct.c:228 +#: ../../utils/net_rpc_sh_acct.c:258 +#: ../../utils/net_rpc_sh_acct.c:288 +#: ../../utils/net_rpc_sh_acct.c:318 +#: ../../utils/net_rpc_sh_acct.c:348 +#: ../../utils/net_rpc_sh_acct.c:378 +#: ../../utils/net_rpc_sh_acct.c:408 #, c-format msgid "usage: %s <count>\n" msgstr "" @@ -7459,7 +7727,10 @@ msgstr "" msgid "%s: unknown cmd\n" msgstr "" -#: ../../utils/net_rpc_shell.c:150 ../../utils/net_rpc_shell.c:231 ../../utils/net_sam.c:1573 ../../utils/net_sam.c:1835 +#: ../../utils/net_rpc_shell.c:150 +#: ../../utils/net_rpc_shell.c:231 +#: ../../utils/net_sam.c:1573 +#: ../../utils/net_sam.c:1835 msgid "talloc failed\n" msgstr "" @@ -7514,21 +7785,34 @@ msgstr "Kommandozeile ungültig: %s\n" msgid "usage: net sam set %s <user> <value>\n" msgstr "" -#: ../../utils/net_sam.c:47 ../../utils/net_sam.c:152 ../../utils/net_sam.c:244 ../../utils/net_sam.c:307 ../../utils/net_sam.c:697 ../../utils/net_sam.c:735 ../../utils/net_sam.c:1527 +#: ../../utils/net_sam.c:47 +#: ../../utils/net_sam.c:152 +#: ../../utils/net_sam.c:244 +#: ../../utils/net_sam.c:307 +#: ../../utils/net_sam.c:697 +#: ../../utils/net_sam.c:735 +#: ../../utils/net_sam.c:1527 #, c-format msgid "Could not find name %s\n" msgstr "" -#: ../../utils/net_sam.c:58 ../../utils/net_sam.c:68 ../../utils/net_sam.c:163 ../../utils/net_sam.c:255 +#: ../../utils/net_sam.c:58 +#: ../../utils/net_sam.c:68 +#: ../../utils/net_sam.c:163 +#: ../../utils/net_sam.c:255 msgid "Internal error\n" msgstr "" -#: ../../utils/net_sam.c:63 ../../utils/net_sam.c:168 ../../utils/net_sam.c:260 +#: ../../utils/net_sam.c:63 +#: ../../utils/net_sam.c:168 +#: ../../utils/net_sam.c:260 #, c-format msgid "Loading user %s failed\n" msgstr "" -#: ../../utils/net_sam.c:74 ../../utils/net_sam.c:184 ../../utils/net_sam.c:272 +#: ../../utils/net_sam.c:74 +#: ../../utils/net_sam.c:184 +#: ../../utils/net_sam.c:272 #, c-format msgid "Updating sam account %s failed with %s\n" msgstr "" @@ -7712,11 +7996,14 @@ msgid "" "\n" msgstr "" -#: ../../utils/net_sam.c:493 ../../utils/net_sam.c:545 ../../utils/net_sam.c:583 +#: ../../utils/net_sam.c:493 +#: ../../utils/net_sam.c:545 +#: ../../utils/net_sam.c:583 msgid "Valid account policies are:\n" msgstr "" -#: ../../utils/net_sam.c:504 ../../utils/net_sam.c:556 +#: ../../utils/net_sam.c:504 +#: ../../utils/net_sam.c:556 #, c-format msgid "Valid account policy, but unable to fetch value!\n" msgstr "" @@ -7803,7 +8090,8 @@ msgstr "" msgid "usage: net sam rights grant <name> <rights> ...\n" msgstr "" -#: ../../utils/net_sam.c:703 ../../utils/net_sam.c:742 +#: ../../utils/net_sam.c:703 +#: ../../utils/net_sam.c:742 #, c-format msgid "%s unknown\n" msgstr "" @@ -7864,7 +8152,10 @@ msgstr "" msgid "usage: net sam mapunixgroup <name>\n" msgstr "" -#: ../../utils/net_sam.c:861 ../../utils/net_sam.c:1161 ../../utils/net_sam.c:1248 ../../utils/net_sam.c:1320 +#: ../../utils/net_sam.c:861 +#: ../../utils/net_sam.c:1161 +#: ../../utils/net_sam.c:1248 +#: ../../utils/net_sam.c:1320 #, c-format msgid "Could not find group %s\n" msgstr "" @@ -7902,7 +8193,9 @@ msgstr "" msgid "usage: net sam createdomaingroup <name>\n" msgstr "" -#: ../../utils/net_sam.c:960 ../../utils/net_sam.c:1038 ../../utils/net_sam.c:1133 +#: ../../utils/net_sam.c:960 +#: ../../utils/net_sam.c:1038 +#: ../../utils/net_sam.c:1133 #, c-format msgid "Creating %s failed with %s\n" msgstr "" @@ -7912,11 +8205,13 @@ msgstr "" msgid "Created domain group %s with RID %d\n" msgstr "" -#: ../../utils/net_sam.c:984 ../../utils/net_sam.c:1060 +#: ../../utils/net_sam.c:984 +#: ../../utils/net_sam.c:1060 msgid "usage: net sam deletelocalgroup <name>\n" msgstr "" -#: ../../utils/net_sam.c:990 ../../utils/net_sam.c:1066 +#: ../../utils/net_sam.c:990 +#: ../../utils/net_sam.c:1066 #, c-format msgid "Could not find %s.\n" msgstr "" @@ -7991,7 +8286,8 @@ msgstr "" msgid "usage: net sam addmem <group> <member>\n" msgstr "" -#: ../../utils/net_sam.c:1173 ../../utils/net_sam.c:1255 +#: ../../utils/net_sam.c:1173 +#: ../../utils/net_sam.c:1255 #, c-format msgid "Could not find member %s\n" msgstr "" @@ -8061,7 +8357,8 @@ msgstr "" msgid "usage: net sam listmem <group>\n" msgstr "" -#: ../../utils/net_sam.c:1329 ../../utils/net_sam.c:1339 +#: ../../utils/net_sam.c:1329 +#: ../../utils/net_sam.c:1339 #, c-format msgid "Listing group members failed with %s\n" msgstr "" @@ -8153,7 +8450,14 @@ msgid "" " Init an LDAP tree with default users/groups\n" msgstr "" -#: ../../utils/net_sam.c:1568 ../../utils/net_sam.c:1697 ../../utils/net_sam.c:1729 ../../utils/net_sam.c:1773 ../../utils/net_sam.c:1811 ../../utils/net_sam.c:1849 ../../utils/net_sam.c:1860 ../../utils/net_sam.c:1929 +#: ../../utils/net_sam.c:1568 +#: ../../utils/net_sam.c:1697 +#: ../../utils/net_sam.c:1729 +#: ../../utils/net_sam.c:1773 +#: ../../utils/net_sam.c:1811 +#: ../../utils/net_sam.c:1849 +#: ../../utils/net_sam.c:1860 +#: ../../utils/net_sam.c:1929 msgid "Out of Memory!\n" msgstr "" @@ -8189,9 +8493,14 @@ msgstr "" msgid "Failed to add Domain Users group to ldap directory\n" msgstr "" -#: ../../utils/net_sam.c:1663 ../../utils/net_sam.c:1720 ../../utils/net_sam.c:1804 ../../utils/net_sam.c:1893 ../../utils/net_sam.c:1907 ../../utils/net_sam.c:1954 +#: ../../utils/net_sam.c:1663 +#: ../../utils/net_sam.c:1720 +#: ../../utils/net_sam.c:1804 +#: ../../utils/net_sam.c:1893 +#: ../../utils/net_sam.c:1907 +#: ../../utils/net_sam.c:1954 msgid "found!\n" -msgstr "" +msgstr "gefunden!\n" #: ../../utils/net_sam.c:1668 msgid "Checking for Domain Admins group.\n" @@ -8493,7 +8802,8 @@ msgid "" "-------------------------------------------------------------------\n" msgstr "" -#: ../../utils/net_status.c:92 ../../utils/net_status.c:198 +#: ../../utils/net_status.c:92 +#: ../../utils/net_status.c:198 #, c-format msgid "%s not initialised\n" msgstr "" @@ -8564,6 +8874,18 @@ msgid "" "\n" "\n" msgstr "" +"net time\n" +"\tZeigt die Zeit eines Servers an\n" +"\n" +"net time system\n" +"\tZeigt die Zeit eines Servers im /bin/date Format an\n" +"\n" +"net time set\n" +"\tFührt /bin/date mit der Serverzeit aus\n" +"\n" +"net time zone\n" +"\tZeigt die Zeitzone in Stunden zur GMT auf dem entfernten Computer\n" +"\n" #: ../../utils/net_time.c:123 #, c-format @@ -8703,7 +9025,7 @@ msgstr "" #: ../../utils/net_usershare.c:39 msgid "System error" -msgstr "" +msgstr "System Fehler" #: ../../utils/net_usershare.c:55 #, c-format @@ -9011,7 +9333,7 @@ msgstr "" #: ../../utils/net_util.c:124 msgid "The username or password was not correct.\n" -msgstr "" +msgstr "Benutzername oder Passwort nicht korrekt.\n" #: ../../utils/net_util.c:129 msgid "The account was locked out.\n" @@ -9039,7 +9361,8 @@ msgstr "" msgid "Encryption required and setup failed with error %s.\n" msgstr "" -#: ../../utils/net_util.c:343 ../../utils/net_util.c:365 +#: ../../utils/net_util.c:343 +#: ../../utils/net_util.c:365 msgid "ERROR: Unable to open secrets database\n" msgstr "" @@ -9051,7 +9374,7 @@ msgstr "" #: ../../utils/net_util.c:524 #, c-format msgid "Connection failed: %s\n" -msgstr "" +msgstr "Verbindung fehlgeschlagen: %s\n" #: ../../utils/net_util.c:558 #, c-format @@ -9069,7 +9392,7 @@ msgstr "" #: ../../utils/net_util.c:608 msgid "Print" -msgstr "" +msgstr "Drucken" #: ../../utils/net_util.c:609 msgid "Dev" @@ -9078,3 +9401,4 @@ msgstr "" #: ../../utils/net_util.c:610 msgid "IPC" msgstr "" + diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c index 06bcfb856b..1eec448083 100644 --- a/source3/modules/vfs_acl_common.c +++ b/source3/modules/vfs_acl_common.c @@ -157,6 +157,85 @@ static NTSTATUS create_acl_blob(const struct security_descriptor *psd, } /******************************************************************* + Add in 3 inheritable components for a non-inheritable directory ACL. + CREATOR_OWNER/CREATOR_GROUP/WORLD. +*******************************************************************/ + +static void add_directory_inheritable_components(vfs_handle_struct *handle, + const char *name, + SMB_STRUCT_STAT *psbuf, + struct security_descriptor *psd) +{ + struct connection_struct *conn = handle->conn; + int num_aces = (psd->dacl ? psd->dacl->num_aces : 0); + struct smb_filename smb_fname; + enum security_ace_type acl_type; + uint32_t access_mask; + mode_t dir_mode; + mode_t file_mode; + mode_t mode; + struct security_ace *new_ace_list = TALLOC_ZERO_ARRAY(talloc_tos(), + struct security_ace, + num_aces + 3); + + if (new_ace_list == NULL) { + return; + } + + /* Fake a quick smb_filename. */ + ZERO_STRUCT(smb_fname); + smb_fname.st = *psbuf; + smb_fname.base_name = CONST_DISCARD(char *, name); + + dir_mode = unix_mode(conn, + FILE_ATTRIBUTE_DIRECTORY, &smb_fname, NULL); + file_mode = unix_mode(conn, + FILE_ATTRIBUTE_ARCHIVE, &smb_fname, NULL); + + mode = dir_mode | file_mode; + + DEBUG(10, ("add_directory_inheritable_components: directory %s, " + "mode = 0%o\n", + name, + (unsigned int)mode )); + + if (num_aces) { + memcpy(new_ace_list, psd->dacl->aces, + num_aces * sizeof(struct security_ace)); + } + access_mask = map_canon_ace_perms(SNUM(conn), &acl_type, + mode & 0700, false); + + init_sec_ace(&new_ace_list[num_aces], + &global_sid_Creator_Owner, + acl_type, + access_mask, + SEC_ACE_FLAG_CONTAINER_INHERIT| + SEC_ACE_FLAG_OBJECT_INHERIT| + SEC_ACE_FLAG_INHERIT_ONLY); + access_mask = map_canon_ace_perms(SNUM(conn), &acl_type, + (mode << 3) & 0700, false); + init_sec_ace(&new_ace_list[num_aces+1], + &global_sid_Creator_Group, + acl_type, + access_mask, + SEC_ACE_FLAG_CONTAINER_INHERIT| + SEC_ACE_FLAG_OBJECT_INHERIT| + SEC_ACE_FLAG_INHERIT_ONLY); + access_mask = map_canon_ace_perms(SNUM(conn), &acl_type, + (mode << 6) & 0700, false); + init_sec_ace(&new_ace_list[num_aces+2], + &global_sid_World, + acl_type, + access_mask, + SEC_ACE_FLAG_CONTAINER_INHERIT| + SEC_ACE_FLAG_OBJECT_INHERIT| + SEC_ACE_FLAG_INHERIT_ONLY); + psd->dacl->aces = new_ace_list; + psd->dacl->num_aces += 3; +} + +/******************************************************************* Pull a DATA_BLOB from an xattr given a pathname. If the hash doesn't match, or doesn't exist - return the underlying filesystem sd. @@ -261,6 +340,33 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, /* We're returning the blob, throw * away the filesystem SD. */ TALLOC_FREE(pdesc_next); + } else { + SMB_STRUCT_STAT sbuf; + SMB_STRUCT_STAT *psbuf = &sbuf; + bool is_directory = false; + /* + * We're returning the underlying ACL from the + * filesystem. If it's a directory, and has no + * inheritable ACE entries we have to fake them. + */ + if (fsp) { + is_directory = fsp->is_directory; + psbuf = &fsp->fsp_name->st; + } else { + if (vfs_stat_smb_fname(handle->conn, + name, + &sbuf) == 0) { + is_directory = S_ISDIR(sbuf.st_ex_mode); + } + } + if (is_directory && + !sd_has_inheritable_components(psd, + true)) { + add_directory_inheritable_components(handle, + name, + psbuf, + psd); + } } if (!(security_info & OWNER_SECURITY_INFORMATION)) { diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 23f002ceeb..96531666d5 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -23,6 +23,7 @@ #include "../libcli/auth/schannel.h" #include "../libcli/auth/spnego.h" #include "smb_krb5.h" +#include "ntlmssp.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_CLI @@ -631,7 +632,7 @@ static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *pr RPC_HDR_AUTH auth_info; uint32 save_offset = prs_offset(current_pdu); uint32 auth_len = prhdr->auth_len; - NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state; + struct ntlmssp_state *ntlmssp_state = cli->auth->a_u.ntlmssp_state; unsigned char *data = NULL; size_t data_len; unsigned char *full_packet_data = NULL; diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 46f67f499b..f92a100d0a 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -31,6 +31,7 @@ #include "../librpc/gen_ndr/ndr_schannel.h" #include "../libcli/auth/schannel.h" #include "../libcli/auth/spnego.h" +#include "ntlmssp.h" extern struct current_user current_user; diff --git a/source3/smbd/error.c b/source3/smbd/error.c index 279b7baff0..252eb77416 100644 --- a/source3/smbd/error.c +++ b/source3/smbd/error.c @@ -30,9 +30,29 @@ bool use_nt_status(void) /**************************************************************************** Create an error packet. Normally called using the ERROR() macro. - Setting eclass and ecode only and status to NT_STATUS_OK forces DOS errors. - Setting status only and eclass and ecode to zero forces NT errors. - If the override errors are set they take precedence over any passed in values. + + Setting eclass and ecode to zero and status to a valid NT error will + reply with an NT error if the client supports CAP_STATUS32, otherwise + it maps to and returns a DOS error if the client doesn't support CAP_STATUS32. + This is the normal mode of calling this function via reply_nterror(req, status). + + Setting eclass and ecode to non-zero and status to NT_STATUS_OK (0) will map + from a DOS error to an NT error and reply with an NT error if the client + supports CAP_STATUS32, otherwise it replies with the given DOS error. + This mode is currently not used in the server. + + Setting both eclass, ecode and status to non-zero values allows a non-default + mapping from NT error codes to DOS error codes, and will return one or the + other depending on the client supporting CAP_STATUS32 or not. This is the + path taken by calling reply_botherror(req, eclass, ecode, status); + + Setting status to NT_STATUS_DOS(eclass, ecode) forces DOS errors even if the + client supports CAP_STATUS32. This is the path taken to force a DOS error + reply by calling reply_force_doserror(req, eclass, ecode). + + Setting status only and eclass to -1 forces NT errors even if the client + doesn't support CAP_STATUS32. This mode is currently never used in the + server. ****************************************************************************/ void error_packet_set(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file) @@ -95,21 +115,20 @@ void reply_nt_error(struct smb_request *req, NTSTATUS ntstatus, error_packet_set((char *)req->outbuf, 0, 0, ntstatus, line, file); } -void reply_force_nt_error(struct smb_request *req, NTSTATUS ntstatus, - int line, const char *file) -{ - TALLOC_FREE(req->outbuf); - reply_outbuf(req, 0, 0); - error_packet_set((char *)req->outbuf, -1, -1, ntstatus, line, file); -} +/**************************************************************************** + Forces a DOS error on the wire. +****************************************************************************/ -void reply_dos_error(struct smb_request *req, uint8 eclass, uint32 ecode, +void reply_force_dos_error(struct smb_request *req, uint8 eclass, uint32 ecode, int line, const char *file) { TALLOC_FREE(req->outbuf); reply_outbuf(req, 0, 0); - error_packet_set((char *)req->outbuf, eclass, ecode, NT_STATUS_OK, line, - file); + error_packet_set((char *)req->outbuf, + eclass, ecode, + NT_STATUS_DOS(eclass, ecode), + line, + file); } void reply_both_error(struct smb_request *req, uint8 eclass, uint32 ecode, @@ -134,8 +153,9 @@ void reply_openerror(struct smb_request *req, NTSTATUS status) ERRDOS, ERRfilexists); } else if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) { /* EMFILE always seems to be returned as a DOS error. - * See bug 6837. */ - reply_doserror(req, ERRDOS, ERRnofids); + * See bug 6837. NOTE this forces a DOS error on the wire + * even though it's calling reply_nterror(). */ + reply_force_doserror(req, ERRDOS, ERRnofids); } else { reply_nterror(req, status); } diff --git a/source3/smbd/mangle_hash.c b/source3/smbd/mangle_hash.c index c08bc4019a..8369af418a 100644 --- a/source3/smbd/mangle_hash.c +++ b/source3/smbd/mangle_hash.c @@ -429,6 +429,13 @@ static void cache_mangled_name( const char mangled_name[13], if( !s1[i] && !s2[i] ) { /* Truncate at the '.' */ *s1 = '\0'; + /* + * DANGER WILL ROBINSON - this + * is changing a const string via + * an aliased pointer ! Remember to + * put it back once we've used it. + * JRA + */ *s2 = '\0'; } } @@ -440,6 +447,8 @@ static void cache_mangled_name( const char mangled_name[13], } else { DEBUG(5,("cache_mangled_name: Stored entry %s -> %s\n", mangled_name_key, raw_name)); } + /* Restore the change we made to the const string. */ + *s2 = '.'; } /* ************************************************************************** ** diff --git a/source3/smbd/message.c b/source3/smbd/message.c index e6d5f451cd..82b3dc30a2 100644 --- a/source3/smbd/message.c +++ b/source3/smbd/message.c @@ -145,7 +145,7 @@ void reply_sends(struct smb_request *req) START_PROFILE(SMBsends); if (!(*lp_msg_command())) { - reply_doserror(req, ERRSRV, ERRmsgoff); + reply_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED); END_PROFILE(SMBsends); return; } @@ -193,7 +193,7 @@ void reply_sendstrt(struct smb_request *req) START_PROFILE(SMBsendstrt); if (!(*lp_msg_command())) { - reply_doserror(req, ERRSRV, ERRmsgoff); + reply_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED); END_PROFILE(SMBsendstrt); return; } @@ -240,7 +240,7 @@ void reply_sendtxt(struct smb_request *req) START_PROFILE(SMBsendtxt); if (! (*lp_msg_command())) { - reply_doserror(req, ERRSRV, ERRmsgoff); + reply_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED); END_PROFILE(SMBsendtxt); return; } @@ -288,7 +288,7 @@ void reply_sendend(struct smb_request *req) START_PROFILE(SMBsendend); if (! (*lp_msg_command())) { - reply_doserror(req, ERRSRV, ERRmsgoff); + reply_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED); END_PROFILE(SMBsendend); return; } diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index be50090192..656375499f 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -512,7 +512,7 @@ void reply_ntcreate_and_X(struct smb_request *req) do_ntcreate_pipe_open(conn, req); goto out; } - reply_doserror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); goto out; } @@ -752,7 +752,7 @@ static void do_nt_transact_create_pipe(connection_struct *conn, if(parameter_count < 54) { DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count)); - reply_doserror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } @@ -782,7 +782,7 @@ static void do_nt_transact_create_pipe(connection_struct *conn, } params = nttrans_realloc(ppparams, param_len); if(params == NULL) { - reply_doserror(req, ERRDOS, ERRnomem); + reply_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -957,7 +957,7 @@ static void call_nt_transact_create(connection_struct *conn, ppdata, data_count); goto out; } - reply_doserror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); goto out; } @@ -1159,7 +1159,7 @@ static void call_nt_transact_create(connection_struct *conn, } params = nttrans_realloc(ppparams, param_len); if(params == NULL) { - reply_doserror(req, ERRDOS, ERRnomem); + reply_nterror(req, NT_STATUS_NO_MEMORY); goto out; } @@ -1595,7 +1595,7 @@ static void call_nt_transact_notify_change(connection_struct *conn, bool recursive; if(setup_count < 6) { - reply_doserror(req, ERRDOS, ERRbadfunc); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } @@ -1606,7 +1606,7 @@ static void call_nt_transact_notify_change(connection_struct *conn, DEBUG(3,("call_nt_transact_notify_change\n")); if(!fsp) { - reply_doserror(req, ERRDOS, ERRbadfid); + reply_nterror(req, NT_STATUS_INVALID_HANDLE); return; } @@ -1700,7 +1700,7 @@ static void call_nt_transact_rename(connection_struct *conn, TALLOC_CTX *ctx = talloc_tos(); if(parameter_count < 5) { - reply_doserror(req, ERRDOS, ERRbadfunc); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } @@ -1769,13 +1769,13 @@ static void call_nt_transact_query_security_desc(connection_struct *conn, DATA_BLOB blob; if(parameter_count < 8) { - reply_doserror(req, ERRDOS, ERRbadfunc); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } fsp = file_fsp(req, SVAL(params,0)); if(!fsp) { - reply_doserror(req, ERRDOS, ERRbadfid); + reply_nterror(req, NT_STATUS_INVALID_HANDLE); return; } @@ -1787,7 +1787,7 @@ static void call_nt_transact_query_security_desc(connection_struct *conn, params = nttrans_realloc(ppparams, 4); if(params == NULL) { - reply_doserror(req, ERRDOS, ERRnomem); + reply_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -1839,7 +1839,7 @@ static void call_nt_transact_query_security_desc(connection_struct *conn, data = nttrans_realloc(ppdata, sd_size); if(data == NULL) { - reply_doserror(req, ERRDOS, ERRnomem); + reply_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -1880,12 +1880,12 @@ static void call_nt_transact_set_security_desc(connection_struct *conn, NTSTATUS status; if(parameter_count < 8) { - reply_doserror(req, ERRDOS, ERRbadfunc); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } if((fsp = file_fsp(req, SVAL(params,0))) == NULL) { - reply_doserror(req, ERRDOS, ERRbadfid); + reply_nterror(req, NT_STATUS_INVALID_HANDLE); return; } @@ -1899,7 +1899,7 @@ static void call_nt_transact_set_security_desc(connection_struct *conn, fsp_str_dbg(fsp), (unsigned int)security_info_sent)); if (data_count == 0) { - reply_doserror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } @@ -2243,7 +2243,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, DEBUG(1,("get_user_quota: access_denied service [%s] user " "[%s]\n", lp_servicename(SNUM(conn)), conn->server_info->unix_name)); - reply_doserror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); return; } @@ -2253,7 +2253,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, if (parameter_count < 4) { DEBUG(0,("TRANSACT_GET_USER_QUOTA: requires %d >= 4 bytes parameters\n",parameter_count)); - reply_doserror(req, ERRDOS, ERRinvalidparam); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } @@ -2288,7 +2288,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, param_len = 4; params = nttrans_realloc(ppparams, param_len); if(params == NULL) { - reply_doserror(req, ERRDOS, ERRnomem); + reply_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -2308,7 +2308,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, } if (start_enum && vfs_get_user_ntquota_list(fsp,&(qt_handle->quota_list))!=0) { - reply_doserror(req, ERRSRV, ERRerror); + reply_nterror(req, NT_STATUS_INTERNAL_ERROR); return; } @@ -2316,7 +2316,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, param_len = 4; params = nttrans_realloc(ppparams, param_len); if(params == NULL) { - reply_doserror(req, ERRDOS, ERRnomem); + reply_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -2325,7 +2325,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, pdata = nttrans_realloc(ppdata, max_data_count);/* should be max data count from client*/ if(pdata == NULL) { - reply_doserror(req, ERRDOS, ERRnomem); + reply_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -2388,20 +2388,20 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, if (data_count < 8) { DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8)); - reply_doserror(req, ERRDOS, ERRunknownlevel); + reply_nterror(req, NT_STATUS_INVALID_LEVEL); return; } sid_len = IVAL(pdata,4); /* Ensure this is less than 1mb. */ if (sid_len > (1024*1024)) { - reply_doserror(req, ERRDOS, ERRnomem); + reply_nterror(req, NT_STATUS_NO_MEMORY); return; } if (data_count < 8+sid_len) { DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %lu bytes data\n",data_count,(unsigned long)(8+sid_len))); - reply_doserror(req, ERRDOS, ERRunknownlevel); + reply_nterror(req, NT_STATUS_INVALID_LEVEL); return; } @@ -2432,13 +2432,13 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, param_len = 4; params = nttrans_realloc(ppparams, param_len); if(params == NULL) { - reply_doserror(req, ERRDOS, ERRnomem); + reply_nterror(req, NT_STATUS_NO_MEMORY); return; } pdata = nttrans_realloc(ppdata, data_len); if(pdata == NULL) { - reply_doserror(req, ERRDOS, ERRnomem); + reply_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -2472,7 +2472,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, default: DEBUG(0,("do_nt_transact_get_user_quota: fnum %d unknown level 0x%04hX\n",fsp->fnum,level)); - reply_doserror(req, ERRSRV, ERRerror); + reply_nterror(req, NT_STATUS_INVALID_LEVEL); return; break; } @@ -2510,7 +2510,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn, DEBUG(1,("set_user_quota: access_denied service [%s] user " "[%s]\n", lp_servicename(SNUM(conn)), conn->server_info->unix_name)); - reply_doserror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); return; } @@ -2520,7 +2520,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn, if (parameter_count < 2) { DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count)); - reply_doserror(req, ERRDOS, ERRinvalidparam); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } @@ -2534,7 +2534,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn, if (data_count < 40) { DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %d bytes data\n",data_count,40)); - reply_doserror(req, ERRDOS, ERRunknownlevel); + reply_nterror(req, NT_STATUS_INVALID_LEVEL); return; } @@ -2548,7 +2548,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn, if (data_count < 40+sid_len) { DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %lu bytes data\n",data_count,(unsigned long)40+sid_len)); - reply_doserror(req, ERRDOS, ERRunknownlevel); + reply_nterror(req, NT_STATUS_INVALID_LEVEL); return; } @@ -2565,7 +2565,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn, ((qt.usedspace != 0xFFFFFFFF)|| (IVAL(pdata,20)!=0xFFFFFFFF))) { /* more than 32 bits? */ - reply_doserror(req, ERRDOS, ERRunknownlevel); + reply_nterror(req, NT_STATUS_INVALID_LEVEL); return; } #endif /* LARGE_SMB_OFF_T */ @@ -2579,7 +2579,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn, ((qt.softlim != 0xFFFFFFFF)|| (IVAL(pdata,28)!=0xFFFFFFFF))) { /* more than 32 bits? */ - reply_doserror(req, ERRDOS, ERRunknownlevel); + reply_nterror(req, NT_STATUS_INVALID_LEVEL); return; } #endif /* LARGE_SMB_OFF_T */ @@ -2593,7 +2593,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn, ((qt.hardlim != 0xFFFFFFFF)|| (IVAL(pdata,36)!=0xFFFFFFFF))) { /* more than 32 bits? */ - reply_doserror(req, ERRDOS, ERRunknownlevel); + reply_nterror(req, NT_STATUS_INVALID_LEVEL); return; } #endif /* LARGE_SMB_OFF_T */ @@ -2604,7 +2604,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn, /* 44 unknown bytes left... */ if (vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) { - reply_doserror(req, ERRSRV, ERRerror); + reply_nterror(req, NT_STATUS_INTERNAL_ERROR); return; } @@ -2738,7 +2738,7 @@ static void handle_nttrans(connection_struct *conn, /* Error in request */ DEBUG(0,("handle_nttrans: Unknown request %d in " "nttrans call\n", state->call)); - reply_doserror(req, ERRSRV, ERRerror); + reply_nterror(req, NT_STATUS_INVALID_LEVEL); return; } return; @@ -2774,7 +2774,7 @@ void reply_nttrans(struct smb_request *req) function_code = SVAL(req->vwv+18, 0); if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) { - reply_doserror(req, ERRSRV, ERRaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBnttrans); return; } @@ -2788,7 +2788,7 @@ void reply_nttrans(struct smb_request *req) } if ((state = TALLOC_P(conn, struct trans_state)) == NULL) { - reply_doserror(req, ERRSRV, ERRaccess); + reply_nterror(req, NT_STATUS_NO_MEMORY); END_PROFILE(SMBnttrans); return; } @@ -2834,7 +2834,7 @@ void reply_nttrans(struct smb_request *req) /* Don't allow more than 128mb for each value. */ if ((state->total_data > (1024*1024*128)) || (state->total_param > (1024*1024*128))) { - reply_doserror(req, ERRDOS, ERRnomem); + reply_nterror(req, NT_STATUS_NO_MEMORY); END_PROFILE(SMBnttrans); return; } @@ -2855,7 +2855,7 @@ void reply_nttrans(struct smb_request *req) DEBUG(0,("reply_nttrans: data malloc fail for %u " "bytes !\n", (unsigned int)state->total_data)); TALLOC_FREE(state); - reply_doserror(req, ERRDOS, ERRnomem); + reply_nterror(req, NT_STATUS_NO_MEMORY); END_PROFILE(SMBnttrans); return; } @@ -2877,7 +2877,7 @@ void reply_nttrans(struct smb_request *req) "bytes !\n", (unsigned int)state->total_param)); SAFE_FREE(state->data); TALLOC_FREE(state); - reply_doserror(req, ERRDOS, ERRnomem); + reply_nterror(req, NT_STATUS_NO_MEMORY); END_PROFILE(SMBnttrans); return; } @@ -2910,7 +2910,7 @@ void reply_nttrans(struct smb_request *req) SAFE_FREE(state->data); SAFE_FREE(state->param); TALLOC_FREE(state); - reply_doserror(req, ERRDOS, ERRnomem); + reply_nterror(req, NT_STATUS_NO_MEMORY); END_PROFILE(SMBnttrans); return; } diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 091db09987..bf64c59afd 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -105,7 +105,7 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) /* at a mailslot or something we really, really don't understand, */ /* not just something we really don't understand. */ if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 ) { - reply_doserror(req, ERRSRV, ERRaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); return; } @@ -119,7 +119,7 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) * Hack for NT printers... JRA. */ if(should_fail_next_srvsvc_open(fname)) { - reply_doserror(req, ERRSRV, ERRaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); return; } #endif @@ -171,7 +171,7 @@ void reply_pipe_write(struct smb_request *req) struct tevent_req *subreq; if (!fsp_is_np(fsp)) { - reply_doserror(req, ERRDOS, ERRbadfid); + reply_nterror(req, NT_STATUS_INVALID_HANDLE); return; } @@ -223,7 +223,7 @@ static void pipe_write_done(struct tevent_req *subreq) /* Looks bogus to me now. Needs to be removed ? JRA. */ if ((nwritten == 0 && state->numtowrite != 0)) { - reply_doserror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); goto send; } @@ -266,7 +266,7 @@ void reply_pipe_write_and_X(struct smb_request *req) struct tevent_req *subreq; if (!fsp_is_np(fsp)) { - reply_doserror(req, ERRDOS, ERRbadfid); + reply_nterror(req, NT_STATUS_INVALID_HANDLE); return; } @@ -340,7 +340,7 @@ static void pipe_write_andx_done(struct tevent_req *subreq) /* Looks bogus to me now. Is this error message correct ? JRA. */ if (nwritten != state->numtowrite) { - reply_doserror(req, ERRDOS,ERRnoaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); goto done; } @@ -384,7 +384,7 @@ void reply_pipe_read_and_X(struct smb_request *req) #endif if (!fsp_is_np(fsp)) { - reply_doserror(req, ERRDOS, ERRbadfid); + reply_nterror(req, NT_STATUS_INVALID_HANDLE); return; } diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 65d0929024..828053811b 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -1068,7 +1068,7 @@ bool nt4_compatible_acls(void) not get. Deny entries are implicit on get with ace->perms = 0. ****************************************************************************/ -static uint32_t map_canon_ace_perms(int snum, +uint32_t map_canon_ace_perms(int snum, enum security_ace_type *pacl_type, mode_t perms, bool directory_ace) @@ -1570,7 +1570,7 @@ static bool dup_owning_ace(canon_ace *dir_ace, canon_ace *ace) ****************************************************************************/ static bool create_canon_ace_lists(files_struct *fsp, - SMB_STRUCT_STAT *pst, + const SMB_STRUCT_STAT *pst, DOM_SID *pfile_owner_sid, DOM_SID *pfile_grp_sid, canon_ace **ppfile_ace, @@ -2305,7 +2305,7 @@ static mode_t create_default_mode(files_struct *fsp, bool interitable_mode) ****************************************************************************/ static bool unpack_canon_ace(files_struct *fsp, - SMB_STRUCT_STAT *pst, + const SMB_STRUCT_STAT *pst, DOM_SID *pfile_owner_sid, DOM_SID *pfile_grp_sid, canon_ace **ppfile_ace, @@ -2313,6 +2313,7 @@ static bool unpack_canon_ace(files_struct *fsp, uint32 security_info_sent, const SEC_DESC *psd) { + SMB_STRUCT_STAT st; canon_ace *file_ace = NULL; canon_ace *dir_ace = NULL; @@ -2376,14 +2377,17 @@ static bool unpack_canon_ace(files_struct *fsp, print_canon_ace_list( "file ace - before valid", file_ace); + st = *pst; + /* * A default 3 element mode entry for a file should be r-- --- ---. * A default 3 element mode entry for a directory should be rwx --- ---. */ - pst->st_ex_mode = create_default_mode(fsp, False); + st.st_ex_mode = create_default_mode(fsp, False); - if (!ensure_canon_entry_valid(&file_ace, fsp->conn->params, fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) { + if (!ensure_canon_entry_valid(&file_ace, fsp->conn->params, + fsp->is_directory, pfile_owner_sid, pfile_grp_sid, &st, True)) { free_canon_ace_list(file_ace); free_canon_ace_list(dir_ace); return False; @@ -2397,9 +2401,10 @@ static bool unpack_canon_ace(files_struct *fsp, * it's a directory. */ - pst->st_ex_mode = create_default_mode(fsp, True); + st.st_ex_mode = create_default_mode(fsp, True); - if (dir_ace && !ensure_canon_entry_valid(&dir_ace, fsp->conn->params, fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) { + if (dir_ace && !ensure_canon_entry_valid(&dir_ace, fsp->conn->params, + fsp->is_directory, pfile_owner_sid, pfile_grp_sid, &st, True)) { free_canon_ace_list(file_ace); free_canon_ace_list(dir_ace); return False; @@ -4086,6 +4091,9 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); + /* Ensure the stat struct in the fsp is correct. */ + status = vfs_stat_fsp(fsp); + return NT_STATUS_OK; } diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 15d89a5450..572f37dbbe 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -1335,7 +1335,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in if (type == SMBntcreateX) { reply_nterror(req, NT_STATUS_INVALID_HANDLE); } else { - reply_doserror(req, ERRSRV, ERRinvnid); + reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED); } return NULL; } @@ -1343,7 +1343,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in if (!change_to_user(conn,session_tag)) { DEBUG(0, ("Error: Could not change to user. Removing " "deferred open, mid=%d.\n", req->mid)); - reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid)); + reply_force_doserror(req, ERRSRV, ERRbaduid); return conn; } @@ -1357,7 +1357,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in /* IPC services are limited */ if (IS_IPC(conn) && !(flags & CAN_IPC)) { - reply_doserror(req, ERRSRV,ERRaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); return conn; } } else { @@ -1382,7 +1382,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in if (!set_current_service(conn,SVAL(req->inbuf,smb_flg), (flags & (AS_USER|DO_CHDIR) ?True:False))) { - reply_doserror(req, ERRSRV, ERRaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); return conn; } conn->num_smb_operations++; @@ -1393,7 +1393,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in && (!change_to_guest() || !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1)))) { - reply_doserror(req, ERRSRV, ERRaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); return conn; } @@ -1608,6 +1608,180 @@ static void fixup_chain_error_packet(struct smb_request *req) SCVAL(req->outbuf, smb_vwv0, 0xff); } +/** + * @brief Find the smb_cmd offset of the last command pushed + * @param[in] buf The buffer we're building up + * @retval Where can we put our next andx cmd? + * + * While chaining requests, the "next" request we're looking at needs to put + * its SMB_Command before the data the previous request already built up added + * to the chain. Find the offset to the place where we have to put our cmd. + */ + +static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs) +{ + uint8_t cmd; + size_t ofs; + + cmd = CVAL(buf, smb_com); + + SMB_ASSERT(is_andx_req(cmd)); + + ofs = smb_vwv0; + + while (CVAL(buf, ofs) != 0xff) { + + if (!is_andx_req(CVAL(buf, ofs))) { + return false; + } + + /* + * ofs is from start of smb header, so add the 4 length + * bytes. The next cmd is right after the wct field. + */ + ofs = SVAL(buf, ofs+2) + 4 + 1; + + SMB_ASSERT(ofs+4 < talloc_get_size(buf)); + } + + *pofs = ofs; + return true; +} + +/** + * @brief Do the smb chaining at a buffer level + * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified + * @param[in] smb_command The command that we want to issue + * @param[in] wct How many words? + * @param[in] vwv The words, already in network order + * @param[in] bytes_alignment How shall we align "bytes"? + * @param[in] num_bytes How many bytes? + * @param[in] bytes The data the request ships + * + * smb_splice_chain() adds the vwv and bytes to the request already present in + * *poutbuf. + */ + +static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command, + uint8_t wct, const uint16_t *vwv, + size_t bytes_alignment, + uint32_t num_bytes, const uint8_t *bytes) +{ + uint8_t *outbuf; + size_t old_size, new_size; + size_t ofs; + size_t chain_padding = 0; + size_t bytes_padding = 0; + bool first_request; + + old_size = talloc_get_size(*poutbuf); + + /* + * old_size == smb_wct means we're pushing the first request in for + * libsmb/ + */ + + first_request = (old_size == smb_wct); + + if (!first_request && ((old_size % 4) != 0)) { + /* + * Align the wct field of subsequent requests to a 4-byte + * boundary + */ + chain_padding = 4 - (old_size % 4); + } + + /* + * After the old request comes the new wct field (1 byte), the vwv's + * and the num_bytes field. After at we might need to align the bytes + * given to us to "bytes_alignment", increasing the num_bytes value. + */ + + new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2; + + if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) { + bytes_padding = bytes_alignment - (new_size % bytes_alignment); + } + + new_size += bytes_padding + num_bytes; + + if ((smb_command != SMBwriteX) && (new_size > 0xffff)) { + DEBUG(1, ("splice_chain: %u bytes won't fit\n", + (unsigned)new_size)); + return false; + } + + outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size); + if (outbuf == NULL) { + DEBUG(0, ("talloc failed\n")); + return false; + } + *poutbuf = outbuf; + + if (first_request) { + SCVAL(outbuf, smb_com, smb_command); + } else { + size_t andx_cmd_ofs; + + if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) { + DEBUG(1, ("invalid command chain\n")); + *poutbuf = TALLOC_REALLOC_ARRAY( + NULL, *poutbuf, uint8_t, old_size); + return false; + } + + if (chain_padding != 0) { + memset(outbuf + old_size, 0, chain_padding); + old_size += chain_padding; + } + + SCVAL(outbuf, andx_cmd_ofs, smb_command); + SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4); + } + + ofs = old_size; + + /* + * Push the chained request: + * + * wct field + */ + + SCVAL(outbuf, ofs, wct); + ofs += 1; + + /* + * vwv array + */ + + memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct); + ofs += sizeof(uint16_t) * wct; + + /* + * bcc (byte count) + */ + + SSVAL(outbuf, ofs, num_bytes + bytes_padding); + ofs += sizeof(uint16_t); + + /* + * padding + */ + + if (bytes_padding != 0) { + memset(outbuf + ofs, 0, bytes_padding); + ofs += bytes_padding; + } + + /* + * The bytes field + */ + + memcpy(outbuf + ofs, bytes, num_bytes); + + return true; +} + /**************************************************************************** Construct a chained reply and add it to the already made reply ****************************************************************************/ @@ -1809,7 +1983,7 @@ void chain_reply(struct smb_request *req) * We end up here if there's any error in the chain syntax. Report a * DOS error, just like Windows does. */ - reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror)); + reply_force_doserror(req, ERRSRV, ERRerror); fixup_chain_error_packet(req); done: diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 185f6014d1..b2d98bfbc0 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -704,7 +704,7 @@ void reply_tcon_and_X(struct smb_request *req) } if ((passlen > MAX_PASS_LEN) || (passlen >= req->buflen)) { - reply_doserror(req, ERRDOS, ERRbuftoosmall); + reply_force_doserror(req, ERRDOS, ERRbuftoosmall); END_PROFILE(SMBtconX); return; } @@ -744,7 +744,7 @@ void reply_tcon_and_X(struct smb_request *req) q = strchr_m(path+2,'\\'); if (!q) { data_blob_clear_free(&password); - reply_doserror(req, ERRDOS, ERRnosuchshare); + reply_nterror(req, NT_STATUS_BAD_NETWORK_NAME); END_PROFILE(SMBtconX); return; } @@ -864,7 +864,7 @@ void reply_unknown_new(struct smb_request *req, uint8 type) { DEBUG(0, ("unknown command type (%s): type=%d (0x%X)\n", smb_fn_name(type), type, type)); - reply_doserror(req, ERRSRV, ERRunknownsmb); + reply_force_doserror(req, ERRSRV, ERRunknownsmb); return; } @@ -901,7 +901,7 @@ void reply_ioctl(struct smb_request *req) replysize = 32; break; default: - reply_doserror(req, ERRSRV, ERRnosupport); + reply_force_doserror(req, ERRSRV, ERRnosupport); END_PROFILE(SMBioctl); return; } @@ -920,7 +920,7 @@ void reply_ioctl(struct smb_request *req) files_struct *fsp = file_fsp( req, SVAL(req->vwv+0, 0)); if (!fsp) { - reply_doserror(req, ERRDOS, ERRbadfid); + reply_nterror(req, NT_STATUS_INVALID_HANDLE); END_PROFILE(SMBioctl); return; } @@ -1652,7 +1652,7 @@ void reply_fclose(struct smb_request *req) p += 2; if (status_len == 0) { - reply_doserror(req, ERRSRV, ERRsrverror); + reply_force_doserror(req, ERRSRV, ERRsrverror); END_PROFILE(SMBfclose); return; } @@ -1738,7 +1738,7 @@ void reply_open(struct smb_request *req) OPENX_FILE_EXISTS_OPEN, &access_mask, &share_mode, &create_disposition, &create_options)) { - reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess)); + reply_force_doserror(req, ERRDOS, ERRbadaccess); goto out; } @@ -1789,7 +1789,8 @@ void reply_open(struct smb_request *req) DEBUG(3,("attempt to open a directory %s\n", fsp_str_dbg(fsp))); close_file(req, fsp, ERROR_CLOSE); - reply_doserror(req, ERRDOS,ERRnoaccess); + reply_botherror(req, NT_STATUS_ACCESS_DENIED, + ERRDOS, ERRnoaccess); goto out; } @@ -1875,7 +1876,7 @@ void reply_open_and_X(struct smb_request *req) if (lp_nt_pipe_support()) { reply_open_pipe_and_X(conn, req); } else { - reply_doserror(req, ERRSRV, ERRaccess); + reply_nterror(req, NT_STATUS_NETWORK_ACCESS_DENIED); } goto out; } @@ -1910,7 +1911,7 @@ void reply_open_and_X(struct smb_request *req) &access_mask, &share_mode, &create_disposition, &create_options)) { - reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess)); + reply_force_doserror(req, ERRDOS, ERRbadaccess); goto out; } @@ -1963,7 +1964,7 @@ void reply_open_and_X(struct smb_request *req) mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime); if (fattr & aDIR) { close_file(req, fsp, ERROR_CLOSE); - reply_doserror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); goto out; } @@ -3198,7 +3199,7 @@ void reply_lockread(struct smb_request *req) } if (!CHECK_READ(fsp,req)) { - reply_doserror(req, ERRDOS, ERRbadaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBlockread); return; } @@ -3308,7 +3309,7 @@ void reply_read(struct smb_request *req) } if (!CHECK_READ(fsp,req)) { - reply_doserror(req, ERRDOS, ERRbadaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBread); return; } @@ -3338,7 +3339,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n", &lock); if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { - reply_doserror(req, ERRDOS,ERRlock); + reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT); END_PROFILE(SMBread); return; } @@ -3420,7 +3421,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, &lock); if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { - reply_doserror(req, ERRDOS, ERRlock); + reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT); return; } @@ -3618,7 +3619,7 @@ void reply_read_and_X(struct smb_request *req) } if (!CHECK_READ(fsp,req)) { - reply_doserror(req, ERRDOS,ERRbadaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBreadX); return; } @@ -3669,7 +3670,7 @@ void reply_read_and_X(struct smb_request *req) "used and we don't support 64 bit offsets.\n", (unsigned int)IVAL(req->vwv+10, 0) )); END_PROFILE(SMBreadX); - reply_doserror(req, ERRDOS, ERRbadaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); return; } @@ -3752,7 +3753,7 @@ void reply_writebraw(struct smb_request *req) } if (!CHECK_WRITE(fsp)) { - reply_doserror(req, ERRDOS, ERRbadaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); error_to_writebrawerr(req); END_PROFILE(SMBwritebraw); return; @@ -3786,7 +3787,7 @@ void reply_writebraw(struct smb_request *req) &lock); if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { - reply_doserror(req, ERRDOS, ERRlock); + reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT); error_to_writebrawerr(req); END_PROFILE(SMBwritebraw); return; @@ -3802,7 +3803,7 @@ void reply_writebraw(struct smb_request *req) (int)nwritten, (int)write_through)); if (nwritten < (ssize_t)numtowrite) { - reply_doserror(req, ERRHRD, ERRdiskfull); + reply_nterror(req, NT_STATUS_DISK_FULL); error_to_writebrawerr(req); goto strict_unlock; } @@ -3812,7 +3813,7 @@ void reply_writebraw(struct smb_request *req) /* Allocate a buffer of 64k + length. */ buf = TALLOC_ARRAY(NULL, char, 65540); if (!buf) { - reply_doserror(req, ERRDOS, ERRnomem); + reply_nterror(req, NT_STATUS_NO_MEMORY); error_to_writebrawerr(req); goto strict_unlock; } @@ -3968,7 +3969,7 @@ void reply_writeunlock(struct smb_request *req) } if (!CHECK_WRITE(fsp)) { - reply_doserror(req, ERRDOS,ERRbadaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBwriteunlock); return; } @@ -3983,7 +3984,7 @@ void reply_writeunlock(struct smb_request *req) &lock); if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { - reply_doserror(req, ERRDOS, ERRlock); + reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT); END_PROFILE(SMBwriteunlock); return; } @@ -4013,7 +4014,7 @@ void reply_writeunlock(struct smb_request *req) } if((nwritten < numtowrite) && (numtowrite != 0)) { - reply_doserror(req, ERRHRD, ERRdiskfull); + reply_nterror(req, NT_STATUS_DISK_FULL); goto strict_unlock; } @@ -4089,7 +4090,7 @@ void reply_write(struct smb_request *req) } if (!CHECK_WRITE(fsp)) { - reply_doserror(req, ERRDOS, ERRbadaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBwrite); return; } @@ -4103,7 +4104,7 @@ void reply_write(struct smb_request *req) &lock); if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { - reply_doserror(req, ERRDOS, ERRlock); + reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT); END_PROFILE(SMBwrite); return; } @@ -4147,7 +4148,7 @@ void reply_write(struct smb_request *req) } if((nwritten == 0) && (numtowrite != 0)) { - reply_doserror(req, ERRHRD, ERRdiskfull); + reply_nterror(req, NT_STATUS_DISK_FULL); goto strict_unlock; } @@ -4299,14 +4300,14 @@ void reply_write_and_X(struct smb_request *req) return; } if (numtowrite != req->unread_bytes) { - reply_doserror(req, ERRDOS, ERRbadmem); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); END_PROFILE(SMBwriteX); return; } } else { if (smb_doff > smblen || smb_doff + numtowrite < numtowrite || smb_doff + numtowrite > smblen) { - reply_doserror(req, ERRDOS, ERRbadmem); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); END_PROFILE(SMBwriteX); return; } @@ -4315,7 +4316,7 @@ void reply_write_and_X(struct smb_request *req) /* If it's an IPC, pass off the pipe handler. */ if (IS_IPC(conn)) { if (req->unread_bytes) { - reply_doserror(req, ERRDOS, ERRbadmem); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); END_PROFILE(SMBwriteX); return; } @@ -4334,7 +4335,7 @@ void reply_write_and_X(struct smb_request *req) } if (!CHECK_WRITE(fsp)) { - reply_doserror(req, ERRDOS, ERRbadaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBwriteX); return; } @@ -4358,7 +4359,7 @@ void reply_write_and_X(struct smb_request *req) DEBUG(0,("reply_write_and_X - large offset (%x << 32) " "used and we don't support 64 bit offsets.\n", (unsigned int)IVAL(req->vwv+12, 0) )); - reply_doserror(req, ERRDOS, ERRbadaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBwriteX); return; } @@ -4371,7 +4372,7 @@ void reply_write_and_X(struct smb_request *req) &lock); if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { - reply_doserror(req, ERRDOS, ERRlock); + reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT); END_PROFILE(SMBwriteX); return; } @@ -4400,7 +4401,7 @@ void reply_write_and_X(struct smb_request *req) } if((nwritten == 0) && (numtowrite != 0)) { - reply_doserror(req, ERRHRD, ERRdiskfull); + reply_nterror(req, NT_STATUS_DISK_FULL); goto strict_unlock; } @@ -4611,7 +4612,7 @@ void reply_close(struct smb_request *req) */ if(!fsp || (fsp->conn != conn) || (fsp->vuid != req->vuid)) { - reply_doserror(req, ERRDOS, ERRbadfid); + reply_nterror(req, NT_STATUS_INVALID_HANDLE); END_PROFILE(SMBclose); return; } @@ -4690,7 +4691,7 @@ void reply_writeclose(struct smb_request *req) return; } if (!CHECK_WRITE(fsp)) { - reply_doserror(req, ERRDOS,ERRbadaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBwriteclose); return; } @@ -4706,7 +4707,7 @@ void reply_writeclose(struct smb_request *req) &lock); if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { - reply_doserror(req, ERRDOS,ERRlock); + reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT); END_PROFILE(SMBwriteclose); return; } @@ -4732,7 +4733,7 @@ void reply_writeclose(struct smb_request *req) conn->num_files_open)); if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { - reply_doserror(req, ERRHRD, ERRdiskfull); + reply_nterror(req, NT_STATUS_DISK_FULL); goto strict_unlock; } @@ -4882,7 +4883,7 @@ void reply_tdis(struct smb_request *req) if (!conn) { DEBUG(4,("Invalid connection in tdis\n")); - reply_doserror(req, ERRSRV, ERRinvnid); + reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED); END_PROFILE(SMBtdis); return; } @@ -4982,7 +4983,7 @@ void reply_printopen(struct smb_request *req) } if (!CAN_PRINT(conn)) { - reply_doserror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBsplopen); return; } @@ -5040,7 +5041,7 @@ void reply_printclose(struct smb_request *req) } if (!CAN_PRINT(conn)) { - reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror)); + reply_force_doserror(req, ERRSRV, ERRerror); END_PROFILE(SMBsplclose); return; } @@ -5088,7 +5089,7 @@ void reply_printqueue(struct smb_request *req) one printer - I think we should now only accept it if they get it right (tridge) */ if (!CAN_PRINT(conn)) { - reply_doserror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBsplretq); return; } @@ -5182,13 +5183,13 @@ void reply_printwrite(struct smb_request *req) } if (!CAN_PRINT(conn)) { - reply_doserror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBsplwr); return; } if (!CHECK_WRITE(fsp)) { - reply_doserror(req, ERRDOS, ERRbadaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBsplwr); return; } @@ -6548,7 +6549,7 @@ void reply_copy(struct smb_request *req) if (tid2 != conn->cnum) { /* can't currently handle inter share copies XXXX */ DEBUG(3,("Rejecting inter-share copy\n")); - reply_doserror(req, ERRSRV, ERRinvdevice); + reply_nterror(req, NT_STATUS_BAD_DEVICE_TYPE); goto out; } @@ -6587,19 +6588,19 @@ void reply_copy(struct smb_request *req) target_is_directory = VALID_STAT_OF_DIR(smb_fname_dst->st); if ((flags&1) && target_is_directory) { - reply_doserror(req, ERRDOS, ERRbadfile); + reply_nterror(req, NT_STATUS_NO_SUCH_FILE); goto out; } if ((flags&2) && !target_is_directory) { - reply_doserror(req, ERRDOS, ERRbadpath); + reply_nterror(req, NT_STATUS_OBJECT_PATH_NOT_FOUND); goto out; } if ((flags&(1<<5)) && VALID_STAT_OF_DIR(smb_fname_src->st)) { /* wants a tree copy! XXXX */ DEBUG(3,("Rejecting tree copy\n")); - reply_doserror(req, ERRSRV, ERRerror); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); goto out; } @@ -6810,7 +6811,7 @@ void reply_copy(struct smb_request *req) } if (count == 0) { - reply_doserror(req, ERRDOS, error); + reply_nterror(req, dos_to_ntstatus(ERRDOS, error)); goto out; } @@ -7239,7 +7240,7 @@ void reply_lockingX(struct smb_request *req) /* we don't support these - and CANCEL_LOCK makes w2k and XP reboot so I don't really want to be compatible! (tridge) */ - reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks)); + reply_force_doserror(req, ERRDOS, ERRnoatomiclocks); END_PROFILE(SMBlockingX); return; } @@ -7282,7 +7283,7 @@ void reply_lockingX(struct smb_request *req) return; } else { END_PROFILE(SMBlockingX); - reply_doserror(req, ERRDOS, ERRlock); + reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT); return; } } @@ -7350,8 +7351,8 @@ void reply_lockingX(struct smb_request *req) * There is no error code marked "stupid client bug".... :-). */ if(err) { + reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBlockingX); - reply_doserror(req, ERRDOS, ERRnoaccess); return; } } @@ -7385,8 +7386,8 @@ void reply_lockingX(struct smb_request *req) * There is no error code marked "stupid client bug".... :-). */ if(err) { + reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBlockingX); - reply_doserror(req, ERRDOS, ERRnoaccess); return; } } @@ -7427,7 +7428,7 @@ void reply_lockingX(struct smb_request *req) void reply_readbmpx(struct smb_request *req) { START_PROFILE(SMBreadBmpx); - reply_doserror(req, ERRSRV, ERRuseSTD); + reply_force_doserror(req, ERRSRV, ERRuseSTD); END_PROFILE(SMBreadBmpx); return; } @@ -7441,7 +7442,7 @@ void reply_readbmpx(struct smb_request *req) void reply_readbs(struct smb_request *req) { START_PROFILE(SMBreadBs); - reply_doserror(req, ERRSRV, ERRuseSTD); + reply_force_doserror(req, ERRSRV, ERRuseSTD); END_PROFILE(SMBreadBs); return; } @@ -7468,7 +7469,7 @@ void reply_setattrE(struct smb_request *req) fsp = file_fsp(req, SVAL(req->vwv+0, 0)); if(!fsp || (fsp->conn != conn)) { - reply_doserror(req, ERRDOS, ERRbadfid); + reply_nterror(req, NT_STATUS_INVALID_HANDLE); goto out; } @@ -7499,7 +7500,7 @@ void reply_setattrE(struct smb_request *req) status = smb_set_file_time(conn, fsp, fsp->fsp_name, &ft, true); if (!NT_STATUS_IS_OK(status)) { - reply_doserror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, status); goto out; } @@ -7527,7 +7528,7 @@ void reply_setattrE(struct smb_request *req) void reply_writebmpx(struct smb_request *req) { START_PROFILE(SMBwriteBmpx); - reply_doserror(req, ERRSRV, ERRuseSTD); + reply_force_doserror(req, ERRSRV, ERRuseSTD); END_PROFILE(SMBwriteBmpx); return; } @@ -7541,7 +7542,7 @@ void reply_writebmpx(struct smb_request *req) void reply_writebs(struct smb_request *req) { START_PROFILE(SMBwriteBs); - reply_doserror(req, ERRSRV, ERRuseSTD); + reply_force_doserror(req, ERRSRV, ERRuseSTD); END_PROFILE(SMBwriteBs); return; } @@ -7568,7 +7569,7 @@ void reply_getattrE(struct smb_request *req) fsp = file_fsp(req, SVAL(req->vwv+0, 0)); if(!fsp || (fsp->conn != conn)) { - reply_doserror(req, ERRDOS, ERRbadfid); + reply_nterror(req, NT_STATUS_INVALID_HANDLE); END_PROFILE(SMBgetattrE); return; } diff --git a/source3/smbd/seal.c b/source3/smbd/seal.c index 2d738cbd12..700d7ea02e 100644 --- a/source3/smbd/seal.c +++ b/source3/smbd/seal.c @@ -20,6 +20,7 @@ #include "includes.h" #include "smbd/globals.h" #include "../libcli/auth/spnego.h" +#include "ntlmssp.h" /****************************************************************************** Server side encryption. diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index addd386fb4..612cf2231a 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -25,6 +25,7 @@ #include "includes.h" #include "smbd/globals.h" #include "../libcli/auth/spnego.h" +#include "ntlmssp.h" /* For split krb5 SPNEGO blobs. */ struct pending_auth_data { diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index dc24124b54..0df4bd6c56 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -22,6 +22,7 @@ #include "smbd/globals.h" #include "../libcli/smb/smb_common.h" #include "../libcli/auth/spnego.h" +#include "ntlmssp.h" static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req, uint64_t in_session_id, diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 40c1af2aeb..df61167354 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1012,7 +1012,7 @@ static void call_trans2open(connection_struct *conn, pname = ¶ms[28]; if (IS_IPC(conn)) { - reply_doserror(req, ERRSRV, ERRaccess); + reply_nterror(req, NT_STATUS_NETWORK_ACCESS_DENIED); goto out; } @@ -1055,7 +1055,7 @@ static void call_trans2open(connection_struct *conn, &access_mask, &share_mode, &create_disposition, &create_options)) { - reply_doserror(req, ERRDOS, ERRbadaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); goto out; } @@ -1121,7 +1121,7 @@ static void call_trans2open(connection_struct *conn, inode = smb_fname->st.st_ex_ino; if (fattr & aDIR) { close_file(req, fsp, ERROR_CLOSE); - reply_doserror(req, ERRDOS,ERRnoaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); goto out; } @@ -2334,7 +2334,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } if (!lp_ea_support(SNUM(conn))) { - reply_doserror(req, ERRDOS, ERReasnotsupported); + reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED); goto out; } @@ -2462,7 +2462,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd if(numentries == 0) { dptr_close(sconn, &dptr_num); if (get_Protocol() < PROTOCOL_NT1) { - reply_doserror(req, ERRDOS, ERRnofiles); + reply_force_doserror(req, ERRDOS, ERRnofiles); goto out; } else { reply_botherror(req, NT_STATUS_NO_SUCH_FILE, @@ -2649,7 +2649,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } if (!lp_ea_support(SNUM(conn))) { - reply_doserror(req, ERRDOS, ERReasnotsupported); + reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED); return; } @@ -2682,7 +2682,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd /* Check that the dptr is valid */ if(!(dirptr = dptr_fetch_lanman2(sconn, dptr_num))) { - reply_doserror(req, ERRDOS, ERRnofiles); + reply_nterror(req, STATUS_NO_MORE_FILES); return; } @@ -2691,7 +2691,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd /* Get the wildcard mask from the dptr */ if((p = dptr_wcard(sconn, dptr_num))== NULL) { DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num)); - reply_doserror(req, ERRDOS, ERRnofiles); + reply_nterror(req, STATUS_NO_MORE_FILES); return; } @@ -5231,8 +5231,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } if (!lp_ea_support(SNUM(conn))) { - reply_doserror(req, ERRDOS, - ERReasnotsupported); + reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED); return; } @@ -7664,7 +7663,8 @@ static void call_trans2setfilepathinfo(connection_struct *conn, max_data_bytes); return; } else { - reply_doserror(req, ERRDOS, ERRbadpath); + reply_nterror(req, + NT_STATUS_OBJECT_PATH_NOT_FOUND); return; } } else { @@ -7804,7 +7804,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req, TALLOC_CTX *ctx = talloc_tos(); if (!CAN_WRITE(conn)) { - reply_doserror(req, ERRSRV, ERRaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); return; } @@ -8023,7 +8023,7 @@ static void call_trans2getdfsreferral(connection_struct *conn, max_referral_level = SVAL(params,0); if(!lp_host_msdfs()) { - reply_doserror(req, ERRDOS, ERRbadfunc); + reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED); return; } @@ -8065,7 +8065,7 @@ static void call_trans2ioctl(connection_struct *conn, /* check for an invalid fid before proceeding */ if (!fsp) { - reply_doserror(req, ERRDOS, ERRbadfid); + reply_nterror(req, NT_STATUS_INVALID_HANDLE); return; } @@ -8094,7 +8094,7 @@ static void call_trans2ioctl(connection_struct *conn, } DEBUG(2,("Unknown TRANS2_IOCTL\n")); - reply_doserror(req, ERRSRV, ERRerror); + reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED); } /**************************************************************************** @@ -8320,7 +8320,7 @@ static void handle_trans2(connection_struct *conn, struct smb_request *req, default: /* Error in request */ DEBUG(2,("Unknown request %d in trans2 call\n", state->call)); - reply_doserror(req, ERRSRV,ERRerror); + reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED); } } @@ -8372,7 +8372,7 @@ void reply_trans2(struct smb_request *req) case TRANSACT2_SETFSINFO: break; default: - reply_doserror(req, ERRSRV, ERRaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBtrans2); return; } diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 5a0a300092..c7a69ae403 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -364,8 +364,11 @@ bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid) bool torture_close_connection(struct cli_state *c) { bool ret = True; - if (!cli_tdis(c)) { - printf("tdis failed (%s)\n", cli_errstr(c)); + NTSTATUS status; + + status = cli_tdis(c); + if (!NT_STATUS_IS_OK(status)) { + printf("tdis failed (%s)\n", nt_errstr(status)); ret = False; } @@ -1192,8 +1195,9 @@ static bool run_tcon_test(int dummy) cli->cnum = cnum2; - if (!cli_tdis(cli)) { - printf("secondary tdis failed (%s)\n", cli_errstr(cli)); + status = cli_tdis(cli); + if (!NT_STATUS_IS_OK(status)) { + printf("secondary tdis failed (%s)\n", nt_errstr(status)); return False; } @@ -5321,9 +5325,10 @@ static bool run_sesssetup_bench(int dummy) d_printf("\r%d ", (int)c->vuid); - if (!cli_ulogoff(c)) { + status = cli_ulogoff(c); + if (!NT_STATUS_IS_OK(status)) { d_printf("(%s) cli_ulogoff failed: %s\n", - __location__, cli_errstr(c)); + __location__, nt_errstr(status)); return false; } c->vuid = 0; @@ -5796,7 +5801,8 @@ static bool run_notify_bench(int dummy) struct tevent_context *ev; NTSTATUS status; uint16_t dnum; - struct tevent_req *req1, *req2; + struct tevent_req *req1; + struct tevent_req *req2 = NULL; int i, num_unc_names; int num_finished = 0; @@ -5964,7 +5970,7 @@ static bool run_windows_write(int dummy) int i; bool ret = false; const char *fname = "\\writetest.txt"; - struct timeval start; + struct timeval start_time; double seconds; double kbytes; @@ -5980,7 +5986,7 @@ static bool run_windows_write(int dummy) cli_sockopt(cli1, sockops); - start = timeval_current(); + start_time = timeval_current(); for (i=0; i<torture_numops; i++) { char c = 0; @@ -6002,7 +6008,7 @@ static bool run_windows_write(int dummy) } } - seconds = timeval_elapsed(&start); + seconds = timeval_elapsed(&start_time); kbytes = (double)torture_blocksize * torture_numops; kbytes /= 1024; @@ -6042,6 +6048,7 @@ static bool run_uid_regression_test(int dummy) int16_t old_vuid; int16_t old_cnum; bool correct = True; + NTSTATUS status; printf("starting uid regression test\n"); @@ -6054,9 +6061,10 @@ static bool run_uid_regression_test(int dummy) /* Ok - now save then logoff our current user. */ old_vuid = cli->vuid; - if (!cli_ulogoff(cli)) { + status = cli_ulogoff(cli); + if (!NT_STATUS_IS_OK(status)) { d_printf("(%s) cli_ulogoff failed: %s\n", - __location__, cli_errstr(cli)); + __location__, nt_errstr(status)); correct = false; goto out; } @@ -6078,17 +6086,20 @@ static bool run_uid_regression_test(int dummy) cli->vuid = 0; /* This should succeed. */ - if (cli_tdis(cli)) { + status = cli_tdis(cli); + + if (NT_STATUS_IS_OK(status)) { printf("First tdis with invalid vuid should succeed.\n"); } else { - printf("First tdis failed (%s)\n", cli_errstr(cli)); + printf("First tdis failed (%s)\n", nt_errstr(status)); } cli->vuid = old_vuid; cli->cnum = old_cnum; /* This should fail. */ - if (cli_tdis(cli)) { + status = cli_tdis(cli); + if (NT_STATUS_IS_OK(status)) { printf("Second tdis with invalid vuid should fail - succeeded instead !.\n"); } else { /* Should be bad tid. */ diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index f133eec0fc..8e644bb6b2 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -1007,6 +1007,8 @@ static NTSTATUS net_ads_join_ok(struct net_context *c) { ADS_STRUCT *ads = NULL; ADS_STATUS status; + fstring dc_name; + struct sockaddr_storage dcip; if (!secrets_init()) { DEBUG(1,("Failed to initialise secrets database\n")); @@ -1015,6 +1017,8 @@ static NTSTATUS net_ads_join_ok(struct net_context *c) net_use_krb_machine_account(c); + get_dc_name(lp_workgroup(), lp_realm(), dc_name, &dcip); + status = ads_startup(c, true, &ads); if (!ADS_ERR_OK(status)) { return ads_ntstatus(status); diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 5b3b1e34d7..7dc8c1dd2c 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -3074,13 +3074,19 @@ static int rpc_share_list(struct net_context *c, int argc, const char **argv) static bool check_share_availability(struct cli_state *cli, const char *netname) { - if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, netname, "A:", "", 0))) { + NTSTATUS status; + + status = cli_tcon_andx(cli, netname, "A:", "", 0); + if (!NT_STATUS_IS_OK(status)) { d_printf(_("skipping [%s]: not a file share.\n"), netname); return false; } - if (!cli_tdis(cli)) + status = cli_tdis(cli); + if (!NT_STATUS_IS_OK(status)) { + d_printf(_("cli_tdis returned %s\n"), nt_errstr(status)); return false; + } return true; } diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 87df3c6160..57e4251543 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -27,6 +27,7 @@ #include "utils/ntlm_auth.h" #include "../libcli/auth/libcli_auth.h" #include "../libcli/auth/spnego.h" +#include "ntlmssp.h" #include "smb_krb5.h" #include <iniparser.h> @@ -635,7 +636,7 @@ static NTSTATUS local_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *u return nt_status; } -static NTSTATUS ntlm_auth_start_ntlmssp_client(NTLMSSP_STATE **client_ntlmssp_state) +static NTSTATUS ntlm_auth_start_ntlmssp_client(struct ntlmssp_state **client_ntlmssp_state) { NTSTATUS status; if ( (opt_username == NULL) || (opt_domain == NULL) ) { @@ -685,7 +686,7 @@ static NTSTATUS ntlm_auth_start_ntlmssp_client(NTLMSSP_STATE **client_ntlmssp_st return NT_STATUS_OK; } -static NTSTATUS ntlm_auth_start_ntlmssp_server(NTLMSSP_STATE **ntlmssp_state) +static NTSTATUS ntlm_auth_start_ntlmssp_server(struct ntlmssp_state **ntlmssp_state) { NTSTATUS status = ntlmssp_server_start(ntlmssp_state); @@ -1172,7 +1173,7 @@ static void offer_gss_spnego_mechs(void) { static void manage_gss_spnego_request(struct ntlm_auth_state *state, char *buf, int length) { - static NTLMSSP_STATE *ntlmssp_state = NULL; + static struct ntlmssp_state *ntlmssp_state = NULL; struct spnego_data request, response; DATA_BLOB token; NTSTATUS status; @@ -1415,7 +1416,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, return; } -static NTLMSSP_STATE *client_ntlmssp_state = NULL; +static struct ntlmssp_state *client_ntlmssp_state = NULL; static bool manage_client_ntlmssp_init(struct spnego_data spnego) { diff --git a/source3/winbindd/wb_getgrsid.c b/source3/winbindd/wb_getgrsid.c index 03d71e45b9..bb93be2174 100644 --- a/source3/winbindd/wb_getgrsid.c +++ b/source3/winbindd/wb_getgrsid.c @@ -52,6 +52,17 @@ struct tevent_req *wb_getgrsid_send(TALLOC_CTX *mem_ctx, state->ev = ev; state->max_nesting = max_nesting; + if (lp_winbind_trusted_domains_only()) { + struct winbindd_domain *our_domain = find_our_domain(); + + if (sid_compare_domain(group_sid, &our_domain->sid) == 0) { + DEBUG(7, ("winbindd_getgrsid: My domain -- rejecting " + "getgrsid() for %s\n", sid_string_tos(group_sid))); + tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP); + return tevent_req_post(req, ev); + } + } + subreq = wb_lookupsid_send(state, ev, &state->sid); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); diff --git a/source3/winbindd/wb_gettoken.c b/source3/winbindd/wb_gettoken.c index 26189e5a97..ca407b2117 100644 --- a/source3/winbindd/wb_gettoken.c +++ b/source3/winbindd/wb_gettoken.c @@ -60,6 +60,13 @@ struct tevent_req *wb_gettoken_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } + if (lp_winbind_trusted_domains_only() && domain->primary) { + DEBUG(7, ("wb_gettoken: My domain -- rejecting getgroups() " + "for %s.\n", sid_string_tos(sid))); + tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); + return tevent_req_post(req, ev); + } + subreq = wb_lookupusergroups_send(state, ev, domain, &state->usersid); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); diff --git a/source3/winbindd/wb_sid2gid.c b/source3/winbindd/wb_sid2gid.c index a578746ea2..e15d563cd7 100644 --- a/source3/winbindd/wb_sid2gid.c +++ b/source3/winbindd/wb_sid2gid.c @@ -54,7 +54,7 @@ struct tevent_req *wb_sid2gid_send(TALLOC_CTX *mem_ctx, DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n", (int)state->gid, expired ? " (expired)": "")); - if (!expired || IS_DOMAIN_OFFLINE(find_our_domain())) { + if (!expired || is_domain_offline(find_our_domain())) { if (state->gid == -1) { tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); } else { diff --git a/source3/winbindd/wb_sid2uid.c b/source3/winbindd/wb_sid2uid.c index abfe257bfa..9c22b8d10b 100644 --- a/source3/winbindd/wb_sid2uid.c +++ b/source3/winbindd/wb_sid2uid.c @@ -53,7 +53,7 @@ struct tevent_req *wb_sid2uid_send(TALLOC_CTX *mem_ctx, DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n", (int)state->uid, expired ? " (expired)": "")); - if (!expired || IS_DOMAIN_OFFLINE(find_our_domain())) { + if (!expired || is_domain_offline(find_our_domain())) { if (state->uid == -1) { tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); } else { diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index e09374c5cb..f6f4a8fee7 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -532,6 +532,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = { winbindd_list_groups_send, winbindd_list_groups_recv }, { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC", winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv }, + { WINBINDD_PING_DC, "PING_DC", + winbindd_ping_dc_send, winbindd_ping_dc_recv }, { 0, NULL, NULL, NULL } }; @@ -796,10 +798,15 @@ static void winbind_client_request_read(struct tevent_req *req) ret = wb_req_read_recv(req, state, &state->request, &err); TALLOC_FREE(req); if (ret == -1) { + if (err == EPIPE) { + DEBUG(6, ("closing socket %d, client exited\n", + state->sock)); + } else { + DEBUG(2, ("Could not read client request from fd %d: " + "%s\n", state->sock, strerror(err))); + } close(state->sock); state->sock = -1; - DEBUG(2, ("Could not read client request: %s\n", - strerror(err))); remove_client(state); return; } @@ -833,10 +840,6 @@ static void remove_client(struct winbindd_cli_state *state) state->sock = -1; } - /* Free any getent state */ - - free_getent_state(state->getgrent_state); - TALLOC_FREE(state->mem_ctx); /* Remove from list and free */ @@ -855,7 +858,7 @@ static bool remove_idle_client(void) for (state = winbindd_client_list(); state; state = state->next) { if (state->response == NULL && - !state->pwent_state && !state->getgrent_state) { + !state->pwent_state && !state->grent_state) { nidle++; if (!last_access || state->last_access < last_access) { last_access = state->last_access; diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h index 2e7d09f442..ea791234fb 100644 --- a/source3/winbindd/winbindd.h +++ b/source3/winbindd/winbindd.h @@ -65,22 +65,11 @@ struct winbindd_cli_state { * initialized? */ bool getgrent_initialized; /* Has getgrent_state been * initialized? */ - struct getent_state *getgrent_state; /* State for getgrent() */ struct getpwent_state *pwent_state; /* State for getpwent() */ struct getgrent_state *grent_state; /* State for getgrent() */ }; -/* State between get{pw,gr}ent() calls */ - -struct getent_state { - struct getent_state *prev, *next; - void *sam_entries; - uint32 sam_entry_index, num_sam_entries; - bool got_sam_entries; - fstring domain_name; -}; - struct getpwent_state { struct winbindd_domain *domain; int next_user; @@ -121,8 +110,6 @@ struct winbindd_cm_conn { struct rpc_pipe_client *netlogon_pipe; }; -struct winbindd_async_request; - /* Async child */ struct winbindd_domain; @@ -326,10 +313,7 @@ struct winbindd_methods { /* enumerate trusted domains */ NTSTATUS (*trusted_domains)(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *num_domains, - char ***names, - char ***alt_names, - DOM_SID **dom_sids); + struct netr_DomainTrustList *trusts); }; /* Filled out by IDMAP backends */ @@ -400,9 +384,4 @@ struct WINBINDD_CCACHE_ENTRY { #define WINBINDD_PAM_AUTH_KRB5_RENEW_TIME 2592000 /* one month */ #define DOM_SEQUENCE_NONE ((uint32)-1) -#define IS_DOMAIN_OFFLINE(x) ( lp_winbind_offline_logon() && \ - ( get_global_winbindd_state_offline() \ - || !(x)->online ) ) -#define IS_DOMAIN_ONLINE(x) (!IS_DOMAIN_OFFLINE(x)) - #endif /* _WINBINDD_H */ diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c index 92c0272088..d15fb86d86 100644 --- a/source3/winbindd/winbindd_ads.c +++ b/source3/winbindd/winbindd_ads.c @@ -1257,33 +1257,23 @@ static NTSTATUS password_policy(struct winbindd_domain *domain, /* get a list of trusted domains */ static NTSTATUS trusted_domains(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *num_domains, - char ***names, - char ***alt_names, - DOM_SID **dom_sids) + struct netr_DomainTrustList *trusts) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - struct netr_DomainTrustList trusts; int i; uint32 flags; struct rpc_pipe_client *cli; - uint32 fr_flags = (NETR_TRUST_FLAG_IN_FOREST | NETR_TRUST_FLAG_TREEROOT); int ret_count; DEBUG(3,("ads: trusted_domains\n")); - *num_domains = 0; - *alt_names = NULL; - *names = NULL; - *dom_sids = NULL; + ZERO_STRUCTP(trusts); /* If this is our primary domain or a root in our forest, query for all trusts. If not, then just look for domain trusts in the target forest */ - if ( domain->primary || - ((domain->domain_flags&fr_flags) == fr_flags) ) - { + if (domain->primary || domain_is_forest_root(domain)) { flags = NETR_TRUST_FLAG_OUTBOUND | NETR_TRUST_FLAG_INBOUND | NETR_TRUST_FLAG_IN_FOREST; @@ -1303,142 +1293,121 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx, cli->desthost, flags, - &trusts, + trusts, NULL); - if ( NT_STATUS_IS_OK(result) && trusts.count) { - - /* Allocate memory for trusted domain names and sids */ - - if ( !(*names = TALLOC_ARRAY(mem_ctx, char *, trusts.count)) ) { - DEBUG(0, ("trusted_domains: out of memory\n")); - return NT_STATUS_NO_MEMORY; - } - - if ( !(*alt_names = TALLOC_ARRAY(mem_ctx, char *, trusts.count)) ) { - DEBUG(0, ("trusted_domains: out of memory\n")); - return NT_STATUS_NO_MEMORY; - } - - if ( !(*dom_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, trusts.count)) ) { - DEBUG(0, ("trusted_domains: out of memory\n")); - return NT_STATUS_NO_MEMORY; - } - - /* Copy across names and sids */ - - - ret_count = 0; - for (i = 0; i < trusts.count; i++) { - struct winbindd_domain d; + if (!NT_STATUS_IS_OK(result)) { + return result; + } + if (trusts->count == 0) { + return NT_STATUS_OK; + } - ZERO_STRUCT(d); + /* Copy across names and sids */ - /* drop external trusts if this is not our primary - domain. This means that the returned number of - domains may be less that the ones actually trusted - by the DC. */ + ret_count = 0; + for (i = 0; i < trusts->count; i++) { + struct netr_DomainTrust *trust = &trusts->array[i]; + struct winbindd_domain d; - if ( (trusts.array[i].trust_attributes == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) && - !domain->primary ) - { - DEBUG(10,("trusted_domains: Skipping external trusted domain " - "%s because it is outside of our primary domain\n", - trusts.array[i].netbios_name)); - continue; - } + ZERO_STRUCT(d); - /* We must check that the SID of each trusted domain - * was returned to work around a bug in Windows: - * http://support.microsoft.com/kb/922832 */ + /* + * drop external trusts if this is not our primary + * domain. This means that the returned number of + * domains may be less that the ones actually trusted + * by the DC. + */ - (*names)[ret_count] = CONST_DISCARD(char *, trusts.array[i].netbios_name); - (*alt_names)[ret_count] = CONST_DISCARD(char *, trusts.array[i].dns_name); - if (trusts.array[i].sid) { - sid_copy(&(*dom_sids)[ret_count], trusts.array[i].sid); - } else { - sid_copy(&(*dom_sids)[ret_count], &global_sid_NULL); - } + if ((trust->trust_attributes + == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) && + !domain->primary ) + { + DEBUG(10,("trusted_domains: Skipping external trusted " + "domain %s because it is outside of our " + "primary domain\n", + trust->netbios_name)); + continue; + } - /* add to the trusted domain cache */ + /* add to the trusted domain cache */ - fstrcpy( d.name, trusts.array[i].netbios_name); - fstrcpy( d.alt_name, trusts.array[i].dns_name); - if (trusts.array[i].sid) { - sid_copy( &d.sid, trusts.array[i].sid); - } else { - sid_copy(&d.sid, &global_sid_NULL); - } + fstrcpy(d.name, trust->netbios_name); + fstrcpy(d.alt_name, trust->dns_name); + if (trust->sid) { + sid_copy(&d.sid, trust->sid); + } else { + sid_copy(&d.sid, &global_sid_NULL); + } - if ( domain->primary ) { + if ( domain->primary ) { + DEBUG(10,("trusted_domains(ads): Searching " + "trusted domain list of %s and storing " + "trust flags for domain %s\n", + domain->name, d.alt_name)); + + d.domain_flags = trust->trust_flags; + d.domain_type = trust->trust_type; + d.domain_trust_attribs = trust->trust_attributes; + + wcache_tdc_add_domain( &d ); + ret_count++; + } else if (domain_is_forest_root(domain)) { + /* Check if we already have this record. If + * we are following our forest root that is not + * our primary domain, we want to keep trust + * flags from the perspective of our primary + * domain not our forest root. */ + struct winbindd_tdc_domain *exist = NULL; + + exist = wcache_tdc_fetch_domain( + talloc_tos(), trust->netbios_name); + if (!exist) { DEBUG(10,("trusted_domains(ads): Searching " - "trusted domain list of %s and storing " - "trust flags for domain %s\n", - domain->name, d.alt_name)); - - d.domain_flags = trusts.array[i].trust_flags; - d.domain_type = trusts.array[i].trust_type; - d.domain_trust_attribs = trusts.array[i].trust_attributes; + "trusted domain list of %s and " + "storing trust flags for domain " + "%s\n", domain->name, d.alt_name)); + d.domain_flags = trust->trust_flags; + d.domain_type = trust->trust_type; + d.domain_trust_attribs = + trust->trust_attributes; wcache_tdc_add_domain( &d ); ret_count++; - } else if ( (domain->domain_flags&fr_flags) == fr_flags ) { - /* Check if we already have this record. If - * we are following our forest root that is not - * our primary domain, we want to keep trust - * flags from the perspective of our primary - * domain not our forest root. */ - struct winbindd_tdc_domain *exist = NULL; - - exist = - wcache_tdc_fetch_domain(NULL, trusts.array[i].netbios_name); - if (!exist) { - DEBUG(10,("trusted_domains(ads): Searching " - "trusted domain list of %s and storing " - "trust flags for domain %s\n", - domain->name, d.alt_name)); - d.domain_flags = trusts.array[i].trust_flags; - d.domain_type = trusts.array[i].trust_type; - d.domain_trust_attribs = trusts.array[i].trust_attributes; - - wcache_tdc_add_domain( &d ); - ret_count++; - } - TALLOC_FREE(exist); + } + TALLOC_FREE(exist); + } else { + /* This gets a little tricky. If we are + following a transitive forest trust, then + innerit the flags, type, and attribs from + the domain we queried to make sure we don't + record the view of the trust from the wrong + side. Always view it from the side of our + primary domain. --jerry */ + struct winbindd_tdc_domain *parent = NULL; + + DEBUG(10,("trusted_domains(ads): Searching " + "trusted domain list of %s and inheriting " + "trust flags for domain %s\n", + domain->name, d.alt_name)); + + parent = wcache_tdc_fetch_domain(talloc_tos(), + domain->name); + if (parent) { + d.domain_flags = parent->trust_flags; + d.domain_type = parent->trust_type; + d.domain_trust_attribs = parent->trust_attribs; } else { - /* This gets a little tricky. If we are - following a transitive forest trust, then - innerit the flags, type, and attribs from - the domain we queried to make sure we don't - record the view of the trust from the wrong - side. Always view it from the side of our - primary domain. --jerry */ - struct winbindd_tdc_domain *parent = NULL; - - DEBUG(10,("trusted_domains(ads): Searching " - "trusted domain list of %s and inheriting " - "trust flags for domain %s\n", - domain->name, d.alt_name)); - - parent = wcache_tdc_fetch_domain(NULL, domain->name); - if (parent) { - d.domain_flags = parent->trust_flags; - d.domain_type = parent->trust_type; - d.domain_trust_attribs = parent->trust_attribs; - } else { - d.domain_flags = domain->domain_flags; - d.domain_type = domain->domain_type; - d.domain_trust_attribs = domain->domain_trust_attribs; - } - TALLOC_FREE(parent); - - wcache_tdc_add_domain( &d ); - ret_count++; + d.domain_flags = domain->domain_flags; + d.domain_type = domain->domain_type; + d.domain_trust_attribs = + domain->domain_trust_attribs; } - } + TALLOC_FREE(parent); - *num_domains = ret_count; + wcache_tdc_add_domain( &d ); + ret_count++; + } } - return result; } diff --git a/source3/winbindd/winbindd_async.c b/source3/winbindd/winbindd_async.c index 6c5d92e71b..5a350b99bc 100644 --- a/source3/winbindd/winbindd_async.c +++ b/source3/winbindd/winbindd_async.c @@ -6,17 +6,6 @@ Copyright (C) Volker Lendecke 2005 Copyright (C) Gerald Carter 2006 - The helpers always consist of three functions: - - * A request setup function that takes the necessary parameters together - with a continuation function that is to be called upon completion - - * A private continuation function that is internal only. This is to be - called by the lower-level functions in do_async(). Its only task is to - properly call the continuation function named above. - - * A worker function that is called inside the appropriate child process. - 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 @@ -37,423 +26,6 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND -struct do_async_state { - TALLOC_CTX *mem_ctx; - struct winbindd_request request; - struct winbindd_response response; - void (*cont)(TALLOC_CTX *mem_ctx, - bool success, - struct winbindd_response *response, - void *c, void *private_data); - void *c, *private_data; -}; - -static void do_async_recv(void *private_data, bool success) -{ - struct do_async_state *state = - talloc_get_type_abort(private_data, struct do_async_state); - - state->cont(state->mem_ctx, success, &state->response, - state->c, state->private_data); -} - -void do_async(TALLOC_CTX *mem_ctx, struct winbindd_child *child, - const struct winbindd_request *request, - void (*cont)(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data), - void *c, void *private_data) -{ - struct do_async_state *state; - - state = TALLOC_ZERO_P(mem_ctx, struct do_async_state); - if (state == NULL) { - DEBUG(0, ("talloc failed\n")); - cont(mem_ctx, False, NULL, c, private_data); - return; - } - - state->mem_ctx = mem_ctx; - state->request = *request; - state->request.length = sizeof(state->request); - state->cont = cont; - state->c = c; - state->private_data = private_data; - - async_request(mem_ctx, child, &state->request, - &state->response, do_async_recv, state); -} - -static void do_async_domain(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, - const struct winbindd_request *request, - void (*cont)(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data), - void *c, void *private_data) -{ - struct do_async_state *state; - - state = TALLOC_ZERO_P(mem_ctx, struct do_async_state); - if (state == NULL) { - DEBUG(0, ("talloc failed\n")); - cont(mem_ctx, False, NULL, c, private_data); - return; - } - - state->mem_ctx = mem_ctx; - state->request = *request; - state->request.length = sizeof(state->request); - state->cont = cont; - state->c = c; - state->private_data = private_data; - - async_domain_request(mem_ctx, domain, &state->request, - &state->response, do_async_recv, state); -} - -struct lookupsid_state { - DOM_SID sid; - void *caller_private_data; -}; - - -static void lookupsid_recv2(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, const char *dom_name, - const char *name, enum lsa_SidType type) = - (void (*)(void *, bool, const char *, const char *, - enum lsa_SidType))c; - struct lookupsid_state *s = talloc_get_type_abort(private_data, - struct lookupsid_state); - - if (!success) { - DEBUG(5, ("Could not trigger lookupsid\n")); - cont(s->caller_private_data, False, NULL, NULL, SID_NAME_UNKNOWN); - return; - } - - if (response->result != WINBINDD_OK) { - DEBUG(5, ("lookupsid (forest root) returned an error\n")); - cont(s->caller_private_data, False, NULL, NULL, SID_NAME_UNKNOWN); - return; - } - - cont(s->caller_private_data, True, response->data.name.dom_name, - response->data.name.name, - (enum lsa_SidType)response->data.name.type); -} - -static void lookupsid_recv(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, const char *dom_name, - const char *name, enum lsa_SidType type) = - (void (*)(void *, bool, const char *, const char *, - enum lsa_SidType))c; - struct lookupsid_state *s = talloc_get_type_abort(private_data, - struct lookupsid_state); - - if (!success) { - DEBUG(5, ("Could not trigger lookupsid\n")); - cont(s->caller_private_data, False, NULL, NULL, SID_NAME_UNKNOWN); - return; - } - - if (response->result != WINBINDD_OK) { - /* Try again using the forest root */ - struct winbindd_domain *root_domain = find_root_domain(); - struct winbindd_request request; - - if ( !root_domain ) { - DEBUG(5,("lookupsid_recv: unable to determine forest root\n")); - cont(s->caller_private_data, False, NULL, NULL, SID_NAME_UNKNOWN); - return; - } - - ZERO_STRUCT(request); - request.cmd = WINBINDD_LOOKUPSID; - sid_to_fstring(request.data.sid, &s->sid); - - do_async_domain(mem_ctx, root_domain, &request, lookupsid_recv2, - (void *)cont, s); - - return; - } - - cont(s->caller_private_data, True, response->data.name.dom_name, - response->data.name.name, - (enum lsa_SidType)response->data.name.type); -} - -void winbindd_lookupsid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - void (*cont)(void *private_data, bool success, - const char *dom_name, - const char *name, - enum lsa_SidType type), - void *private_data) -{ - struct winbindd_domain *domain; - struct winbindd_request request; - struct lookupsid_state *s; - - domain = find_lookup_domain_from_sid(sid); - if (domain == NULL) { - DEBUG(5, ("Could not find domain for sid %s\n", - sid_string_dbg(sid))); - cont(private_data, False, NULL, NULL, SID_NAME_UNKNOWN); - return; - } - - ZERO_STRUCT(request); - request.cmd = WINBINDD_LOOKUPSID; - sid_to_fstring(request.data.sid, sid); - - if ( (s = TALLOC_ZERO_P(mem_ctx, struct lookupsid_state)) == NULL ) { - DEBUG(0, ("winbindd_lookupsid_async: talloc failed\n")); - cont(private_data, False, NULL, NULL, SID_NAME_UNKNOWN); - return; - } - - sid_copy( &s->sid, sid ); - s->caller_private_data = private_data; - - do_async_domain(mem_ctx, domain, &request, lookupsid_recv, - (void *)cont, s); -} - -enum winbindd_result winbindd_dual_lookupsid(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - enum lsa_SidType type; - DOM_SID sid; - char *name; - char *dom_name; - - /* Ensure null termination */ - state->request->data.sid[sizeof(state->request->data.sid)-1]='\0'; - - DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid, - state->request->data.sid)); - - /* Lookup sid from PDC using lsa_lookup_sids() */ - - if (!string_to_sid(&sid, state->request->data.sid)) { - DEBUG(5, ("%s not a SID\n", state->request->data.sid)); - return WINBINDD_ERROR; - } - - /* Lookup the sid */ - - if (!winbindd_lookup_name_by_sid(state->mem_ctx, domain, &sid, - &dom_name, &name, &type)) - { - TALLOC_FREE(dom_name); - TALLOC_FREE(name); - return WINBINDD_ERROR; - } - - fstrcpy(state->response->data.name.dom_name, dom_name); - fstrcpy(state->response->data.name.name, name); - state->response->data.name.type = type; - - TALLOC_FREE(dom_name); - TALLOC_FREE(name); - return WINBINDD_OK; -} - -/******************************************************************** - This is the second callback after contacting the forest root -********************************************************************/ - -struct lookupname_state { - char *dom_name; - char *name; - void *caller_private_data; -}; - - -static void lookupname_recv2(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, const DOM_SID *sid, - enum lsa_SidType type) = - (void (*)(void *, bool, const DOM_SID *, enum lsa_SidType))c; - DOM_SID sid; - struct lookupname_state *s = talloc_get_type_abort( private_data, - struct lookupname_state ); - - if (!success) { - DEBUG(5, ("Could not trigger lookup_name\n")); - cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN); - return; - } - - if (response->result != WINBINDD_OK) { - DEBUG(5, ("lookup_name returned an error\n")); - cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN); - return; - } - - if (!string_to_sid(&sid, response->data.sid.sid)) { - DEBUG(0, ("Could not convert string %s to sid\n", - response->data.sid.sid)); - cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN); - return; - } - - cont(s->caller_private_data, True, &sid, - (enum lsa_SidType)response->data.sid.type); -} - -/******************************************************************** - This is the first callback after contacting our own domain -********************************************************************/ - -static void lookupname_recv(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, const DOM_SID *sid, - enum lsa_SidType type) = - (void (*)(void *, bool, const DOM_SID *, enum lsa_SidType))c; - DOM_SID sid; - struct lookupname_state *s = talloc_get_type_abort( private_data, - struct lookupname_state ); - - if (!success) { - DEBUG(5, ("lookupname_recv: lookup_name() failed!\n")); - cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN); - return; - } - - if (response->result != WINBINDD_OK) { - /* Try again using the forest root */ - struct winbindd_domain *root_domain = find_root_domain(); - struct winbindd_request request; - - if ( !root_domain ) { - DEBUG(5,("lookupname_recv: unable to determine forest root\n")); - cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN); - return; - } - - ZERO_STRUCT(request); - request.cmd = WINBINDD_LOOKUPNAME; - - fstrcpy( request.data.name.dom_name, s->dom_name ); - fstrcpy( request.data.name.name, s->name ); - - do_async_domain(mem_ctx, root_domain, &request, lookupname_recv2, - (void *)cont, s); - - return; - } - - if (!string_to_sid(&sid, response->data.sid.sid)) { - DEBUG(0, ("Could not convert string %s to sid\n", - response->data.sid.sid)); - cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN); - return; - } - - cont(s->caller_private_data, True, &sid, - (enum lsa_SidType)response->data.sid.type); -} - -/******************************************************************** - The lookup name call first contacts a DC in its own domain - and fallbacks to contact a DC if the forest in our domain doesn't - know the name. -********************************************************************/ - -void winbindd_lookupname_async(TALLOC_CTX *mem_ctx, - const char *dom_name, const char *name, - void (*cont)(void *private_data, bool success, - const DOM_SID *sid, - enum lsa_SidType type), - enum winbindd_cmd orig_cmd, - void *private_data) -{ - struct winbindd_request request; - struct winbindd_domain *domain; - struct lookupname_state *s; - - domain = find_lookup_domain_from_name(dom_name); - if (domain == NULL) { - DEBUG(5, ("Could not find domain for name '%s'\n", dom_name)); - cont(private_data, False, NULL, SID_NAME_UNKNOWN); - return; - } - - ZERO_STRUCT(request); - request.cmd = WINBINDD_LOOKUPNAME; - request.original_cmd = orig_cmd; - fstrcpy(request.data.name.dom_name, dom_name); - fstrcpy(request.data.name.name, name); - - if ( (s = TALLOC_ZERO_P(mem_ctx, struct lookupname_state)) == NULL ) { - DEBUG(0, ("winbindd_lookupname_async: talloc failed\n")); - cont(private_data, False, NULL, SID_NAME_UNKNOWN); - return; - } - - s->dom_name = talloc_strdup( s, dom_name ); - s->name = talloc_strdup( s, name ); - if (!s->dom_name || !s->name) { - cont(private_data, False, NULL, SID_NAME_UNKNOWN); - return; - } - - s->caller_private_data = private_data; - - do_async_domain(mem_ctx, domain, &request, lookupname_recv, - (void *)cont, s); -} - -enum winbindd_result winbindd_dual_lookupname(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - enum lsa_SidType type; - char *name_domain, *name_user; - DOM_SID sid; - char *p; - - /* Ensure null termination */ - state->request->data.name.dom_name[sizeof(state->request->data.name.dom_name)-1]='\0'; - - /* Ensure null termination */ - state->request->data.name.name[sizeof(state->request->data.name.name)-1]='\0'; - - /* cope with the name being a fully qualified name */ - p = strstr(state->request->data.name.name, lp_winbind_separator()); - if (p) { - *p = 0; - name_domain = state->request->data.name.name; - name_user = p+1; - } else { - name_domain = state->request->data.name.dom_name; - name_user = state->request->data.name.name; - } - - DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state->pid, - name_domain, lp_winbind_separator(), name_user)); - - /* Lookup name from DC using lsa_lookup_names() */ - if (!winbindd_lookup_sid_by_name(state->mem_ctx, state->request->original_cmd, domain, name_domain, - name_user, &sid, &type)) { - return WINBINDD_ERROR; - } - - sid_to_fstring(state->response->data.sid.sid, &sid); - state->response->data.sid.type = type; - - return WINBINDD_OK; -} - bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids, size_t num_sids, char **result, ssize_t *len) { @@ -514,127 +86,6 @@ bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr, return True; } -static void getsidaliases_recv(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, - DOM_SID *aliases, size_t num_aliases) = - (void (*)(void *, bool, DOM_SID *, size_t))c; - char *aliases_str; - DOM_SID *sids = NULL; - size_t num_sids = 0; - - if (!success) { - DEBUG(5, ("Could not trigger getsidaliases\n")); - cont(private_data, success, NULL, 0); - return; - } - - if (response->result != WINBINDD_OK) { - DEBUG(5, ("getsidaliases returned an error\n")); - cont(private_data, False, NULL, 0); - return; - } - - aliases_str = (char *)response->extra_data.data; - - if (aliases_str == NULL) { - DEBUG(10, ("getsidaliases return 0 SIDs\n")); - cont(private_data, True, NULL, 0); - return; - } - - if (!parse_sidlist(mem_ctx, aliases_str, &sids, &num_sids)) { - DEBUG(0, ("Could not parse sids\n")); - cont(private_data, False, NULL, 0); - return; - } - - cont(private_data, True, sids, num_sids); -} - -void winbindd_getsidaliases_async(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - const DOM_SID *sids, size_t num_sids, - void (*cont)(void *private_data, - bool success, - const DOM_SID *aliases, - size_t num_aliases), - void *private_data) -{ - struct winbindd_request request; - char *sidstr = NULL; - ssize_t len; - - if (num_sids == 0) { - cont(private_data, True, NULL, 0); - return; - } - - if (!print_sidlist(mem_ctx, sids, num_sids, &sidstr, &len)) { - cont(private_data, False, NULL, 0); - return; - } - - ZERO_STRUCT(request); - request.cmd = WINBINDD_DUAL_GETSIDALIASES; - request.extra_len = len; - request.extra_data.data = sidstr; - - do_async_domain(mem_ctx, domain, &request, getsidaliases_recv, - (void *)cont, private_data); -} - -static void query_user_recv(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, const char *acct_name, - const char *full_name, const char *homedir, - const char *shell, uint32 gid, uint32 group_rid) = - (void (*)(void *, bool, const char *, const char *, - const char *, const char *, uint32, uint32))c; - - if (!success) { - DEBUG(5, ("Could not trigger query_user\n")); - cont(private_data, False, NULL, NULL, NULL, NULL, -1, -1); - return; - } - - if (response->result != WINBINDD_OK) { - DEBUG(5, ("query_user returned an error\n")); - cont(private_data, False, NULL, NULL, NULL, NULL, -1, -1); - return; - } - - cont(private_data, True, response->data.user_info.acct_name, - response->data.user_info.full_name, - response->data.user_info.homedir, - response->data.user_info.shell, - response->data.user_info.primary_gid, - response->data.user_info.group_rid); -} - -void query_user_async(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, - const DOM_SID *sid, - void (*cont)(void *private_data, bool success, - const char *acct_name, - const char *full_name, - const char *homedir, - const char *shell, - gid_t gid, - uint32 group_rid), - void *private_data) -{ - struct winbindd_request request; - ZERO_STRUCT(request); - request.cmd = WINBINDD_DUAL_USERINFO; - sid_to_fstring(request.data.sid, sid); - do_async_domain(mem_ctx, domain, &request, query_user_recv, - (void *)cont, private_data); -} - enum winbindd_result winbindd_dual_ping(struct winbindd_domain *domain, struct winbindd_cli_state *state) { diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index c4bc936a5d..ddbd9d9d5b 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -514,7 +514,7 @@ static void refresh_sequence_number(struct winbindd_domain *domain, bool force) time_t t = time(NULL); unsigned cache_time = lp_winbind_cache_time(); - if ( IS_DOMAIN_OFFLINE(domain) ) { + if (is_domain_offline(domain)) { return; } @@ -2446,62 +2446,9 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) * Guenther */ static NTSTATUS trusted_domains(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *num_domains, - char ***names, - char ***alt_names, - DOM_SID **dom_sids) + struct netr_DomainTrustList *trusts) { - struct winbind_cache *cache = get_cache(domain); - struct cache_entry *centry = NULL; NTSTATUS status; - int i; - - if (!cache->tdb) - goto do_query; - - centry = wcache_fetch(cache, domain, "TRUSTDOMS/%s", domain->name); - - if (!centry) { - goto do_query; - } - - *num_domains = centry_uint32(centry); - - if (*num_domains) { - (*names) = TALLOC_ARRAY(mem_ctx, char *, *num_domains); - (*alt_names) = TALLOC_ARRAY(mem_ctx, char *, *num_domains); - (*dom_sids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_domains); - - if (! (*dom_sids) || ! (*names) || ! (*alt_names)) { - smb_panic_fn("trusted_domains out of memory"); - } - } else { - (*names) = NULL; - (*alt_names) = NULL; - (*dom_sids) = NULL; - } - - for (i=0; i<(*num_domains); i++) { - (*names)[i] = centry_string(centry, mem_ctx); - (*alt_names)[i] = centry_string(centry, mem_ctx); - if (!centry_sid(centry, &(*dom_sids)[i])) { - sid_copy(&(*dom_sids)[i], &global_sid_NULL); - } - } - - status = centry->status; - - DEBUG(10,("trusted_domains: [Cached] - cached info for domain %s (%d trusts) status: %s\n", - domain->name, *num_domains, nt_errstr(status) )); - - centry_free(centry); - return status; - -do_query: - (*num_domains) = 0; - (*dom_sids) = NULL; - (*names) = NULL; - (*alt_names) = NULL; /* Return status value returned by seq number check */ @@ -2511,8 +2458,7 @@ do_query: DEBUG(10,("trusted_domains: [Cached] - doing backend query for info for domain %s\n", domain->name )); - status = domain->backend->trusted_domains(domain, mem_ctx, num_domains, - names, alt_names, dom_sids); + status = domain->backend->trusted_domains(domain, mem_ctx, trusts); /* no trusts gives NT_STATUS_NO_MORE_ENTRIES resetting to NT_STATUS_OK * so that the generic centry handling still applies correctly - @@ -2521,33 +2467,6 @@ do_query: if (!NT_STATUS_IS_ERR(status)) { status = NT_STATUS_OK; } - - -#if 0 /* Disabled as we want the trust dom list to be managed by - the main parent and always to make the query. --jerry */ - - /* and save it */ - refresh_sequence_number(domain, false); - - centry = centry_start(domain, status); - if (!centry) - goto skip_save; - - centry_put_uint32(centry, *num_domains); - - for (i=0; i<(*num_domains); i++) { - centry_put_string(centry, (*names)[i]); - centry_put_string(centry, (*alt_names)[i]); - centry_put_sid(centry, &(*dom_sids)[i]); - } - - centry_end(centry, "TRUSTDOMS/%s", domain->name); - - centry_free(centry); - -skip_save: -#endif - return status; } @@ -3557,34 +3476,6 @@ static int validate_nss_na(TALLOC_CTX *mem_ctx, const char *keystr, return 0; } -static int validate_trustdoms(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf, - struct tdb_validation_status *state) -{ - struct cache_entry *centry = create_centry_validate(keystr, dbuf, state); - int32 num_domains, i; - - if (!centry) { - return 1; - } - - num_domains = centry_uint32(centry); - - for (i=0; i< num_domains; i++) { - DOM_SID sid; - (void)centry_string(centry, mem_ctx); - (void)centry_string(centry, mem_ctx); - (void)centry_sid(centry, &sid); - } - - centry_free(centry); - - if (!(state->success)) { - return 1; - } - DEBUG(10,("validate_trustdoms: %s ok\n", keystr)); - return 0; -} - static int validate_trustdomcache(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf, struct tdb_validation_status *state) @@ -3666,7 +3557,6 @@ struct key_val_struct { {"DR/", validate_dr}, {"DE/", validate_de}, {"NSS/PWINFO/", validate_pwinfo}, - {"TRUSTDOMS/", validate_trustdoms}, {"TRUSTDOMCACHE/", validate_trustdomcache}, {"NSS/NA/", validate_nss_na}, {"NSS/AN/", validate_nss_an}, @@ -4361,6 +4251,7 @@ static bool wcache_opnum_cacheable(uint32_t opnum) case NDR_WBINT_ALLOCATEGID: case NDR_WBINT_CHECKMACHINEACCOUNT: case NDR_WBINT_CHANGEMACHINEACCOUNT: + case NDR_WBINT_PINGDC: return false; } return true; @@ -4393,7 +4284,7 @@ bool wcache_fetch_ndr(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, goto fail; } - if (IS_DOMAIN_ONLINE(domain)) { + if (!is_domain_offline(domain)) { uint32_t entry_seqnum, dom_seqnum, last_check; if (!wcache_fetch_seqnum(domain->name, &dom_seqnum, diff --git a/source3/winbindd/winbindd_ccache_access.c b/source3/winbindd/winbindd_ccache_access.c index 86017e2215..921110a0be 100644 --- a/source3/winbindd/winbindd_ccache_access.c +++ b/source3/winbindd/winbindd_ccache_access.c @@ -6,23 +6,24 @@ Copyright (C) Robert O'Callahan 2006 Copyright (C) Jeremy Allison 2006 (minor fixes to fit into Samba and protect against integer wrap). - + 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 "winbindd.h" +#include "ntlmssp.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND @@ -49,7 +50,7 @@ static NTSTATUS do_ntlm_auth_with_hashes(const char *username, DATA_BLOB *auth_msg) { NTSTATUS status; - NTLMSSP_STATE *ntlmssp_state = NULL; + struct ntlmssp_state *ntlmssp_state = NULL; DATA_BLOB dummy_msg, reply; status = ntlmssp_client_start(&ntlmssp_state); @@ -77,7 +78,7 @@ static NTSTATUS do_ntlm_auth_with_hashes(const char *username, } status = ntlmssp_set_hashes(ntlmssp_state, lm_hash, nt_hash); - + if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not set hashes: %s\n", nt_errstr(status))); @@ -250,21 +251,15 @@ enum winbindd_result winbindd_dual_ccache_ntlm_auth(struct winbindd_domain *doma goto process_result; } - initial = data_blob(state->request->extra_data.data, initial_blob_len); - challenge = data_blob(state->request->extra_data.data + initial_blob_len, - state->request->data.ccache_ntlm_auth.challenge_blob_len); - - if (!initial.data || !challenge.data) { - result = NT_STATUS_NO_MEMORY; - } else { - result = do_ntlm_auth_with_hashes(name_user, name_domain, - entry->lm_hash, entry->nt_hash, - initial, challenge, &auth); - } - - data_blob_free(&initial); - data_blob_free(&challenge); + initial = data_blob_const(state->request->extra_data.data, + initial_blob_len); + challenge = data_blob_const( + state->request->extra_data.data + initial_blob_len, + state->request->data.ccache_ntlm_auth.challenge_blob_len); + result = do_ntlm_auth_with_hashes(name_user, name_domain, + entry->lm_hash, entry->nt_hash, + initial, challenge, &auth); if (!NT_STATUS_IS_OK(result)) { goto process_result; } diff --git a/source3/winbindd/winbindd_check_machine_acct.c b/source3/winbindd/winbindd_check_machine_acct.c index 610e9edfaa..33b6d9fba4 100644 --- a/source3/winbindd/winbindd_check_machine_acct.c +++ b/source3/winbindd/winbindd_check_machine_acct.c @@ -42,7 +42,7 @@ struct tevent_req *winbindd_check_machine_acct_send(TALLOC_CTX *mem_ctx, return NULL; } - if (request->domain_name[0] == '0') { + if (request->domain_name[0] == '\0') { /* preserve old behavior, when no domain name is given */ domain = find_our_domain(); } else { diff --git a/source3/winbindd/winbindd_domain.c b/source3/winbindd/winbindd_domain.c index ad3d6d7916..45da57e132 100644 --- a/source3/winbindd/winbindd_domain.c +++ b/source3/winbindd/winbindd_domain.c @@ -31,14 +31,6 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = { .struct_cmd = WINBINDD_PING, .struct_fn = winbindd_dual_ping, },{ - .name = "LOOKUPSID", - .struct_cmd = WINBINDD_LOOKUPSID, - .struct_fn = winbindd_dual_lookupsid, - },{ - .name = "LOOKUPNAME", - .struct_cmd = WINBINDD_LOOKUPNAME, - .struct_fn = winbindd_dual_lookupname, - },{ .name = "LIST_TRUSTDOM", .struct_cmd = WINBINDD_LIST_TRUSTDOM, .struct_fn = winbindd_dual_list_trusted_domains, @@ -47,10 +39,6 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = { .struct_cmd = WINBINDD_INIT_CONNECTION, .struct_fn = winbindd_dual_init_connection, },{ - .name = "GETDCNAME", - .struct_cmd = WINBINDD_GETDCNAME, - .struct_fn = winbindd_dual_getdcname, - },{ .name = "SHOW_SEQUENCE", .struct_cmd = WINBINDD_SHOW_SEQUENCE, .struct_fn = winbindd_dual_show_sequence, @@ -75,22 +63,6 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = { .struct_cmd = WINBINDD_PAM_CHAUTHTOK, .struct_fn = winbindd_dual_pam_chauthtok, },{ - .name = "DUAL_USERINFO", - .struct_cmd = WINBINDD_DUAL_USERINFO, - .struct_fn = winbindd_dual_userinfo, - },{ - .name = "GETUSERDOMGROUPS", - .struct_cmd = WINBINDD_GETUSERDOMGROUPS, - .struct_fn = winbindd_dual_getuserdomgroups, - },{ - .name = "GETSIDALIASES", - .struct_cmd = WINBINDD_DUAL_GETSIDALIASES, - .struct_fn = winbindd_dual_getsidaliases, - },{ - .name = "GETSIDALIASES", - .struct_cmd = WINBINDD_GETSIDALIASES, - .struct_fn = winbindd_dual_getsidaliases, - },{ .name = "CCACHE_NTLM_AUTH", .struct_cmd = WINBINDD_CCACHE_NTLMAUTH, .struct_fn = winbindd_dual_ccache_ntlm_auth, @@ -108,6 +80,4 @@ void setup_domain_child(struct winbindd_domain *domain, { setup_child(domain, child, domain_dispatch_table, "log.wb", domain->name); - - child->domain = domain; } diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index 376d7c7309..74b2b99b7f 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -367,85 +367,6 @@ int wb_domain_request_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, return 0; } -/* - * Machinery for async requests sent to children. You set up a - * winbindd_request, select a child to query, and issue a async_request - * call. When the request is completed, the callback function you specified is - * called back with the private pointer you gave to async_request. - */ - -struct winbindd_async_request { - struct winbindd_async_request *next, *prev; - TALLOC_CTX *mem_ctx; - struct winbindd_child *child; - struct winbindd_response *response; - void (*continuation)(void *private_data, bool success); - struct timed_event *reply_timeout_event; - pid_t child_pid; /* pid of the child we're waiting on. Used to detect - a restart of the child (child->pid != child_pid). */ - void *private_data; -}; - -static void async_request_done(struct tevent_req *req); - -void async_request(TALLOC_CTX *mem_ctx, struct winbindd_child *child, - struct winbindd_request *request, - struct winbindd_response *response, - void (*continuation)(void *private_data, bool success), - void *private_data) -{ - struct winbindd_async_request *state; - struct tevent_req *req; - - DEBUG(10, ("Sending request to child pid %d (domain=%s)\n", - (int)child->pid, - (child->domain != NULL) ? child->domain->name : "''")); - - state = talloc(mem_ctx, struct winbindd_async_request); - if (state == NULL) { - DEBUG(0, ("talloc failed\n")); - continuation(private_data, False); - return; - } - - state->mem_ctx = mem_ctx; - state->child = child; - state->reply_timeout_event = NULL; - state->response = response; - state->continuation = continuation; - state->private_data = private_data; - - request->pid = child->pid; - - req = wb_child_request_send(state, winbind_event_context(), - child, request); - if (req == NULL) { - DEBUG(0, ("wb_child_request_send failed\n")); - continuation(private_data, false); - return; - } - tevent_req_set_callback(req, async_request_done, state); -} - -static void async_request_done(struct tevent_req *req) -{ - struct winbindd_async_request *state = tevent_req_callback_data( - req, struct winbindd_async_request); - struct winbindd_response *response; - int ret, err; - - ret = wb_child_request_recv(req, state, &response, &err); - TALLOC_FREE(req); - if (ret == -1) { - DEBUG(2, ("wb_child_request_recv failed: %s\n", - strerror(err))); - state->continuation(state->private_data, false); - return; - } - *state->response = *response; - state->continuation(state->private_data, true); -} - struct domain_request_state { struct winbindd_domain *domain; struct winbindd_request *request; @@ -527,13 +448,6 @@ static void recvfrom_child(void *private_data_data, bool success) request_ok(state); } -void sendto_child(struct winbindd_cli_state *state, - struct winbindd_child *child) -{ - async_request(state->mem_ctx, child, state->request, - state->response, recvfrom_child, state); -} - void sendto_domain(struct winbindd_cli_state *state, struct winbindd_domain *domain) { @@ -588,7 +502,7 @@ void setup_child(struct winbindd_domain *domain, struct winbindd_child *child, "logname == NULL"); } - child->domain = NULL; + child->domain = domain; child->table = table; child->queue = tevent_queue_create(NULL, "winbind_child"); SMB_ASSERT(child->queue != NULL); @@ -696,7 +610,7 @@ void winbind_msg_offline(struct messaging_context *msg_ctx, } for (child = children; child != NULL; child = child->next) { - /* Don't send message to internal childs. We've already + /* Don't send message to internal children. We've already done so above. */ if (!child->domain || winbindd_internal_child(child)) { continue; @@ -830,7 +744,7 @@ void winbind_msg_onlinestatus(struct messaging_context *msg_ctx, TALLOC_CTX *mem_ctx; const char *message; struct server_id *sender; - + DEBUG(5,("winbind_msg_onlinestatus received.\n")); if (!data->data) { @@ -843,7 +757,7 @@ void winbind_msg_onlinestatus(struct messaging_context *msg_ctx, if (mem_ctx == NULL) { return; } - + message = collect_onlinestatus(mem_ctx); if (message == NULL) { talloc_destroy(mem_ctx); diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index cecbb61051..b247d5a233 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -510,6 +510,54 @@ again: return status; } +NTSTATUS _wbint_PingDc(pipes_struct *p, struct wbint_PingDc *r) +{ + NTSTATUS status; + struct winbindd_domain *domain; + struct rpc_pipe_client *netlogon_pipe; + union netr_CONTROL_QUERY_INFORMATION info; + WERROR werr; + fstring logon_server; + + domain = wb_child_domain(); + if (domain == NULL) { + return NT_STATUS_REQUEST_NOT_ACCEPTED; + } + + status = cm_connect_netlogon(domain, &netlogon_pipe); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("could not open handle to NETLOGON pipe\n")); + return status; + } + + fstr_sprintf(logon_server, "\\\\%s", domain->dcname); + + /* + * This provokes a WERR_NOT_SUPPORTED error message. This is + * documented in the wspp docs. I could not get a successful + * call to work, but the main point here is testing that the + * netlogon pipe works. + */ + status = rpccli_netr_LogonControl(netlogon_pipe, p->mem_ctx, + logon_server, NETLOGON_CONTROL_QUERY, + 2, &info, &werr); + + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + DEBUG(2, ("rpccli_netr_LogonControl timed out\n")); + invalidate_cm_connection(&domain->conn); + return status; + } + + if (!NT_STATUS_EQUAL(status, NT_STATUS_CTL_FILE_NOT_SUPPORTED)) { + DEBUG(2, ("rpccli_netr_LogonControl returned %s, expected " + "NT_STATUS_CTL_FILE_NOT_SUPPORTED\n", + nt_errstr(status))); + return status; + } + + DEBUG(5, ("winbindd_dual_ping_dc succeeded\n")); + return NT_STATUS_OK; +} NTSTATUS _wbint_SetMapping(pipes_struct *p, struct wbint_SetMapping *r) { diff --git a/source3/winbindd/winbindd_getgrnam.c b/source3/winbindd/winbindd_getgrnam.c index d888393399..3ca1aa6111 100644 --- a/source3/winbindd/winbindd_getgrnam.c +++ b/source3/winbindd/winbindd_getgrnam.c @@ -40,7 +40,6 @@ struct tevent_req *winbindd_getgrnam_send(TALLOC_CTX *mem_ctx, { struct tevent_req *req, *subreq; struct winbindd_getgrnam_state *state; - struct winbindd_domain *domain; char *tmp; NTSTATUS nt_status; @@ -77,27 +76,7 @@ struct tevent_req *winbindd_getgrnam_send(TALLOC_CTX *mem_ctx, fstrcpy(state->name_domain, get_global_sam_name()); } - /* Get info for the domain */ - - domain = find_domain_from_name_noinit(state->name_domain); - if (domain == NULL) { - DEBUG(3, ("could not get domain sid for domain %s\n", - state->name_domain)); - tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP); - return tevent_req_post(req, ev); - } - - /* should we deal with users for our domain? */ - - if ( lp_winbind_trusted_domains_only() && domain->primary) { - DEBUG(7,("winbindd_getgrnam: My domain -- rejecting " - "getgrnam() for %s\\%s.\n", state->name_domain, - state->name_group)); - tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP); - return tevent_req_post(req, ev); - } - - subreq = wb_lookupname_send(state, ev, domain->name, state->name_group, + subreq = wb_lookupname_send(state, ev, state->name_domain, state->name_group, 0); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); diff --git a/source3/winbindd/winbindd_getgroups.c b/source3/winbindd/winbindd_getgroups.c index 3bdf762c45..736eba698a 100644 --- a/source3/winbindd/winbindd_getgroups.c +++ b/source3/winbindd/winbindd_getgroups.c @@ -45,7 +45,6 @@ struct tevent_req *winbindd_getgroups_send(TALLOC_CTX *mem_ctx, struct tevent_req *req, *subreq; struct winbindd_getgroups_state *state; char *domuser, *mapped_user; - struct winbindd_domain *domain; NTSTATUS status; req = tevent_req_create(mem_ctx, &state, @@ -76,29 +75,6 @@ struct tevent_req *winbindd_getgroups_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - domain = find_domain_from_name_noinit(state->domname); - if (domain == NULL) { - /* Retry with DNS name */ - char *p = strchr(domuser, '@'); - if (p != NULL) { - domain = find_domain_from_name_noinit(p+1); - } - } - if (domain == NULL) { - DEBUG(7, ("could not find domain entry for domain %s\n", - state->domname)); - tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); - return tevent_req_post(req, ev); - } - - if (lp_winbind_trusted_domains_only() && domain->primary) { - DEBUG(7,("winbindd_getgroups: My domain -- " - "rejecting getgroups() for %s\\%s.\n", - state->domname, state->username)); - tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); - return tevent_req_post(req, ev); - } - subreq = wb_lookupname_send(state, ev, state->domname, state->username, LOOKUP_NAME_NO_NSS); if (tevent_req_nomem(subreq, req)) { diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c index eab5c26df4..a985fa254f 100644 --- a/source3/winbindd/winbindd_group.c +++ b/source3/winbindd/winbindd_group.c @@ -66,290 +66,6 @@ bool fill_grent(TALLOC_CTX *mem_ctx, struct winbindd_gr *gr, return True; } -/* Get the list of domain groups and domain aliases for a domain. We fill in - the sam_entries and num_sam_entries fields with domain group information. - Return True if some groups were returned, False otherwise. */ - -bool get_sam_group_entries(struct getent_state *ent) -{ - NTSTATUS status; - uint32 num_entries; - struct acct_info *name_list = NULL; - TALLOC_CTX *mem_ctx; - bool result = False; - struct acct_info *sam_grp_entries = NULL; - struct winbindd_domain *domain; - - if (ent->got_sam_entries) - return False; - - if (!(mem_ctx = talloc_init("get_sam_group_entries(%s)", - ent->domain_name))) { - DEBUG(1, ("get_sam_group_entries: " - "could not create talloc context!\n")); - return False; - } - - /* Free any existing group info */ - - SAFE_FREE(ent->sam_entries); - ent->num_sam_entries = 0; - ent->got_sam_entries = True; - - /* Enumerate domain groups */ - - num_entries = 0; - - if (!(domain = find_domain_from_name(ent->domain_name))) { - DEBUG(3, ("no such domain %s in get_sam_group_entries\n", - ent->domain_name)); - goto done; - } - - /* always get the domain global groups */ - - status = domain->methods->enum_dom_groups(domain, mem_ctx, &num_entries, - &sam_grp_entries); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("get_sam_group_entries: " - "could not enumerate domain groups! Error: %s\n", - nt_errstr(status))); - result = False; - goto done; - } - - /* Copy entries into return buffer */ - - if (num_entries) { - name_list = SMB_MALLOC_ARRAY(struct acct_info, num_entries); - if (!name_list) { - DEBUG(0,("get_sam_group_entries: Failed to malloc " - "memory for %d domain groups!\n", - num_entries)); - result = False; - goto done; - } - memcpy(name_list, sam_grp_entries, - num_entries * sizeof(struct acct_info)); - } - - ent->num_sam_entries = num_entries; - - /* get the domain local groups if we are a member of a native win2k - * domain and are not using LDAP to get the groups */ - - if ( ( lp_security() != SEC_ADS && domain->native_mode - && domain->primary) || domain->internal ) - { - DEBUG(4,("get_sam_group_entries: %s domain; " - "enumerating local groups as well\n", - domain->native_mode ? "Native Mode 2k": - "BUILTIN or local")); - - status = domain->methods->enum_local_groups(domain, mem_ctx, - &num_entries, - &sam_grp_entries); - - if ( !NT_STATUS_IS_OK(status) ) { - DEBUG(3,("get_sam_group_entries: " - "Failed to enumerate " - "domain local groups with error %s!\n", - nt_errstr(status))); - num_entries = 0; - } - else - DEBUG(4,("get_sam_group_entries: " - "Returned %d local groups\n", - num_entries)); - - /* Copy entries into return buffer */ - - if ( num_entries ) { - name_list = SMB_REALLOC_ARRAY(name_list, - struct acct_info, - ent->num_sam_entries+ - num_entries); - if (!name_list) { - DEBUG(0,("get_sam_group_entries: " - "Failed to realloc more memory " - "for %d local groups!\n", - num_entries)); - result = False; - goto done; - } - - memcpy(&name_list[ent->num_sam_entries], - sam_grp_entries, - num_entries * sizeof(struct acct_info)); - } - - ent->num_sam_entries += num_entries; - } - - - /* Fill in remaining fields */ - - ent->sam_entries = name_list; - ent->sam_entry_index = 0; - - result = (ent->num_sam_entries > 0); - - done: - talloc_destroy(mem_ctx); - - return result; -} - -/* Get user supplementary groups. This is much quicker than trying to - invert the groups database. We merge the groups from the gids and - other_sids info3 fields as trusted domain, universal group - memberships, and nested groups (win2k native mode only) are not - returned by the getgroups RPC call but are present in the info3. */ - -struct getgroups_state { - struct winbindd_cli_state *state; - struct winbindd_domain *domain; - char *domname; - char *username; - DOM_SID user_sid; - - const DOM_SID *token_sids; - size_t i, num_token_sids; - - gid_t *token_gids; - size_t num_token_gids; -}; - -enum winbindd_result winbindd_dual_getuserdomgroups(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - DOM_SID user_sid; - NTSTATUS status; - - char *sidstring; - ssize_t len; - DOM_SID *groups; - uint32 num_groups; - - /* Ensure null termination */ - state->request->data.sid[sizeof(state->request->data.sid)-1]='\0'; - - if (!string_to_sid(&user_sid, state->request->data.sid)) { - DEBUG(1, ("Could not get convert sid %s from string\n", - state->request->data.sid)); - return WINBINDD_ERROR; - } - - status = domain->methods->lookup_usergroups(domain, state->mem_ctx, - &user_sid, &num_groups, - &groups); - if (!NT_STATUS_IS_OK(status)) - return WINBINDD_ERROR; - - if (num_groups == 0) { - state->response->data.num_entries = 0; - state->response->extra_data.data = NULL; - return WINBINDD_OK; - } - - if (!print_sidlist(state->mem_ctx, - groups, num_groups, - &sidstring, &len)) { - DEBUG(0, ("talloc failed\n")); - return WINBINDD_ERROR; - } - - state->response->extra_data.data = sidstring; - state->response->length += len+1; - state->response->data.num_entries = num_groups; - - return WINBINDD_OK; -} - -enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - DOM_SID *sids = NULL; - size_t num_sids = 0; - char *sidstr = NULL; - ssize_t len; - size_t i; - uint32 num_aliases; - uint32 *alias_rids; - NTSTATUS result; - - DEBUG(3, ("[%5lu]: getsidaliases\n", (unsigned long)state->pid)); - - sidstr = state->request->extra_data.data; - if (sidstr == NULL) { - sidstr = talloc_strdup(state->mem_ctx, "\n"); /* No SID */ - if (!sidstr) { - DEBUG(0, ("Out of memory\n")); - return WINBINDD_ERROR; - } - } - - DEBUG(10, ("Sidlist: %s\n", sidstr)); - - if (!parse_sidlist(state->mem_ctx, sidstr, &sids, &num_sids)) { - DEBUG(0, ("Could not parse SID list: %s\n", sidstr)); - return WINBINDD_ERROR; - } - - num_aliases = 0; - alias_rids = NULL; - - result = domain->methods->lookup_useraliases(domain, - state->mem_ctx, - num_sids, sids, - &num_aliases, - &alias_rids); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(3, ("Could not lookup_useraliases: %s\n", - nt_errstr(result))); - return WINBINDD_ERROR; - } - - num_sids = 0; - sids = NULL; - sidstr = NULL; - - DEBUG(10, ("Got %d aliases\n", num_aliases)); - - for (i=0; i<num_aliases; i++) { - DOM_SID sid; - DEBUGADD(10, (" rid %d\n", alias_rids[i])); - sid_copy(&sid, &domain->sid); - sid_append_rid(&sid, alias_rids[i]); - result = add_sid_to_array(state->mem_ctx, &sid, &sids, - &num_sids); - if (!NT_STATUS_IS_OK(result)) { - return WINBINDD_ERROR; - } - } - - - if (!print_sidlist(state->mem_ctx, sids, num_sids, &sidstr, &len)) { - DEBUG(0, ("Could not print_sidlist\n")); - state->response->extra_data.data = NULL; - return WINBINDD_ERROR; - } - - state->response->extra_data.data = NULL; - - if (sidstr) { - state->response->extra_data.data = sidstr; - DEBUG(10, ("aliases_list: %s\n", - (char *)state->response->extra_data.data)); - state->response->length += len+1; - state->response->data.num_entries = num_sids; - } - - return WINBINDD_OK; -} - struct getgr_countmem { int num; size_t len; diff --git a/source3/winbindd/winbindd_idmap.c b/source3/winbindd/winbindd_idmap.c index 1d275014ce..028026087d 100644 --- a/source3/winbindd/winbindd_idmap.c +++ b/source3/winbindd/winbindd_idmap.c @@ -7,17 +7,6 @@ Copyright (C) Gerald Carter 2006 Copyright (C) Simo Sorce 2007 - The helpers always consist of three functions: - - * A request setup function that takes the necessary parameters together - with a continuation function that is to be called upon completion - - * A private continuation function that is internal only. This is to be - called by the lower-level functions in do_async(). Its only task is to - properly call the continuation function named above. - - * A worker function that is called inside the appropriate child process. - 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 @@ -45,322 +34,12 @@ struct winbindd_child *idmap_child(void) return &static_idmap_child; } -static void winbindd_sid2uid_recv(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, uid_t uid) = - (void (*)(void *, bool, uid_t))c; - - if (!success) { - DEBUG(5, ("Could not trigger sid2uid\n")); - cont(private_data, False, 0); - return; - } - - if (response->result != WINBINDD_OK) { - DEBUG(5, ("sid2uid returned an error\n")); - cont(private_data, False, 0); - return; - } - - cont(private_data, True, response->data.uid); -} - -void winbindd_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - void (*cont)(void *private_data, bool success, uid_t uid), - void *private_data) -{ - struct winbindd_request request; - struct winbindd_domain *domain; - - ZERO_STRUCT(request); - request.cmd = WINBINDD_DUAL_SID2UID; - - domain = find_domain_from_sid(sid); - - if (domain != NULL) { - DEBUG(10, ("winbindd_sid2uid_async found domain %s, " - "have_idmap_config = %d\n", domain->name, - (int)domain->have_idmap_config)); - - } - else { - DEBUG(10, ("winbindd_sid2uid_async did not find a domain for " - "%s\n", sid_string_dbg(sid))); - } - - if ((domain != NULL) && (domain->have_idmap_config)) { - fstrcpy(request.domain_name, domain->name); - } - - sid_to_fstring(request.data.dual_sid2id.sid, sid); - do_async(mem_ctx, idmap_child(), &request, winbindd_sid2uid_recv, - (void *)cont, private_data); -} - -enum winbindd_result winbindd_dual_sid2uid(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - DOM_SID sid; - NTSTATUS result; - - DEBUG(3, ("[%5lu]: sid to uid %s\n", (unsigned long)state->pid, - state->request->data.dual_sid2id.sid)); - - if (!string_to_sid(&sid, state->request->data.dual_sid2id.sid)) { - DEBUG(1, ("Could not get convert sid %s from string\n", - state->request->data.dual_sid2id.sid)); - return WINBINDD_ERROR; - } - - result = idmap_sid_to_uid(state->request->domain_name, &sid, - &state->response->data.uid); - - DEBUG(10, ("winbindd_dual_sid2uid: 0x%08x - %s - %u\n", - NT_STATUS_V(result), sid_string_dbg(&sid), - (unsigned int)state->response->data.uid)); - - return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; -} - -static void winbindd_sid2gid_recv(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, gid_t gid) = - (void (*)(void *, bool, gid_t))c; - - if (!success) { - DEBUG(5, ("Could not trigger sid2gid\n")); - cont(private_data, False, 0); - return; - } - - if (response->result != WINBINDD_OK) { - DEBUG(5, ("sid2gid returned an error\n")); - cont(private_data, False, 0); - return; - } - - cont(private_data, True, response->data.gid); -} - -void winbindd_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - void (*cont)(void *private_data, bool success, gid_t gid), - void *private_data) -{ - struct winbindd_request request; - struct winbindd_domain *domain; - - ZERO_STRUCT(request); - request.cmd = WINBINDD_DUAL_SID2GID; - - domain = find_domain_from_sid(sid); - if ((domain != NULL) && (domain->have_idmap_config)) { - fstrcpy(request.domain_name, domain->name); - } - - sid_to_fstring(request.data.dual_sid2id.sid, sid); - - DEBUG(7,("winbindd_sid2gid_async: Resolving %s to a gid\n", - request.data.dual_sid2id.sid)); - - do_async(mem_ctx, idmap_child(), &request, winbindd_sid2gid_recv, - (void *)cont, private_data); -} - -enum winbindd_result winbindd_dual_sid2gid(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - DOM_SID sid; - NTSTATUS result; - - DEBUG(3, ("[%5lu]: sid to gid %s\n", (unsigned long)state->pid, - state->request->data.dual_sid2id.sid)); - - if (!string_to_sid(&sid, state->request->data.dual_sid2id.sid)) { - DEBUG(1, ("Could not get convert sid %s from string\n", - state->request->data.dual_sid2id.sid)); - return WINBINDD_ERROR; - } - - /* Find gid for this sid and return it, possibly ask the slow remote idmap */ - - result = idmap_sid_to_gid(state->request->domain_name, &sid, - &state->response->data.gid); - - DEBUG(10, ("winbindd_dual_sid2gid: 0x%08x - %s - %u\n", - NT_STATUS_V(result), sid_string_dbg(&sid), - (unsigned int)state->response->data.gid)); - - return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; -} - -/* The following uid2sid/gid2sid functions has been contributed by - * Keith Reynolds <Keith.Reynolds@centrify.com> */ - -static void winbindd_uid2sid_recv(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, const char *sid) = - (void (*)(void *, bool, const char *))c; - - if (!success) { - DEBUG(5, ("Could not trigger uid2sid\n")); - cont(private_data, False, NULL); - return; - } - - if (response->result != WINBINDD_OK) { - DEBUG(5, ("uid2sid returned an error\n")); - cont(private_data, False, NULL); - return; - } - - cont(private_data, True, response->data.sid.sid); -} - -void winbindd_uid2sid_async(TALLOC_CTX *mem_ctx, uid_t uid, - void (*cont)(void *private_data, bool success, const char *sid), - void *private_data) -{ - struct winbindd_domain *domain; - struct winbindd_request request; - - ZERO_STRUCT(request); - request.cmd = WINBINDD_DUAL_UID2SID; - request.data.uid = uid; - - for (domain = domain_list(); domain != NULL; domain = domain->next) { - if (domain->have_idmap_config - && (uid >= domain->id_range_low) - && (uid <= domain->id_range_high)) { - fstrcpy(request.domain_name, domain->name); - } - } - - do_async(mem_ctx, idmap_child(), &request, winbindd_uid2sid_recv, - (void *)cont, private_data); -} - -enum winbindd_result winbindd_dual_uid2sid(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - DOM_SID sid; - NTSTATUS result; - - DEBUG(3,("[%5lu]: uid to sid %lu\n", - (unsigned long)state->pid, - (unsigned long) state->request->data.uid)); - - /* Find sid for this uid and return it, possibly ask the slow remote idmap */ - result = idmap_uid_to_sid(state->request->domain_name, &sid, - state->request->data.uid); - - if (NT_STATUS_IS_OK(result)) { - sid_to_fstring(state->response->data.sid.sid, &sid); - state->response->data.sid.type = SID_NAME_USER; - return WINBINDD_OK; - } - - return WINBINDD_ERROR; -} - -static void winbindd_gid2sid_recv(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, const char *sid) = - (void (*)(void *, bool, const char *))c; - - if (!success) { - DEBUG(5, ("Could not trigger gid2sid\n")); - cont(private_data, False, NULL); - return; - } - - if (response->result != WINBINDD_OK) { - DEBUG(5, ("gid2sid returned an error\n")); - cont(private_data, False, NULL); - return; - } - - cont(private_data, True, response->data.sid.sid); -} - -void winbindd_gid2sid_async(TALLOC_CTX *mem_ctx, gid_t gid, - void (*cont)(void *private_data, bool success, const char *sid), - void *private_data) -{ - struct winbindd_domain *domain; - struct winbindd_request request; - - ZERO_STRUCT(request); - request.cmd = WINBINDD_DUAL_GID2SID; - request.data.gid = gid; - - for (domain = domain_list(); domain != NULL; domain = domain->next) { - if (domain->have_idmap_config - && (gid >= domain->id_range_low) - && (gid <= domain->id_range_high)) { - fstrcpy(request.domain_name, domain->name); - } - } - - do_async(mem_ctx, idmap_child(), &request, winbindd_gid2sid_recv, - (void *)cont, private_data); -} - -enum winbindd_result winbindd_dual_gid2sid(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - DOM_SID sid; - NTSTATUS result; - - DEBUG(3,("[%5lu]: gid %lu to sid\n", - (unsigned long)state->pid, - (unsigned long) state->request->data.gid)); - - /* Find sid for this gid and return it, possibly ask the slow remote idmap */ - result = idmap_gid_to_sid(state->request->domain_name, &sid, - state->request->data.gid); - - if (NT_STATUS_IS_OK(result)) { - sid_to_fstring(state->response->data.sid.sid, &sid); - DEBUG(10, ("[%5lu]: retrieved sid: %s\n", - (unsigned long)state->pid, - state->response->data.sid.sid)); - state->response->data.sid.type = SID_NAME_DOM_GRP; - return WINBINDD_OK; - } - - return WINBINDD_ERROR; -} - static const struct winbindd_child_dispatch_table idmap_dispatch_table[] = { { .name = "PING", .struct_cmd = WINBINDD_PING, .struct_fn = winbindd_dual_ping, },{ - .name = "DUAL_SID2UID", - .struct_cmd = WINBINDD_DUAL_SID2UID, - .struct_fn = winbindd_dual_sid2uid, - },{ - .name = "DUAL_SID2GID", - .struct_cmd = WINBINDD_DUAL_SID2GID, - .struct_fn = winbindd_dual_sid2gid, - },{ - .name = "DUAL_UID2SID", - .struct_cmd = WINBINDD_DUAL_UID2SID, - .struct_fn = winbindd_dual_uid2sid, - },{ - .name = "DUAL_GID2SID", - .struct_cmd = WINBINDD_DUAL_GID2SID, - .struct_fn = winbindd_dual_gid2sid, - },{ .name = "NDRCMD", .struct_cmd = WINBINDD_DUAL_NDRCMD, .struct_fn = winbindd_dual_ndrcmd, diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 3ebd9ffdbd..ac8f1a7dfd 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -5,17 +5,17 @@ Copyright (C) Tim Potter 2000 Copyright (C) Andrew Bartlett 2002 - + 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/>. */ @@ -93,7 +93,7 @@ void winbindd_list_trusted_domains(struct winbindd_cli_state *state) int extra_data_len = 0; char *extra_data = NULL; int i = 0; - + DEBUG(3, ("[%5lu]: list trusted domains\n", (unsigned long)state->pid)); @@ -102,6 +102,12 @@ void winbindd_list_trusted_domains(struct winbindd_cli_state *state) goto done; } + extra_data = talloc_strdup(state->mem_ctx, ""); + if (extra_data == NULL) { + request_error(state); + goto done; + } + for ( i = 0; i < num_domains; i++ ) { struct winbindd_domain *domain; bool is_online = true; @@ -111,41 +117,27 @@ void winbindd_list_trusted_domains(struct winbindd_cli_state *state) if (domain) { is_online = domain->online; } - - if ( !extra_data ) { - extra_data = talloc_asprintf(state->mem_ctx, - "%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s", - d->domain_name, - d->dns_name ? d->dns_name : d->domain_name, - sid_string_talloc(state->mem_ctx, &d->sid), - get_trust_type_string(d), - trust_is_transitive(d) ? "Yes" : "No", - trust_is_inbound(d) ? "Yes" : "No", - trust_is_outbound(d) ? "Yes" : "No", - is_online ? "Online" : "Offline" ); - } else { - extra_data = talloc_asprintf(state->mem_ctx, - "%s\n%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s", - extra_data, - d->domain_name, - d->dns_name ? d->dns_name : d->domain_name, - sid_string_talloc(state->mem_ctx, &d->sid), - get_trust_type_string(d), - trust_is_transitive(d) ? "Yes" : "No", - trust_is_inbound(d) ? "Yes" : "No", - trust_is_outbound(d) ? "Yes" : "No", - is_online ? "Online" : "Offline" ); - } - } - - extra_data_len = 0; - if (extra_data != NULL) { - extra_data_len = strlen(extra_data); + extra_data = talloc_asprintf_append_buffer( + extra_data, + "%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s\n", + d->domain_name, + d->dns_name ? d->dns_name : d->domain_name, + sid_string_talloc(state->mem_ctx, &d->sid), + get_trust_type_string(d), + trust_is_transitive(d) ? "Yes" : "No", + trust_is_inbound(d) ? "Yes" : "No", + trust_is_outbound(d) ? "Yes" : "No", + is_online ? "Online" : "Offline" ); } + extra_data_len = strlen(extra_data); if (extra_data_len > 0) { + + /* Strip the last \n */ + extra_data[extra_data_len-1] = '\0'; + state->response->extra_data.data = extra_data; - state->response->length += extra_data_len+1; + state->response->length += extra_data_len; } request_ok(state); @@ -156,20 +148,18 @@ done: enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain *domain, struct winbindd_cli_state *state) { - uint32 i, num_domains; - char **names, **alt_names; - DOM_SID *sids; + int i; int extra_data_len = 0; char *extra_data; NTSTATUS result; bool have_own_domain = False; + struct netr_DomainTrustList trusts; DEBUG(3, ("[%5lu]: list trusted domains\n", (unsigned long)state->pid)); result = domain->methods->trusted_domains(domain, state->mem_ctx, - &num_domains, &names, - &alt_names, &sids); + &trusts); if (!NT_STATUS_IS_OK(result)) { DEBUG(3, ("winbindd_dual_list_trusted_domains: trusted_domains returned %s\n", @@ -179,45 +169,37 @@ enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain * extra_data = talloc_strdup(state->mem_ctx, ""); - if (num_domains > 0) - extra_data = talloc_asprintf( - state->mem_ctx, "%s\\%s\\%s", - names[0], alt_names[0] ? alt_names[0] : names[0], - sid_string_talloc(state->mem_ctx, &sids[0])); - - for (i=1; i<num_domains; i++) - extra_data = talloc_asprintf( - state->mem_ctx, "%s\n%s\\%s\\%s", - extra_data, names[i], - alt_names[i] ? alt_names[i] : names[i], - sid_string_talloc(state->mem_ctx, &sids[i])); + for (i=0; i<trusts.count; i++) { + extra_data = talloc_asprintf_append_buffer( + extra_data, "%s\\%s\\%s\n", + trusts.array[i].netbios_name, + trusts.array[i].dns_name, + sid_string_talloc(state->mem_ctx, + trusts.array[i].sid)); + } /* add our primary domain */ - - for (i=0; i<num_domains; i++) { - if (strequal(names[i], domain->name)) { + + for (i=0; i<trusts.count; i++) { + if (strequal(trusts.array[i].netbios_name, domain->name)) { have_own_domain = True; break; } } if (state->request->data.list_all_domains && !have_own_domain) { - extra_data = talloc_asprintf( - state->mem_ctx, "%s\n%s\\%s\\%s", - extra_data, domain->name, + extra_data = talloc_asprintf_append_buffer( + extra_data, "%s\\%s\\%s\n", domain->name, domain->alt_name ? domain->alt_name : domain->name, sid_string_talloc(state->mem_ctx, &domain->sid)); } - /* This is a bit excessive, but the extra data sooner or later will be - talloc'ed */ + extra_data_len = strlen(extra_data); + if (extra_data_len > 0) { - extra_data_len = 0; - if (extra_data != NULL) { - extra_data_len = strlen(extra_data); - } + /* Strip the last \n */ + extra_data[extra_data_len-1] = '\0'; - if (extra_data_len > 0) { state->response->extra_data.data = extra_data; state->response->length += extra_data_len+1; } @@ -225,78 +207,6 @@ enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain * return WINBINDD_OK; } -enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - const char *dcname_slash = NULL; - const char *p; - struct rpc_pipe_client *netlogon_pipe; - NTSTATUS result; - WERROR werr; - unsigned int orig_timeout; - struct winbindd_domain *req_domain; - - state->request->domain_name - [sizeof(state->request->domain_name)-1] = '\0'; - - DEBUG(3, ("[%5lu]: Get DC name for %s\n", (unsigned long)state->pid, - state->request->domain_name)); - - result = cm_connect_netlogon(domain, &netlogon_pipe); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(1, ("Can't contact the NETLOGON pipe\n")); - return WINBINDD_ERROR; - } - - /* This call can take a long time - allow the server to time out. - 35 seconds should do it. */ - - orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000); - - req_domain = find_domain_from_name_noinit(state->request->domain_name); - if (req_domain == domain) { - result = rpccli_netr_GetDcName(netlogon_pipe, - state->mem_ctx, - domain->dcname, - state->request->domain_name, - &dcname_slash, - &werr); - } else { - result = rpccli_netr_GetAnyDCName(netlogon_pipe, - state->mem_ctx, - domain->dcname, - state->request->domain_name, - &dcname_slash, - &werr); - } - /* And restore our original timeout. */ - rpccli_set_timeout(netlogon_pipe, orig_timeout); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(5,("Error requesting DCname for domain %s: %s\n", - state->request->domain_name, nt_errstr(result))); - return WINBINDD_ERROR; - } - - if (!W_ERROR_IS_OK(werr)) { - DEBUG(5, ("Error requesting DCname for domain %s: %s\n", - state->request->domain_name, win_errstr(werr))); - return WINBINDD_ERROR; - } - - p = dcname_slash; - if (*p == '\\') { - p+=1; - } - if (*p == '\\') { - p+=1; - } - - fstrcpy(state->response->data.dc_name, p); - return WINBINDD_OK; -} - /* This is the child-only version of --sequence. It only allows for a single * domain (ie "our" one) to be displayed. */ @@ -440,7 +350,7 @@ void winbindd_interface_version(struct winbindd_cli_state *state) { DEBUG(3, ("[%5lu]: request interface version\n", (unsigned long)state->pid)); - + state->response->data.interface_version = WINBIND_INTERFACE_VERSION; request_ok(state); } @@ -450,7 +360,7 @@ void winbindd_interface_version(struct winbindd_cli_state *state) void winbindd_domain_name(struct winbindd_cli_state *state) { DEBUG(3, ("[%5lu]: request domain name\n", (unsigned long)state->pid)); - + fstrcpy(state->response->data.domain_name, lp_workgroup()); request_ok(state); } @@ -461,7 +371,7 @@ void winbindd_netbios_name(struct winbindd_cli_state *state) { DEBUG(3, ("[%5lu]: request netbios name\n", (unsigned long)state->pid)); - + fstrcpy(state->response->data.netbios_name, global_myname()); request_ok(state); } @@ -473,7 +383,7 @@ void winbindd_priv_pipe_dir(struct winbindd_cli_state *state) char *priv_dir; DEBUG(3, ("[%5lu]: request location of privileged pipe\n", (unsigned long)state->pid)); - + priv_dir = get_winbind_priv_pipe_dir(); state->response->extra_data.data = talloc_move(state->mem_ctx, &priv_dir); diff --git a/source3/winbindd/winbindd_passdb.c b/source3/winbindd/winbindd_passdb.c index c23f87dcd5..34b5990a3f 100644 --- a/source3/winbindd/winbindd_passdb.c +++ b/source3/winbindd/winbindd_passdb.c @@ -398,16 +398,10 @@ static NTSTATUS builtin_query_user(struct winbindd_domain *domain, /* get a list of trusted domains - builtin domain */ static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - uint32 *num_domains, - char ***names, - char ***alt_names, - DOM_SID **dom_sids) + TALLOC_CTX *mem_ctx, + struct netr_DomainTrustList *trusts) { - *num_domains = 0; - *names = NULL; - *alt_names = NULL; - *dom_sids = NULL; + ZERO_STRUCTP(trusts); return NT_STATUS_OK; } @@ -649,58 +643,44 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain, /* get a list of trusted domains */ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - uint32 *num_domains, - char ***names, - char ***alt_names, - DOM_SID **dom_sids) + TALLOC_CTX *mem_ctx, + struct netr_DomainTrustList *trusts) { NTSTATUS nt_status; struct trustdom_info **domains; int i; - TALLOC_CTX *tmp_ctx; - - *num_domains = 0; - *names = NULL; - *alt_names = NULL; - *dom_sids = NULL; - - if (!(tmp_ctx = talloc_init("trusted_domains"))) { - return NT_STATUS_NO_MEMORY; - } - nt_status = pdb_enum_trusteddoms(tmp_ctx, num_domains, &domains); + nt_status = pdb_enum_trusteddoms(talloc_tos(), &trusts->count, + &domains); if (!NT_STATUS_IS_OK(nt_status)) { - TALLOC_FREE(tmp_ctx); return nt_status; } - if (*num_domains) { - *names = TALLOC_ARRAY(mem_ctx, char *, *num_domains); - *alt_names = TALLOC_ARRAY(mem_ctx, char *, *num_domains); - *dom_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_domains); + if (trusts->count == 0) { + trusts->array = NULL; + return NT_STATUS_OK; + } - if ((*alt_names == NULL) || (*names == NULL) || (*dom_sids == NULL)) { - TALLOC_FREE(tmp_ctx); - return NT_STATUS_NO_MEMORY; - } - } else { - *names = NULL; - *alt_names = NULL; - *dom_sids = NULL; + trusts->array = talloc_zero_array( + mem_ctx, struct netr_DomainTrust, trusts->count); + if (trusts->array == NULL) { + return NT_STATUS_NO_MEMORY; } - for (i=0; i<*num_domains; i++) { - (*alt_names)[i] = NULL; - if (!((*names)[i] = talloc_strdup((*names), - domains[i]->name))) { - TALLOC_FREE(tmp_ctx); + for (i=0; i<trusts->count; i++) { + struct dom_sid *sid; + + trusts->array[i].netbios_name = talloc_move( + trusts->array, &domains[i]->name); + trusts->array[i].dns_name = NULL; + + sid = talloc(trusts->array, struct dom_sid); + if (sid == NULL) { return NT_STATUS_NO_MEMORY; } - sid_copy(&(*dom_sids)[i], &domains[i]->sid); + sid_copy(sid, &domains[i]->sid); + trusts->array[i].sid = sid; } - - TALLOC_FREE(tmp_ctx); return NT_STATUS_OK; } diff --git a/source3/winbindd/winbindd_ping_dc.c b/source3/winbindd/winbindd_ping_dc.c new file mode 100644 index 0000000000..e06e5896c2 --- /dev/null +++ b/source3/winbindd/winbindd_ping_dc.c @@ -0,0 +1,96 @@ +/* + Unix SMB/CIFS implementation. + async implementation of WINBINDD_PING_DC + Copyright (C) Volker Lendecke 2009 + + 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 "winbindd.h" +#include "librpc/gen_ndr/cli_wbint.h" + +struct winbindd_ping_dc_state { + uint8_t dummy; +}; + +static void winbindd_ping_dc_done(struct tevent_req *subreq); + +struct tevent_req *winbindd_ping_dc_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct winbindd_cli_state *cli, + struct winbindd_request *request) +{ + struct tevent_req *req, *subreq; + struct winbindd_ping_dc_state *state; + struct winbindd_domain *domain; + + req = tevent_req_create(mem_ctx, &state, + struct winbindd_ping_dc_state); + if (req == NULL) { + return NULL; + } + + if (request->domain_name[0] == '\0') { + /* preserve old behavior, when no domain name is given */ + domain = find_our_domain(); + } else { + domain = find_domain_from_name(request->domain_name); + } + if (domain == NULL) { + tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN); + return tevent_req_post(req, ev); + } + if (domain->internal) { + /* + * Internal domains are passdb based, we can always + * contact them. + */ + tevent_req_done(req); + return tevent_req_post(req, ev); + } + + subreq = rpccli_wbint_PingDc_send(state, ev, domain->child.rpccli); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, winbindd_ping_dc_done, req); + return req; +} + +static void winbindd_ping_dc_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct winbindd_ping_dc_state *state = tevent_req_data( + req, struct winbindd_ping_dc_state); + NTSTATUS status, result; + + status = rpccli_wbint_PingDc_recv(subreq, state, &result); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + if (!NT_STATUS_IS_OK(result)) { + tevent_req_nterror(req, result); + return; + } + tevent_req_done(req); +} + +NTSTATUS winbindd_ping_dc_recv(struct tevent_req *req, + struct winbindd_response *presp) +{ + return tevent_req_simple_recv_ntstatus(req); +} diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 6e232c9db8..93d5748c49 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -82,62 +82,10 @@ NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx, /* The following definitions come from winbindd/winbindd_async.c */ -void do_async(TALLOC_CTX *mem_ctx, struct winbindd_child *child, - const struct winbindd_request *request, - void (*cont)(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data), - void *c, void *private_data); -void winbindd_lookupsid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - void (*cont)(void *private_data, bool success, - const char *dom_name, - const char *name, - enum lsa_SidType type), - void *private_data); -enum winbindd_result winbindd_dual_lookupsid(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_lookupname_async(TALLOC_CTX *mem_ctx, - const char *dom_name, const char *name, - void (*cont)(void *private_data, bool success, - const DOM_SID *sid, - enum lsa_SidType type), - enum winbindd_cmd orig_cmd, - void *private_data); -enum winbindd_result winbindd_dual_lookupname(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_listent_async(TALLOC_CTX *mem_ctx, - struct winbindd_domain *domain, - void (*cont)(void *private_data, bool success, - fstring dom_name, char* extra_data), - void *private_data, enum ent_type type); -enum winbindd_result winbindd_dual_list_users(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -enum winbindd_result winbindd_dual_list_groups(struct winbindd_domain *domain, - struct winbindd_cli_state *state); bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids, size_t num_sids, char **result, ssize_t *len); bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr, DOM_SID **sids, size_t *num_sids); -void winbindd_getsidaliases_async(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - const DOM_SID *sids, size_t num_sids, - void (*cont)(void *private_data, - bool success, - const DOM_SID *aliases, - size_t num_aliases), - void *private_data); -enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void query_user_async(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, - const DOM_SID *sid, - void (*cont)(void *private_data, bool success, - const char *acct_name, - const char *full_name, - const char *homedir, - const char *shell, - gid_t gid, - uint32 group_rid), - void *private_data); /* The following definitions come from winbindd/winbindd_cache.c */ @@ -328,19 +276,12 @@ struct tevent_req *wb_domain_request_send(TALLOC_CTX *mem_ctx, int wb_domain_request_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct winbindd_response **presponse, int *err); -void async_request(TALLOC_CTX *mem_ctx, struct winbindd_child *child, - struct winbindd_request *request, - struct winbindd_response *response, - void (*continuation)(void *private_data, bool success), - void *private_data); void async_domain_request(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, struct winbindd_request *request, struct winbindd_response *response, void (*continuation)(void *private_data_data, bool success), void *private_data_data); -void sendto_child(struct winbindd_cli_state *state, - struct winbindd_child *child); void sendto_domain(struct winbindd_cli_state *state, struct winbindd_domain *domain); void setup_child(struct winbindd_domain *domain, struct winbindd_child *child, @@ -394,9 +335,6 @@ void winbindd_getgroups(struct winbindd_cli_state *state); void winbindd_getusersids(struct winbindd_cli_state *state); void winbindd_getuserdomgroups(struct winbindd_cli_state *state); void winbindd_getsidaliases(struct winbindd_cli_state *state); -enum winbindd_result winbindd_dual_getuserdomgroups(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -bool get_sam_group_entries(struct getent_state *ent); bool fill_grent(TALLOC_CTX *mem_ctx, struct winbindd_gr *gr, const char *dom_name, const char *gr_name, gid_t unix_gid); NTSTATUS winbindd_print_groupmembers(struct talloc_dict *members, @@ -408,64 +346,17 @@ NTSTATUS winbindd_print_groupmembers(struct talloc_dict *members, void init_idmap_child(void); struct winbindd_child *idmap_child(void); -void winbindd_set_mapping_async(TALLOC_CTX *mem_ctx, const struct id_map *map, - void (*cont)(void *private_data, bool success), - void *private_data); -enum winbindd_result winbindd_dual_set_mapping(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_remove_mapping_async(TALLOC_CTX *mem_ctx, const struct id_map *map, - void (*cont)(void *private_data, bool success), - void *private_data); -enum winbindd_result winbindd_dual_remove_mapping(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_set_hwm_async(TALLOC_CTX *mem_ctx, const struct unixid *xid, - void (*cont)(void *private_data, bool success), - void *private_data); -enum winbindd_result winbindd_dual_set_hwm(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_sids2xids_async(TALLOC_CTX *mem_ctx, void *sids, int size, - void (*cont)(void *private_data, bool success, void *data, int len), - void *private_data); -enum winbindd_result winbindd_dual_sids2xids(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - void (*cont)(void *private_data, bool success, uid_t uid), - void *private_data); -enum winbindd_result winbindd_dual_sid2uid(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - void (*cont)(void *private_data, bool success, gid_t gid), - void *private_data); -enum winbindd_result winbindd_dual_sid2gid(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_uid2sid_async(TALLOC_CTX *mem_ctx, uid_t uid, - void (*cont)(void *private_data, bool success, const char *sid), - void *private_data); -enum winbindd_result winbindd_dual_uid2sid(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_gid2sid_async(TALLOC_CTX *mem_ctx, gid_t gid, - void (*cont)(void *private_data, bool success, const char *sid), - void *private_data); -enum winbindd_result winbindd_dual_gid2sid(struct winbindd_domain *domain, - struct winbindd_cli_state *state); /* The following definitions come from winbindd/winbindd_locator.c */ void init_locator_child(void); struct winbindd_child *locator_child(void); -void winbindd_dsgetdcname(struct winbindd_cli_state *state); /* The following definitions come from winbindd/winbindd_misc.c */ -void winbindd_check_machine_acct(struct winbindd_cli_state *state); -enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_list_ent(struct winbindd_cli_state *state, enum ent_type type); void winbindd_list_trusted_domains(struct winbindd_cli_state *state); enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain *domain, struct winbindd_cli_state *state); -enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, - struct winbindd_cli_state *state); void winbindd_show_sequence(struct winbindd_cli_state *state); enum winbindd_result winbindd_dual_show_sequence(struct winbindd_domain *domain, struct winbindd_cli_state *state); @@ -518,47 +409,10 @@ enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain, void winbindd_pam_chng_pswd_auth_crap(struct winbindd_cli_state *state); enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domain *domainSt, struct winbindd_cli_state *state); -/* The following definitions come from winbindd/winbindd_passdb.c */ - - -/* The following definitions come from winbindd/winbindd_reconnect.c */ - - -/* The following definitions come from winbindd/winbindd_sid.c */ - -void winbindd_lookupsid(struct winbindd_cli_state *state); -void winbindd_lookupname(struct winbindd_cli_state *state); -void winbindd_lookuprids(struct winbindd_cli_state *state); -void winbindd_sid_to_uid(struct winbindd_cli_state *state); -void winbindd_sid_to_gid(struct winbindd_cli_state *state); -void winbindd_set_mapping(struct winbindd_cli_state *state); -void winbindd_remove_mapping(struct winbindd_cli_state *state); -void winbindd_set_hwm(struct winbindd_cli_state *state); -void winbindd_uid_to_sid(struct winbindd_cli_state *state); -void winbindd_gid_to_sid(struct winbindd_cli_state *state); -void winbindd_allocate_uid(struct winbindd_cli_state *state); -enum winbindd_result winbindd_dual_allocate_uid(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_allocate_gid(struct winbindd_cli_state *state); -enum winbindd_result winbindd_dual_allocate_gid(struct winbindd_domain *domain, - struct winbindd_cli_state *state); - -/* The following definitions come from winbindd/winbindd_user.c */ - -enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_getpwnam(struct winbindd_cli_state *state); -void winbindd_getpwuid(struct winbindd_cli_state *state); -void winbindd_getpwsid(struct winbindd_cli_state *state); -void winbindd_setpwent(struct winbindd_cli_state *state); -void winbindd_endpwent(struct winbindd_cli_state *state); -void winbindd_getpwent(struct winbindd_cli_state *state); -void winbindd_list_users(struct winbindd_cli_state *state); - /* The following definitions come from winbindd/winbindd_util.c */ struct winbindd_domain *domain_list(void); -void free_domain_list(void); +bool domain_is_forest_root(const struct winbindd_domain *domain); void rescan_trusted_domains(struct tevent_context *ev, struct tevent_timer *te, struct timeval now, void *private_data); enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domain, @@ -574,19 +428,6 @@ struct winbindd_domain *find_root_domain(void); struct winbindd_domain *find_builtin_domain(void); struct winbindd_domain *find_lookup_domain_from_sid(const DOM_SID *sid); struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name); -bool winbindd_lookup_sid_by_name(TALLOC_CTX *mem_ctx, - enum winbindd_cmd orig_cmd, - struct winbindd_domain *domain, - const char *domain_name, - const char *name, DOM_SID *sid, - enum lsa_SidType *type); -bool winbindd_lookup_name_by_sid(TALLOC_CTX *mem_ctx, - struct winbindd_domain *domain, - DOM_SID *sid, - char **dom_name, - char **name, - enum lsa_SidType *type); -void free_getent_state(struct getent_state *state); bool parse_domain_user(const char *domuser, fstring domain, fstring user); bool parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser, char **domain, char **user); @@ -633,6 +474,7 @@ void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain); void winbindd_set_locator_kdc_envs(const struct winbindd_domain *domain); void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain); void set_auth_errors(struct winbindd_response *resp, NTSTATUS result); +bool is_domain_offline(const struct winbindd_domain *domain); /* The following definitions come from winbindd/winbindd_wins.c */ @@ -987,6 +829,13 @@ struct tevent_req *winbindd_check_machine_acct_send(TALLOC_CTX *mem_ctx, NTSTATUS winbindd_check_machine_acct_recv(struct tevent_req *req, struct winbindd_response *presp); +struct tevent_req *winbindd_ping_dc_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct winbindd_cli_state *cli, + struct winbindd_request *request); +NTSTATUS winbindd_ping_dc_recv(struct tevent_req *req, + struct winbindd_response *presp); + struct tevent_req *winbindd_change_machine_acct_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct winbindd_cli_state *cli, diff --git a/source3/winbindd/winbindd_reconnect.c b/source3/winbindd/winbindd_reconnect.c index 3efd4a9428..bf6e577f29 100644 --- a/source3/winbindd/winbindd_reconnect.c +++ b/source3/winbindd/winbindd_reconnect.c @@ -279,21 +279,15 @@ static NTSTATUS password_policy(struct winbindd_domain *domain, /* get a list of trusted domains */ static NTSTATUS trusted_domains(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *num_domains, - char ***names, - char ***alt_names, - DOM_SID **dom_sids) + struct netr_DomainTrustList *trusts) { NTSTATUS result; - result = msrpc_methods.trusted_domains(domain, mem_ctx, - num_domains, names, - alt_names, dom_sids); + result = msrpc_methods.trusted_domains(domain, mem_ctx, trusts); if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) result = msrpc_methods.trusted_domains(domain, mem_ctx, - num_domains, names, - alt_names, dom_sids); + trusts); return result; } diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c index 1018a2952b..e7003766d8 100644 --- a/source3/winbindd/winbindd_rpc.c +++ b/source3/winbindd/winbindd_rpc.c @@ -787,16 +787,16 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, if (!NT_STATUS_IS_OK(result)) return result; - *num_names = rids->count; - rid_mem = rids->rids; - - if (!*num_names) { + if (!rids || !rids->count) { names = NULL; name_types = NULL; sid_mem = NULL; return NT_STATUS_OK; } + *num_names = rids->count; + rid_mem = rids->rids; + /* Step #2: Convert list of rids into list of usernames. Do this in bunches of ~1000 to avoid crashing NT4. It looks like there is a buffer overflow or something like that lurking around @@ -1032,10 +1032,7 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) /* get a list of trusted domains */ static NTSTATUS trusted_domains(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *num_domains, - char ***names, - char ***alt_names, - DOM_SID **dom_sids) + struct netr_DomainTrustList *trusts) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 enum_ctx = 0; @@ -1044,10 +1041,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, DEBUG(3,("rpc: trusted_domains\n")); - *num_domains = 0; - *names = NULL; - *alt_names = NULL; - *dom_sids = NULL; + ZERO_STRUCTP(trusts); result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); if (!NT_STATUS_IS_OK(result)) @@ -1070,22 +1064,33 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) break; - start_idx = *num_domains; - *num_domains += dom_list.count; - *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names, - char *, *num_domains); - *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids, - DOM_SID, *num_domains); - *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names, - char *, *num_domains); - if ((*names == NULL) || (*dom_sids == NULL) || - (*alt_names == NULL)) + start_idx = trusts->count; + trusts->count += dom_list.count; + + trusts->array = talloc_realloc( + mem_ctx, trusts->array, struct netr_DomainTrust, + trusts->count); + if (trusts->array == NULL) { return NT_STATUS_NO_MEMORY; + } for (i=0; i<dom_list.count; i++) { - (*names)[start_idx+i] = CONST_DISCARD(char *, dom_list.domains[i].name.string); - (*dom_sids)[start_idx+i] = *dom_list.domains[i].sid; - (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, ""); + struct netr_DomainTrust *trust = &trusts->array[i]; + struct dom_sid *sid; + + ZERO_STRUCTP(trust); + + trust->netbios_name = talloc_move( + trusts->array, + &dom_list.domains[i].name.string); + trust->dns_name = NULL; + + sid = talloc(trusts->array, struct dom_sid); + if (sid == NULL) { + return NT_STATUS_NO_MEMORY; + } + sid_copy(sid, dom_list.domains[i].sid); + trust->sid = sid; } } return result; @@ -1258,7 +1263,7 @@ NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx, NTSTATUS status; struct rpc_pipe_client *cli = NULL; struct policy_handle lsa_policy; - unsigned int orig_timeout; + unsigned int orig_timeout = 0; lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names; if (domain->can_do_ncacn_ip_tcp) { diff --git a/source3/winbindd/winbindd_user.c b/source3/winbindd/winbindd_user.c deleted file mode 100644 index 6afa941b7f..0000000000 --- a/source3/winbindd/winbindd_user.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Winbind daemon - user related functions - - Copyright (C) Tim Potter 2000 - Copyright (C) Jeremy Allison 2001. - Copyright (C) Gerald (Jerry) Carter 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" -#include "winbindd.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_WINBIND - -/* Wrapper for domain->methods->query_user, only on the parent->child pipe */ - -enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - DOM_SID sid; - struct wbint_userinfo user_info; - NTSTATUS status; - - /* Ensure null termination */ - state->request->data.sid[sizeof(state->request->data.sid)-1]='\0'; - - DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid, - state->request->data.sid)); - - if (!string_to_sid(&sid, state->request->data.sid)) { - DEBUG(5, ("%s not a SID\n", state->request->data.sid)); - return WINBINDD_ERROR; - } - - status = domain->methods->query_user(domain, state->mem_ctx, - &sid, &user_info); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("error getting user info for sid %s\n", - sid_string_dbg(&sid))); - return WINBINDD_ERROR; - } - - fstrcpy(state->response->data.user_info.acct_name, - user_info.acct_name); - fstrcpy(state->response->data.user_info.full_name, - user_info.full_name); - fstrcpy(state->response->data.user_info.homedir, user_info.homedir); - fstrcpy(state->response->data.user_info.shell, user_info.shell); - state->response->data.user_info.primary_gid = user_info.primary_gid; - if (!sid_peek_check_rid(&domain->sid, &user_info.group_sid, - &state->response->data.user_info.group_rid)) { - DEBUG(1, ("Could not extract group rid out of %s\n", - sid_string_dbg(&sid))); - return WINBINDD_ERROR; - } - - return WINBINDD_OK; -} diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index ff8c101b37..3e03f4091c 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -58,7 +58,7 @@ struct winbindd_domain *domain_list(void) /* Free all entries in the trusted domain list */ -void free_domain_list(void) +static void free_domain_list(void) { struct winbindd_domain *domain = _domain_list; @@ -143,13 +143,14 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const } } - /* See if we found a match. Check if we need to update the - SID. */ - - if ( domain && sid) { - if ( sid_equal( &domain->sid, &global_sid_NULL ) ) + if (domain != NULL) { + /* + * We found a match. Possibly update the SID + */ + if ((sid != NULL) + && sid_equal(&domain->sid, &global_sid_NULL)) { sid_copy( &domain->sid, sid ); - + } return domain; } @@ -223,6 +224,14 @@ done: return domain; } +bool domain_is_forest_root(const struct winbindd_domain *domain) +{ + const uint32_t fr_flags = + (NETR_TRUST_FLAG_TREEROOT|NETR_TRUST_FLAG_IN_FOREST); + + return ((domain->domain_flags & fr_flags) == fr_flags); +} + /******************************************************************** rescan our domains looking for new trusted domains ********************************************************************/ @@ -243,8 +252,6 @@ static void add_trusted_domains( struct winbindd_domain *domain ) TALLOC_CTX *mem_ctx; struct winbindd_request *request; struct winbindd_response *response; - uint32 fr_flags = (NETR_TRUST_FLAG_TREEROOT|NETR_TRUST_FLAG_IN_FOREST); - struct trustdom_state *state; mem_ctx = talloc_init("add_trusted_domains"); @@ -269,7 +276,7 @@ static void add_trusted_domains( struct winbindd_domain *domain ) /* Flags used to know how to continue the forest trust search */ state->primary = domain->primary; - state->forest_root = ((domain->domain_flags & fr_flags) == fr_flags ); + state->forest_root = domain_is_forest_root(domain); request->length = sizeof(*request); request->cmd = WINBINDD_LIST_TRUSTDOM; @@ -792,23 +799,18 @@ struct winbindd_domain *find_root_domain(void) { struct winbindd_domain *ours = find_our_domain(); - if ( !ours ) - return NULL; - - if ( strlen(ours->forest_name) == 0 ) + if (ours->forest_name[0] == '\0') { return NULL; + } return find_domain_from_name( ours->forest_name ); } struct winbindd_domain *find_builtin_domain(void) { - DOM_SID sid; struct winbindd_domain *domain; - string_to_sid(&sid, "S-1-5-32"); - domain = find_domain_from_sid(&sid); - + domain = find_domain_from_sid(&global_sid_Builtin); if (domain == NULL) { smb_panic("Could not find BUILTIN domain"); } @@ -868,95 +870,6 @@ struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name) return find_our_domain(); } -/* Lookup a sid in a domain from a name */ - -bool winbindd_lookup_sid_by_name(TALLOC_CTX *mem_ctx, - enum winbindd_cmd orig_cmd, - struct winbindd_domain *domain, - const char *domain_name, - const char *name, DOM_SID *sid, - enum lsa_SidType *type) -{ - NTSTATUS result; - - /* - * For all but LOOKUPNAME we have to avoid nss calls to avoid - * recursion - */ - result = domain->methods->name_to_sid( - domain, mem_ctx, domain_name, name, - orig_cmd == WINBINDD_LOOKUPNAME ? 0 : LOOKUP_NAME_NO_NSS, - sid, type); - - /* Return sid and type if lookup successful */ - if (!NT_STATUS_IS_OK(result)) { - *type = SID_NAME_UNKNOWN; - } - - return NT_STATUS_IS_OK(result); -} - -/** - * @brief Lookup a name in a domain from a sid. - * - * @param sid Security ID you want to look up. - * @param name On success, set to the name corresponding to @p sid. - * @param dom_name On success, set to the 'domain name' corresponding to @p sid. - * @param type On success, contains the type of name: alias, group or - * user. - * @retval True if the name exists, in which case @p name and @p type - * are set, otherwise False. - **/ -bool winbindd_lookup_name_by_sid(TALLOC_CTX *mem_ctx, - struct winbindd_domain *domain, - DOM_SID *sid, - char **dom_name, - char **name, - enum lsa_SidType *type) -{ - NTSTATUS result; - - *dom_name = NULL; - *name = NULL; - - /* Lookup name */ - - result = domain->methods->sid_to_name(domain, mem_ctx, sid, dom_name, name, type); - - /* Return name and type if successful */ - - if (NT_STATUS_IS_OK(result)) { - return True; - } - - *type = SID_NAME_UNKNOWN; - - return False; -} - -/* Free state information held for {set,get,end}{pw,gr}ent() functions */ - -void free_getent_state(struct getent_state *state) -{ - struct getent_state *temp; - - /* Iterate over state list */ - - temp = state; - - while(temp != NULL) { - struct getent_state *next = temp->next; - - /* Free sam entries then list entry */ - - SAFE_FREE(state->sam_entries); - DLIST_REMOVE(state, state); - - SAFE_FREE(temp); - temp = next; - } -} - /* Is this a domain which we may assume no DOMAIN\ prefix? */ static bool assume_domain(const char *domain) @@ -1550,3 +1463,14 @@ void set_auth_errors(struct winbindd_response *resp, NTSTATUS result) get_friendly_nt_error_msg(result)); resp->data.auth.pam_error = nt_status_to_pam(result); } + +bool is_domain_offline(const struct winbindd_domain *domain) +{ + if (!lp_winbind_offline_logon()) { + return false; + } + if (get_global_winbindd_state_offline()) { + return true; + } + return !domain->online; +} |