diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2015-03-17 22:18:09 +0300 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2015-03-17 22:18:09 +0300 |
commit | 1095152992d77a7c3e3ad6a4cc1e5a4042ffafac (patch) | |
tree | ba7a6e80661eb5ec05f779da021c6a823706b5d9 /source3 | |
parent | 96ccbc68d81ae0713a5072cbb5815441eef5f3e3 (diff) | |
parent | 85232b25a2bbf24b2677778653e6017cf329ec46 (diff) | |
download | samba-1095152992d77a7c3e3ad6a4cc1e5a4042ffafac.tar.gz |
Merge branch 'master' of git://anonscm.debian.org/pkg-samba/samba
Conflicts:
debian/changelog
debian/patches/series
Diffstat (limited to 'source3')
41 files changed, 495 insertions, 293 deletions
diff --git a/source3/client/client.c b/source3/client/client.c index ab46cb80a9..20932cc4e0 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -5307,7 +5307,7 @@ static int do_host_query(const char *query_host) if (cli == NULL) { d_printf("NetBIOS over TCP disabled -- no workgroup available\n"); - return 1; + return 0; } cli_set_timeout(cli, io_timeout*1000); diff --git a/source3/include/local.h b/source3/include/local.h index a87ab8f100..5ea7960ad3 100644 --- a/source3/include/local.h +++ b/source3/include/local.h @@ -217,4 +217,6 @@ #define DEFAULT_SMB2_MAX_TRANSACT (1024*1024) #define DEFAULT_SMB2_MAX_CREDITS 8192 +#define WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK 31 + #endif diff --git a/source3/include/printing.h b/source3/include/printing.h index ec5a53b7fd..563659a693 100644 --- a/source3/include/printing.h +++ b/source3/include/printing.h @@ -195,6 +195,7 @@ uint16_t print_spool_rap_jobid(struct print_file_data *print_file); uint32 sysjob_to_jobid_pdb(struct tdb_print_db *pdb, int sysjob); uint32 sysjob_to_jobid(int unix_jobid); +int jobid_to_sysjob_pdb(struct tdb_print_db *pdb, uint32_t jobid); bool print_notify_register_pid(int snum); bool print_notify_deregister_pid(int snum); bool print_job_exists(const char* sharename, uint32 jobid); diff --git a/source3/include/proto.h b/source3/include/proto.h index cbad7ac36a..4eb7ba40ec 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -718,9 +718,6 @@ int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list); void ipstr_list_free(char* ipstr_list); uint64_t STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr); uint64_t conv_str_size(const char * str); -bool add_string_to_array(TALLOC_CTX *mem_ctx, - const char *str, const char ***strings, - int *num); void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len, size_t *bufsize, const char *fmt, ...); int asprintf_strupper_m(char **strp, const char *fmt, ...); diff --git a/source3/lib/eventlog/eventlog.c b/source3/lib/eventlog/eventlog.c index 0cc0240bcc..7a190bd2c4 100644 --- a/source3/lib/eventlog/eventlog.c +++ b/source3/lib/eventlog/eventlog.c @@ -581,7 +581,7 @@ bool parse_logentry( TALLOC_CTX *mem_ctx, char *line, struct eventlog_Record_tdb } } else if ( 0 == strncmp( start, "STR", stop - start ) ) { size_t tmp_len; - int num_of_strings; + size_t num_of_strings; /* skip past initial ":" */ stop++; /* now skip any other leading whitespace */ diff --git a/source3/lib/util_cmdline.c b/source3/lib/util_cmdline.c index d15f32535b..80c3ecdb46 100644 --- a/source3/lib/util_cmdline.c +++ b/source3/lib/util_cmdline.c @@ -251,7 +251,8 @@ void set_cmdline_auth_info_getpass(struct user_auth_info *auth_info) TALLOC_CTX *frame; if (get_cmdline_auth_info_got_pass(auth_info) || - get_cmdline_auth_info_use_kerberos(auth_info)) { + get_cmdline_auth_info_use_ccache(auth_info) || + get_cmdline_auth_info_use_kerberos(auth_info)) { /* Already got one... */ return; } diff --git a/source3/lib/util_names.c b/source3/lib/util_names.c index cf54a0eece..1392b488e0 100644 --- a/source3/lib/util_names.c +++ b/source3/lib/util_names.c @@ -60,7 +60,15 @@ static bool set_my_netbios_names(const char *name, int i) { SAFE_FREE(smb_my_netbios_names[i]); - smb_my_netbios_names[i] = SMB_STRDUP(name); + /* + * Don't include space for terminating '\0' in strndup, + * it is automatically added. This screws up if the name + * is greater than MAX_NETBIOSNAME_LEN-1 in the unix + * charset, but less than or equal to MAX_NETBIOSNAME_LEN-1 + * in the DOS charset, but this is so old we have to live + * with that. + */ + smb_my_netbios_names[i] = SMB_STRNDUP(name, MAX_NETBIOSNAME_LEN-1); if (!smb_my_netbios_names[i]) return False; return strupper_m(smb_my_netbios_names[i]); diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index d13625b27e..56f0a772b5 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -664,14 +664,13 @@ int ads_keytab_create_default(ADS_STRUCT *ads) goto done; } - oldEntries = talloc_array(frame, char *, found); + oldEntries = talloc_zero_array(frame, char *, found + 1); if (!oldEntries) { DEBUG(1, (__location__ ": Failed to allocate space to store " "the old keytab entries (talloc failed?).\n")); ret = -1; goto done; } - memset(oldEntries, '\0', found * sizeof(char *)); ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret == KRB5_KT_END || ret == ENOENT) { diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8d104c2f59..b9adc9d918 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3300,7 +3300,7 @@ ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads, if (!add_string_to_array(mem_ctx, dn, (const char ***)ous, - (int *)num_ous)) { + num_ous)) { TALLOC_FREE(dn); ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); diff --git a/source3/libnet/libnet_dssync.c b/source3/libnet/libnet_dssync.c index a8431066ef..94f06285a8 100644 --- a/source3/libnet/libnet_dssync.c +++ b/source3/libnet/libnet_dssync.c @@ -195,9 +195,19 @@ static NTSTATUS libnet_dssync_bind(TALLOC_CTX *mem_ctx, ctx->remote_info28.repl_epoch = 0; break; } - case 28: + case 28: { ctx->remote_info28 = bind_info.info.info28; break; + } + case 32: { + struct drsuapi_DsBindInfo32 *info32; + info32 = &bind_info.info.info32; + ctx->remote_info28.site_guid = info32->site_guid; + ctx->remote_info28.supported_extensions = info32->supported_extensions; + ctx->remote_info28.pid = info32->pid; + ctx->remote_info28.repl_epoch = info32->repl_epoch; + break; + } case 48: { struct drsuapi_DsBindInfo48 *info48; info48 = &bind_info.info.info48; @@ -207,6 +217,15 @@ static NTSTATUS libnet_dssync_bind(TALLOC_CTX *mem_ctx, ctx->remote_info28.repl_epoch = info48->repl_epoch; break; } + case 52: { + struct drsuapi_DsBindInfo52 *info52; + info52 = &bind_info.info.info52; + ctx->remote_info28.site_guid = info52->site_guid; + ctx->remote_info28.supported_extensions = info52->supported_extensions; + ctx->remote_info28.pid = info52->pid; + ctx->remote_info28.repl_epoch = info52->repl_epoch; + break; + } default: DEBUG(1, ("Warning: invalid info length in bind info: %d\n", bind_info.length)); diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index aa7b5cb83e..9a34e9423d 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -421,7 +421,7 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, ok = ads_element_in_array(spn_array, num_spns, spn); if (!ok) { ok = add_string_to_array(spn_array, spn, - &spn_array, (int *)&num_spns); + &spn_array, &num_spns); if (!ok) { return ADS_ERROR_LDAP(LDAP_NO_MEMORY); } @@ -446,7 +446,7 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, ok = ads_element_in_array(spn_array, num_spns, spn); if (!ok) { ok = add_string_to_array(spn_array, spn, - &spn_array, (int *)&num_spns); + &spn_array, &num_spns); if (!ok) { return ADS_ERROR_LDAP(LDAP_NO_MEMORY); } diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c index 8eb776a132..aeade88e24 100644 --- a/source3/libsmb/cli_smb2_fnum.c +++ b/source3/libsmb/cli_smb2_fnum.c @@ -501,6 +501,7 @@ NTSTATUS cli_smb2_list(struct cli_state *cli, bool processed_file = false; TALLOC_CTX *frame = talloc_stackframe(); TALLOC_CTX *subframe = NULL; + bool mask_has_wild; if (smbXcli_conn_has_async_calls(cli->conn)) { /* @@ -524,6 +525,8 @@ NTSTATUS cli_smb2_list(struct cli_state *cli, goto fail; } + mask_has_wild = ms_has_wild(mask); + status = cli_smb2_create_fnum(cli, parent_dir, 0, /* create_flags */ @@ -625,6 +628,17 @@ NTSTATUS cli_smb2_list(struct cli_state *cli, TALLOC_FREE(subframe); + if (!mask_has_wild) { + /* + * MacOSX 10 doesn't set STATUS_NO_MORE_FILES + * when handed a non-wildcard path. Do it + * for the server (with a non-wildcard path + * there should only ever be one file returned. + */ + status = STATUS_NO_MORE_FILES; + break; + } + } while (NT_STATUS_IS_OK(status)); if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES)) { diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index e8c9ebfe72..617b34b497 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -383,6 +383,15 @@ static NTSTATUS ntlmssp3_client_challenge(struct ntlmssp_state *ntlmssp_state, wbcErr wbc_status; int i; + /* + * We need to set the netbios name or we are not able to connect + * a Windows DC. + */ + if (ntlmssp_state->server.netbios_domain == NULL || + ntlmssp_state->server.netbios_domain[0] == '\0') { + ntlmssp_state->server.netbios_domain = ntlmssp_state->domain; + } + params.account_name = ntlmssp_state->user; params.domain_name = ntlmssp_state->domain; params.level = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP; @@ -413,9 +422,12 @@ static NTSTATUS ntlmssp3_client_challenge(struct ntlmssp_state *ntlmssp_state, goto noccache; } - *next_request = data_blob(wbc_next->data, wbc_next->length); - ntlmssp_state->session_key = data_blob( - wbc_session_key->data, wbc_session_key->length); + *next_request = data_blob_talloc(ntlmssp_state, + wbc_next->data, + wbc_next->length); + ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state, + wbc_session_key->data, + wbc_session_key->length); wbcFreeMemory(info); goto done; diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c index e402ff1141..b0a00249f1 100644 --- a/source3/modules/vfs_ceph.c +++ b/source3/modules/vfs_ceph.c @@ -795,15 +795,14 @@ static int strict_allocate_ftruncate(struct vfs_handle_struct *handle, files_str return ENOTSUP or EINVAL in cases like that. */ ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE, pst->st_ex_size, space_to_write); - if (ret == ENOSPC) { - errno = ENOSPC; + if (ret == -1 && errno == ENOSPC) { return -1; } if (ret == 0) { return 0; } DEBUG(10,("[CEPH] strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with " - "error %d. Falling back to slow manual allocation\n", ret)); + "error %d. Falling back to slow manual allocation\n", errno)); /* available disk space is enough or not? */ space_avail = get_dfree_info(fsp->conn, @@ -817,13 +816,7 @@ static int strict_allocate_ftruncate(struct vfs_handle_struct *handle, files_str } /* Write out the real space on disk. */ - ret = vfs_slow_fallocate(fsp, pst->st_ex_size, space_to_write); - if (ret != 0) { - errno = ret; - ret = -1; - } - - return 0; + return vfs_slow_fallocate(fsp, pst->st_ex_size, space_to_write); } static int cephwrap_ftruncate(struct vfs_handle_struct *handle, files_struct *fsp, off_t len) diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index ed14c673b5..23c1cc2a00 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -1819,15 +1819,14 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs return ENOTSUP or EINVAL in cases like that. */ ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE, pst->st_ex_size, space_to_write); - if (ret == ENOSPC) { - errno = ENOSPC; + if (ret == -1 && errno == ENOSPC) { return -1; } if (ret == 0) { return 0; } DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with " - "error %d. Falling back to slow manual allocation\n", ret)); + "error %d. Falling back to slow manual allocation\n", errno)); /* available disk space is enough or not? */ space_avail = get_dfree_info(fsp->conn, @@ -1843,8 +1842,7 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs /* Write out the real space on disk. */ ret = vfs_slow_fallocate(fsp, pst->st_ex_size, space_to_write); if (ret != 0) { - errno = ret; - ret = -1; + return -1; } return 0; @@ -1929,6 +1927,15 @@ static int vfswrap_fallocate(vfs_handle_struct *handle, START_PROFILE(syscall_fallocate); if (mode == VFS_FALLOCATE_EXTEND_SIZE) { result = sys_posix_fallocate(fsp->fh->fd, offset, len); + /* + * posix_fallocate returns 0 on success, errno on error + * and doesn't set errno. Make it behave like fallocate() + * which returns -1, and sets errno on failure. + */ + if (result != 0) { + errno = result; + result = -1; + } } else if (mode == VFS_FALLOCATE_KEEP_SIZE) { result = sys_fallocate(fsp->fh->fd, mode, offset, len); } else { diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c index 9bcd0cb67b..ba2d8e8b57 100644 --- a/source3/modules/vfs_glusterfs.c +++ b/source3/modules/vfs_glusterfs.c @@ -19,6 +19,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +/** + * @file vfs_glusterfs.c + * @author Anand Avati <avati@redhat.com> + * @date May 2013 + * @brief Samba VFS module for glusterfs + * + * @todo + * - AIO support\n + * See, for example \c vfs_aio_linux.c in the \c sourc3/modules directory + * - sendfile/recvfile support + * + * A Samba VFS module for GlusterFS, based on Gluster's libgfapi. + * This is a "bottom" vfs module (not something to be stacked on top of + * another module), and translates (most) calls to the closest actions + * available in libgfapi. + * + */ + #include "includes.h" #include "smbd/smbd.h" #include <stdio.h> @@ -27,82 +45,9 @@ #define DEFAULT_VOLFILE_SERVER "localhost" -/* - TODO - ---- - Short term: - - AIO support - - sendfile/recvfile support -*/ - -/* Helpers to provide 'integer' fds */ - -/* This is global. gfapi's FD operations do not - require filesystem context. -*/ - -static glfs_fd_t **glfd_fd; -static int glfd_fd_size; -static int glfd_fd_used; - -static int glfd_fd_store(glfs_fd_t *glfd) -{ - int i; - void *tmp; - - if (glfd_fd_size == glfd_fd_used) { - if (glfd_fd_size >= INT_MAX - 1) { - errno = ENOMEM; - return -1; - } - - tmp = talloc_realloc(glfd_fd, glfd_fd, glfs_fd_t *, - glfd_fd_size + 1); - if (tmp == NULL) { - errno = ENOMEM; - return -1; - } - - glfd_fd = tmp; - glfd_fd[glfd_fd_size] = 0; - glfd_fd_size++; - } - - for (i = 0; i < glfd_fd_size; i++) { - if (glfd_fd[i] == NULL) { - break; - } - } - glfd_fd_used++; - glfd_fd[i] = glfd; - return i; -} - -static glfs_fd_t *glfd_fd_get(int i) -{ - if (i < 0 || i >= glfd_fd_size) { - return NULL; - } - return glfd_fd[i]; -} - -static glfs_fd_t *glfd_fd_clear(int i) -{ - glfs_fd_t *glfd = NULL; - - if (i < 0 || i >= glfd_fd_size) { - return NULL; - } - - glfd = glfd_fd[i]; - - glfd_fd[i] = 0; - glfd_fd_used--; - return glfd; -} - -/* Helper to convert stat to stat_ex */ - +/** + * Helper to convert struct stat to struct stat_ex. + */ static void smb_stat_ex_from_stat(struct stat_ex *dst, const struct stat *src) { ZERO_STRUCTP(dst); @@ -116,23 +61,17 @@ static void smb_stat_ex_from_stat(struct stat_ex *dst, const struct stat *src) dst->st_ex_rdev = src->st_rdev; dst->st_ex_size = src->st_size; dst->st_ex_atime.tv_sec = src->st_atime; -#ifdef STAT_HAVE_NSEC - dst->st_ex_atime.tv_nsec = src->st_atime_nsec; -#endif dst->st_ex_mtime.tv_sec = src->st_mtime; -#ifdef STAT_HAVE_NSEC - dst->st_ex_mtime.tv_nsec = src->st_mtime_nsec; -#endif dst->st_ex_ctime.tv_sec = src->st_ctime; -#ifdef STAT_HAVE_NSEC - dst->st_ex_ctime.tv_nsec = src->st_ctime_nsec; -#endif dst->st_ex_btime.tv_sec = src->st_mtime; + dst->st_ex_blksize = src->st_blksize; + dst->st_ex_blocks = src->st_blocks; #ifdef STAT_HAVE_NSEC + dst->st_ex_atime.tv_nsec = src->st_atime_nsec; + dst->st_ex_mtime.tv_nsec = src->st_mtime_nsec; + dst->st_ex_ctime.tv_nsec = src->st_ctime_nsec; dst->st_ex_btime.tv_nsec = src->st_mtime_nsec; #endif - dst->st_ex_blksize = src->st_blksize; - dst->st_ex_blocks = src->st_blocks; } /* pre-opened glfs_t */ @@ -407,7 +346,7 @@ static DIR *vfs_gluster_fdopendir(struct vfs_handle_struct *handle, files_struct *fsp, const char *mask, uint32 attributes) { - return (DIR *) glfd_fd_get(fsp->fh->fd); + return (DIR *) *(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp); } static int vfs_gluster_closedir(struct vfs_handle_struct *handle, DIR *dirp) @@ -479,6 +418,7 @@ static int vfs_gluster_open(struct vfs_handle_struct *handle, int flags, mode_t mode) { glfs_fd_t *glfd; + glfs_fd_t **p_tmp; if (flags & O_DIRECTORY) { glfd = glfs_opendir(handle->data, smb_fname->base_name); @@ -492,26 +432,33 @@ static int vfs_gluster_open(struct vfs_handle_struct *handle, if (glfd == NULL) { return -1; } - return glfd_fd_store(glfd); + p_tmp = (glfs_fd_t **)VFS_ADD_FSP_EXTENSION(handle, fsp, + glfs_fd_t *, NULL); + *p_tmp = glfd; + /* An arbitrary value for error reporting, so you know its us. */ + return 13371337; } static int vfs_gluster_close(struct vfs_handle_struct *handle, files_struct *fsp) { - return glfs_close(glfd_fd_clear(fsp->fh->fd)); + glfs_fd_t *glfd; + glfd = *(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp); + VFS_REMOVE_FSP_EXTENSION(handle, fsp); + return glfs_close(glfd); } static ssize_t vfs_gluster_read(struct vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n) { - return glfs_read(glfd_fd_get(fsp->fh->fd), data, n, 0); + return glfs_read(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), data, n, 0); } static ssize_t vfs_gluster_pread(struct vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n, off_t offset) { - return glfs_pread(glfd_fd_get(fsp->fh->fd), data, n, offset, 0); + return glfs_pread(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), data, n, offset, 0); } static struct tevent_req *vfs_gluster_pread_send(struct vfs_handle_struct @@ -533,14 +480,14 @@ static ssize_t vfs_gluster_pread_recv(struct tevent_req *req, int *err) static ssize_t vfs_gluster_write(struct vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n) { - return glfs_write(glfd_fd_get(fsp->fh->fd), data, n, 0); + return glfs_write(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), data, n, 0); } static ssize_t vfs_gluster_pwrite(struct vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n, off_t offset) { - return glfs_pwrite(glfd_fd_get(fsp->fh->fd), data, n, offset, 0); + return glfs_pwrite(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), data, n, offset, 0); } static struct tevent_req *vfs_gluster_pwrite_send(struct vfs_handle_struct @@ -563,7 +510,7 @@ static ssize_t vfs_gluster_pwrite_recv(struct tevent_req *req, int *err) static off_t vfs_gluster_lseek(struct vfs_handle_struct *handle, files_struct *fsp, off_t offset, int whence) { - return glfs_lseek(glfd_fd_get(fsp->fh->fd), offset, whence); + return glfs_lseek(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), offset, whence); } static ssize_t vfs_gluster_sendfile(struct vfs_handle_struct *handle, int tofd, @@ -594,7 +541,7 @@ static int vfs_gluster_rename(struct vfs_handle_struct *handle, static int vfs_gluster_fsync(struct vfs_handle_struct *handle, files_struct *fsp) { - return glfs_fsync(glfd_fd_get(fsp->fh->fd)); + return glfs_fsync(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp)); } static struct tevent_req *vfs_gluster_fsync_send(struct vfs_handle_struct @@ -635,7 +582,7 @@ static int vfs_gluster_fstat(struct vfs_handle_struct *handle, struct stat st; int ret; - ret = glfs_fstat(glfd_fd_get(fsp->fh->fd), &st); + ret = glfs_fstat(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), &st); if (ret == 0) { smb_stat_ex_from_stat(sbuf, &st); } @@ -685,7 +632,7 @@ static int vfs_gluster_chmod(struct vfs_handle_struct *handle, static int vfs_gluster_fchmod(struct vfs_handle_struct *handle, files_struct *fsp, mode_t mode) { - return glfs_fchmod(glfd_fd_get(fsp->fh->fd), mode); + return glfs_fchmod(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), mode); } static int vfs_gluster_chown(struct vfs_handle_struct *handle, @@ -697,7 +644,7 @@ static int vfs_gluster_chown(struct vfs_handle_struct *handle, static int vfs_gluster_fchown(struct vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid) { - return glfs_fchown(glfd_fd_get(fsp->fh->fd), uid, gid); + return glfs_fchown(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), uid, gid); } static int vfs_gluster_lchown(struct vfs_handle_struct *handle, @@ -763,7 +710,7 @@ static int vfs_gluster_ntimes(struct vfs_handle_struct *handle, static int vfs_gluster_ftruncate(struct vfs_handle_struct *handle, files_struct *fsp, off_t offset) { - return glfs_ftruncate(glfd_fd_get(fsp->fh->fd), offset); + return glfs_ftruncate(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), offset); } static int vfs_gluster_fallocate(struct vfs_handle_struct *handle, @@ -794,7 +741,7 @@ static bool vfs_gluster_lock(struct vfs_handle_struct *handle, flock.l_len = count; flock.l_pid = 0; - ret = glfs_posix_lock(glfd_fd_get(fsp->fh->fd), op, &flock); + ret = glfs_posix_lock(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), op, &flock); if (op == F_GETLK) { /* lock query, true if someone else has locked */ @@ -841,7 +788,7 @@ static bool vfs_gluster_getlock(struct vfs_handle_struct *handle, flock.l_len = *pcount; flock.l_pid = 0; - ret = glfs_posix_lock(glfd_fd_get(fsp->fh->fd), F_GETLK, &flock); + ret = glfs_posix_lock(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), F_GETLK, &flock); if (ret == -1) { return false; @@ -949,7 +896,7 @@ static ssize_t vfs_gluster_fgetxattr(struct vfs_handle_struct *handle, files_struct *fsp, const char *name, void *value, size_t size) { - return glfs_fgetxattr(glfd_fd_get(fsp->fh->fd), name, value, size); + return glfs_fgetxattr(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), name, value, size); } static ssize_t vfs_gluster_listxattr(struct vfs_handle_struct *handle, @@ -962,7 +909,7 @@ static ssize_t vfs_gluster_flistxattr(struct vfs_handle_struct *handle, files_struct *fsp, char *list, size_t size) { - return glfs_flistxattr(glfd_fd_get(fsp->fh->fd), list, size); + return glfs_flistxattr(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), list, size); } static int vfs_gluster_removexattr(struct vfs_handle_struct *handle, @@ -974,7 +921,7 @@ static int vfs_gluster_removexattr(struct vfs_handle_struct *handle, static int vfs_gluster_fremovexattr(struct vfs_handle_struct *handle, files_struct *fsp, const char *name) { - return glfs_fremovexattr(glfd_fd_get(fsp->fh->fd), name); + return glfs_fremovexattr(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), name); } static int vfs_gluster_setxattr(struct vfs_handle_struct *handle, @@ -988,7 +935,7 @@ static int vfs_gluster_fsetxattr(struct vfs_handle_struct *handle, files_struct *fsp, const char *name, const void *value, size_t size, int flags) { - return glfs_fsetxattr(glfd_fd_get(fsp->fh->fd), name, value, size, + return glfs_fsetxattr(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), name, value, size, flags); } @@ -1365,16 +1312,16 @@ static SMB_ACL_T vfs_gluster_sys_acl_get_fd(struct vfs_handle_struct *handle, struct smb_acl_t *result; int ret; char *buf; + glfs_fd_t *glfd; - ret = glfs_fgetxattr(glfd_fd_get(fsp->fh->fd), - "system.posix_acl_access", 0, 0); + glfd = *(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp); + ret = glfs_fgetxattr(glfd, "system.posix_acl_access", 0, 0); if (ret <= 0) { return NULL; } buf = alloca(ret); - ret = glfs_fgetxattr(glfd_fd_get(fsp->fh->fd), - "system.posix_acl_access", buf, ret); + ret = glfs_fgetxattr(glfd, "system.posix_acl_access", buf, ret); if (ret <= 0) { return NULL; } @@ -1435,7 +1382,7 @@ static int vfs_gluster_sys_acl_set_fd(struct vfs_handle_struct *handle, return -1; } - ret = glfs_fsetxattr(glfd_fd_get(fsp->fh->fd), + ret = glfs_fsetxattr(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), "system.posix_acl_access", buf, size, 0); return ret; } diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index 5e9bd3e864..0409c058d7 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -1021,11 +1021,12 @@ static int streams_xattr_fallocate(struct vfs_handle_struct *handle, } if (!streams_xattr_recheck(sio)) { - return errno; + return -1; } /* Let the pwrite code path handle it. */ - return ENOSYS; + errno = ENOSYS; + return -1; } diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index 1b14d650af..e0dcc90a67 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -1211,18 +1211,24 @@ static int smb_time_audit_fallocate(vfs_handle_struct *handle, off_t len) { int result; + int saved_errno = 0; struct timespec ts1,ts2; double timediff; clock_gettime_mono(&ts1); result = SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len); + if (result == -1) { + saved_errno = errno; + } clock_gettime_mono(&ts2); timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9; if (timediff > audit_timeout) { smb_time_audit_log_fsp("fallocate", timediff, fsp); } - + if (result == -1) { + errno = saved_errno; + } return result; } diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index 9ea662c50f..ae84818a07 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -798,7 +798,8 @@ static bool open_sockets(bool isdaemon, int port) {"hosts", 'H', POPT_ARG_STRING, &p_lmhosts, 0, "Load a netbios hosts file"}, {"port", 'p', POPT_ARG_INT, &global_nmb_port, 0, "Listen on the specified port" }, POPT_COMMON_SAMBA - { NULL } + POPT_COMMON_DYNCONFIG + POPT_TABLEEND }; TALLOC_CTX *frame; NTSTATUS status; diff --git a/source3/nmbd/nmbd_nameregister.c b/source3/nmbd/nmbd_nameregister.c index 71c4751d7c..8b078e6859 100644 --- a/source3/nmbd/nmbd_nameregister.c +++ b/source3/nmbd/nmbd_nameregister.c @@ -482,17 +482,77 @@ void register_name(struct subnet_record *subrec, { struct nmb_name nmbname; nstring nname; + size_t converted_size; errno = 0; - push_ascii_nstring(nname, name); - if (errno == E2BIG) { - unstring tname; - pull_ascii_nstring(tname, sizeof(tname), nname); - DEBUG(0,("register_name: NetBIOS name %s is too long. Truncating to %s\n", - name, tname)); - make_nmb_name(&nmbname, tname, type); - } else { + converted_size = push_ascii_nstring(nname, name); + if (converted_size != (size_t)-1) { + /* Success. */ make_nmb_name(&nmbname, name, type); + } else if (errno == E2BIG) { + /* + * Name converted to CH_DOS is too large. + * try to truncate. + */ + char *converted_str_dos = NULL; + char *converted_str_unix = NULL; + bool ok; + + converted_size = 0; + + ok = convert_string_talloc(talloc_tos(), + CH_UNIX, + CH_DOS, + name, + strlen(name)+1, + &converted_str_dos, + &converted_size); + if (!ok) { + DEBUG(0,("register_name: NetBIOS name %s cannot be " + "converted. Failing to register name.\n", + name)); + return; + } + + /* + * As it's now CH_DOS codepage + * we truncate by writing '\0' at + * MAX_NETBIOSNAME_LEN-1 and then + * convert back to CH_UNIX which we + * need for the make_nmb_name() call. + */ + if (converted_size >= MAX_NETBIOSNAME_LEN) { + converted_str_dos[MAX_NETBIOSNAME_LEN-1] = '\0'; + } + + ok = convert_string_talloc(talloc_tos(), + CH_DOS, + CH_UNIX, + converted_str_dos, + strlen(converted_str_dos)+1, + &converted_str_unix, + &converted_size); + if (!ok) { + DEBUG(0,("register_name: NetBIOS name %s cannot be " + "converted back to CH_UNIX. " + "Failing to register name.\n", + converted_str_dos)); + TALLOC_FREE(converted_str_dos); + return; + } + + make_nmb_name(&nmbname, converted_str_unix, type); + + TALLOC_FREE(converted_str_dos); + TALLOC_FREE(converted_str_unix); + } else { + /* + * Generic conversion error. Fail to register. + */ + DEBUG(0,("register_name: NetBIOS name %s cannot be " + "converted (%s). Failing to register name.\n", + name, strerror(errno))); + return; } /* Always set the NB_ACTIVE flag on the name we are diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index f256e6c7fb..d6ef15565c 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -600,7 +600,7 @@ static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, if (!init_samu_from_buffer(user, SAMU_BUFFER_LATEST, data.dptr, data.dsize)) { DEBUG(0,("pdb_getsampwent: Bad struct samu entry returned from TDB!\n")); - SAFE_FREE(data.dptr); + TALLOC_FREE(data.dptr); return NT_STATUS_NO_MEMORY; } diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 52d24dcccc..3129e10edf 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -490,19 +490,18 @@ err_out: return pjob; } -/* Convert a unix jobid to a smb jobid */ - -struct unixjob_traverse_state { +struct job_traverse_state { int sysjob; - uint32 sysjob_to_jobid_value; + uint32_t jobid; }; -static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, - TDB_DATA data, void *private_data) +/* find spoolss jobid based on sysjob */ +static int sysjob_to_jobid_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, + TDB_DATA data, void *private_data) { struct printjob *pjob; - struct unixjob_traverse_state *state = - (struct unixjob_traverse_state *)private_data; + struct job_traverse_state *state = + (struct job_traverse_state *)private_data; if (!data.dptr || data.dsize == 0) return 0; @@ -512,7 +511,7 @@ static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, return 0; if (state->sysjob == pjob->sysjob) { - state->sysjob_to_jobid_value = pjob->jobid; + state->jobid = pjob->jobid; return 1; } @@ -521,14 +520,14 @@ static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, uint32 sysjob_to_jobid_pdb(struct tdb_print_db *pdb, int sysjob) { - struct unixjob_traverse_state state; + struct job_traverse_state state; state.sysjob = sysjob; - state.sysjob_to_jobid_value = (uint32)-1; + state.jobid = (uint32_t)-1; - tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state); + tdb_traverse(pdb->tdb, sysjob_to_jobid_traverse_fn, &state); - return state.sysjob_to_jobid_value; + return state.jobid; } /**************************************************************************** @@ -540,10 +539,10 @@ uint32 sysjob_to_jobid(int unix_jobid) { int services = lp_numservices(); int snum; - struct unixjob_traverse_state state; + struct job_traverse_state state; state.sysjob = unix_jobid; - state.sysjob_to_jobid_value = (uint32)-1; + state.jobid = (uint32_t)-1; for (snum = 0; snum < services; snum++) { struct tdb_print_db *pdb; @@ -553,14 +552,49 @@ uint32 sysjob_to_jobid(int unix_jobid) if (!pdb) { continue; } - tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state); + tdb_traverse(pdb->tdb, sysjob_to_jobid_traverse_fn, &state); release_print_db(pdb); - if (state.sysjob_to_jobid_value != (uint32)-1) - return state.sysjob_to_jobid_value; + if (state.jobid != (uint32_t)-1) + return state.jobid; } return (uint32)-1; } +/* find sysjob based on spoolss jobid */ +static int jobid_to_sysjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, + TDB_DATA data, void *private_data) +{ + struct printjob *pjob; + struct job_traverse_state *state = + (struct job_traverse_state *)private_data; + + if (!data.dptr || data.dsize == 0) + return 0; + + pjob = (struct printjob *)data.dptr; + if (key.dsize != sizeof(uint32_t)) + return 0; + + if (state->jobid == pjob->jobid) { + state->sysjob = pjob->sysjob; + return 1; + } + + return 0; +} + +int jobid_to_sysjob_pdb(struct tdb_print_db *pdb, uint32_t jobid) +{ + struct job_traverse_state state; + + state.sysjob = -1; + state.jobid = jobid; + + tdb_traverse(pdb->tdb, jobid_to_sysjob_traverse_fn, &state); + + return state.sysjob; +} + /**************************************************************************** Send notifications based on what has changed after a pjob_store. ****************************************************************************/ diff --git a/source3/registry/regfio.c b/source3/registry/regfio.c index fe800948c2..e49de2625e 100644 --- a/source3/registry/regfio.c +++ b/source3/registry/regfio.c @@ -768,8 +768,10 @@ static bool hbin_prs_sk_rec( const char *desc, REGF_HBIN *hbin, int depth, REGF_ if (!prs_copy_data_in(&hbin->ps, (const char *)blob.data, blob.length)) return False; } else { - blob = data_blob_const(prs_data_p(&hbin->ps), - prs_data_size(&hbin->ps)); + blob = data_blob_const( + prs_data_p(&hbin->ps) + prs_offset(&hbin->ps), + prs_data_size(&hbin->ps) - prs_offset(&hbin->ps) + ); status = unmarshall_sec_desc(mem_ctx, blob.data, blob.length, &sk->sec_desc); @@ -1739,7 +1741,7 @@ static bool create_vk_record(REGF_FILE *file, REGF_VK_REC *vk, /* make sure we don't try to copy from a NULL value pointer */ if ( vk->data_size != 0 ) - memcpy( &vk->data_off, regval_data_p(value), sizeof(uint32) ); + memcpy( &vk->data_off, regval_data_p(value), vk->data_size); vk->data_size |= VK_DATA_IN_OFFSET; } @@ -1804,7 +1806,7 @@ static int hashrec_cmp( REGF_HASH_REC *h1, REGF_HASH_REC *h2 ) REGF_HASH_REC *hash = &parent->subkeys.hashes[parent->subkey_index]; hash->nk_off = prs_offset( &nk->hbin->ps ) + nk->hbin->first_hbin_off - HBIN_HDR_SIZE; - memcpy( hash->keycheck, name, sizeof(uint32) ); + memcpy(hash->keycheck, name, MIN(strlen(name),sizeof(uint32))); hash->fullname = talloc_strdup( file->mem_ctx, name ); parent->subkey_index++; diff --git a/source3/rpc_server/lsa/srv_lsa_nt.c b/source3/rpc_server/lsa/srv_lsa_nt.c index 46f42d5320..6b0028bdb3 100644 --- a/source3/rpc_server/lsa/srv_lsa_nt.c +++ b/source3/rpc_server/lsa/srv_lsa_nt.c @@ -3335,7 +3335,7 @@ static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx, uint32 i; const char *privname; const char **privname_array = NULL; - int num_priv = 0; + size_t num_priv = 0; for (i=0; i<privileges->count; i++) { if (privileges->set[i].luid.high) { diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c index e5ca474064..2ba3278320 100644 --- a/source3/rpc_server/netlogon/srv_netlog_nt.c +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c @@ -397,7 +397,7 @@ NTSTATUS _netr_NetrEnumerateTrustedDomains(struct pipes_struct *p, NTSTATUS status; NTSTATUS result = NT_STATUS_OK; DATA_BLOB blob; - int num_domains = 0; + size_t num_domains = 0; const char **trusted_domains = NULL; struct lsa_DomainList domain_list; struct dcerpc_binding_handle *h = NULL; @@ -1101,6 +1101,10 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p, bool schannel_global_required = (lp_server_schannel() == true) ? true:false; struct loadparm_context *lp_ctx; + if (creds_out != NULL) { + *creds_out = NULL; + } + if (schannel_global_required) { status = schannel_check_required(&p->auth, computer_name, @@ -1258,7 +1262,7 @@ NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p, { NTSTATUS status = NT_STATUS_OK; int i; - struct netlogon_creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds = NULL; DEBUG(5,("_netr_ServerPasswordSet: %d\n", __LINE__)); @@ -1271,9 +1275,14 @@ NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p, unbecome_root(); if (!NT_STATUS_IS_OK(status)) { + const char *computer_name = "<unknown>"; + + if (creds != NULL && creds->computer_name != NULL) { + computer_name = creds->computer_name; + } DEBUG(2,("_netr_ServerPasswordSet: netlogon_creds_server_step failed. Rejecting auth " "request from client %s machine account %s\n", - r->in.computer_name, creds->computer_name)); + r->in.computer_name, computer_name)); TALLOC_FREE(creds); return status; } diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c index 335647bf16..c451212449 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_nt.c +++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c @@ -4897,7 +4897,8 @@ static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx, const char *arch, int version) { - int i, num_strings = 0; + int i; + size_t num_strings = 0; const char **array = NULL; if (string_array == NULL) { @@ -7052,6 +7053,7 @@ fill_job_info1 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx, struct spoolss_JobInfo1 *r, const print_queue_struct *queue, + uint32_t jobid, int position, int snum, struct spoolss_PrinterInfo2 *pinfo2) { @@ -7059,7 +7061,7 @@ static WERROR fill_job_info1(TALLOC_CTX *mem_ctx, t = gmtime(&queue->time); - r->job_id = queue->sysjob; + r->job_id = jobid; r->printer_name = lp_servicename(mem_ctx, snum); W_ERROR_HAVE_NO_MEMORY(r->printer_name); @@ -7092,6 +7094,7 @@ fill_job_info2 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx, struct spoolss_JobInfo2 *r, const print_queue_struct *queue, + uint32_t jobid, int position, int snum, struct spoolss_PrinterInfo2 *pinfo2, struct spoolss_DeviceMode *devmode) @@ -7100,7 +7103,7 @@ static WERROR fill_job_info2(TALLOC_CTX *mem_ctx, t = gmtime(&queue->time); - r->job_id = queue->sysjob; + r->job_id = jobid; r->printer_name = lp_servicename(mem_ctx, snum); W_ERROR_HAVE_NO_MEMORY(r->printer_name); @@ -7143,27 +7146,6 @@ static WERROR fill_job_info2(TALLOC_CTX *mem_ctx, } /**************************************************************************** -fill_job_info3 -****************************************************************************/ - -static WERROR fill_job_info3(TALLOC_CTX *mem_ctx, - struct spoolss_JobInfo3 *r, - const print_queue_struct *queue, - const print_queue_struct *next_queue, - int position, int snum, - struct spoolss_PrinterInfo2 *pinfo2) -{ - r->job_id = queue->sysjob; - r->next_job_id = 0; - if (next_queue) { - r->next_job_id = next_queue->sysjob; - } - r->reserved = 0; - - return WERR_OK; -} - -/**************************************************************************** Enumjobs at level 1. ****************************************************************************/ @@ -7177,34 +7159,56 @@ static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx, union spoolss_JobInfo *info; int i; WERROR result = WERR_OK; + uint32_t num_filled; + struct tdb_print_db *pdb; info = talloc_array(mem_ctx, union spoolss_JobInfo, num_queues); - W_ERROR_HAVE_NO_MEMORY(info); + if (info == NULL) { + result = WERR_NOMEM; + goto err_out; + } - *count = num_queues; + pdb = get_print_db_byname(pinfo2->sharename); + if (pdb == NULL) { + result = WERR_INVALID_PARAM; + goto err_info_free; + } + + num_filled = 0; + for (i = 0; i < num_queues; i++) { + uint32_t jobid = sysjob_to_jobid_pdb(pdb, queue[i].sysjob); + if (jobid == (uint32_t)-1) { + DEBUG(4, ("skipping sysjob %d\n", queue[i].sysjob)); + continue; + } - for (i=0; i<*count; i++) { result = fill_job_info1(info, - &info[i].info1, + &info[num_filled].info1, &queue[i], + jobid, i, snum, pinfo2); if (!W_ERROR_IS_OK(result)) { - goto out; + goto err_pdb_drop; } - } - out: - if (!W_ERROR_IS_OK(result)) { - TALLOC_FREE(info); - *count = 0; - return result; + num_filled++; } + release_print_db(pdb); *info_p = info; + *count = num_filled; return WERR_OK; + +err_pdb_drop: + release_print_db(pdb); +err_info_free: + TALLOC_FREE(info); +err_out: + *count = 0; + return result; } /**************************************************************************** @@ -7221,45 +7225,65 @@ static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx, union spoolss_JobInfo *info; int i; WERROR result = WERR_OK; + uint32_t num_filled; + struct tdb_print_db *pdb; info = talloc_array(mem_ctx, union spoolss_JobInfo, num_queues); - W_ERROR_HAVE_NO_MEMORY(info); + if (info == NULL) { + result = WERR_NOMEM; + goto err_out; + } - *count = num_queues; + pdb = get_print_db_byname(pinfo2->sharename); + if (pdb == NULL) { + result = WERR_INVALID_PARAM; + goto err_info_free; + } - for (i=0; i<*count; i++) { + num_filled = 0; + for (i = 0; i< num_queues; i++) { struct spoolss_DeviceMode *devmode; + uint32_t jobid = sysjob_to_jobid_pdb(pdb, queue[i].sysjob); + if (jobid == (uint32_t)-1) { + DEBUG(4, ("skipping sysjob %d\n", queue[i].sysjob)); + continue; + } result = spoolss_create_default_devmode(info, pinfo2->printername, &devmode); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Can't proceed w/o a devmode!")); - goto out; + goto err_pdb_drop; } result = fill_job_info2(info, - &info[i].info2, + &info[num_filled].info2, &queue[i], + jobid, i, snum, pinfo2, devmode); if (!W_ERROR_IS_OK(result)) { - goto out; + goto err_pdb_drop; } + num_filled++; } - out: - if (!W_ERROR_IS_OK(result)) { - TALLOC_FREE(info); - *count = 0; - return result; - } - + release_print_db(pdb); *info_p = info; + *count = num_filled; return WERR_OK; + +err_pdb_drop: + release_print_db(pdb); +err_info_free: + TALLOC_FREE(info); +err_out: + *count = 0; + return result; } /**************************************************************************** @@ -7276,41 +7300,51 @@ static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx, union spoolss_JobInfo *info; int i; WERROR result = WERR_OK; + uint32_t num_filled; + struct tdb_print_db *pdb; info = talloc_array(mem_ctx, union spoolss_JobInfo, num_queues); - W_ERROR_HAVE_NO_MEMORY(info); - - *count = num_queues; + if (info == NULL) { + result = WERR_NOMEM; + goto err_out; + } - for (i=0; i<*count; i++) { - const print_queue_struct *next_queue = NULL; + pdb = get_print_db_byname(pinfo2->sharename); + if (pdb == NULL) { + result = WERR_INVALID_PARAM; + goto err_info_free; + } - if (i+1 < *count) { - next_queue = &queue[i+1]; + num_filled = 0; + for (i = 0; i < num_queues; i++) { + uint32_t jobid = sysjob_to_jobid_pdb(pdb, queue[i].sysjob); + if (jobid == (uint32_t)-1) { + DEBUG(4, ("skipping sysjob %d\n", queue[i].sysjob)); + continue; } - result = fill_job_info3(info, - &info[i].info3, - &queue[i], - next_queue, - i, - snum, - pinfo2); - if (!W_ERROR_IS_OK(result)) { - goto out; - } - } + info[num_filled].info3.job_id = jobid; + /* next_job_id is overwritten on next iteration */ + info[num_filled].info3.next_job_id = 0; + info[num_filled].info3.reserved = 0; - out: - if (!W_ERROR_IS_OK(result)) { - TALLOC_FREE(info); - *count = 0; - return result; + if (num_filled > 0) { + info[num_filled - 1].info3.next_job_id = jobid; + } + num_filled++; } + release_print_db(pdb); *info_p = info; + *count = num_filled; return WERR_OK; + +err_info_free: + TALLOC_FREE(info); +err_out: + *count = 0; + return result; } /**************************************************************** @@ -7333,6 +7367,11 @@ WERROR _spoolss_EnumJobs(struct pipes_struct *p, return WERR_INVALID_PARAM; } + if ((r->in.level != 1) && (r->in.level != 2) && (r->in.level != 3)) { + DEBUG(4, ("EnumJobs level %d not supported\n", r->in.level)); + return WERR_UNKNOWN_LEVEL; + } + DEBUG(4,("_spoolss_EnumJobs\n")); *r->out.needed = 0; @@ -7378,7 +7417,7 @@ WERROR _spoolss_EnumJobs(struct pipes_struct *p, pinfo2, r->out.info, r->out.count); break; default: - result = WERR_UNKNOWN_LEVEL; + SMB_ASSERT(false); /* level checked on entry */ break; } @@ -9337,13 +9376,14 @@ static WERROR getjob_level_1(TALLOC_CTX *mem_ctx, int count, int snum, struct spoolss_PrinterInfo2 *pinfo2, uint32_t jobid, + int sysjob, struct spoolss_JobInfo1 *r) { int i = 0; bool found = false; for (i=0; i<count; i++) { - if (queue[i].sysjob == (int)jobid) { + if (queue[i].sysjob == sysjob) { found = true; break; } @@ -9357,6 +9397,7 @@ static WERROR getjob_level_1(TALLOC_CTX *mem_ctx, return fill_job_info1(mem_ctx, r, &queue[i], + jobid, i, snum, pinfo2); @@ -9370,6 +9411,7 @@ static WERROR getjob_level_2(TALLOC_CTX *mem_ctx, int count, int snum, struct spoolss_PrinterInfo2 *pinfo2, uint32_t jobid, + int sysjob, struct spoolss_JobInfo2 *r) { int i = 0; @@ -9378,7 +9420,7 @@ static WERROR getjob_level_2(TALLOC_CTX *mem_ctx, WERROR result; for (i=0; i<count; i++) { - if (queue[i].sysjob == (int)jobid) { + if (queue[i].sysjob == sysjob) { found = true; break; } @@ -9410,6 +9452,7 @@ static WERROR getjob_level_2(TALLOC_CTX *mem_ctx, return fill_job_info2(mem_ctx, r, &queue[i], + jobid, i, snum, pinfo2, @@ -9425,8 +9468,11 @@ WERROR _spoolss_GetJob(struct pipes_struct *p, { WERROR result = WERR_OK; struct spoolss_PrinterInfo2 *pinfo2 = NULL; + const char *svc_name; + int sysjob; int snum; int count; + struct tdb_print_db *pdb; print_queue_struct *queue = NULL; print_status_struct prt_status; @@ -9444,15 +9490,35 @@ WERROR _spoolss_GetJob(struct pipes_struct *p, return WERR_BADFID; } + svc_name = lp_const_servicename(snum); + if (svc_name == NULL) { + return WERR_INVALID_PARAM; + } + result = winreg_get_printer_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, - lp_const_servicename(snum), + svc_name, &pinfo2); if (!W_ERROR_IS_OK(result)) { return result; } + pdb = get_print_db_byname(svc_name); + if (pdb == NULL) { + DEBUG(3, ("failed to get print db for svc %s\n", svc_name)); + TALLOC_FREE(pinfo2); + return WERR_INVALID_PARAM; + } + + sysjob = jobid_to_sysjob_pdb(pdb, r->in.job_id); + release_print_db(pdb); + if (sysjob == -1) { + DEBUG(3, ("no sysjob for spoolss jobid %u\n", r->in.job_id)); + TALLOC_FREE(pinfo2); + return WERR_INVALID_PARAM; + } + count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status); DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n", @@ -9462,12 +9528,14 @@ WERROR _spoolss_GetJob(struct pipes_struct *p, case 1: result = getjob_level_1(p->mem_ctx, queue, count, snum, pinfo2, - r->in.job_id, &r->out.info->info1); + r->in.job_id, sysjob, + &r->out.info->info1); break; case 2: result = getjob_level_2(p->mem_ctx, queue, count, snum, pinfo2, - r->in.job_id, &r->out.info->info2); + r->in.job_id, sysjob, + &r->out.info->info2); break; default: result = WERR_UNKNOWN_LEVEL; diff --git a/source3/rpcclient/cmd_drsuapi.c b/source3/rpcclient/cmd_drsuapi.c index 0c281cf8d1..6a1fac7bfa 100644 --- a/source3/rpcclient/cmd_drsuapi.c +++ b/source3/rpcclient/cmd_drsuapi.c @@ -420,8 +420,12 @@ static WERROR cmd_drsuapi_getncchanges(struct rpc_pipe_client *cli, supported_extensions = bind_info.info.info24.supported_extensions; } else if (bind_info.length == 28) { supported_extensions = bind_info.info.info28.supported_extensions; + } else if (bind_info.length == 32) { + supported_extensions = bind_info.info.info32.supported_extensions; } else if (bind_info.length == 48) { supported_extensions = bind_info.info.info48.supported_extensions; + } else if (bind_info.length == 52) { + supported_extensions = bind_info.info.info52.supported_extensions; } if (!nc_dn) { diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 5c499d4638..3f83abfb2b 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -1659,7 +1659,7 @@ static bool init_drv_info_3_members(TALLOC_CTX *mem_ctx, struct spoolss_AddDrive char *args) { char *str, *str2; - int count = 0; + size_t count = 0; char *saveptr = NULL; struct spoolss_StringArray *deps; const char **file_array = NULL; @@ -2636,7 +2636,8 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, data.binary = strhex_to_data_blob(mem_ctx, argv[4]); break; case REG_MULTI_SZ: { - int i, num_strings; + int i; + size_t num_strings; const char **strings = NULL; num_strings = 0; diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh index 596cd425ff..f73643f448 100755 --- a/source3/script/tests/test_smbclient_s3.sh +++ b/source3/script/tests/test_smbclient_s3.sh @@ -602,7 +602,7 @@ test_ccache_access() return fi - $SMBCLIENT //$SERVER_IP/tmp -C -U "${USERNAME}%" \ + $SMBCLIENT //$SERVER_IP/tmp -C -U "${USERNAME}" \ -c quit 2>&1 ret=$? @@ -621,7 +621,7 @@ test_ccache_access() return fi - $SMBCLIENT //$SERVER_IP/tmp -C -U "${USERNAME}%" \ + $SMBCLIENT //$SERVER_IP/tmp -C -U "${USERNAME}" \ -c quit 2>&1 ret=$? diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index f2d39b808a..ed4de13e8d 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -151,6 +151,9 @@ static void downgrade_file_oplock(files_struct *fsp) sconn->oplocks.level_II_open++; fsp->sent_oplock_break = NO_BREAK_SENT; + flush_write_cache(fsp, OPLOCK_RELEASE_FLUSH); + delete_write_cache(fsp); + TALLOC_FREE(fsp->oplock_timeout); } diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 45bde2f085..d01bf39f08 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -201,7 +201,7 @@ out: SMB_PERFCOUNT_END(pcd); smbd_unlock_socket(sconn); - return true; + return (ret > 0); } /******************************************************************* diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 58eddee54a..f7798fadd7 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -1910,11 +1910,6 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) if (x != NULL) { signing_required = x->global->signing_required; encryption_required = x->global->encryption_required; - - if (opcode == SMB2_OP_SESSSETUP && - x->global->channels[0].signing_key.length) { - signing_required = true; - } } req->do_signing = false; diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index e911945fb6..a82d696027 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -422,6 +422,10 @@ static NTSTATUS smbd_smb2_reauth_generic_return(struct smbXsrv_session *session, conn_clear_vuid_caches(conn->sconn, session->compat->vuid); + if (security_session_user_level(session_info, NULL) >= SECURITY_USER) { + smb2req->do_signing = true; + } + *out_session_id = session->global->session_wire_id; return NT_STATUS_OK; diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 4a0588e6f5..cdd5042d1f 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -580,6 +580,10 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len) return 0; } + if (ret == -1 && errno == ENOSPC) { + return -1; + } + len -= fsp->fsp_name->st.st_ex_size; len /= 1024; /* Len is now number of 1k blocks needed. */ space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false, @@ -634,7 +638,7 @@ int vfs_set_filelen(files_struct *fsp, off_t len) fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE as this is also called from the default SMB_VFS_FTRUNCATE code. Always extends the file size. - Returns 0 on success, errno on failure. + Returns 0 on success, -1 on failure. ****************************************************************************/ #define SPARSE_BUF_WRITE_SIZE (32*1024) @@ -648,7 +652,7 @@ int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len) sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE); if (!sparse_buf) { errno = ENOMEM; - return ENOMEM; + return -1; } } @@ -657,10 +661,12 @@ int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len) pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total); if (pwrite_ret == -1) { + int saved_errno = errno; DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file " "%s failed with error %s\n", - fsp_str_dbg(fsp), strerror(errno))); - return errno; + fsp_str_dbg(fsp), strerror(saved_errno))); + errno = saved_errno; + return -1; } total += pwrite_ret; } @@ -718,9 +724,7 @@ int vfs_fill_sparse(files_struct *fsp, off_t len) * return ENOTSUP or EINVAL in cases like that. */ ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE, offset, num_to_write); - if (ret == ENOSPC) { - errno = ENOSPC; - ret = -1; + if (ret == -1 && errno == ENOSPC) { goto out; } if (ret == 0) { @@ -731,10 +735,6 @@ int vfs_fill_sparse(files_struct *fsp, off_t len) } ret = vfs_slow_fallocate(fsp, offset, num_to_write); - if (ret != 0) { - errno = ret; - ret = -1; - } out: diff --git a/source3/utils/profiles.c b/source3/utils/profiles.c index 30c6ad0a1f..a88469a919 100644 --- a/source3/utils/profiles.c +++ b/source3/utils/profiles.c @@ -182,12 +182,12 @@ static bool copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk, } } - /* values is a talloc()'d child of subkeys here so just throw it all away */ - - TALLOC_FREE( subkeys ); verbose_output("[%s]\n", path); + /* values is a talloc()'d child of subkeys here so just throw it all away */ + TALLOC_FREE(subkeys); + return True; } diff --git a/source3/utils/status.c b/source3/utils/status.c index be7c52fac4..9ce92aafb4 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -363,6 +363,7 @@ static void print_notify_recs(const char *path, TALLOC_CTX *frame = talloc_stackframe(); int ret = 0; struct messaging_context *msg_ctx; + bool ok; sec_init(); load_case_tables(); @@ -462,10 +463,12 @@ static void print_notify_recs(const char *path, switch (profile_only) { case 'P': /* Dump profile data */ - return status_profile_dump(verbose); + ok = status_profile_dump(verbose); + return ok ? 0 : 1; case 'R': /* Continuously display rate-converted data */ - return status_profile_rates(verbose); + ok = status_profile_rates(verbose); + return ok ? 0 : 1; default: break; } diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index f101e52f65..27c43dc29d 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -1364,6 +1364,7 @@ int main(int argc, char **argv, char **envp) { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" }, { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" }, POPT_COMMON_SAMBA + POPT_COMMON_DYNCONFIG POPT_TABLEEND }; poptContext pc; diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 8bbc886855..ee4b482204 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -1443,7 +1443,7 @@ static bool find_new_dc(TALLOC_CTX *mem_ctx, int num_dcs = 0; const char **dcnames = NULL; - int num_dcnames = 0; + size_t num_dcnames = 0; struct sockaddr_storage *addrs = NULL; int num_addrs = 0; diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index b873655579..911fd7565b 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -687,13 +687,23 @@ NTSTATUS _wbint_PingDc(struct pipes_struct *p, struct wbint_PingDc *r) WERROR werr; fstring logon_server; struct dcerpc_binding_handle *b; + bool retry = false; domain = wb_child_domain(); if (domain == NULL) { return NT_STATUS_REQUEST_NOT_ACCEPTED; } +reconnect: status = cm_connect_netlogon(domain, &netlogon_pipe); + if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) { + /* + * Retry to open new connection with new kerberos ticket. + */ + invalidate_cm_connection(&domain->conn); + status = cm_connect_netlogon(domain, &netlogon_pipe); + } + reset_cm_connection_on_error(domain, status); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("could not open handle to NETLOGON pipe: %s\n", @@ -720,6 +730,14 @@ NTSTATUS _wbint_PingDc(struct pipes_struct *p, struct wbint_PingDc *r) logon_server, NETLOGON_CONTROL_QUERY, 2, &info, &werr); + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) { + DEBUG(10, ("Session might have expired. " + "Reconnect and retry once.\n")); + invalidate_cm_connection(&domain->conn); + retry = true; + goto reconnect; + } + reset_cm_connection_on_error(domain, status); if (!NT_STATUS_IS_OK(status)) { DEBUG(2, ("dcerpc_netr_LogonControl failed: %s\n", diff --git a/source3/wscript b/source3/wscript index bac3dd588a..10aa23263c 100644 --- a/source3/wscript +++ b/source3/wscript @@ -565,7 +565,6 @@ msg.msg_acctrightslen = sizeof(fd); conf.DEFINE('WITH_WINBIND', '1') conf.find_program('awk', var='AWK') - conf.find_program('perl', var='PERL') conf.CHECK_HEADERS('asm/types.h') diff --git a/source3/wscript_build b/source3/wscript_build index c849604c6c..061cc0d4f8 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -655,13 +655,6 @@ bld.SAMBA3_LIBRARY('smbsharemodes', vnum='0', vars=locals()) -bld.SAMBA3_LIBRARY('nss_wins', - source=WINBIND_WINS_NSS_SRC, - deps='''param libsmb LIBTSOCKET''', - realname='libnss_wins.so.2', - soname='libnss_wins.so', - vnum='2') - bld.SAMBA3_LIBRARY('gse', source='librpc/crypto/gse_krb5.c librpc/crypto/gse.c', deps='krb5samba gensec param KRBCLIENT secrets3', |