diff options
author | Gerald Carter <jerry@samba.org> | 2006-11-21 01:11:05 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2006-11-21 01:11:05 +0000 |
commit | 8500889d9a644f4fe77bc15dcb8cb1809a305110 (patch) | |
tree | 4675b0062fb0a11b90176eeed076ec9bdf6886d7 /source/libsmb | |
parent | 526f189263e9f2cd383073ffe14a723c645690a7 (diff) | |
download | samba-8500889d9a644f4fe77bc15dcb8cb1809a305110.tar.gz samba-8500889d9a644f4fe77bc15dcb8cb1809a305110.tar.xz samba-8500889d9a644f4fe77bc15dcb8cb1809a305110.zip |
r19810: more merge work....does not compile currently. Working on smbd merge
Diffstat (limited to 'source/libsmb')
-rw-r--r-- | source/libsmb/cliconnect.c | 177 | ||||
-rw-r--r-- | source/libsmb/clidfs.c | 16 | ||||
-rw-r--r-- | source/libsmb/clientgen.c | 42 | ||||
-rw-r--r-- | source/libsmb/clikrb5.c | 21 | ||||
-rw-r--r-- | source/libsmb/clirap.c | 3 | ||||
-rw-r--r-- | source/libsmb/libsmb_cache.c | 8 | ||||
-rw-r--r-- | source/libsmb/libsmbclient.c | 393 | ||||
-rw-r--r-- | source/libsmb/passchange.c | 143 |
8 files changed, 426 insertions, 377 deletions
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c index 783cf0c1853..f29449cfb22 100644 --- a/source/libsmb/cliconnect.c +++ b/source/libsmb/cliconnect.c @@ -56,16 +56,19 @@ static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_ Do an old lanman2 style session setup. ****************************************************************************/ -static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, - const char *pass, size_t passlen, const char *workgroup) +static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, + const char *user, + const char *pass, size_t passlen, + const char *workgroup) { DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB lm_response = data_blob(NULL, 0); fstring pword; char *p; - if (passlen > sizeof(pword)-1) - return False; + if (passlen > sizeof(pword)-1) { + return NT_STATUS_INVALID_PARAMETER; + } /* LANMAN servers predate NT status codes and Unicode and ignore those smb flags so we must disable the corresponding default capabilities @@ -83,7 +86,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, lm_response = data_blob(NULL, 24); if (!SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data)) { DEBUG(1, ("Password is > 14 chars in length, and is therefore incompatible with Lanman authentication\n")); - return False; + return NT_STATUS_ACCESS_DENIED; } } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) { /* Encrypted mode needed, and encrypted password supplied. */ @@ -116,14 +119,15 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { + return cli_nt_error(cli); + } show_msg(cli->inbuf); - if (cli_is_error(cli)) - return False; + if (cli_is_error(cli)) { + return cli_nt_error(cli); + } /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -134,7 +138,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, cli_set_session_key(cli, session_key); } - return True; + return NT_STATUS_OK; } /**************************************************************************** @@ -159,7 +163,7 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) Do a NT1 guest session setup. ****************************************************************************/ -static BOOL cli_session_setup_guest(struct cli_state *cli) +static NTSTATUS cli_session_setup_guest(struct cli_state *cli) { char *p; uint32 capabilities = cli_session_setup_capabilities(cli); @@ -184,14 +188,15 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { + return cli_nt_error(cli); + } show_msg(cli->inbuf); - if (cli_is_error(cli)) - return False; + if (cli_is_error(cli)) { + return cli_nt_error(cli); + } cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -206,15 +211,16 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) fstrcpy(cli->user_name, ""); - return True; + return NT_STATUS_OK; } /**************************************************************************** Do a NT1 plaintext session setup. ****************************************************************************/ -static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, - const char *pass, const char *workgroup) +static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, + const char *user, const char *pass, + const char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); char *p; @@ -253,14 +259,15 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, p += clistr_push(cli, p, lanman, -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { + return cli_nt_error(cli); + } show_msg(cli->inbuf); - if (cli_is_error(cli)) - return False; + if (cli_is_error(cli)) { + return cli_nt_error(cli); + } cli->vuid = SVAL(cli->inbuf,smb_uid); p = smb_buf(cli->inbuf); @@ -273,7 +280,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, cli->is_samba = True; } - return True; + return NT_STATUS_OK; } /**************************************************************************** @@ -286,16 +293,16 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, @param workgroup The user's domain. ****************************************************************************/ -static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, - const char *pass, size_t passlen, - const char *ntpass, size_t ntpasslen, - const char *workgroup) +static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, + const char *pass, size_t passlen, + const char *ntpass, size_t ntpasslen, + const char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); DATA_BLOB lm_response = data_blob(NULL, 0); DATA_BLOB nt_response = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); - BOOL ret = False; + NTSTATUS result; char *p; if (passlen == 0) { @@ -317,7 +324,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, &lm_response, &nt_response, &session_key)) { data_blob_free(&names_blob); data_blob_free(&server_chal); - return False; + return NT_STATUS_ACCESS_DENIED; } data_blob_free(&names_blob); data_blob_free(&server_chal); @@ -399,14 +406,14 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, cli_setup_bcc(cli, p); if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { - ret = False; + result = cli_nt_error(cli); goto end; } /* show_msg(cli->inbuf); */ if (cli_is_error(cli)) { - ret = False; + result = cli_nt_error(cli); goto end; } @@ -429,12 +436,12 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, cli_set_session_key(cli, session_key); } - ret = True; + result = NT_STATUS_OK; end: data_blob_free(&lm_response); data_blob_free(&nt_response); data_blob_free(&session_key); - return ret; + return result; } /**************************************************************************** @@ -600,6 +607,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { return nt_status; } + ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { return nt_status; @@ -762,7 +770,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, * sent. -- VL */ DEBUG(1, ("Kerberos mech was offered, but no principal was " - "sent, disabling Kerberos\n")); + "sent, disabling Kerberos\n")); cli->use_kerberos = False; } @@ -811,11 +819,11 @@ ntlmssp: password is in plaintext, the same should be done. ****************************************************************************/ -BOOL cli_session_setup(struct cli_state *cli, - const char *user, - const char *pass, int passlen, - const char *ntpass, int ntpasslen, - const char *workgroup) +NTSTATUS cli_session_setup(struct cli_state *cli, + const char *user, + const char *pass, int passlen, + const char *ntpass, int ntpasslen, + const char *workgroup) { char *p; fstring user2; @@ -829,8 +837,9 @@ BOOL cli_session_setup(struct cli_state *cli, workgroup = user2; } - if (cli->protocol < PROTOCOL_LANMAN1) - return True; + if (cli->protocol < PROTOCOL_LANMAN1) { + return NT_STATUS_OK; + } /* now work out what sort of session setup we are going to do. I have split this into separate functions to make the @@ -842,17 +851,18 @@ BOOL cli_session_setup(struct cli_state *cli, if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) { DEBUG(1, ("Server requested LM password but 'client lanman auth'" " is disabled\n")); - return False; + return NT_STATUS_ACCESS_DENIED; } if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 && !lp_client_plaintext_auth() && (*pass)) { DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" " is disabled\n")); - return False; + return NT_STATUS_ACCESS_DENIED; } - return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup); + return cli_session_setup_lanman2(cli, user, pass, passlen, + workgroup); } /* if no user is supplied then we have to do an anonymous connection. @@ -875,7 +885,7 @@ BOOL cli_session_setup(struct cli_state *cli, if (!lp_client_plaintext_auth() && (*pass)) { DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" " is disabled\n")); - return False; + return NT_STATUS_ACCESS_DENIED; } return cli_session_setup_plaintext(cli, user, pass, workgroup); } @@ -886,13 +896,18 @@ BOOL cli_session_setup(struct cli_state *cli, ADS_STATUS status = cli_session_setup_spnego(cli, user, pass, workgroup); if (!ADS_ERR_OK(status)) { DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status))); - return False; + return ads_ntstatus(status); } } else { + NTSTATUS status; + /* otherwise do a NT1 style session setup */ - if ( !cli_session_setup_nt1(cli, user, pass, passlen, ntpass, ntpasslen, workgroup) ) { - DEBUG(3,("cli_session_setup: NT1 session setup failed!\n")); - return False; + status = cli_session_setup_nt1(cli, user, pass, passlen, + ntpass, ntpasslen, workgroup); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3,("cli_session_setup: NT1 session setup " + "failed: %s\n", nt_errstr(status))); + return status; } } @@ -900,7 +915,7 @@ BOOL cli_session_setup(struct cli_state *cli, cli->is_samba = True; } - return True; + return NT_STATUS_OK; } @@ -1406,8 +1421,9 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli, if (!my_name) my_name = global_myname(); - if (!(cli = cli_initialise(NULL))) + if (!(cli = cli_initialise())) { return NT_STATUS_NO_MEMORY; + } make_nmb_name(&calling, my_name, 0x0); make_nmb_name(&called , dest_host, 0x20); @@ -1507,6 +1523,8 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct cli_state *cli = NULL; int pw_len = password ? strlen(password)+1 : 0; + *output_cli = NULL; + if (password == NULL) { password = ""; } @@ -1518,19 +1536,26 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, return nt_status; } - if (!cli_session_setup(cli, user, password, pw_len, password, pw_len, domain)) { - if ((flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK) - && cli_session_setup(cli, "", "", 0, "", 0, domain)) { - } else { - nt_status = cli_nt_error(cli); - DEBUG(1,("failed session setup with %s\n", nt_errstr(nt_status))); + nt_status = cli_session_setup(cli, user, password, pw_len, password, + pw_len, domain); + if (!NT_STATUS_IS_OK(nt_status)) { + + if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) { + DEBUG(1,("failed session setup with %s\n", + nt_errstr(nt_status))); cli_shutdown(cli); - if (NT_STATUS_IS_OK(nt_status)) - nt_status = NT_STATUS_UNSUCCESSFUL; return nt_status; } - } + nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(1,("anonymous failed session setup with %s\n", + nt_errstr(nt_status))); + cli_shutdown(cli); + return nt_status; + } + } + if (service) { if (!cli_send_tconX(cli, service, service_type, password, pw_len)) { nt_status = cli_nt_error(cli); @@ -1553,7 +1578,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, Attempt a NetBIOS session request, falling back to *SMBSERVER if needed. ****************************************************************************/ -BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost, const char *desthost, +BOOL attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost, struct in_addr *pdest_ip) { struct nmb_name calling, called; @@ -1571,7 +1596,7 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost, make_nmb_name(&called, desthost, 0x20); } - if (!cli_session_request(cli, &calling, &called)) { + if (!cli_session_request(*ppcli, &calling, &called)) { struct nmb_name smbservername; make_nmb_name(&smbservername , "*SMBSERVER", 0x20); @@ -1588,23 +1613,23 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost, */ DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ -with error %s.\n", desthost, cli_errstr(cli) )); +with error %s.\n", desthost, cli_errstr(*ppcli) )); return False; } - /* - * We need to close the connection here but can't call cli_shutdown as - * will free an allocated cli struct. cli_close_connection was invented - * for this purpose. JRA. Based on work by "Kim R. Pedersen" <krp@filanet.dk>. - */ + /* Try again... */ + cli_shutdown(*ppcli); - cli_close_connection(cli); + *ppcli = cli_initialise(); + if (!*ppcli) { + /* Out of memory... */ + return False; + } - if (!cli_initialise(cli) || - !cli_connect(cli, desthost, pdest_ip) || - !cli_session_request(cli, &calling, &smbservername)) { + if (!cli_connect(*ppcli, desthost, pdest_ip) || + !cli_session_request(*ppcli, &calling, &smbservername)) { DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ -name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); +name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) )); return False; } } diff --git a/source/libsmb/clidfs.c b/source/libsmb/clidfs.c index e0c55057675..916e4cefc6e 100644 --- a/source/libsmb/clidfs.c +++ b/source/libsmb/clidfs.c @@ -51,7 +51,7 @@ static struct client_connection *connections; static struct cli_state *do_connect( const char *server, const char *share, BOOL show_sessetup ) { - struct cli_state *c; + struct cli_state *c = NULL; struct nmb_name called, calling; const char *server_n; struct in_addr ip; @@ -83,7 +83,7 @@ static struct cli_state *do_connect( const char *server, const char *share, ip = dest_ip; /* have to open a new connection */ - if (!(c=cli_initialise(NULL)) || (cli_set_port(c, port) != port) || + if (!(c=cli_initialise()) || (cli_set_port(c, port) != port) || !cli_connect(c, server_n, &ip)) { d_printf("Connection to %s failed\n", server_n); return NULL; @@ -99,6 +99,7 @@ static struct cli_state *do_connect( const char *server, const char *share, d_printf("session request to %s failed (%s)\n", called.name, cli_errstr(c)); cli_shutdown(c); + c = NULL; if ((p=strchr_m(called.name, '.'))) { *p = 0; goto again; @@ -126,13 +127,14 @@ static struct cli_state *do_connect( const char *server, const char *share, } } - if (!cli_session_setup(c, username, - password, strlen(password), - password, strlen(password), - lp_workgroup())) { + if (!NT_STATUS_IS_OK(cli_session_setup(c, username, + password, strlen(password), + password, strlen(password), + lp_workgroup()))) { /* if a password was not supplied then try again with a null username */ if (password[0] || !username[0] || use_kerberos || - !cli_session_setup(c, "", "", 0, "", 0, lp_workgroup())) { + !NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0, "", 0, + lp_workgroup()))) { d_printf("session setup failed: %s\n", cli_errstr(c)); if (NT_STATUS_V(cli_nt_error(c)) == NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED)) diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c index 8342df0f1d1..24851961d03 100644 --- a/source/libsmb/clientgen.c +++ b/source/libsmb/clientgen.c @@ -107,8 +107,8 @@ BOOL cli_receive_smb(struct cli_state *cli) } /* If the server is not responding, note that now */ - if (!ret) { + DEBUG(0, ("Receiving SMB: Server stopped responding\n")); cli->smb_rw_error = smb_read_error; close(cli->fd); cli->fd = -1; @@ -255,12 +255,12 @@ void cli_setup_signing_state(struct cli_state *cli, int signing_state) } /**************************************************************************** - Initialise a client structure. + Initialise a client structure. Always returns a malloc'ed struct. ****************************************************************************/ -struct cli_state *cli_initialise(struct cli_state *cli) +struct cli_state *cli_initialise(void) { - BOOL alloced_cli = False; + struct cli_state *cli = NULL; /* Check the effective uid - make sure we are not setuid */ if (is_setuid_root()) { @@ -268,17 +268,11 @@ struct cli_state *cli_initialise(struct cli_state *cli) return NULL; } + cli = SMB_MALLOC_P(struct cli_state); if (!cli) { - cli = SMB_MALLOC_P(struct cli_state); - if (!cli) - return NULL; - ZERO_STRUCTP(cli); - alloced_cli = True; + return NULL; } - if (cli->initialised) - cli_close_connection(cli); - ZERO_STRUCTP(cli); cli->port = 0; @@ -333,7 +327,6 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli_null_set_signing(cli); cli->initialised = 1; - cli->allocated = alloced_cli; return cli; @@ -343,10 +336,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) SAFE_FREE(cli->inbuf); SAFE_FREE(cli->outbuf); - - if (alloced_cli) - SAFE_FREE(cli); - + SAFE_FREE(cli); return NULL; } @@ -403,10 +393,10 @@ void cli_nt_pipes_close(struct cli_state *cli) } /**************************************************************************** - Close a client connection and free the memory without destroying cli itself. + Shutdown a client structure. ****************************************************************************/ -void cli_close_connection(struct cli_state *cli) +void cli_shutdown(struct cli_state *cli) { cli_nt_pipes_close(cli); @@ -443,20 +433,8 @@ void cli_close_connection(struct cli_state *cli) } cli->fd = -1; cli->smb_rw_error = 0; -} -/**************************************************************************** - Shutdown a client structure. -****************************************************************************/ - -void cli_shutdown(struct cli_state *cli) -{ - BOOL allocated = cli->allocated; - cli_close_connection(cli); - ZERO_STRUCTP(cli); - if (allocated) { - free(cli); - } + SAFE_FREE(cli); } /**************************************************************************** diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c index 485f5abc0a8..14b5285e45a 100644 --- a/source/libsmb/clikrb5.c +++ b/source/libsmb/clikrb5.c @@ -852,6 +852,27 @@ failed: #endif } +static int get_kvno_from_ap_req(krb5_ap_req *ap_req) +{ +#ifdef HAVE_TICKET_POINTER_IN_KRB5_AP_REQ /* MIT */ + if (ap_req->ticket->enc_part.kvno) + return ap_req->ticket->enc_part.kvno; +#else /* Heimdal */ + if (ap_req->ticket.enc_part.kvno) + return *ap_req->ticket.enc_part.kvno; +#endif + return 0; +} + +static krb5_enctype get_enctype_from_ap_req(krb5_ap_req *ap_req) +{ +#ifdef HAVE_ETYPE_IN_ENCRYPTEDDATA /* Heimdal */ + return ap_req->ticket.enc_part.etype; +#else /* MIT */ + return ap_req->ticket->enc_part.enctype; +#endif +} + static krb5_error_code get_key_from_keytab(krb5_context context, krb5_const_principal server, diff --git a/source/libsmb/clirap.c b/source/libsmb/clirap.c index caa23b59d9a..61cdd79f36b 100644 --- a/source/libsmb/clirap.c +++ b/source/libsmb/clirap.c @@ -244,7 +244,8 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, )) { int res = rparam? SVAL(rparam,0) : -1; - if (res == 0 || res == ERRmoredata) { + if (res == 0 || res == ERRmoredata || + (res != -1 && cli_errno(cli) == 0)) { int i; int converter=SVAL(rparam,2); diff --git a/source/libsmb/libsmb_cache.c b/source/libsmb/libsmb_cache.c index 5d948ea5e25..8c4fd7c89f7 100644 --- a/source/libsmb/libsmb_cache.c +++ b/source/libsmb/libsmb_cache.c @@ -150,9 +150,10 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, * doesn't match the requested share, so * disconnect from the current share. */ - if (! cli_tdis(&srv->server->cli)) { + if (! cli_tdis(srv->server->cli)) { /* Sigh. Couldn't disconnect. */ - cli_shutdown(&srv->server->cli); + cli_shutdown(srv->server->cli); + srv->server->cli = NULL; context->callbacks.remove_cached_srv_fn(context, srv->server); continue; } @@ -166,7 +167,8 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, srv->share_name = SMB_STRDUP(share); if (!srv->share_name) { /* Out of memory. */ - cli_shutdown(&srv->server->cli); + cli_shutdown(srv->server->cli); + srv->server->cli = NULL; context->callbacks.remove_cached_srv_fn(context, srv->server); continue; } diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c index 8c6218c6431..c7f17d3d013 100644 --- a/source/libsmb/libsmbclient.c +++ b/source/libsmb/libsmbclient.c @@ -496,7 +496,7 @@ static int smbc_check_server(SMBCCTX * context, SMBCSRV * server) { - if ( send_keepalive(server->cli.fd) == False ) + if ( send_keepalive(server->cli->fd) == False ) return 1; /* connection is ok */ @@ -533,7 +533,8 @@ smbc_remove_unused_server(SMBCCTX * context, DLIST_REMOVE(context->internal->_servers, srv); - cli_shutdown(&srv->cli); + cli_shutdown(srv->cli); + srv->cli = NULL; DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv)); @@ -639,7 +640,7 @@ smbc_server(SMBCCTX *context, fstring password) { SMBCSRV *srv=NULL; - struct cli_state c; + struct cli_state *c; struct nmb_name called, calling; const char *server_n = server; pstring ipenv; @@ -675,7 +676,7 @@ smbc_server(SMBCCTX *context, * disconnect if the requested share is not the same as the * one that was already connected. */ - if (srv->cli.cnum == (uint16) -1) { + if (srv->cli->cnum == (uint16) -1) { /* Ensure we have accurate auth info */ if (context->internal->_auth_fn_with_context != NULL) { context->internal->_auth_fn_with_context( @@ -692,11 +693,12 @@ smbc_server(SMBCCTX *context, password, sizeof(fstring)); } - if (! cli_send_tconX(&srv->cli, share, "?????", + if (! cli_send_tconX(srv->cli, share, "?????", password, strlen(password)+1)) { - errno = smbc_errno(context, &srv->cli); - cli_shutdown(&srv->cli); + errno = smbc_errno(context, srv->cli); + cli_shutdown(srv->cli); + srv->cli = NULL; context->callbacks.remove_cached_srv_fn(context, srv); srv = NULL; @@ -739,19 +741,19 @@ smbc_server(SMBCCTX *context, zero_ip(&ip); /* have to open a new connection */ - if (!cli_initialise(&c)) { + if ((c = cli_initialise()) == NULL) { errno = ENOMEM; return NULL; } if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) { - c.use_kerberos = True; + c->use_kerberos = True; } if (context->flags & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) { - c.fallback_after_kerberos = True; + c->fallback_after_kerberos = True; } - c.timeout = context->timeout; + c->timeout = context->timeout; /* * Force use of port 139 for first try if share is $IPC, empty, or @@ -765,49 +767,47 @@ smbc_server(SMBCCTX *context, port_try_next = 139; } - c.port = port_try_first; + c->port = port_try_first; - if (!cli_connect(&c, server_n, &ip)) { + if (!cli_connect(c, server_n, &ip)) { /* First connection attempt failed. Try alternate port. */ - c.port = port_try_next; + c->port = port_try_next; - if (!cli_connect(&c, server_n, &ip)) { - cli_shutdown(&c); + if (!cli_connect(c, server_n, &ip)) { + cli_shutdown(c); errno = ETIMEDOUT; return NULL; } } - if (!cli_session_request(&c, &calling, &called)) { - cli_shutdown(&c); + if (!cli_session_request(c, &calling, &called)) { + cli_shutdown(c); if (strcmp(called.name, "*SMBSERVER")) { make_nmb_name(&called , "*SMBSERVER", 0x20); goto again; } else { /* Try one more time, but ensure we don't loop */ - /* Only try this if server is an IP address ... */ + /* Only try this if server is an IP address ... */ - if (is_ipaddress(server) && !tried_reverse) { - fstring remote_name; - struct in_addr rem_ip; + if (is_ipaddress(server) && !tried_reverse) { + fstring remote_name; + struct in_addr rem_ip; - if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) { + if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) { DEBUG(4, ("Could not convert IP address " "%s to struct in_addr\n", server)); - errno = ETIMEDOUT; - return NULL; - } - - tried_reverse++; /* Yuck */ - - if (name_status_find("*", 0, 0, rem_ip, remote_name)) { - make_nmb_name(&called, remote_name, 0x20); - goto again; - } + errno = ETIMEDOUT; + return NULL; + } + tried_reverse++; /* Yuck */ - } + if (name_status_find("*", 0, 0, rem_ip, remote_name)) { + make_nmb_name(&called, remote_name, 0x20); + goto again; + } + } } errno = ETIMEDOUT; return NULL; @@ -815,29 +815,29 @@ smbc_server(SMBCCTX *context, DEBUG(4,(" session request ok\n")); - if (!cli_negprot(&c)) { - cli_shutdown(&c); + if (!cli_negprot(c)) { + cli_shutdown(c); errno = ETIMEDOUT; return NULL; } username_used = username; - if (!cli_session_setup(&c, username_used, - password, strlen(password), - password, strlen(password), - workgroup)) { + if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used, + password, strlen(password), + password, strlen(password), + workgroup))) { /* Failed. Try an anonymous login, if allowed by flags. */ username_used = ""; if ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) || - !cli_session_setup(&c, username_used, - password, 1, - password, 0, - workgroup)) { + !NT_STATUS_IS_OK(cli_session_setup(c, username_used, + password, 1, + password, 0, + workgroup))) { - cli_shutdown(&c); + cli_shutdown(c); errno = EPERM; return NULL; } @@ -845,10 +845,10 @@ smbc_server(SMBCCTX *context, DEBUG(4,(" session setup ok\n")); - if (!cli_send_tconX(&c, share, "?????", + if (!cli_send_tconX(c, share, "?????", password, strlen(password)+1)) { - errno = smbc_errno(context, &c); - cli_shutdown(&c); + errno = smbc_errno(context, c); + cli_shutdown(c); return NULL; } @@ -867,7 +867,6 @@ smbc_server(SMBCCTX *context, ZERO_STRUCTP(srv); srv->cli = c; - srv->cli.allocated = False; srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); srv->no_pathinfo = False; srv->no_pathinfo2 = False; @@ -893,8 +892,10 @@ smbc_server(SMBCCTX *context, return srv; failed: - cli_shutdown(&c); - if (!srv) return NULL; + cli_shutdown(c); + if (!srv) { + return NULL; + } SAFE_FREE(srv); return NULL; @@ -969,19 +970,16 @@ smbc_attr_server(SMBCCTX *context, } ZERO_STRUCTP(ipc_srv); - ipc_srv->cli = *ipc_cli; - ipc_srv->cli.allocated = False; - - free(ipc_cli); + ipc_srv->cli = ipc_cli; if (pol) { - pipe_hnd = cli_rpc_pipe_open_noauth(&ipc_srv->cli, + pipe_hnd = cli_rpc_pipe_open_noauth(ipc_srv->cli, PI_LSARPC, &nt_status); if (!pipe_hnd) { DEBUG(1, ("cli_nt_session_open fail!\n")); errno = ENOTSUP; - cli_shutdown(&ipc_srv->cli); + cli_shutdown(ipc_srv->cli); free(ipc_srv); return NULL; } @@ -994,14 +992,14 @@ smbc_attr_server(SMBCCTX *context, nt_status = rpccli_lsa_open_policy( pipe_hnd, - ipc_srv->cli.mem_ctx, + ipc_srv->cli->mem_ctx, True, GENERIC_EXECUTE_ACCESS, pol); if (!NT_STATUS_IS_OK(nt_status)) { - errno = smbc_errno(context, &ipc_srv->cli); - cli_shutdown(&ipc_srv->cli); + errno = smbc_errno(context, ipc_srv->cli); + cli_shutdown(ipc_srv->cli); return NULL; } } @@ -1018,7 +1016,7 @@ smbc_attr_server(SMBCCTX *context, if (errno == 0) { errno = ENOMEM; } - cli_shutdown(&ipc_srv->cli); + cli_shutdown(ipc_srv->cli); free(ipc_srv); return NULL; } @@ -1107,7 +1105,7 @@ smbc_open_ctx(SMBCCTX *context, ZERO_STRUCTP(file); /*d_printf(">>>open: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); SAFE_FREE(file); @@ -1122,7 +1120,8 @@ smbc_open_ctx(SMBCCTX *context, cli_dfs_make_full_path( targetpath, targetcli->desthost, targetcli->share, temppath); } - if ((fd = cli_open(targetcli, targetpath, flags, DENY_NONE)) < 0) { + if ((fd = cli_open(targetcli, targetpath, flags, + context->internal->_share_mode)) < 0) { /* Handle the error ... */ @@ -1181,7 +1180,7 @@ smbc_open_ctx(SMBCCTX *context, if (fd == -1) { int eno = 0; - eno = smbc_errno(context, &srv->cli); + eno = smbc_errno(context, srv->cli); file = context->opendir(context, fname); if (!file) errno = eno; return file; @@ -1284,7 +1283,7 @@ smbc_read_ctx(SMBCCTX *context, } /*d_printf(">>>read: resolving %s\n", path);*/ - if (!cli_resolve_path("", &file->srv->cli, path, + if (!cli_resolve_path("", file->srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -1292,7 +1291,7 @@ smbc_read_ctx(SMBCCTX *context, } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - ret = cli_read(targetcli, file->cli_fd, buf, offset, count); + ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count); if (ret < 0) { @@ -1367,7 +1366,7 @@ smbc_write_ctx(SMBCCTX *context, } /*d_printf(">>>write: resolving %s\n", path);*/ - if (!cli_resolve_path("", &file->srv->cli, path, + if (!cli_resolve_path("", file->srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -1376,7 +1375,7 @@ smbc_write_ctx(SMBCCTX *context, /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ - ret = cli_write(targetcli, file->cli_fd, 0, buf, offset, count); + ret = cli_write(targetcli, file->cli_fd, 0, (char *)buf, offset, count); if (ret <= 0) { @@ -1439,7 +1438,7 @@ smbc_close_ctx(SMBCCTX *context, } /*d_printf(">>>close: resolving %s\n", path);*/ - if (!cli_resolve_path("", &file->srv->cli, path, + if (!cli_resolve_path("", file->srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -1511,7 +1510,7 @@ smbc_getatr(SMBCCTX * context, } DEBUG(4,("smbc_getatr: sending qpathinfo\n")); - if (!cli_resolve_path( "", &srv->cli, fixedpath, &targetcli, targetpath)) + if (!cli_resolve_path( "", srv->cli, fixedpath, &targetcli, targetpath)) { d_printf("Couldn't resolve %s\n", path); return False; @@ -1562,6 +1561,7 @@ smbc_getatr(SMBCCTX * context, if (change_time_ts != NULL) { *change_time_ts = w_time_ts; } + srv->no_pathinfo2 = True; return True; } @@ -1599,7 +1599,7 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, * attributes manipulated. */ if (srv->no_pathinfo || - ! cli_setpathinfo(&srv->cli, path, + ! cli_setpathinfo(srv->cli, path, create_time, access_time, write_time, @@ -1620,20 +1620,20 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, srv->no_pathinfo = True; /* Open the file */ - if ((fd = cli_open(&srv->cli, path, O_RDWR, DENY_NONE)) < 0) { + if ((fd = cli_open(srv->cli, path, O_RDWR, DENY_NONE)) < 0) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); return -1; } - /* Set the new attributes */ - ret = cli_setattrE(&srv->cli, fd, + /* Set the new attributes */ + ret = cli_setattrE(srv->cli, fd, change_time, access_time, write_time); /* Close the file */ - cli_close(&srv->cli, fd); + cli_close(srv->cli, fd); /* * Unfortunately, setattrE() doesn't have a provision for @@ -1642,11 +1642,11 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, * seems to work on win98. */ if (ret && mode != (uint16) -1) { - ret = cli_setatr(&srv->cli, path, mode, 0); + ret = cli_setatr(srv->cli, path, mode, 0); } if (! ret) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); return False; } } @@ -1706,7 +1706,7 @@ smbc_unlink_ctx(SMBCCTX *context, } /*d_printf(">>>unlink: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); return -1; @@ -1845,14 +1845,14 @@ smbc_rename_ctx(SMBCCTX *ocontext, } /*d_printf(">>>rename: resolving %s\n", path1);*/ - if (!cli_resolve_path( "", &srv->cli, path1, &targetcli1, targetpath1)) + if (!cli_resolve_path( "", srv->cli, path1, &targetcli1, targetpath1)) { d_printf("Could not resolve %s\n", path1); return -1; } /*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/ /*d_printf(">>>rename: resolving %s\n", path2);*/ - if (!cli_resolve_path( "", &srv->cli, path2, &targetcli2, targetpath2)) + if (!cli_resolve_path( "", srv->cli, path2, &targetcli2, targetpath2)) { d_printf("Could not resolve %s\n", path2); return -1; @@ -1947,7 +1947,7 @@ smbc_lseek_ctx(SMBCCTX *context, } /*d_printf(">>>lseek: resolving %s\n", path);*/ - if (!cli_resolve_path("", &file->srv->cli, path, + if (!cli_resolve_path("", file->srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -2120,7 +2120,7 @@ smbc_stat_ctx(SMBCCTX *context, &change_time_ts, &ino)) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); return -1; } @@ -2196,7 +2196,7 @@ smbc_fstat_ctx(SMBCCTX *context, } /*d_printf(">>>fstat: resolving %s\n", path);*/ - if (!cli_resolve_path("", &file->srv->cli, path, + if (!cli_resolve_path("", file->srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -2213,12 +2213,12 @@ smbc_fstat_ctx(SMBCCTX *context, time_t change_time, access_time, write_time; - if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, + if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, &change_time, &access_time, &write_time)) { - errno = EINVAL; - return -1; - } + errno = EINVAL; + return -1; + } change_time_ts = convert_time_t_to_timespec(change_time); access_time_ts = convert_time_t_to_timespec(access_time); @@ -2472,16 +2472,16 @@ net_share_enum_rpc(struct cli_state *cli, void *state) { int i; - WERROR result; - ENUM_HND enum_hnd; + NTSTATUS result; + uint32 enum_hnd; + uint32 *penum_hnd = &enum_hnd; uint32 info_level = 1; uint32 preferred_len = 0xffffffff; - uint32 type; - SRV_SHARE_INFO_CTR ctr; - fstring name = ""; - fstring comment = ""; + struct srvsvc_NetShareCtr1 ctr1; + union srvsvc_NetShareCtr ctr; void *mem_ctx; struct rpc_pipe_client *pipe_hnd; + uint32 numentries; NTSTATUS nt_status; /* Open the server service pipe */ @@ -2499,37 +2499,28 @@ net_share_enum_rpc(struct cli_state *cli, return -1; } + ZERO_STRUCT(ctr1); + ctr.ctr1 = &ctr1; + /* Issue the NetShareEnum RPC call and retrieve the response */ - init_enum_hnd(&enum_hnd, 0); - result = rpccli_srvsvc_net_share_enum(pipe_hnd, - mem_ctx, - info_level, - &ctr, - preferred_len, - &enum_hnd); + enum_hnd = 0; + result = rpccli_srvsvc_NetShareEnum(pipe_hnd, mem_ctx, NULL, + &info_level, &ctr, preferred_len, + &numentries, &penum_hnd); /* Was it successful? */ - if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) { + if (!NT_STATUS_IS_OK(result) || numentries == 0) { /* Nope. Go clean up. */ goto done; } /* For each returned entry... */ - for (i = 0; i < ctr.num_entries; i++) { - - /* pull out the share name */ - rpcstr_pull_unistr2_fstring( - name, &ctr.share.info1[i].info_1_str.uni_netname); - - /* pull out the share's comment */ - rpcstr_pull_unistr2_fstring( - comment, &ctr.share.info1[i].info_1_str.uni_remark); - - /* Get the type value */ - type = ctr.share.info1[i].info_1.type; + for (i = 0; i < numentries; i++) { /* Add this share to the list */ - (*fn)(name, type, comment, state); + (*fn)(ctr.ctr1->array[i].name, + ctr.ctr1->array[i].type, + ctr.ctr1->array[i].comment, state); } done: @@ -2540,7 +2531,7 @@ done: TALLOC_FREE(mem_ctx); /* Tell 'em if it worked */ - return W_ERROR_IS_OK(result) ? 0 : -1; + return NT_STATUS_IS_OK(result) ? 0 : -1; } @@ -2549,6 +2540,7 @@ static SMBCFILE * smbc_opendir_ctx(SMBCCTX *context, const char *fname) { + int saved_errno; fstring server, share, user, password, options; pstring workgroup; pstring path; @@ -2556,6 +2548,7 @@ smbc_opendir_ctx(SMBCCTX *context, char *p; SMBCSRV *srv = NULL; SMBCFILE *dir = NULL; + struct _smbc_callbacks *cb; struct in_addr rem_ip; if (!context || !context->internal || @@ -2708,7 +2701,7 @@ smbc_opendir_ctx(SMBCCTX *context, /* Now, list the stuff ... */ - if (!cli_NetServerEnum(&srv->cli, + if (!cli_NetServerEnum(srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_unique_wg_fn, @@ -2804,7 +2797,7 @@ smbc_opendir_ctx(SMBCCTX *context, dir->srv = srv; /* Now, list the servers ... */ - if (!cli_NetServerEnum(&srv->cli, server, + if (!cli_NetServerEnum(srv->cli, server, 0x0000FFFE, list_fn, (void *)dir)) { @@ -2840,15 +2833,15 @@ smbc_opendir_ctx(SMBCCTX *context, /* List the shares ... */ if (net_share_enum_rpc( - &srv->cli, + srv->cli, list_fn, (void *) dir) < 0 && cli_RNetShareEnum( - &srv->cli, + srv->cli, list_fn, (void *)dir) < 0) { - errno = cli_errno(&srv->cli); + errno = cli_errno(srv->cli); if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); @@ -2898,7 +2891,7 @@ smbc_opendir_ctx(SMBCCTX *context, p = path + strlen(path); pstrcat(path, "\\*"); - if (!cli_resolve_path("", &srv->cli, path, + if (!cli_resolve_path("", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -2917,9 +2910,9 @@ smbc_opendir_ctx(SMBCCTX *context, SAFE_FREE(dir->fname); SAFE_FREE(dir); } - errno = smbc_errno(context, targetcli); + saved_errno = smbc_errno(context, targetcli); - if (errno == EINVAL) { + if (saved_errno == EINVAL) { /* * See if they asked to opendir something * other than a directory. If so, the @@ -2935,12 +2928,34 @@ smbc_opendir_ctx(SMBCCTX *context, ! IS_DOS_DIR(mode)) { /* It is. Correct the error value */ - errno = ENOTDIR; + saved_errno = ENOTDIR; } } - return NULL; + /* + * If there was an error and the server is no + * good any more... + */ + cb = &context->callbacks; + if (cli_is_error(targetcli) && + cb->check_server_fn(context, srv)) { + + /* ... then remove it. */ + if (cb->remove_unused_server_fn(context, + srv)) { + /* + * We could not remove the server + * completely, remove it from the + * cache so we will not get it + * again. It will be removed when the + * last file/dir is closed. + */ + cb->remove_cached_srv_fn(context, srv); + } + } + errno = saved_errno; + return NULL; } } @@ -3247,7 +3262,7 @@ smbc_mkdir_ctx(SMBCCTX *context, } /*d_printf(">>>mkdir: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); return -1; @@ -3344,7 +3359,7 @@ smbc_rmdir_ctx(SMBCCTX *context, } /*d_printf(">>>rmdir: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); return -1; @@ -3600,8 +3615,8 @@ smbc_chmod_ctx(SMBCCTX *context, if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM; if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN; - if (!cli_setatr(&srv->cli, path, mode, 0)) { - errno = smbc_errno(context, &srv->cli); + if (!cli_setatr(srv->cli, path, mode, 0)) { + errno = smbc_errno(context, srv->cli); return -1; } @@ -3718,8 +3733,8 @@ ace_compare(SEC_ACE *ace1, if (ace1->flags != ace2->flags) return ace1->flags - ace2->flags; - if (ace1->info.mask != ace2->info.mask) - return ace1->info.mask - ace2->info.mask; + if (ace1->access_mask != ace2->access_mask) + return ace1->access_mask - ace2->access_mask; if (ace1->size != ace2->size) return ace1->size - ace2->size; @@ -3734,14 +3749,14 @@ sort_acl(SEC_ACL *the_acl) uint32 i; if (!the_acl) return; - qsort(the_acl->ace, the_acl->num_aces, sizeof(the_acl->ace[0]), + qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]), QSORT_CAST ace_compare); for (i=1;i<the_acl->num_aces;) { - if (sec_ace_equal(&the_acl->ace[i-1], &the_acl->ace[i])) { + if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) { int j; for (j=i; j<the_acl->num_aces-1; j++) { - the_acl->ace[j] = the_acl->ace[j+1]; + the_acl->aces[j] = the_acl->aces[j+1]; } the_acl->num_aces--; } else { @@ -3946,7 +3961,7 @@ parse_ace(struct cli_state *ipc_cli, } done: - mask.mask = amask; + mask = amask; init_sec_ace(ace, &sid, atype, mask, aflags); return True; } @@ -3968,7 +3983,7 @@ add_ace(SEC_ACL **the_acl, if ((aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces)) == NULL) { return False; } - memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE)); + memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(SEC_ACE)); memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE)); newacl = make_sec_acl(ctx, (*the_acl)->revision, 1+(*the_acl)->num_aces, aces); @@ -4138,7 +4153,7 @@ dos_attr_query(SMBCCTX *context, &change_time_ts, &inode)) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); DEBUG(5, ("dos_attr_query Failed to query old attributes\n")); return NULL; @@ -4164,7 +4179,7 @@ dos_attr_parse(SMBCCTX *context, char *str) { int n; - const char *p = str; + const char *p = str; fstring tok; struct { const char * create_time_attr; @@ -4297,7 +4312,7 @@ cacl_get(SMBCCTX *context, SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T ino = 0; - struct cli_state *cli = &srv->cli; + struct cli_state *cli = srv->cli; struct { const char * create_time_attr; const char * access_time_attr; @@ -4540,10 +4555,10 @@ cacl_get(SMBCCTX *context, } if (! exclude_nt_group) { - if (sd->grp_sid) { + if (sd->group_sid) { convert_sid_to_string(ipc_cli, pol, sidstr, numeric, - sd->grp_sid); + sd->group_sid); } else { fstrcpy(sidstr, ""); } @@ -4588,7 +4603,7 @@ cacl_get(SMBCCTX *context, /* Add aces to value buffer */ for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { - SEC_ACE *ace = &sd->dacl->ace[i]; + SEC_ACE *ace = &sd->dacl->aces[i]; convert_sid_to_string(ipc_cli, pol, sidstr, numeric, &ace->trustee); @@ -4602,7 +4617,7 @@ cacl_get(SMBCCTX *context, sidstr, ace->type, ace->flags, - ace->info.mask); + ace->access_mask); if (!p) { errno = ENOMEM; return -1; @@ -4615,7 +4630,7 @@ cacl_get(SMBCCTX *context, sidstr, ace->type, ace->flags, - ace->info.mask); + ace->access_mask); } } else if ((StrnCaseCmp(name, "acl", 3) == 0 && StrCaseCmp(name+3, sidstr) == 0) || @@ -4627,7 +4642,7 @@ cacl_get(SMBCCTX *context, "%d/%d/0x%08x", ace->type, ace->flags, - ace->info.mask); + ace->access_mask); if (!p) { errno = ENOMEM; return -1; @@ -4638,7 +4653,7 @@ cacl_get(SMBCCTX *context, "%d/%d/0x%08x", ace->type, ace->flags, - ace->info.mask); + ace->access_mask); } } else if (all_nt_acls) { if (determine_size) { @@ -4649,7 +4664,7 @@ cacl_get(SMBCCTX *context, sidstr, ace->type, ace->flags, - ace->info.mask); + ace->access_mask); if (!p) { errno = ENOMEM; return -1; @@ -4662,7 +4677,7 @@ cacl_get(SMBCCTX *context, sidstr, ace->type, ace->flags, - ace->info.mask); + ace->access_mask); } } if (n > bufsize) { @@ -4691,11 +4706,11 @@ cacl_get(SMBCCTX *context, &change_time_ts, &ino)) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); return -1; } - + create_time = convert_timespec_to_time_t(create_time_ts); access_time = convert_timespec_to_time_t(access_time_ts); write_time = convert_timespec_to_time_t(write_time_ts); @@ -4811,7 +4826,7 @@ cacl_get(SMBCCTX *context, attr_strings.create_time_attr, create_time); } - } else if (StrCaseCmp(name, "c_time") == 0) { + } else if (StrCaseCmp(name, attr_strings.create_time_attr) == 0) { if (determine_size) { p = talloc_asprintf(ctx, "%lu", create_time); if (!p) { @@ -4852,7 +4867,7 @@ cacl_get(SMBCCTX *context, attr_strings.access_time_attr, access_time); } - } else if (StrCaseCmp(name, "a_time") == 0) { + } else if (StrCaseCmp(name, attr_strings.access_time_attr) == 0) { if (determine_size) { p = talloc_asprintf(ctx, "%lu", access_time); if (!p) { @@ -5093,9 +5108,9 @@ cacl_set(TALLOC_CTX *ctx, switch (mode) { case SMBC_XATTR_MODE_REMOVE_ALL: old->dacl->num_aces = 0; - SAFE_FREE(old->dacl->ace); + SAFE_FREE(old->dacl->aces); SAFE_FREE(old->dacl); - old->off_dacl = 0; + old->dacl = NULL; dacl = old->dacl; break; @@ -5104,18 +5119,18 @@ cacl_set(TALLOC_CTX *ctx, BOOL found = False; for (j=0;old->dacl && j<old->dacl->num_aces;j++) { - if (sec_ace_equal(&sd->dacl->ace[i], - &old->dacl->ace[j])) { + if (sec_ace_equal(&sd->dacl->aces[i], + &old->dacl->aces[j])) { uint32 k; for (k=j; k<old->dacl->num_aces-1;k++) { - old->dacl->ace[k] = - old->dacl->ace[k+1]; + old->dacl->aces[k] = + old->dacl->aces[k+1]; } old->dacl->num_aces--; if (old->dacl->num_aces == 0) { - SAFE_FREE(old->dacl->ace); + SAFE_FREE(old->dacl->aces); SAFE_FREE(old->dacl); - old->off_dacl = 0; + old->dacl = NULL; } found = True; dacl = old->dacl; @@ -5136,14 +5151,14 @@ cacl_set(TALLOC_CTX *ctx, BOOL found = False; for (j=0;old->dacl && j<old->dacl->num_aces;j++) { - if (sid_equal(&sd->dacl->ace[i].trustee, - &old->dacl->ace[j].trustee)) { + if (sid_equal(&sd->dacl->aces[i].trustee, + &old->dacl->aces[j].trustee)) { if (!(flags & SMBC_XATTR_FLAG_CREATE)) { err = EEXIST; ret = -1; goto failed; } - old->dacl->ace[j] = sd->dacl->ace[i]; + old->dacl->aces[j] = sd->dacl->aces[i]; ret = -1; found = True; } @@ -5156,7 +5171,7 @@ cacl_set(TALLOC_CTX *ctx, } for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { - add_ace(&old->dacl, &sd->dacl->ace[i], ctx); + add_ace(&old->dacl, &sd->dacl->aces[i], ctx); } } dacl = old->dacl; @@ -5165,7 +5180,7 @@ cacl_set(TALLOC_CTX *ctx, case SMBC_XATTR_MODE_SET: old = sd; owner_sid = old->owner_sid; - grp_sid = old->grp_sid; + grp_sid = old->group_sid; dacl = old->dacl; break; @@ -5174,7 +5189,7 @@ cacl_set(TALLOC_CTX *ctx, break; case SMBC_XATTR_MODE_CHGRP: - grp_sid = sd->grp_sid; + grp_sid = sd->group_sid; break; } @@ -5310,8 +5325,8 @@ smbc_setxattr_ctx(SMBCCTX *context, } if (ipc_srv) { - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, namevalue, (*namevalue == '*' ? SMBC_XATTR_MODE_SET @@ -5374,8 +5389,8 @@ smbc_setxattr_ctx(SMBCCTX *context, errno = ENOMEM; ret = -1; } else { - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, namevalue, (*namevalue == '*' ? SMBC_XATTR_MODE_SET @@ -5405,8 +5420,8 @@ smbc_setxattr_ctx(SMBCCTX *context, errno = ENOMEM; ret = -1; } else { - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, namevalue, SMBC_XATTR_MODE_CHOWN, 0); } talloc_destroy(ctx); @@ -5432,8 +5447,8 @@ smbc_setxattr_ctx(SMBCCTX *context, errno = ENOMEM; ret = -1; } else { - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, namevalue, SMBC_XATTR_MODE_CHOWN, 0); } talloc_destroy(ctx); @@ -5632,12 +5647,12 @@ smbc_getxattr_ctx(SMBCCTX *context, /* Yup. */ ret = cacl_get(context, ctx, srv, - ipc_srv == NULL ? NULL : &ipc_srv->cli, + ipc_srv == NULL ? NULL : ipc_srv->cli, &pol, path, CONST_DISCARD(char *, name), CONST_DISCARD(char *, value), size); if (ret < 0 && errno == 0) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); } talloc_destroy(ctx); return ret; @@ -5728,8 +5743,8 @@ smbc_removexattr_ctx(SMBCCTX *context, StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) { /* Yup. */ - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0); talloc_destroy(ctx); return ret; @@ -5748,8 +5763,8 @@ smbc_removexattr_ctx(SMBCCTX *context, StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { /* Yup. */ - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, name + 19, SMBC_XATTR_MODE_REMOVE, 0); talloc_destroy(ctx); return ret; @@ -6026,10 +6041,10 @@ smbc_list_print_jobs_ctx(SMBCCTX *context, } - if (cli_print_queue(&srv->cli, + if (cli_print_queue(srv->cli, (void (*)(struct print_job_info *))fn) < 0) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); return -1; } @@ -6096,10 +6111,10 @@ smbc_unlink_print_job_ctx(SMBCCTX *context, } - if ((err = cli_printjob_del(&srv->cli, id)) != 0) { + if ((err = cli_printjob_del(srv->cli, id)) != 0) { if (err < 0) - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); else if (err == ERRnosuchprintjob) errno = EINVAL; return -1; @@ -6220,8 +6235,8 @@ smbc_free_context(SMBCCTX *context, s = context->internal->_servers; while (s) { DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", - s, s->cli.fd)); - cli_shutdown(&s->cli); + s, s->cli->fd)); + cli_shutdown(s->cli); context->callbacks.remove_cached_srv_fn(context, s); next = s->next; @@ -6350,9 +6365,9 @@ smbc_option_get(SMBCCTX *context, * Log to standard error instead of standard output. */ #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->internal->_debug_stderr; + return (void *) (intptr_t) context->internal->_debug_stderr; #else - return (void *) context->internal->_debug_stderr; + return (void *) context->internal->_debug_stderr; #endif } else if (strcmp(option_name, "full_time_names") == 0) { /* diff --git a/source/libsmb/passchange.c b/source/libsmb/passchange.c index 90eb67aceaa..5b4b0896c0f 100644 --- a/source/libsmb/passchange.c +++ b/source/libsmb/passchange.c @@ -29,7 +29,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam char *err_str, size_t err_str_len) { struct nmb_name calling, called; - struct cli_state cli; + struct cli_state *cli; struct rpc_pipe_client *pipe_hnd; struct in_addr ip; @@ -44,91 +44,96 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam return NT_STATUS_UNSUCCESSFUL; } - ZERO_STRUCT(cli); - - if (!cli_initialise(&cli) || !cli_connect(&cli, remote_machine, &ip)) { + cli = cli_initialise(); + if (!cli) { + return NT_STATUS_NO_MEMORY; + } + + if (!cli_connect(cli, remote_machine, &ip)) { slprintf(err_str, err_str_len-1, "unable to connect to SMB server on machine %s. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - return NT_STATUS_UNSUCCESSFUL; + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); + return result; } make_nmb_name(&calling, global_myname() , 0x0); make_nmb_name(&called , remote_machine, 0x20); - if (!cli_session_request(&cli, &calling, &called)) { + if (!cli_session_request(cli, &calling, &called)) { slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - cli_shutdown(&cli); - return NT_STATUS_UNSUCCESSFUL; + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); + return result; } - cli.protocol = PROTOCOL_NT1; + cli->protocol = PROTOCOL_NT1; - if (!cli_negprot(&cli)) { + if (!cli_negprot(cli)) { slprintf(err_str, err_str_len-1, "machine %s rejected the negotiate protocol. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); return result; } /* Given things like SMB signing, restrict anonymous and the like, try an authenticated connection first */ - if (!cli_session_setup(&cli, user_name, old_passwd, strlen(old_passwd)+1, old_passwd, strlen(old_passwd)+1, "")) { - - result = cli_nt_error(&cli); - - if (!NT_STATUS_IS_OK(result)) { - - /* Password must change or Password expired are the only valid - * error conditions here from where we can proceed, the rest like - * account locked out or logon failure will lead to errors later - * anyway */ - - if (!NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_MUST_CHANGE) && - !NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_EXPIRED)) { - - slprintf(err_str, err_str_len-1, "Could not " - "connect to machine %s: %s\n", - remote_machine, cli_errstr(&cli)); - cli_shutdown(&cli); - return result; - } - - pass_must_change = True; + result = cli_session_setup(cli, user_name, + old_passwd, strlen(old_passwd)+1, + old_passwd, strlen(old_passwd)+1, ""); + + if (!NT_STATUS_IS_OK(result)) { + + /* Password must change or Password expired are the only valid + * error conditions here from where we can proceed, the rest like + * account locked out or logon failure will lead to errors later + * anyway */ + + if (!NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_MUST_CHANGE) && + !NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_EXPIRED)) { + slprintf(err_str, err_str_len-1, "Could not " + "connect to machine %s: %s\n", + remote_machine, cli_errstr(cli)); + cli_shutdown(cli); + return result; } + pass_must_change = True; + /* * We should connect as the anonymous user here, in case * the server has "must change password" checked... * Thanks to <Nicholas.S.Jenkins@cdc.com> for this fix. */ - if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { + result = cli_session_setup(cli, "", "", 0, "", 0, ""); + + if (!NT_STATUS_IS_OK(result)) { slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + remote_machine, cli_errstr(cli) ); + cli_shutdown(cli); return result; } - cli_init_creds(&cli, "", "", NULL); + cli_init_creds(cli, "", "", NULL); } else { - cli_init_creds(&cli, user_name, "", old_passwd); + cli_init_creds(cli, user_name, "", old_passwd); } - if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { + if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) { slprintf(err_str, err_str_len-1, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); return result; } /* Try not to give the password away too easily */ if (!pass_must_change) { - pipe_hnd = cli_rpc_pipe_open_ntlmssp(&cli, + pipe_hnd = cli_rpc_pipe_open_ntlmssp(cli, PI_SAMR, PIPE_AUTH_LEVEL_PRIVACY, "", /* what domain... ? */ @@ -144,17 +149,17 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam * will just fail. So we do it anonymously, there's no other * way. */ - pipe_hnd = cli_rpc_pipe_open_noauth(&cli, PI_SAMR, &result); + pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result); } if (!pipe_hnd) { if (lp_client_lanman_auth()) { /* Use the old RAP method. */ - if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { + if (!cli_oem_change_password(cli, user_name, new_passwd, old_passwd)) { slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); return result; } } else { @@ -162,16 +167,16 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam "SAMR connection to machine %s failed. Error was %s, " "but LANMAN password changed are disabled\n", nt_errstr(result), remote_machine); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + result = cli_nt_error(cli); + cli_shutdown(cli); return result; } } - if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, cli.mem_ctx, user_name, + if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, cli->mem_ctx, user_name, new_passwd, old_passwd))) { /* Great - it all worked! */ - cli_shutdown(&cli); + cli_shutdown(cli); return NT_STATUS_OK; } else if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) @@ -180,7 +185,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", remote_machine, get_friendly_nt_error_msg(result)); - cli_shutdown(&cli); + cli_shutdown(cli); return result; } @@ -188,21 +193,21 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam cli_rpc_pipe_close(pipe_hnd); /* Try anonymous NTLMSSP... */ - cli_init_creds(&cli, "", "", NULL); + cli_init_creds(cli, "", "", NULL); result = NT_STATUS_UNSUCCESSFUL; /* OK, this is ugly, but... try an anonymous pipe. */ - pipe_hnd = cli_rpc_pipe_open_noauth(&cli, PI_SAMR, &result); + pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result); if ( pipe_hnd && (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, - cli.mem_ctx, + cli->mem_ctx, user_name, new_passwd, old_passwd)))) { /* Great - it all worked! */ - cli_shutdown(&cli); + cli_shutdown(cli); return NT_STATUS_OK; } else { if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) @@ -212,7 +217,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam slprintf(err_str, err_str_len-1, "machine %s rejected the (anonymous) password change: Error was : %s.\n", remote_machine, get_friendly_nt_error_msg(result)); - cli_shutdown(&cli); + cli_shutdown(cli); return result; } @@ -221,24 +226,24 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam if (lp_client_lanman_auth()) { /* Use the old RAP method. */ - if (cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { + if (cli_oem_change_password(cli, user_name, new_passwd, old_passwd)) { /* SAMR failed, but the old LanMan protocol worked! */ - cli_shutdown(&cli); + cli_shutdown(cli); return NT_STATUS_OK; } slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); return result; } else { slprintf(err_str, err_str_len-1, "SAMR connection to machine %s failed. Error was %s, " "but LANMAN password changed are disabled\n", nt_errstr(result), remote_machine); - cli_shutdown(&cli); + cli_shutdown(cli); return NT_STATUS_UNSUCCESSFUL; } } |