diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index fd0ff0a..1dbd308 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -108,15 +108,15 @@ static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle, connection_struct *conn = handle->conn; uint32_t caps = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES; struct smb_filename *smb_fname_cpath = NULL; + struct vfs_statvfs_struct statbuf; NTSTATUS status; - int ret = -1; + int ret; -#if defined(DARWINOS) || (defined(BSD) && defined(BSD_STATVFS_BSIZE)) - struct vfs_statvfs_struct statbuf; ZERO_STRUCT(statbuf); - sys_statvfs(conn->connectpath, &statbuf); - caps = statbuf.FsCapabilities; -#endif + ret = sys_statvfs(conn->connectpath, &statbuf); + if (ret == 0) { + caps = statbuf.FsCapabilities; + } *p_ts_res = TIMESTAMP_SET_SECONDS; diff --git a/source3/smbd/statvfs.c b/source3/smbd/statvfs.c index 1e72a8e..5cefe2d 100644 --- a/source3/smbd/statvfs.c +++ b/source3/smbd/statvfs.c @@ -151,12 +151,17 @@ static int linux_statvfs(const char *path, vfs_statvfs_struct *statbuf) statbuf->TotalFileNodes = statvfs_buf.f_files; statbuf->FreeFileNodes = statvfs_buf.f_ffree; statbuf->FsIdentifier = statvfs_buf.f_fsid; - - /* Good defaults for Linux filesystems are case sensitive - * and case preserving. + /* Try to extrapolate some of the fs flags into the + * capabilities */ statbuf->FsCapabilities = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES; +#ifdef ST_QUOTA + if (statvfs_buf.f_flag & ST_QUOTA) + statbuf->FsCapabilities |= FILE_VOLUME_QUOTAS; +#endif + if (statvfs_buf.f_flag & ST_RDONLY) + statbuf->FsCapabilities |= FILE_READ_ONLY_VOLUME; } return result; } diff --git a/source3/smbd/utmp.c b/source3/smbd/utmp.c index 6837c07..028daf2 100644 --- a/source3/smbd/utmp.c +++ b/source3/smbd/utmp.c @@ -255,14 +255,58 @@ static char *uw_pathname(TALLOC_CTX *ctx, } #ifndef HAVE_PUTUTLINE +#include + /**************************************************************************** Update utmp file directly. No subroutine interface: probably a BSD system. ****************************************************************************/ static void pututline_my(const char *uname, struct utmp *u, bool claim) { - DEBUG(1,("pututline_my: not yet implemented\n")); - /* BSD implementor: may want to consider (or not) adjusting "lastlog" */ + int fd, topslot; + struct utmp ubuf; + + if ((fd = open(uname, O_RDWR, 0)) < 0) + return; + + if (!setttyent()) + return; + + for (topslot = 0; getttyent() != (struct ttyent *)NULL; ) + topslot++; + + if (!endttyent()) + return; + + (void) lseek(fd, (off_t)(topslot * sizeof(struct utmp)), SEEK_SET); + + DEBUG(1,("pututline(%s, %s, %d); topslot=%d\n", + u->ut_line, u->ut_name, claim, topslot)); + + while (1) { + if (read(fd, &ubuf, sizeof(ubuf)) == sizeof(ubuf)) { + if ((claim && !ubuf.ut_name[0]) || + (!claim && ubuf.ut_name[0] && + !strncmp(ubuf.ut_line, u->ut_line, UT_LINESIZE))) { + (void) lseek(fd, -(off_t)sizeof(struct utmp), + SEEK_CUR); + break; + } + topslot++; + } else { + (void) lseek(fd, (off_t)(topslot * + sizeof(struct utmp)), SEEK_SET); + break; + } + } + + if (!claim) { + memset((char *)&u->ut_name, '\0', sizeof(u->ut_name)); + memset((char *)&u->ut_host, '\0', sizeof(u->ut_host)); + } + (void) write(fd, u, sizeof(struct utmp)); + + (void) close(fd); } #endif /* HAVE_PUTUTLINE */