diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/error.c | 50 | ||||
-rw-r--r-- | source3/smbd/mangle_hash.c | 9 | ||||
-rw-r--r-- | source3/smbd/message.c | 8 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 84 | ||||
-rw-r--r-- | source3/smbd/pipes.c | 14 | ||||
-rw-r--r-- | source3/smbd/posix_acls.c | 22 | ||||
-rw-r--r-- | source3/smbd/process.c | 186 | ||||
-rw-r--r-- | source3/smbd/reply.c | 121 | ||||
-rw-r--r-- | source3/smbd/seal.c | 1 | ||||
-rw-r--r-- | source3/smbd/sesssetup.c | 1 | ||||
-rw-r--r-- | source3/smbd/smb2_sesssetup.c | 1 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 34 |
12 files changed, 373 insertions, 158 deletions
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; } |