The branch, master has been updated via 32861b9... Actually explain the twisty paths of tortured logic behind reply_doserror(), reply_nterror(), and reply_nterror(NT_STATUS_DOS()). via 0dd8c8a... reply_doserror() doesn't force DOS errors on the wire. via 69d26d2... reply_force_nterror() is not used anywhere. Remove it. Jeremy. from daa561d... s4 torture: Add test to show archive bit behavior with directories
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 32861b926f1beef009d475b5c903a6b703f5bc1e Author: Jeremy Allison <j...@samba.org> Date: Fri Dec 18 14:28:22 2009 -0800 Actually explain the twisty paths of tortured logic behind reply_doserror(), reply_nterror(), and reply_nterror(NT_STATUS_DOS()). Fix the call in rely_openerror() to actually force a DOS error for "too many open files". Jeremy. commit 0dd8c8a6ffed20be89ff1c407ea1d2876bd30792 Author: Jeremy Allison <j...@samba.org> Date: Fri Dec 18 14:25:39 2009 -0800 reply_doserror() doesn't force DOS errors on the wire. Start migrating uses of reply_doserror() to reply_nterror() with the correct mapping. Eventually we'll get to the point where we can change reply_doserror() to force a DOS error code on the wire, and can change calls to reply_nterror(req, NT_STATUS_DOS()) - which *does* force DOS errors on the wire - to reply_doserror(). Which might actually make the server code look like it's making sense. Jeremy. commit 69d26d25f7f2a46e87337fa50af4ed0a1b11a2b5 Author: Jeremy Allison <j...@samba.org> Date: Fri Dec 18 14:25:07 2009 -0800 reply_force_nterror() is not used anywhere. Remove it. Jeremy. ----------------------------------------------------------------------- Summary of changes: source3/include/proto.h | 2 - source3/include/smb_macros.h | 1 - source3/smbd/error.c | 56 +++++++++++++++++++++++++++++++---------- source3/smbd/reply.c | 20 +++++++------- 4 files changed, 52 insertions(+), 27 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/include/proto.h b/source3/include/proto.h index ab74c9c..f138306 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6277,8 +6277,6 @@ void error_packet_set(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatu int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file); void reply_nt_error(struct smb_request *req, NTSTATUS ntstatus, int line, const char *file); -void reply_force_nt_error(struct smb_request *req, NTSTATUS ntstatus, - int line, const char *file); void reply_dos_error(struct smb_request *req, uint8 eclass, uint32 ecode, int line, const char *file); void reply_both_error(struct smb_request *req, uint8 eclass, uint32 ecode, diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h index 10ee78b..a4a9ca0 100644 --- a/source3/include/smb_macros.h +++ b/source3/include/smb_macros.h @@ -112,7 +112,6 @@ #define ERROR_BOTH(status,class,code) error_packet(outbuf,class,code,status,__LINE__,__FILE__) #define reply_nterror(req,status) reply_nt_error(req,status,__LINE__,__FILE__) -#define reply_force_nterror(req,status) reply_force_nt_error(req,status,__LINE__,__FILE__) #define reply_doserror(req,eclass,ecode) reply_dos_error(req,eclass,ecode,__LINE__,__FILE__) #define reply_botherror(req,status,eclass,ecode) reply_both_error(req,eclass,ecode,status,__LINE__,__FILE__) diff --git a/source3/smbd/error.c b/source3/smbd/error.c index 279b7ba..85b4520 100644 --- a/source3/smbd/error.c +++ b/source3/smbd/error.c @@ -30,9 +30,35 @@ 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 is the path taken by calling reply_doserror(req, eclass, ecode). + + 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_nterror(req, NT_STATUS_DOS(eclass, ecode)). + This is *very* unintuitive and the code should be changed so all + current callers of reply_doserror() which don't care if they return NTSTATUS + or DOS errors are changed to call reply_nterror() instead. + reply_doserror() should then be changed to return DOS errors only and + replace all current callers of reply_nterror(req, NT_STATUS_DOS(eclass, ecode)). + I'll update this comment once the conversion is done. JRA. + + 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 +121,22 @@ 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); -} +/**************************************************************************** + NB. This DOES NOT FORCE A DOS ERROR on the wire (although it + probably should, I'm moving the rest of the Samba code towards that + meaning. JRA. +****************************************************************************/ void reply_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_OK, + line, + file); } void reply_both_error(struct smb_request *req, uint8 eclass, uint32 ecode, @@ -134,8 +161,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_nterror(req, NT_STATUS_DOS(ERRDOS, ERRnofids)); } else { reply_nterror(req, status); } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 185f601..f63ffeb 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3338,7 +3338,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 +3420,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 +3618,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; } @@ -3786,7 +3786,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; @@ -3983,7 +3983,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; } @@ -4103,7 +4103,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; } @@ -4334,7 +4334,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; } @@ -4371,7 +4371,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; } @@ -4611,7 +4611,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; } @@ -4706,7 +4706,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; } -- Samba Shared Repository