diff options
-rw-r--r-- | WHATSNEW.txt | 24 | ||||
-rw-r--r-- | source/client/clitar.c | 49 | ||||
-rw-r--r-- | source/param/loadparm.c | 1 | ||||
-rw-r--r-- | source/smbd/open.c | 100 | ||||
-rw-r--r-- | source/smbd/server.c | 3 | ||||
-rw-r--r-- | source/utils/net_ads.c | 8 | ||||
-rw-r--r-- | source/utils/net_rpc.c | 9 |
7 files changed, 125 insertions, 69 deletions
diff --git a/WHATSNEW.txt b/WHATSNEW.txt index 54953d6e109..177ad8e841f 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -20,11 +20,23 @@ articles: http://news.samba.org/#coverity_zero_bugs http://news.samba.org/#zdnet_quick_response +New features introduced in 3.0.23pre1 include: + o New offline mode in winbindd. + o New kerberos support for pam_winbind.so. + o New handling of unmapped users and groups. + o New non-root share management tools. + o Improved support for local and BUILTIN groups. -Common bugs fixed in 3.0.23pre1 include: -New features introduced in 3.0.23pre1 include: +User and Group changes +====================== + +The user and group internal management routines have been rewritten +to prevent overlaps of assigned Relative Identifiers (RIDs). +Unmapped users are assigned a SID in the S-1-22-1 domain now and +unmapped groups are assigned a SID in the S-1-22-2 domain. + ###################################################################### @@ -100,7 +112,10 @@ o Jeremy Allison <jra@samba.org> * Fix error return on session setup. Ensure no data blob is added if the logon call failed so that Windows clients interpret the NT_STATUS code correctly. - + * Teach Samba the difference between exclusive and batch + oplocks. + * BUG 3592: Ignore a file in a smbtar output if the first + read fails (inspired by Justin Best). o Alexander Bokovoy <ab@samba.org> @@ -215,7 +230,6 @@ o Guenther Deschner <gd@samba.org> in /etc/security/pam_winbind.conf. - o Mathias Dietz <MDIETZ@de.ibm.com> * EPERM can be a valid return from getting an xattr. Don't disable if we get it. @@ -261,6 +275,8 @@ o Volker Lendecke <vl@samba.org> the SAMBA_4_0 tree. * Unsure that the global SAM SID is initialized before any dependent routines are called. + * Enhance consistency checks on local configuration when joining + a domain. o Derrell Lipman <derrell@samba.org> diff --git a/source/client/clitar.c b/source/client/clitar.c index 306848bc0cd..a7bc4bfde34 100644 --- a/source/client/clitar.c +++ b/source/client/clitar.c @@ -561,15 +561,15 @@ static BOOL ensurepath(char *fname) return True; } -static int padit(char *buf, int bufsize, int padsize) +static int padit(char *buf, SMB_BIG_UINT bufsize, SMB_BIG_UINT padsize) { int berr= 0; int bytestowrite; - DEBUG(5, ("Padding with %d zeros\n", padsize)); - memset(buf, 0, bufsize); + DEBUG(5, ("Padding with %0.f zeros\n", (double)padsize)); + memset(buf, 0, (size_t)bufsize); while( !berr && padsize > 0 ) { - bytestowrite= MIN(bufsize, padsize); + bytestowrite= (int)MIN(bufsize, padsize); berr = dotarbuf(tarhandle, buf, bytestowrite) != bytestowrite; padsize -= bytestowrite; } @@ -682,12 +682,11 @@ static void do_atar(char *rname,char *lname,file_info *finfo1) DEBUG(4, ("skipping %s - hidden bit is set\n", finfo.name)); shallitime=0; } else { + BOOL wrote_tar_header = False; + DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s", finfo.name, (double)finfo.size, lname)); - /* write a tar header, don't bother with mode - just set to 100644 */ - writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0", ftype); - while (nread < finfo.size && !close_done) { DEBUG(3,("nread=%.0f\n",(double)nread)); @@ -701,6 +700,13 @@ static void do_atar(char *rname,char *lname,file_info *finfo1) nread += datalen; + /* Only if the first read succeeds, write out the tar header. */ + if (!wrote_tar_header) { + /* write a tar header, don't bother with mode - just set to 100644 */ + writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0", ftype); + wrote_tar_header = True; + } + /* if file size has increased since we made file size query, truncate read so tar header for this file will be correct. */ @@ -727,20 +733,25 @@ static void do_atar(char *rname,char *lname,file_info *finfo1) datalen=0; } - /* pad tar file with zero's if we couldn't get entire file */ - if (nread < finfo.size) { - DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n", - (double)finfo.size, (int)nread)); - if (padit(data, sizeof(data), finfo.size - nread)) - DEBUG(0,("Error writing tar file - %s\n", strerror(errno))); - } + if (wrote_tar_header) { + /* pad tar file with zero's if we couldn't get entire file */ + if (nread < finfo.size) { + DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n", + (double)finfo.size, (int)nread)); + if (padit(data, (SMB_BIG_UINT)sizeof(data), finfo.size - nread)) + DEBUG(0,("Error writing tar file - %s\n", strerror(errno))); + } - /* round tar file to nearest block */ - if (finfo.size % TBLOCK) - dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK)); + /* round tar file to nearest block */ + if (finfo.size % TBLOCK) + dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK)); - ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK); - ntarf++; + ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK); + ntarf++; + } else { + DEBUG(4, ("skipping %s - initial read failed (file was locked ?)\n", finfo.name)); + shallitime=0; + } } cli_close(cli, fnum); diff --git a/source/param/loadparm.c b/source/param/loadparm.c index e0cbc981def..34b463de221 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -54,7 +54,6 @@ #include "includes.h" BOOL in_client = False; /* Not in the client by default */ -BOOL in_server = False; /* Not in the server by default */ BOOL bLoaded = False; extern userdom_struct current_user_info; diff --git a/source/smbd/open.c b/source/smbd/open.c index 99a7894762c..edc5bc98b6e 100644 --- a/source/smbd/open.c +++ b/source/smbd/open.c @@ -608,7 +608,7 @@ static BOOL is_delete_request(files_struct *fsp) { * 3) Only level2 around: Grant level2 and do nothing else. */ -static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp) +static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp, int pass_number) { int i; struct share_mode_entry *exclusive = NULL; @@ -630,9 +630,16 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp) /* At least one entry is not an invalid or deferred entry. */ valid_entry = True; - if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) { - SMB_ASSERT(exclusive == NULL); - exclusive = &lck->share_modes[i]; + if (pass_number == 1) { + if (BATCH_OPLOCK_TYPE(lck->share_modes[i].op_type)) { + SMB_ASSERT(exclusive == NULL); + exclusive = &lck->share_modes[i]; + } + } else { + if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) { + SMB_ASSERT(exclusive == NULL); + exclusive = &lck->share_modes[i]; + } } if (lck->share_modes[i].op_type == LEVEL_II_OPLOCK) { @@ -1024,6 +1031,42 @@ BOOL map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func } +static void schedule_defer_open(struct share_mode_lock *lck, struct timeval request_time) +{ + struct deferred_open_record state; + + /* This is a relative time, added to the absolute + request_time value to get the absolute timeout time. + Note that if this is the second or greater time we enter + this codepath for this particular request mid then + request_time is left as the absolute time of the *first* + time this request mid was processed. This is what allows + the request to eventually time out. */ + + struct timeval timeout; + + /* Normally the smbd we asked should respond within + * OPLOCK_BREAK_TIMEOUT seconds regardless of whether + * the client did, give twice the timeout as a safety + * measure here in case the other smbd is stuck + * somewhere else. */ + + timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0); + + /* Nothing actually uses state.delayed_for_oplocks + but it's handy to differentiate in debug messages + between a 30 second delay due to oplock break, and + a 1 second delay for share mode conflicts. */ + + state.delayed_for_oplocks = True; + state.dev = lck->dev; + state.inode = lck->ino; + + if (!request_timed_out(request_time, timeout)) { + defer_open(lck, request_time, timeout, &state); + } +} + /**************************************************************************** Open a file with a share mode. ****************************************************************************/ @@ -1310,7 +1353,6 @@ files_struct *open_file_ntcreate(connection_struct *conn, } if (file_existed) { - dev = psbuf->st_dev; inode = psbuf->st_ino; @@ -1324,41 +1366,9 @@ files_struct *open_file_ntcreate(connection_struct *conn, return NULL; } - if (delay_for_oplocks(lck, fsp)) { - struct deferred_open_record state; - - /* This is a relative time, added to the absolute - request_time value to get the absolute timeout time. - Note that if this is the second or greater time we enter - this codepath for this particular request mid then - request_time is left as the absolute time of the *first* - time this request mid was processed. This is what allows - the request to eventually time out. */ - - struct timeval timeout; - - /* Normally the smbd we asked should respond within - * OPLOCK_BREAK_TIMEOUT seconds regardless of whether - * the client did, give twice the timeout as a safety - * measure here in case the other smbd is stuck - * somewhere else. */ - - timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0); - - /* Nothing actually uses state.delayed_for_oplocks - but it's handy to differentiate in debug messages - between a 30 second delay due to oplock break, and - a 1 second delay for share mode conflicts. */ - - state.delayed_for_oplocks = True; - state.dev = dev; - state.inode = inode; - - if (!request_timed_out(request_time, timeout)) { - defer_open(lck, request_time, timeout, - &state); - } - + /* First pass - send break only on batch oplocks. */ + if (delay_for_oplocks(lck, fsp, 1)) { + schedule_defer_open(lck, request_time); TALLOC_FREE(lck); return NULL; } @@ -1367,6 +1377,16 @@ files_struct *open_file_ntcreate(connection_struct *conn, access_mask, share_access, create_options, &file_existed); + if (NT_STATUS_IS_OK(status)) { + /* We might be going to allow this open. Check oplock status again. */ + /* Second pass - send break for both batch or exclusive oplocks. */ + if (delay_for_oplocks(lck, fsp, 2)) { + schedule_defer_open(lck, request_time); + TALLOC_FREE(lck); + return NULL; + } + } + if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) { /* DELETE_PENDING is not deferred for a second */ set_saved_ntstatus(status); diff --git a/source/smbd/server.c b/source/smbd/server.c index a1466c408d2..b76ade957c2 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -731,7 +731,6 @@ void build_options(BOOL screen); int main(int argc,const char *argv[]) { - extern BOOL in_server; /* shall I run as a daemon */ static BOOL is_daemon = False; static BOOL interactive = False; @@ -755,8 +754,6 @@ void build_options(BOOL screen); { NULL } }; - in_server = True; - load_case_tables(); #ifdef HAVE_SET_AUTH_PARAMETERS diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c index 6cd332fd3df..11e7ae02826 100644 --- a/source/utils/net_ads.c +++ b/source/utils/net_ads.c @@ -721,12 +721,18 @@ int net_ads_join(int argc, const char **argv) const char *short_domain_name = NULL; TALLOC_CTX *ctx = NULL; - if ((lp_server_role() != ROLE_DOMAIN_MEMBER) || + if ((lp_server_role() != ROLE_DOMAIN_MEMBER) && (lp_server_role() != ROLE_DOMAIN_BDC)) { d_printf("can only join as domain member or as BDC\n"); return -1; } + if (strlen(global_myname()) > 15) { + d_printf("Our netbios name can only be 15 chars long, \"%s\"" + " is %d chars long\n", + global_myname(), strlen(global_myname())); + return -1; + } if (argc > 0) { org_unit = argv[0]; diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c index efc9bfbfafb..0060a39c310 100644 --- a/source/utils/net_rpc.c +++ b/source/utils/net_rpc.c @@ -389,12 +389,19 @@ static int rpc_join_usage(int argc, const char **argv) int net_rpc_join(int argc, const char **argv) { - if ((lp_server_role() != ROLE_DOMAIN_MEMBER) || + if ((lp_server_role() != ROLE_DOMAIN_MEMBER) && (lp_server_role() != ROLE_DOMAIN_BDC)) { d_printf("can only join as domain member or as BDC\n"); return -1; } + if (strlen(global_myname()) > 15) { + d_printf("Our netbios name can only be 15 chars long, \"%s\"" + " is %d chars long\n", + global_myname(), strlen(global_myname())); + return -1; + } + if ((net_rpc_perform_oldjoin(argc, argv) == 0)) return 0; |