diff options
author | Gerald Carter <jerry@samba.org> | 2005-07-11 19:58:09 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2005-07-11 19:58:09 +0000 |
commit | 43e83b009de0dc1e4c2e69eef95407cce69e783d (patch) | |
tree | f24e4772486276e66c81c8e660535df6fdfe4451 | |
parent | 0afb83f20c6f72211f8a0b11d607b07a50d5a8eb (diff) | |
parent | 369c89d3c33bb59f63c029fa0e7a994c89ec92fb (diff) | |
download | samba-43e83b009de0dc1e4c2e69eef95407cce69e783d.tar.gz |
r8329: merging changes from SAMBA_3_0 and setting version to 3.0.20pre2
187 files changed, 8657 insertions, 4690 deletions
@@ -9,12 +9,17 @@ release. The following development objectives for future releases are in progress: ---------------------------------------------------------------------------- -Samba-3.0.0 The Domain Integration Release. +Samba-3.0.20 The release that is focussing on scalability and domain + integration and migration. See the WHATSNEW.txt file for + update notes. Samba-3.0.x Improvements in Management and Migration tools, & - general code stabilization work. + general code stabilization work. It is recommended to use + only stable releases in production environments. You have + been duly warned! -Samba-3.x.x Requirements are currently under discussion. +Samba-3.1.x The test bed for all new developments. Do NOT use in any + production environment. Samba-4 Danger Will Robinson, a big code clean up with major system redesign. More will be announced as this work diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index c7e5295b007..a3aab55c3ea 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -71,9 +71,9 @@ static int skel_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fs return vfswrap_get_shadow_copy_data(NULL, fsp, shadow_copy_data, labels); } -static DIR *skel_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) +static DIR *skel_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr) { - return vfswrap_opendir(NULL, conn, fname); + return vfswrap_opendir(NULL, conn, fname, mask, attr); } static SMB_STRUCT_DIRENT *skel_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp) @@ -146,9 +146,9 @@ static SMB_OFF_T skel_lseek(vfs_handle_struct *handle, files_struct *fsp, int fi return vfswrap_lseek(NULL, fsp, filedes, offset, whence); } -static int skel_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new) +static int skel_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname) { - return vfswrap_rename(NULL, conn, old, new); + return vfswrap_rename(NULL, conn, oldname, newname); } static int skel_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd) @@ -221,12 +221,12 @@ static BOOL skel_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int return vfswrap_lock(NULL, fsp, fd, op, offset, count, type); } -static BOOL skel_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath) +static int skel_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath) { return vfswrap_symlink(NULL, conn, oldpath, newpath); } -static BOOL skel_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz) +static int skel_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz) { return vfswrap_readlink(NULL, conn, path, buf, bufsiz); } @@ -487,6 +487,41 @@ static int skel_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp,in return -1; } +static int skel_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return vfswrap_aio_read(NULL, fsp, aiocb); +} + +static int skel_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return vfswrap_aio_write(NULL, fsp, aiocb); +} + +static ssize_t skel_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return vfswrap_aio_return(NULL, fsp, aiocb); +} + +static int skel_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_AIOCB *aiocb) +{ + return vfswrap_aio_cancel(NULL, fsp, fd, aiocb); +} + +static int skel_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return vfswrap_aio_error(NULL, fsp, aiocb); +} + +static int skel_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb) +{ + return vfswrap_aio_fsync(NULL, fsp, op, aiocb); +} + +static int skel_aio_suspend(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *ts) +{ + return vfswrap_aioi_suspend(NULL, fsp, aiocb, n, ts); +} + /* VFS operations structure */ static vfs_op_tuple skel_op_tuples[] = { @@ -590,6 +625,15 @@ static vfs_op_tuple skel_op_tuples[] = { {SMB_VFS_OP(skel_lsetxattr), SMB_VFS_OP_LSETXATTR, SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(skel_fsetxattr), SMB_VFS_OP_FSETXATTR, SMB_VFS_LAYER_OPAQUE}, + /* AIO operations. */ + {SMB_VFS_OP(skel_aio_read), SMB_VFS_OP_AIO_READ, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_aio_write), SMB_VFS_OP_AIO_WRITE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_aio_return), SMB_VFS_OP_AIO_RETURN, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_aio_cancel), SMB_VFS_OP_AIO_CANCEL, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_aio_error), SMB_VFS_OP_AIO_ERROR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_aio_fsync), SMB_VFS_OP_AIO_FSYNC, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_aio_suspend), SMB_VFS_OP_AIO_SUSPEND, SMB_VFS_LAYER_OPAQUE}, + {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} }; diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index b10161cde19..81069765d0e 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -70,9 +70,9 @@ static int skel_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fs return SMB_VFS_NEXT_GET_SHADOW_COPY_DATA(handle, fsp, shadow_copy_data, labels); } -static DIR *skel_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) +static DIR *skel_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr) { - return SMB_VFS_NEXT_OPENDIR(handle, conn, fname); + return SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr); } static SMB_STRUCT_DIRENT *skel_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp) @@ -145,9 +145,9 @@ static SMB_OFF_T skel_lseek(vfs_handle_struct *handle, files_struct *fsp, int fi return SMB_VFS_NEXT_LSEEK(handle, fsp, filedes, offset, whence); } -static int skel_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new) +static int skel_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname) { - return SMB_VFS_NEXT_RENAME(handle, conn, old, new); + return SMB_VFS_NEXT_RENAME(handle, conn, oldname, newname); } static int skel_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd) @@ -220,12 +220,12 @@ static BOOL skel_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int return SMB_VFS_NEXT_LOCK(handle, fsp, fd, op, offset, count, type); } -static BOOL skel_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath) +static int skel_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath) { return SMB_VFS_NEXT_SYMLINK(handle, conn, oldpath, newpath); } -static BOOL skel_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz) +static int skel_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz) { return SMB_VFS_NEXT_READLINK(handle, conn, path, buf, bufsiz); } @@ -456,6 +456,41 @@ static int skel_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp,in return SMB_VFS_NEXT_FSETXATTR(handle, fsp, fd, name, value, size, flags); } +static int skel_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return SMB_VFS_NEXT_AIO_READ(handle, fsp, aiocb); +} + +static int skel_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return SMB_VFS_NEXT_AIO_WRITE(handle, fsp, aiocb); +} + +static ssize_t skel_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return SMB_VFS_NEXT_AIO_RETURN(handle, fsp, aiocb); +} + +static int skel_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_AIOCB *aiocb) +{ + return SMB_VFS_NEXT_AIO_CANCEL(handle, fsp, fd, aiocb); +} + +static int skel_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return SMB_VFS_NEXT_AIO_ERROR(handle, fsp, aiocb); +} + +static int skel_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb) +{ + return SMB_VFS_NEXT_AIO_FSYNC(handle, fsp, op, aiocb); +} + +static int skel_aio_suspend(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *ts) +{ + return SMB_VFS_NEXT_AIO_SUSPEND(handle, fsp, aiocb, n, ts); +} + /* VFS operations structure */ static vfs_op_tuple skel_op_tuples[] = { @@ -557,6 +592,15 @@ static vfs_op_tuple skel_op_tuples[] = { {SMB_VFS_OP(skel_lsetxattr), SMB_VFS_OP_LSETXATTR, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(skel_fsetxattr), SMB_VFS_OP_FSETXATTR, SMB_VFS_LAYER_TRANSPARENT}, + /* AIO operations. */ + {SMB_VFS_OP(skel_aio_read), SMB_VFS_OP_AIO_READ, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_aio_write), SMB_VFS_OP_AIO_WRITE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_aio_return), SMB_VFS_OP_AIO_RETURN, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_aio_cancel), SMB_VFS_OP_AIO_CANCEL, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_aio_error), SMB_VFS_OP_AIO_ERROR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_aio_fsync), SMB_VFS_OP_AIO_FSYNC, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_aio_suspend), SMB_VFS_OP_AIO_SUSPEND, SMB_VFS_LAYER_TRANSPARENT}, + {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} }; diff --git a/examples/debugging/README b/examples/debugging/README new file mode 100644 index 00000000000..9e336805e50 --- /dev/null +++ b/examples/debugging/README @@ -0,0 +1,28 @@ +Last update: John H Terpstra - June 27, 2005 + +Subject: This directory will contain debugging tools and tips. + +Notes: Identification and confirmation of some bugs can be difficult. + When such bugs are encountered it is necessary to provide as + sufficient detailed debugging information to assist the developer + both by providing incontrivertable proof of the problem, but also + precise information regarding the values of variables being processed + at the time the problem strikes. + + This directory is the ideal place to locate useful hints, tips and + methods that will help Samba users to provide the information that + developers need. + +============================ Solaris Method A ============================== +File: solaris-oops.sh +Contributor: David Collier-Brown +Date: June 27, 2005 +Method and Use: +To the global stanza of smb.conf add: + panic action = /usr/local/bin/solaris-oops.sh %d + +When the panic action is initiated a voluntary core dump file will be placed +in /var/tmp. Use this method with "log level = 10" and an smbd binary that +has been built with the '-g' option. +============================================================================ + diff --git a/examples/debugging/solaris-oops.sh b/examples/debugging/solaris-oops.sh new file mode 100644 index 00000000000..82c49efdf62 --- /dev/null +++ b/examples/debugging/solaris-oops.sh @@ -0,0 +1,55 @@ +#!/bin/sh +# +# solaris_panic_action -- capture supporting information after a failure +# +ProgName=`basename $0` +LOGDIR=/usr/local/samba/var + +main() { + pid=$1 + + if [ $# -lt 1 ]; then + say "$ProgName error: you must supply a pid" + say "Usage: $0 pid" + exit 1 + fi + cat >>$LOGDIR/log.solaris_panic_action <<! + +`date` +State information and vountary core dump for process $pid + +Related processes were: +`/usr/bin/ptree $pid` + +Stack(s) were: +`/usr/bin/pstack $pid` + +Flags were: +`/usr/bin/pflags $pid` + +Credentials were: +`/usr/bin/pcred $pid` + +Libraries used were: +`/usr/bin/pldd $pid` + +Signal-handler settings were: +`/usr/bin/psig $pid` + +Files and devices in use were: +`/usr/bin/pfiles $pid` + +Directory in use was: +`/usr/bin/pwdx $pid` + + +A voluntary core dump was placed in /var/tmp/samba_solaris_panic_action_gcore.$pid +`gcore -o /var/tmp/samba_solaris_panic_action_gcore $pid` +! +} + +say() { + echo "$@" 1>&2 +} + +main "$@" diff --git a/examples/mklogon/mklogon.conf b/examples/mklogon/mklogon.conf new file mode 100644 index 00000000000..1f1faa77e38 --- /dev/null +++ b/examples/mklogon/mklogon.conf @@ -0,0 +1,77 @@ +# Mapping should be kept in the form +# username(USER) or groupname(WEBUSERS) = driveletter (W:), samba share name (WEB) +# ie. user = W:,WEB or webusers = W:,WEB +# Problem found when testing, if there is a duplicate entry only the last one is used, +# not the first or both, another problem is that when testing I found a bug in Config::Simple, if you have a tab +# infront of your # on a comment it breaks ... +# logging = yes # Should Logging be enabled (YES,ON,1 or NO,OFF,0)(if not specified defaults to no) +# logdir = "/root/perl" # What is the base directory the logs should be stored. +# logfile = "userlogs.txt" # What should the file be named. +# logtype = file (default) # file will log to the file specified, syslog is well... the system logs ;) + +[global] +logging = yes +logdir = "/home/samba/netlogon" +logfile = "UserLogs.txt" +logtype = system +mkprofile = 1 +timesync = yes +sambaconf = "/etc/samba/smb.conf" + +# Change and uncomment the below value to force the servername, some clients ocassionally +# have trouble picking up the right servername so it may need to be set. It CANNOT be left blank AND uncommented. +# servername = staticservername + +[common] +public = P:, public +home = H:, /home + +[groupmap] +admin = Y:, UTILS +adm = R:, NETLOGON + +[usermap] +user1 = G:, GHOST +beanbags = Q:, STAR +avinst = P:\\vexira\\vexprof.bat + +# Here is where things get confusing, you can assign a computer, or make a group of computers. +# The same context will go for ip address's as well. +# Use the following examples for help. +# To define a single computer to do commands +# mymachinename = command1, command2 +# To define a group of computers to do commands +# mymachinegroup = machinename1, machinename2 +# [preformcommands] +# mymachinegroup = command1,command2 + +[machines] +#emints 1 is jf +emints1 = school-w88zfod9, school-o8axvv6t, school-mmtudgbo, school-dpokmajd, school-m84hx4iw, school-74548k1j, school-vou4gdap, school-qfuw5uho +#emints 2 is kh +emints2 = school-w7loulcx, school-2tbh64eu, school-uunqieuz, school-pow35do4, school-x0v0cbiz, school-zu5qyjhw, school-l4q4j32o + +[ip] +ipgroup1 = 10.5.1.1 - 10.5.1.10, 10.1.1.255/24 +ipgroup2 = 10.1.1.1 + +# This is the section where you can specify things according to the operating system of the client. +# The clients OS -- Windows 95/98/ME (Win95), Windows NT (WinNT), +# Windows 2000 (Win2K), Windows XP (WinXP), and Windows 2003 +# (Win2K3). Anything else will be known as ``UNKNOWN'' +# That snippet is directly from man smb.conf. +# + +[os] +Win95 = REM your computer is windows 9x based +WinNT = +Win2K = +WinXP = +Win2K3 = +UNKNOWN = + +[preformcommands] +emints1 = START \\\\JF-TEACHER\\Brother, START \\\\JF-TEACHER\\Canon, REGEDIT /S P:\\SETHOME-JF.REG, your in emints 1 +emints2 = START \\\\s0034292474\\Brother, START \\\\s0034292474\\Canon, REGEDIT /S P:\\SETHOME-KH.REG +ipgroup1 = echo your in the ip group +ipgroup2 = echo your in the ip group 2, start command.com diff --git a/examples/mklogon/mklogon.pl b/examples/mklogon/mklogon.pl new file mode 100644 index 00000000000..88ee97c9799 --- /dev/null +++ b/examples/mklogon/mklogon.pl @@ -0,0 +1,383 @@ +#!/usr/bin/perl -w + +# 05/01/2005 - 18:07:10 +# +# mklogon.pl - Login Script Generator +# Copyright (C) 2005 Ricky Nance +# ricky.nance@gmail.com +# http://www.weaubleau.k12.mo.us/~rnance/samba/mklogon.txt +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +# Version: 1.1 Beta +# Revised: 06/28/2005 + +# Comments... +# Working on logging to the system logs, Logs user activity, but not errors yet. + +use strict; +use Getopt::Long; + +eval { require Config::Simple; }; +if ($@) { + print("\n"); + print( "It appears as though you don't have the Config Simple perl module installed.\n" ); + print("The package is typically called 'Config::Simple' \n"); + print("and it needs to be installed, before you can use this utility\n"); + print("Most PERL installations will allow you to use a command like\n"); + print("\ncpan -i Config::Simple\n"); + print("from the command line while logged in as the root user.\n"); + print("\n"); + exit(1); +} + +# use Data::Dumper; #Used for debugging purposes + +# This variable should point to the external conf file, personally I would set +# it to /etc/samba/mklogon.conf +my $configfile; + +foreach my $dir ( ( '/etc', '/etc/samba', '/usr/local/samba/lib' ) ) { + if ( -e "$dir/mklogon.conf" ) { + $configfile = "$dir/mklogon.conf"; + last; + } +} + +# This section will come directly from the samba server. Basically it just makes the script easier to read. +my $getopts = GetOptions( + 'u|username=s' => \my $user, + 'm|machine=s' => \my $machine, + 's|servername=s' => \my $server, + 'o|ostype=s' => \my $os, + 'i|ip=s' => \my $ip, + 'd|date=s' => \my $smbdate, + 'h|help|?' => \my $help +); + +if ($help) { + help(); + exit(0); +} + +# We want the program to error out if its missing an argument. +if ( !defined($user) ) { error("username"); } +if ( !defined($machine) ) { error("machine name") } +if ( !defined($server) ) { error("server name") } +if ( !defined($os) ) { error("operating system") } +if ( !defined($ip) ) { error("ip address") } +if ( !defined($smbdate) ) { error("date") } + +# This section will be read from the external config file +my $cfg = new Config::Simple($configfile) or die "Could not find $configfile"; + +# Read this part from the samba config +my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime(time); +my $sambaconf = $cfg->param("global.sambaconf") or die "Couldn't find your samba config! \n"; +my $smbcfg = new Config::Simple( filename => $sambaconf, syntax => "ini" ); +my $smbprof = $smbcfg->param("profiles.path"); +my $smbnetlogdir = $smbcfg->param("netlogon.path"); +my $logging = lc( $cfg->param("global.logging") ); +my $mkprofile = lc( $cfg->param("global.mkprofile") ); +my $logdir = $cfg->param("global.logdir"); +my $logfile = $cfg->param("global.logfile"); +my $logs = "$logdir\/$logfile"; +my $logtype = $cfg->param("global.logtype"); +my $usermap = "usermap.$user"; +my $osmap = "os.$os"; +my @ostype = $cfg->param($osmap); +my @username = $cfg->param($usermap); +my $compname = $cfg->param( -block => "machines" ); +my $ipname = $cfg->param( -block => "ip" ); +my $timesync = $cfg->param("global.timesync"); +my $altserver = $cfg->param("global.servername"); +if ( defined($altserver) ) { $server = $altserver; } +$server = uc($server); + +# Lets start logging stuff if it is turned on in the config +if ( $logging =~ m/on|yes|1/i ) { + if ($logtype =~ m/file/i) { + print "----- Logging is turned on in the config. -----\n"; + print "----- Location of the logfile is \"$logs\" -----\n"; + open LOG, ">>$logs"; + printf LOG "Date: $smbdate Time: "; + printf LOG '%02d', $hour; + print LOG ":"; + printf LOG '%02d', $min; + print LOG "."; + printf LOG '%02d', $sec; + print LOG " -- User: $user - Machine: $machine - IP: $ip -- \n"; + close(LOG); + } elsif ($logtype =~ m/syslog|system/i){ + use Sys::Syslog; + my $alert = "User: $user Logged into $machine ($ip) at $hour:$min.$sec on $smbdate."; + openlog($0, 'cons', 'user'); + syslog('alert', $alert); + closelog(); + + } +} else { + print "----- Logging is turned off in the config. -----\n"; +} + +# If the user wants to make profiles with this script lets go +if ( defined($smbprof) ) { + if ( $mkprofile =~ m/on|yes|1/i ) { + print "----- Automatic making of user profiles is turned on in the config. ----- \n"; + ( my $login, my $pass, my $uid, my $gid ) = getpwnam($user) + or die "$user not in passwd file \n"; + $smbprof =~ s/\%U/$user/g; + my $dir2 = "$smbprof\/$user"; + print "$smbprof \n"; + print "$dir2 \n"; + if ( !-e $dir2 ) { + print "Creating " . $user . "'s profile \n"; + mkdir $smbprof; + mkdir $dir2; + chomp($user); + chown $uid, $gid, $smbprof; + chown $uid, $gid, $dir2; + } else { + print $user . "'s profile already exists \n"; + } + } else { + print "----- Automatic making of user profiles is turned off in the config. ----- \n"; + } +} + +# Lets start making the batch files. +open LOGON, ">$smbnetlogdir\/$user.bat" or die "Unable to create userfile $smbnetlogdir\/$user.bat"; +print LOGON "\@ECHO OFF \r\n"; + +if ( $timesync =~ m/on|yes|1/i ) { + print LOGON "NET TIME /SET /YES \\\\$server \r\n"; +} else { + print "----- Time syncing to the client is turned off in the config. -----\n"; +} + +# Mapping from the common section +my $common = $cfg->param( -block => "common" ); +for my $key ( keys %$common ) { + drive_map( @{ $common->{$key} } ); +} + +# Map shares on a per user basis. +drive_map(@username); + +# Map shares based on the Operating System. +drive_map(@ostype); + +# Map shares only if they are in a group +# This line checks against the unix "groups" command, to see the secondary groups of a user. +my @usergroups = split( /\s/, do { open my $groups, "-|", groups => $user; <$groups> } ); +foreach (@usergroups) { + my $groupmap = "groupmap.$_"; + my @groupname = $cfg->param($groupmap); + drive_map(@groupname); +} + +#Here is where we check the machine name against the config... +for my $key ( keys %$compname ) { + my $test = $compname->{$key}; + if ( ref $test eq 'ARRAY' ) { + foreach (@$test) { + if ( $_ eq $machine ) { + my $preformit = $cfg->param("preformcommands.$key"); + if ( defined($preformit) ) { + if ( ref $preformit ) { + foreach (@$preformit) { print LOGON "$_ \r\n"; } + } else { + print LOGON "$preformit \r\n"; + } + } + } + } + } + elsif ( $test eq $machine ) { + my $preformit = $cfg->param("preformcommands.$key"); + if ( defined($preformit) ) { + if ( ref $preformit ) { + foreach (@$preformit) { print LOGON "$_ \r\n"; } + } else { + print LOGON "$preformit \r\n"; + } + } + } +} + +# Here is where we test the ip address against the client to see if they have "Special Mapping" +my $val; +for my $key ( sort keys %$ipname ) { + if ( ref $ipname->{$key} eq 'ARRAY' ) { + foreach ( @{ $ipname->{$key} } ) { + getipval( $_, $key ); + } + } else { + getipval( $ipname->{$key}, $key ); + } +} + +sub getipval { + my ( $range, $rangename ) = @_; + if ( parse( $ip, ipmap($range) ) ) { + if ( $val eq 'true' ) { + my $preformit = $cfg->param("preformcommands.$rangename"); + if ( defined($preformit) ) { + if ( ref $preformit ) { + foreach (@$preformit) { print LOGON "$_ \r\n"; } + } else { + print LOGON "$preformit \r\n"; + } + } + } elsif ( $val eq 'false' ) { + } + } else { + } +} + +sub ipmap { + my $pattern = shift; + my ( $iprange, $iprange2, $ipmask ); + if ( $pattern =~ m/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\/(\d{1,2})$/ ) { + # 1.1.1.1/3 notation + $iprange = pack( "U4", $1, $2, $3, $4 ); + $ipmask = pack( "U4", 0, 0, 0, 0 ); + my $numbits = $5; + for ( my $i = 0 ; $i < $numbits ; $i++ ) { + vec( $ipmask, int( $i / 8 ) * 8 + ( 8 - ( $i % 8 ) ) - 1, 1 ) = 1; + } + $iprange &= "$ipmask"; + } elsif ( $pattern =~ m/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/ ) { + # 1.1.1.1/255.255.255.255 notation + $iprange = pack( "U4", $1, $2, $3, $4 ); + $ipmask = pack( "U4", $5, $6, $7, $8 ); + $iprange &= "$ipmask"; + } elsif ( $pattern =~ m/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ ) { + # 1.1.1.1 notation + $iprange = pack( "U4", $1, $2, $3, $4 ); + $ipmask = pack( "U4", 255, 255, 255, 255 ); + } elsif ( $pattern =~ m/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\s*\-\s*(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ ) { + # 1.1.1.1 - 2.2.2.2 notation + $iprange = pack( "U4", $1, $2, $3, $4 ); + $iprange2 = pack( "U4", $5, $6, $7, $8 ); + $ipmask = pack( "U4", 255, 255, 255, 255 ); + } else { + return; + } + return $iprange, $ipmask, $iprange2; +} + +sub parse { + my ( $origip, $ipbase, $ipmask, $iprange2 ) = @_; + $origip =~ m/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/; + $origip = pack( "U4", $1, $2, $3, $4 ); + if ( defined($iprange2) ) { + if ( $ipbase le $origip && $origip le $iprange2 ) { + return $val = 'true'; + } else { + return $val = 'false'; + } + } elsif ( ( "$origip" & "$ipmask" ) eq $ipbase ) { + return $val = 'true'; + } else { + return $val = 'false'; + } +} + +# This sub will distinguish the drive mappings +sub drive_map { + my @data = @_; + for ( my $i = 0 ; $i < scalar(@data) ; ) { + if ( $data[$i] =~ m/^[a-z]\:$/i ) { + my $driveletter = $data[$i]; + $i++; + my $sharename = $data[$i]; + $i++; + if ( $sharename eq '/home' ) { + print LOGON uc("NET USE $driveletter $sharename \/Y \r\n"); + } else { + print LOGON + uc("NET USE $driveletter \\\\$server\\$sharename \/Y \r\n"); + } + } else { + print LOGON uc("$data[$i] \r\n"); + $i++; + } + } +} + +close(LOGON); + +sub error { + my $var = shift(@_); + help(); + print "\n\tCritical!!! \n\n\tNo $var specified\n\n\tYou must specify a $var.\n\n"; + exit(0); +} + +sub help { + + print << "EOF" ; + + Usage: $0 [options] + + Options: + + -h,--help This help screen. + + -u,--username The name of the user from the samba server. + + -m,--machinename The name of the client connecting to the server. + + -s,--server The name of the server this script is running in. + + -o,--os The clients OS -- Windows 95/98/ME (Win95), Windows NT (WinNT), + Windows 2000 (Win2K), Windows XP (WinXP), and Windows 2003 + (Win2K3). Anything else will be known as ``UNKNOWN'' + That snippet is directly from man smb.conf. + + -i,--ip The clients IP address. + + -d,--date Time and Date returned from the samba server. + + + + --IMPORTANT-- + + + All options MUST be specified. + + The mklogon.conf file MUST be located in /etc, /etc/samba, or + /usr/local/samba/lib. + + To use this file from the command line: + $0 -u User -m machine -s servername -o ostype -i X.X.X.X -d MM/DD/YY + + To use this file from the samba server add these lines to your /etc/samba/smb.conf: + + + This line goes in the [global] section + login script = %U.bat + + This line should be at the end of the [netlogon] section. + root preexec = /path/to/mklogon.pl -u %U -m %m -s %L -o %a -i %I -d %t + + +EOF + + print "\n\n"; + +} diff --git a/examples/scripts/python/SambaParm.py b/examples/scripts/python/SambaParm.py new file mode 100644 index 00000000000..292ad42cd2a --- /dev/null +++ b/examples/scripts/python/SambaParm.py @@ -0,0 +1,84 @@ +###################################################################### +## +## smb.conf parameter classes +## +## Copyright (C) Gerald Carter 2004. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +## +###################################################################### + +import string + +##################################################################### +## Base class for Samba smb.conf parameters +class SambaParm : + def __init__( self ) : + pass + + def StringValue( self ) : + return self.value + +##################################################################### +## Boolean smb,conf parm +class SambaParmBool( SambaParm ): + def __init__( self, value ) : + x = string.upper(value) + self.valid = True + + if x=="YES" or x=="TRUE" or x=="1": + self.value = True + elif x=="NO" or x=="FALSE" or x=="0": + self.value = False + else: + self.valid = False + return self + + def SetValue( self, value ) : + x = string.upper(value) + self.valid = True + + if x=="YES" or x=="TRUE" or x=="1": + self.value = True + elif x=="NO" or x=="FALSE" or x=="0": + self.value = False + else: + self.valid = False + return + + def StringValue( self ) : + if self.value : + return "yes" + else: + return "no" + +##################################################################### +## Boolean smb,conf parm (inverts) +class SambaParmBoolRev( SambaParmBool ) : + def __init__( self, value ): + SambaParmBool.__init__( self, value ) + if self.valid : + self.value = not self.value + + +##################################################################### +## string smb.conf parms +class SambaParmString( SambaParm ): + def __init__( self, value ): + self.value = value + self.valid = True + + + diff --git a/examples/scripts/python/generate_parm_table.py b/examples/scripts/python/generate_parm_table.py index d25ff6616e1..1dbc071e9b5 100755 --- a/examples/scripts/python/generate_parm_table.py +++ b/examples/scripts/python/generate_parm_table.py @@ -57,7 +57,7 @@ P_GLOBAL = 1 FOOTER = """##### end of smbparm.y ########################################## #################################################################""" -TESTPARM = "/opt/src/samba-cvs/samba-3.0/source/bin/testparm" +TESTPARM = "/usr/bin/testparm" ## fields in Samba's parameter table displayName = 0 @@ -89,7 +89,7 @@ obj_table = { ## First thing is to build the dictionary of parmeter names ## ## based on the output from testparm ## -cmd = "/opt/samba/bin/testparm -s -v /dev/null" +cmd = "/usr/bin/testparm -s -v /dev/null" ( status, testparm_output ) = commands.getstatusoutput( cmd ) if status: sys.stderr.write( "Failed to execute testparm!\n%s\n" % testparm_output ) @@ -111,7 +111,8 @@ for input_str in lines: parts[0] = string.strip( parts[0] ) parts[1] = string.strip( parts[1] ) key = string.upper( string.join(string.split(parts[0]), "") ) - def_values[key] = parts[1] + new = parts[1].replace('\\', '\\\\') + def_values[key] = new ## open loadparm.c and get the entire list of parameters ## ## including synonums ## @@ -153,6 +154,7 @@ while True: key = string.upper( string.join(string.split(name), "") ) var_name = string.strip( parm[variable] ) + ## try to catch synonyms -- if the parameter was not reported ## ## by testparm, then save it and come back after we will out ## ## the variable list ## diff --git a/source/Makefile.in b/source/Makefile.in index 2e29b94dfce..423c69089b1 100644 --- a/source/Makefile.in +++ b/source/Makefile.in @@ -157,7 +157,7 @@ TDBBASE_OBJ = tdb/tdb.o tdb/spinlock.o TDB_OBJ = $(TDBBASE_OBJ) tdb/tdbutil.o tdb/tdbback.o -SMBLDAP_OBJ = @SMBLDAP@ @SMBLDAPUTIL@ +SMBLDAP_OBJ = @SMBLDAP@ @SMBLDAPUTIL@ VERSION_OBJ = lib/version.o @@ -257,7 +257,7 @@ REGOBJS_OBJ = registry/reg_objects.o REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_printing.o \ registry/reg_db.o registry/reg_eventlog.o registry/reg_shares.o \ - registry/reg_util.o + registry/reg_util.o registry/reg_dynamic.o RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o @@ -387,7 +387,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \ lib/sysquotas_xfs.o lib/sysquotas_4A.o \ smbd/change_trust_pw.o smbd/fake_file.o \ smbd/quotas.o smbd/ntquotas.o $(AFS_OBJ) smbd/msdfs.o \ - $(AFS_SETTOKEN_OBJ) \ + $(AFS_SETTOKEN_OBJ) smbd/aio.o \ $(MANGLE_OBJ) @VFS_STATIC@ SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ @@ -746,6 +746,8 @@ SHOWFLAGS: @echo " LIBS = $(LIBS)" @echo " LDSHFLAGS = $(LDSHFLAGS)" @echo " LDFLAGS = $(LDFLAGS)" + @echo " PIE_CFLAGS = @PIE_CFLAGS@" + @echo " PIE_LDFLAGS = @PIE_LDFLAGS@" MAKEDIR = || exec false; \ if test -d "$$dir"; then :; else \ @@ -759,7 +761,7 @@ MAKEDIR = || exec false; \ @if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \ dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi @echo Compiling $*.c - @$(CC) -I. -I$(srcdir) $(FLAGS) -c $< \ + @$(CC) -I. -I$(srcdir) $(FLAGS) @PIE_CFLAGS@ -c $< \ -o $@ @BROKEN_CC@ -mv `echo $@ | sed 's%^.*/%%g'` $@ @@ -777,7 +779,7 @@ pch: dynconfig.o: dynconfig.c Makefile @echo Compiling $*.c - @$(CC) $(FLAGS) $(PATH_FLAGS) -c dynconfig.c -o $@ + @$(CC) $(FLAGS) $(PATH_FLAGS) @PIE_CFLAGS@ -c dynconfig.c -o $@ dynconfig.@PICSUFFIX@: dynconfig.c Makefile @if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \ @@ -788,7 +790,7 @@ dynconfig.@PICSUFFIX@: dynconfig.c Makefile lib/version.o: lib/version.c include/version.h @echo Compiling $*.c - @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) -c lib/version.c -o $@ + @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) @PIE_CFLAGS@ -c lib/version.c -o $@ lib/version.@PICSUFFIX@: lib/version.c include/version.h @if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \ @@ -799,7 +801,7 @@ lib/version.@PICSUFFIX@: lib/version.c include/version.h smbd/build_options.o: smbd/build_options.c Makefile include/config.h include/build_env.h include/proto.h @echo Compiling $*.c - @$(CC) $(FLAGS) $(PATH_FLAGS) -c smbd/build_options.c -o $@ + @$(CC) $(FLAGS) $(PATH_FLAGS) @PIE_CFLAGS@ -c smbd/build_options.c -o $@ smbd/build_options.c: include/config.h.in script/mkbuildoptions.awk @echo Generating $@ @@ -819,164 +821,164 @@ bin/.dummy: bin/smbd@EXEEXT@: $(SMBD_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \ + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \ $(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \ $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) @POPTLIBS@ bin/nmbd@EXEEXT@: $(NMBD_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(NMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) bin/wrepld@EXEEXT@: $(WREPL_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(WREPL_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(WREPL_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ bin/swat@EXEEXT@: $(SWAT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SWAT_OBJ) $(LDFLAGS) $(DYNEXP) $(PRINT_LIBS) \ + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SWAT_OBJ) $(LDFLAGS) $(DYNEXP) $(PRINT_LIBS) \ $(AUTH_LIBS) $(LIBS) $(PASSDB_LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) bin/rpcclient@EXEEXT@: $(RPCCLIENT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(PASSDB_LIBS) $(RPCCLIENT_OBJ) \ + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LDFLAGS) $(PASSDB_LIBS) $(RPCCLIENT_OBJ) \ $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ \ $(KRB5LIBS) $(LDAP_LIBS) bin/smbclient@EXEEXT@: $(CLIENT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) bin/net@EXEEXT@: $(NET_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) bin/profiles@EXEEXT@: $(PROFILES_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(PROFILES_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ @SOCKWRAP@ + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(PROFILES_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ @SOCKWRAP@ bin/smbspool@EXEEXT@: $(CUPS_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(CUPS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(CUPS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) bin/smbmount@EXEEXT@: $(MOUNT_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(MOUNT_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(MOUNT_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) bin/smbmnt@EXEEXT@: $(MNT_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(MNT_OBJ) $(DYNEXP) $(LDFLAGS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(MNT_OBJ) $(DYNEXP) $(LDFLAGS) bin/smbumount@EXEEXT@: $(UMOUNT_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(UMOUNT_OBJ) $(DYNEXP) $(LDFLAGS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(UMOUNT_OBJ) $(DYNEXP) $(LDFLAGS) bin/testparm@EXEEXT@: $(TESTPARM_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(TESTPARM_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(TESTPARM_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ bin/smbstatus@EXEEXT@: $(STATUS_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(STATUS_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \ + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(STATUS_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \ @POPTLIBS@ bin/smbcontrol@EXEEXT@: $(SMBCONTROL_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) -DUSING_SMBCONTROL $(FLAGS) -o $@ $(SMBCONTROL_OBJ) $(DYNEXP) \ + @$(CC) -DUSING_SMBCONTROL $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBCONTROL_OBJ) $(DYNEXP) \ $(LDFLAGS) $(LIBS) \ @POPTLIBS@ bin/smbtree@EXEEXT@: $(SMBTREE_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBTREE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBTREE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) bin/smbpasswd@EXEEXT@: $(SMBPASSWD_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(LDFLAGS) $(PASSDB_LIBS) \ + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBPASSWD_OBJ) $(LDFLAGS) $(PASSDB_LIBS) \ $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) bin/pdbedit@EXEEXT@: $(PDBEDIT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDB_LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDB_LIBS) $(LDAP_LIBS) bin/smbget@EXEEXT@: $(SMBGET_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBGET_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBGET_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) bin/samtest@EXEEXT@: $(SAMTEST_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SAMTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDB_LIBS) $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SAMTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDB_LIBS) $(KRB5LIBS) $(LDAP_LIBS) bin/nmblookup@EXEEXT@: $(NMBLOOKUP_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(NMBLOOKUP_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(NMBLOOKUP_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(LDAP_LIBS) bin/smbtorture@EXEEXT@: $(SMBTORTURE_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBTORTURE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBTORTURE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) bin/talloctort@EXEEXT@: $(TALLOCTORT_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(TALLOCTORT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(TALLOCTORT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) bin/masktest@EXEEXT@: $(MASKTEST_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(MASKTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(MASKTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) bin/msgtest@EXEEXT@: $(MSGTEST_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(MSGTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(MSGTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) bin/smbcacls@EXEEXT@: $(SMBCACLS_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBCACLS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBCACLS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) bin/smbcquotas@EXEEXT@: $(SMBCQUOTAS_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) bin/locktest@EXEEXT@: $(LOCKTEST_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(LOCKTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LOCKTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) bin/nsstest@EXEEXT@: $(NSSTEST_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(NSSTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(NSSTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) bin/vfstest@EXEEXT@: $(VFSTEST_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) $(ACL_LIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) $(ACL_LIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) bin/smbiconv@EXEEXT@: $(SMBICONV_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBICONV_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBICONV_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @POPTLIBS@ bin/log2pcap@EXEEXT@: $(LOG2PCAP_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(LOG2PCAP_OBJ) $(LDFLAGS) $(DYNEXP) @POPTLIBS@ $(LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LOG2PCAP_OBJ) $(LDFLAGS) $(DYNEXP) @POPTLIBS@ $(LIBS) bin/locktest2@EXEEXT@: $(LOCKTEST2_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(LOCKTEST2_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LOCKTEST2_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) bin/rpctorture@EXEEXT@: $(RPCTORTURE_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(RPCTORTURE_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(RPCTORTURE_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) bin/debug2html@EXEEXT@: $(DEBUG2HTML_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(DEBUG2HTML_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DEBUG2HTML_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) bin/smbfilter@EXEEXT@: $(SMBFILTER_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) bin/smbw_sample@EXEEXT@: $(SMBW_OBJ) utils/smbw_sample.o bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBW_OBJ) utils/smbw_sample.o $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBW_OBJ) utils/smbw_sample.o $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) bin/smbsh@EXEEXT@: $(SMBSH_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBSH_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBSH_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) bin/smbwrapper.@SHLIBEXT@: $(PICOBJS) bin/.dummy @echo Linking shared library $@ @@ -1071,7 +1073,7 @@ bin/librpc_echo.@SHLIBEXT@: $(RPC_ECHO_OBJ) bin/winbindd@EXEEXT@: $(WINBINDD_OBJ) @BUILD_POPT@ bin/.dummy @echo "Linking $@" - @$(CC) $(FLAGS) -o $@ $(WINBINDD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \ + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(WINBINDD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \ @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) # Please don't add .o files to libnss_winbind, libnss_wins, or the pam_winbind @@ -1151,6 +1153,11 @@ bin/idmap_rid.@SHLIBEXT@: sam/idmap_rid.@PICSUFFIX@ @$(SHLD) $(LDSHFLAGS) -o $@ sam/idmap_rid.@PICSUFFIX@ \ @SONAMEFLAG@`basename $@` +bin/idmap_ad.@SHLIBEXT@: sam/idmap_ad.@PICSUFFIX@ + @echo "Building plugin $@" + @$(SHLD) $(LDSHFLAGS) -o $@ sam/idmap_ad.@PICSUFFIX@ \ + @SONAMEFLAG@`basename $@` + bin/weird.@SHLIBEXT@: $(DEVEL_HELP_WEIRD_OBJ:.o=.@PICSUFFIX@) @echo "Building plugin $@" @$(SHLD) $(LDSHFLAGS) -o $@ $(DEVEL_HELP_WEIRD_OBJ:.o=.@PICSUFFIX@) \ @@ -1244,12 +1251,12 @@ bin/catia.@SHLIBEXT@: $(VFS_CATIA_OBJ:.o=.@PICSUFFIX@) bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(WBINFO_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LDFLAGS) $(WBINFO_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@ bin/ntlm_auth@EXEEXT@: $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \ @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(DYNEXP) $(NTLM_AUTH_OBJ) \ + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LDFLAGS) $(DYNEXP) $(NTLM_AUTH_OBJ) \ $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBS) \ @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) @@ -1262,32 +1269,32 @@ bin/libmsrpc.a: $(LIBMSRPC_PICOBJ) bin/tdbbackup@EXEEXT@: $(TDBBACKUP_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(DYNEXP) $(TDBBACKUP_OBJ) @SOCKWRAP@ + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DYNEXP) $(TDBBACKUP_OBJ) @SOCKWRAP@ bin/tdbtool@EXEEXT@: $(TDBTOOL_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(DYNEXP) $(TDBTOOL_OBJ) @SOCKWRAP@ + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DYNEXP) $(TDBTOOL_OBJ) @SOCKWRAP@ bin/tdbdump@EXEEXT@: $(TDBDUMP_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(DYNEXP) $(TDBDUMP_OBJ) @SOCKWRAP@ + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DYNEXP) $(TDBDUMP_OBJ) @SOCKWRAP@ bin/t_strcmp@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_strcmp.o - $(CC) $(FLAGS) -o $@ $(DYNEXP) $(LIBS) torture/t_strcmp.o -L ./bin -lbigballofmud + $(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DYNEXP) $(LIBS) torture/t_strcmp.o -L ./bin -lbigballofmud bin/t_strstr@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_strstr.o - $(CC) $(FLAGS) -o $@ $(DYNEXP) $(LIBS) torture/t_strstr.o -L ./bin -lbigballofmud + $(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DYNEXP) $(LIBS) torture/t_strstr.o -L ./bin -lbigballofmud bin/t_stringoverflow@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_stringoverflow.o - $(CC) $(FLAGS) -o $@ $(DYNEXP) torture/t_stringoverflow.o -L./bin -lbigballofmud + $(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DYNEXP) torture/t_stringoverflow.o -L./bin -lbigballofmud bin/t_doschar@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_doschar.o - $(CC) $(FLAGS) -o $@ $(DYNEXP) $(LIBS) torture/t_doschar.o -L ./bin -lbigballofmud + $(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DYNEXP) $(LIBS) torture/t_doschar.o -L ./bin -lbigballofmud bin/t_push_ucs2@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_push_ucs2.o - $(CC) $(FLAGS) -o $@ $(DYNEXP) $(LIBS) torture/t_push_ucs2.o -L ./bin -lbigballofmud + $(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DYNEXP) $(LIBS) torture/t_push_ucs2.o -L ./bin -lbigballofmud bin/t_snprintf@EXEEXT@: lib/snprintf.c - $(CC) $(FLAGS) -o $@ $(DYNEXP) -DTEST_SNPRINTF lib/snprintf.c -lm + $(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DYNEXP) -DTEST_SNPRINTF lib/snprintf.c -lm install: installbin installman installscripts installdat installswat installmodules @INSTALLCLIENT@ install-everything: install installmodules diff --git a/source/VERSION b/source/VERSION index d79f2e0c026..26b90abba74 100644 --- a/source/VERSION +++ b/source/VERSION @@ -29,7 +29,7 @@ SAMBA_VERSION_RELEASE=20 # e.g. SAMBA_VERSION_PRE_RELEASE=1 # # -> "2.2.9pre1" # ######################################################## -SAMBA_VERSION_PRE_RELEASE=1 +SAMBA_VERSION_PRE_RELEASE=2 ######################################################## # For 'rc' releases the version will be # diff --git a/source/auth/auth_ntlmssp.c b/source/auth/auth_ntlmssp.c index 0e2c359251d..11d9aa09c4c 100644 --- a/source/auth/auth_ntlmssp.c +++ b/source/auth/auth_ntlmssp.c @@ -48,7 +48,7 @@ static BOOL auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_s } /** - * NTLM2 authentication modifies the effective challange, + * NTLM2 authentication modifies the effective challenge, * @param challenge The new challenge value */ static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge) diff --git a/source/auth/auth_winbind.c b/source/auth/auth_winbind.c index 78235d30fce..3a81cba626d 100644 --- a/source/auth/auth_winbind.c +++ b/source/auth/auth_winbind.c @@ -109,7 +109,7 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context, /* we are contacting the privileged pipe */ become_root(); - result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response); + result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response); unbecome_root(); if ( result == NSS_STATUS_UNAVAIL ) { diff --git a/source/client/smbmnt.c b/source/client/smbmnt.c index 99ec9bc14c8..213cf0cfea6 100644 --- a/source/client/smbmnt.c +++ b/source/client/smbmnt.c @@ -4,6 +4,20 @@ * Copyright (C) 1995-1998 by Paal-Kr. Engstad and Volker Lendecke * extensively modified by Tridge * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * */ #define SMBMOUNT_MALLOC 1 diff --git a/source/client/smbspool.c b/source/client/smbspool.c index 1efdc12a1bc..04f293a8e63 100644 --- a/source/client/smbspool.c +++ b/source/client/smbspool.c @@ -29,9 +29,9 @@ #define TICKET_CC_DIR "/tmp" #define CC_PREFIX "krb5cc_" /* prefix of the ticket cache */ #define CC_MAX_FILE_LEN 24 -#define CC_MAX_FILE_PATH_LEN strlen(TICKET_CC_DIR)+ CC_MAX_FILE_LEN+2 +#define CC_MAX_FILE_PATH_LEN (sizeof(TICKET_CC_DIR)-1)+ CC_MAX_FILE_LEN+2 #define OVERWRITE 1 -#define KRB5CCNAME "KRB5CCNAME" +#define KRB5CCNAME "KRB5CCNAME" /* diff --git a/source/configure.in b/source/configure.in index 14fd135093a..8ac3d207056 100644 --- a/source/configure.in +++ b/source/configure.in @@ -210,6 +210,9 @@ AC_SUBST(SHLD) AC_SUBST(HOST_OS) AC_SUBST(PICFLAGS) AC_SUBST(PICSUFFIX) +AC_SUBST(libc_cv_fpie) +AC_SUBST(PIE_CFLAGS) +AC_SUBST(PIE_LDFLAGS) AC_SUBST(SHLIBEXT) AC_SUBST(INSTALLCLIENT) AC_SUBST(INSTALLCLIENTCMD_SH) @@ -231,6 +234,31 @@ AC_SUBST(EXTRA_BIN_PROGS) AC_SUBST(EXTRA_SBIN_PROGS) AC_SUBST(EXTRA_ALL_TARGETS) +# Set defaults +PIE_CFLAGS="" +PIE_LDFLAGS="" +AC_ARG_ENABLE(pie, [ --enable-pie Turn on pie support if available (default=yes)]) + +if test "x$enable_pie" != xno +then + AC_CACHE_CHECK(for -fPIE, libc_cv_fpie, [dnl + cat > conftest.c <<EOF +int foo; +main () { return 0;} +EOF + if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -pie -fPIE -o conftest conftest.c 1>&AS_MESSAGE_LOG_FD]) + then + libc_cv_fpie=yes + PIE_CFLAGS="-fPIE" + PIE_LDFLAGS="-pie" + fi + rm -f conftest*]) +fi +if test "x$PIE_CFLAGS" = x +then + libc_cv_fpie=no +fi + AC_ARG_ENABLE(debug, [ --enable-debug Turn on compiler debugging information (default=no)], [if eval "test x$enable_debug = xyes"; then @@ -700,7 +728,7 @@ AC_HEADER_STDC AC_HEADER_DIRENT AC_HEADER_TIME AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS(arpa/inet.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h rpc/nettype.h) +AC_CHECK_HEADERS(aio.h arpa/inet.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h rpc/nettype.h) AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h limits.h memory.h) AC_CHECK_HEADERS(rpc/rpc.h rpcsvc/nis.h rpcsvc/ypclnt.h) ## These fail to compile on IRIX so just check for their presence @@ -881,6 +909,20 @@ if test x"$samba_cv_sig_atomic_t" = x"yes"; then AC_DEFINE(HAVE_SIG_ATOMIC_T_TYPE,1,[Whether we have the atomic_t variable type]) fi +AC_CACHE_CHECK([for struct timespec type],samba_cv_struct_timespec, [ + AC_TRY_COMPILE([ +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#include <stddef.h> +#endif +#include <time.h> +#include <aio.h>],[struct timespec ts;], + samba_cv_struct_timespec=yes,samba_cv_struct_timespec=no)]) +if test x"$samba_cv_struct_timespec" = x"yes"; then + AC_DEFINE(HAVE_STRUCT_TIMESPEC,1,[Whether we have struct timespec]) +fi + # stupid headers have the functions but no declaration. grrrr. AC_HAVE_DECL(errno, [#include <errno.h>]) AC_HAVE_DECL(setresuid, [#include <unistd.h>]) @@ -4052,6 +4094,57 @@ samba_cv_HAVE_ACL_GET_PERM_NP=yes,samba_cv_HAVE_ACL_GET_PERM_NP=no) ) ################################################# +# check for AIO support + +AC_MSG_CHECKING(whether to support asynchronous io) +AC_ARG_WITH(aio-support, +[ --with-aio-support Include asynchronous io support (default=no)], +[ case "$withval" in + yes) + + case "$host_os" in + *) + AC_CHECK_LIB(rt,aio_read,[AIO_LIBS="$ACL_LIBS -lrt"]) + AC_CACHE_CHECK([for asynchronous io support],samba_cv_HAVE_AIO,[ + aio_LIBS=$LIBS + LIBS="$LIBS -lrt" + AC_TRY_LINK([#include <sys/types.h> +#include <aio.h>], +[ struct aiocb a; return aio_read(&a);], +samba_cv_HAVE_AIO=yes,samba_cv_HAVE_AIO=no) + LIBS=$aio_LIBS]) + AC_CACHE_CHECK([for 64-bit asynchronous io support],samba_cv_HAVE_AIO64,[ + aio_LIBS=$LIBS + LIBS="$LIBS -lrt" + AC_TRY_LINK([#include <sys/types.h> +#include <aio.h>], +[ struct aiocb64 a; return aio_read64(&a);], +samba_cv_HAVE_AIO64=yes,samba_cv_HAVE_AIO64=no) + LIBS=$aio_LIBS]) + if test x"$samba_cv_HAVE_AIO64" = x"yes"; then + AC_DEFINE(HAVE_AIOCB64,1,[Whether 64 bit aio is available]) + AC_DEFINE(WITH_AIO, 1, [Using asynchronous io]) + LIBS="$LIBS -lrt" + elif test x"$samba_cv_HAVE_AIO" = x"yes"; then + AC_DEFINE(WITH_AIO, 1, [Using asynchronous io]) + LIBS="$LIBS -lrt" + fi + ;; + esac + ;; + *) + AC_MSG_RESULT(no) + AC_DEFINE(HAVE_NO_AIO,1,[Whether no asynchronous io support is available]) + ;; + esac ], + AC_DEFINE(HAVE_NO_AIO,1,[Whether no asynchronous io support should be built in]) + AC_MSG_RESULT(no) +) + +AC_CHECK_FUNCS(aio_cancel aio_cancel64 aio_error aio_error64 aio_fsync aio_fsync64 aio_read aio_read64) +AC_CHECK_FUNCS(aio_return aio_return64 aio_suspend aio_suspend64 aio_write aio_write64) + +################################################# # check for sendfile support with_sendfile_support=yes @@ -4576,6 +4669,7 @@ SMB_SUBSYSTEM(RPC,smbd/server.o) SMB_MODULE(idmap_ldap, sam/idmap_ldap.o, "bin/idmap_ldap.$SHLIBEXT", IDMAP) SMB_MODULE(idmap_tdb, sam/idmap_tdb.o, "bin/idmap_tdb.$SHLIBEXT", IDMAP) SMB_MODULE(idmap_rid, sam/idmap_rid.o, "bin/idmap_rid.$SHLIBEXT", IDMAP) +SMB_MODULE(idmap_ad, sam/idmap_ad.o, "bin/idmap_ad.$SHLIBEXT", IDMAP) SMB_SUBSYSTEM(IDMAP,sam/idmap.o) SMB_MODULE(charset_weird, modules/weird.o, "bin/weird.$SHLIBEXT", CHARSET) diff --git a/source/include/ads.h b/source/include/ads.h index 27f9384d5d0..8f6cc6e582b 100644 --- a/source/include/ads.h +++ b/source/include/ads.h @@ -36,9 +36,19 @@ typedef struct { struct { char *realm; char *bind_path; + char *schema_path; char *ldap_server_name; time_t current_time; } config; + + /* info derived from the servers schema */ + struct { + char *sfu_homedir_attr; + char *sfu_shell_attr; + char *sfu_uidnumber_attr; + char *sfu_gidnumber_attr; + } schema; + } ADS_STRUCT; /* there are 5 possible types of errors the ads subsystem can produce */ @@ -77,10 +87,16 @@ typedef void **ADS_MODLIST; #define ADS_RECONNECT_TIME 5 /* ldap control oids */ -#define ADS_PAGE_CTL_OID "1.2.840.113556.1.4.319" -#define ADS_NO_REFERRALS_OID "1.2.840.113556.1.4.1339" -#define ADS_SERVER_SORT_OID "1.2.840.113556.1.4.473" -#define ADS_PERMIT_MODIFY_OID "1.2.840.113556.1.4.1413" +#define ADS_PAGE_CTL_OID "1.2.840.113556.1.4.319" +#define ADS_NO_REFERRALS_OID "1.2.840.113556.1.4.1339" +#define ADS_SERVER_SORT_OID "1.2.840.113556.1.4.473" +#define ADS_PERMIT_MODIFY_OID "1.2.840.113556.1.4.1413" + +/* ldap attribute oids (Services for Unix) */ +#define ADS_ATTR_SFU_UIDNUMBER_OID "1.2.840.113556.1.6.18.1.310" +#define ADS_ATTR_SFU_GIDNUMBER_OID "1.2.840.113556.1.6.18.1.311" +#define ADS_ATTR_SFU_HOMEDIR_OID "1.2.840.113556.1.6.18.1.344" +#define ADS_ATTR_SFU_SHELL_OID "1.2.840.113556.1.6.18.1.312" /* UserFlags for userAccountControl */ #define UF_SCRIPT 0x00000001 diff --git a/source/include/debug.h b/source/include/debug.h index 062bbe1a0a0..f69c213eb70 100644 --- a/source/include/debug.h +++ b/source/include/debug.h @@ -96,6 +96,7 @@ extern int DEBUGLEVEL; #define DBGC_ACLS 15 #define DBGC_PRINTERDB 16 #define DBGC_LOCKING 17 +#define DBGC_MSDFS 18 /* So you can define DBGC_CLASS before including debug.h */ #ifndef DBGC_CLASS diff --git a/source/include/doserr.h b/source/include/doserr.h index 77255ee4c11..647f11527b7 100644 --- a/source/include/doserr.h +++ b/source/include/doserr.h @@ -63,6 +63,9 @@ #define ERRinvalidname 123 /* Invalid name */ #define ERRunknownlevel 124 #define ERRnotlocked 158 /* This region is not locked by this locking context. */ +#define ERRinvalidpath 161 +#define ERRcancelviolation 173 +#define ERRnoatomiclocks 174 #define ERRrename 183 #define ERRbadpipe 230 /* Named pipe invalid */ #define ERRpipebusy 231 /* All instances of pipe are busy */ diff --git a/source/include/idmap.h b/source/include/idmap.h index 7205058ee87..c81b94a718a 100644 --- a/source/include/idmap.h +++ b/source/include/idmap.h @@ -50,7 +50,7 @@ struct idmap_methods { NTSTATUS (*set_mapping)(const DOM_SID *sid, unid_t id, int id_type); /* Called when backend is unloaded */ - NTSTATUS (*close)(void); + NTSTATUS (*close_fn)(void); /* Called to dump backend status */ void (*status)(void); diff --git a/source/include/includes.h b/source/include/includes.h index da4c98fc726..c091506381f 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -25,6 +25,18 @@ #include "config.h" #endif +#ifndef __cplusplus +#define class #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#define private #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#define public #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#define protected #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#define template #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#define this #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#define new #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#define delete #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#define friend #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#endif + #include "local.h" #ifdef AIX @@ -55,7 +67,7 @@ #define PRINTF_ATTRIBUTE(a1, a2) #endif -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__cplusplus) /** gcc attribute used on function parameters so that it does not emit * warnings about them being unused. **/ # define UNUSED(param) param __attribute__ ((unused)) @@ -491,6 +503,10 @@ #include <langinfo.h> #endif +#ifdef HAVE_AIO_H +#include <aio.h> +#endif + /* Special macros that are no-ops except when run under Valgrind on * x86. They've moved a little bit from valgrind 1.0.4 to 1.9.4 */ #if HAVE_VALGRIND_MEMCHECK_H @@ -760,6 +776,29 @@ typedef int socklen_t; # endif #endif +/* + * Type for aiocb structure. + */ + +#ifndef SMB_STRUCT_AIOCB +# if defined(WITH_AIO) +# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) +# define SMB_STRUCT_AIOCB struct aiocb64 +# else +# define SMB_STRUCT_AIOCB struct aiocb +# endif +# else +# define SMB_STRUCT_AIOCB int /* AIO not being used but we still need the define.... */ +# endif +#endif + +#ifndef HAVE_STRUCT_TIMESPEC +struct timespec { + time_t tv_sec; /* Seconds. */ + long tv_nsec; /* Nanoseconds. */ +}; +#endif + #ifndef MIN #define MIN(a,b) ((a)<(b)?(a):(b)) #endif diff --git a/source/include/libsmbclient.h b/source/include/libsmbclient.h index ea013c113a0..3269d6f0bf7 100644 --- a/source/include/libsmbclient.h +++ b/source/include/libsmbclient.h @@ -379,7 +379,7 @@ struct _SMBCCTX { off_t (*lseek) (SMBCCTX *c, SMBCFILE * file, off_t offset, int whence); int (*stat) (SMBCCTX *c, const char *fname, struct stat *st); int (*fstat) (SMBCCTX *c, SMBCFILE *file, struct stat *st); - int (*close) (SMBCCTX *c, SMBCFILE *file); + int (*close_fn) (SMBCCTX *c, SMBCFILE *file); /** callable functions for dirs */ diff --git a/source/include/msdfs.h b/source/include/msdfs.h index 8d6b23bcbfb..ff035ddd493 100644 --- a/source/include/msdfs.h +++ b/source/include/msdfs.h @@ -36,6 +36,7 @@ /* Maximum number of referrals for each Dfs volume */ #define MAX_REFERRAL_COUNT 256 +#define MAX_MSDFS_JUNCTIONS 256 typedef struct _client_referral { uint32 proximity; diff --git a/source/include/nt_printing.h b/source/include/nt_printing.h index ee29636c88d..01835c999ec 100644 --- a/source/include/nt_printing.h +++ b/source/include/nt_printing.h @@ -295,7 +295,7 @@ typedef struct ntdevicemode uint32 reserved2; uint32 panningwidth; uint32 panningheight; - uint8 *private; + uint8 *nt_dev_private; } NT_DEVICEMODE; typedef struct nt_printer_info_level_2 @@ -344,21 +344,6 @@ typedef struct uint32 bottom; } nt_forms_struct; -/* -typedef struct _form -{ - uint32 flags; - uint32 name_ptr; - uint32 size_x; - uint32 size_y; - uint32 left; - uint32 top; - uint32 right; - uint32 bottom; - UNISTR2 name; -} FORM; -*/ - #ifndef SAMBA_PRINTER_PORT_NAME #define SAMBA_PRINTER_PORT_NAME "Samba Printer Port" #endif diff --git a/source/include/ntlmssp.h b/source/include/ntlmssp.h index 24ac7967615..267779c434d 100644 --- a/source/include/ntlmssp.h +++ b/source/include/ntlmssp.h @@ -123,7 +123,7 @@ typedef struct ntlmssp_state * from the DATA_BLOB chal on this structure. * * @param ntlmssp_state This structure - * @param challange 8 bytes of data, agreed by the client and server to be the effective challenge for NTLM2 authentication + * @param challenge 8 bytes of data, agreed by the client and server to be the effective challenge for NTLM2 authentication * */ NTSTATUS (*set_challenge)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge); diff --git a/source/include/passdb.h b/source/include/passdb.h index 9a3dd9c8d3e..114585346e1 100644 --- a/source/include/passdb.h +++ b/source/include/passdb.h @@ -195,7 +195,7 @@ typedef struct sam_passwd const struct pdb_methods *backend_private_methods; void *backend_private_data; void (*backend_private_data_free_fn)(void **); - } private; + } private_u; /* Lets see if the remaining code can get the hint that you are meant to use the pdb_...() functions. */ @@ -221,7 +221,7 @@ typedef struct sam_group { uint32 mem_num; /* Number of member SIDs */ DOM_SID *members; /* SID array */ - } private; + } private_g; } SAM_GROUP; @@ -253,7 +253,7 @@ struct pdb_search { uint32 num_entries; ssize_t cache_size; BOOL search_ended; - void *private; + void *private_data; BOOL (*next_entry)(struct pdb_search *search, struct samr_displayentry *entry); void (*search_end)(struct pdb_search *search); diff --git a/source/include/privileges.h b/source/include/privileges.h index 38edee84e81..052cbb6c5fe 100644 --- a/source/include/privileges.h +++ b/source/include/privileges.h @@ -82,25 +82,22 @@ extern const SE_PRIV se_restore; #define PR_LOG_ON_SERVICE 0x0010 -#ifndef _BOOL -typedef int BOOL; -#define _BOOL /* So we don't typedef BOOL again in vfs.h */ -#endif - -typedef struct LUID -{ - uint32 low; +typedef struct { uint32 high; + uint32 low; } LUID; -typedef struct LUID_ATTR -{ +typedef struct { LUID luid; uint32 attr; } LUID_ATTR; -typedef struct privilege_set -{ +#ifndef _BOOL +typedef int BOOL; +#define _BOOL /* So we don't typedef BOOL again in vfs.h */ +#endif + +typedef struct { TALLOC_CTX *mem_ctx; BOOL ext_ctx; uint32 count; @@ -108,10 +105,11 @@ typedef struct privilege_set LUID_ATTR *set; } PRIVILEGE_SET; -typedef struct _PRIVS { +typedef struct { SE_PRIV se_priv; const char *name; const char *description; + LUID luid; } PRIVS; #endif /* PRIVILEGES_H */ diff --git a/source/include/reg_objects.h b/source/include/reg_objects.h index a31f7097d3c..f6716eba4f3 100644 --- a/source/include/reg_objects.h +++ b/source/include/reg_objects.h @@ -26,6 +26,7 @@ typedef struct { fstring valuename; uint16 type; + /* this should be encapsulated in an RPC_DATA_BLOB */ uint32 size; /* in bytes */ uint8 *data_p; } REGISTRY_VALUE; @@ -46,18 +47,5 @@ typedef struct { char **subkeys; } REGSUBKEY_CTR; -/* represent a registry key with all its subkeys and values */ - -struct _regobj_key; - -typedef struct _regobj_key { - TALLOC_CTX *ctx; - - char *name; - - REGVAL_CTR values; - REGSUBKEY_CTR subkeys; -} REGOBJ_KEY; - #endif /* _REG_OBJECTS_H */ diff --git a/source/include/rpc_reg.h b/source/include/rpc_reg.h index f89571484c3..bbbb1acf8c1 100644 --- a/source/include/rpc_reg.h +++ b/source/include/rpc_reg.h @@ -34,7 +34,7 @@ #define REG_OPEN_HKPD 0x03 #define REG_OPEN_HKU 0x04 #define REG_CLOSE 0x05 -#define REG_CREATE_KEY 0x06 +#define REG_CREATE_KEY_EX 0x06 #define REG_DELETE_KEY 0x07 #define REG_DELETE_VALUE 0x08 #define REG_ENUM_KEY 0x09 @@ -43,7 +43,7 @@ #define REG_GET_KEY_SEC 0x0c #define REG_OPEN_ENTRY 0x0f #define REG_QUERY_KEY 0x10 -#define REG_INFO 0x11 +#define REG_QUERY_VALUE 0x11 #define REG_RESTORE_KEY 0x13 #define REG_SAVE_KEY 0x14 #define REG_SET_KEY_SEC 0x15 @@ -64,7 +64,7 @@ #define KEY_HKU "HKU" #define KEY_HKCR "HKCR" #define KEY_PRINTING "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print" -#define KEY_PRINTING_2K "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print" +#define KEY_PRINTING_2K "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers" #define KEY_PRINTING_PORTS "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Ports" #define KEY_EVENTLOG "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Eventlog" #define KEY_SHARES "HKLM\\SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Shares" @@ -92,10 +92,10 @@ typedef struct { /* functions for enumerating subkeys and values */ - int (*fetch_subkeys)( char *key, REGSUBKEY_CTR *subkeys); - int (*fetch_values) ( char *key, REGVAL_CTR *val ); - BOOL (*store_subkeys)( char *key, REGSUBKEY_CTR *subkeys ); - BOOL (*store_values)( char *key, REGVAL_CTR *val ); + int (*fetch_subkeys)( const char *key, REGSUBKEY_CTR *subkeys); + int (*fetch_values) ( const char *key, REGVAL_CTR *val ); + BOOL (*store_subkeys)( const char *key, REGSUBKEY_CTR *subkeys ); + BOOL (*store_values)( const char *key, REGVAL_CTR *val ); BOOL (*reg_access_check)( const char *keyname, uint32 requested, uint32 *granted, NT_USER_TOKEN *token ); } REGISTRY_OPS; @@ -146,7 +146,7 @@ typedef struct { /***********************************************/ typedef struct { - POLICY_HND pol; + POLICY_HND handle; uint32 sec_info; uint32 ptr; BUFHDR hdr_sec; @@ -161,7 +161,7 @@ typedef struct { /***********************************************/ typedef struct { - POLICY_HND pol; + POLICY_HND handle; uint32 sec_info; uint32 ptr; BUFHDR hdr_sec; @@ -216,7 +216,7 @@ typedef struct { typedef struct { POLICY_HND handle; UNISTR4 name; - UNISTR4 class; + UNISTR4 key_class; uint32 reserved; uint32 access; uint32 *sec_info; @@ -225,13 +225,13 @@ typedef struct { uint32 ptr3; SEC_DESC_BUF *data; uint32 unknown_2; /* 0x0000 0000 */ -} REG_Q_CREATE_KEY; +} REG_Q_CREATE_KEY_EX; typedef struct { POLICY_HND handle; - uint32 unknown; + uint32 disposition; WERROR status; -} REG_R_CREATE_KEY; +} REG_R_CREATE_KEY_EX; /***********************************************/ @@ -241,7 +241,6 @@ typedef struct { } REG_Q_DELETE_KEY; typedef struct { - POLICY_HND key_pol; WERROR status; } REG_R_DELETE_KEY; @@ -253,7 +252,6 @@ typedef struct { } REG_Q_DELETE_VALUE; typedef struct { - POLICY_HND key_pol; WERROR status; } REG_R_DELETE_VALUE; @@ -261,11 +259,11 @@ typedef struct { typedef struct { POLICY_HND pol; - UNISTR4 class; + UNISTR4 key_class; } REG_Q_QUERY_KEY; typedef struct { - UNISTR4 class; + UNISTR4 key_class; uint32 num_subkeys; uint32 max_subkeylen; uint32 reserved; /* 0x0000 0000 - according to MSDN (max_subkeysize?) */ @@ -389,7 +387,7 @@ typedef struct { uint32 ptr_buflen2; uint32 buflen2; -} REG_Q_INFO; +} REG_Q_QUERY_VALUE; typedef struct { uint32 *type; @@ -397,7 +395,7 @@ typedef struct { uint32 *buf_max_len; uint32 *buf_len; WERROR status; /* return status */ -} REG_R_INFO; +} REG_R_QUERY_VALUE; /***********************************************/ diff --git a/source/include/rpc_spoolss.h b/source/include/rpc_spoolss.h index d0422e8d6ea..3b88f76588b 100755 --- a/source/include/rpc_spoolss.h +++ b/source/include/rpc_spoolss.h @@ -517,7 +517,7 @@ typedef struct devicemode uint32 reserved2; uint32 panningwidth; uint32 panningheight; - uint8 *private; + uint8 *dev_private; } DEVICEMODE; diff --git a/source/include/smb.h b/source/include/smb.h index 4bf967bf35d..55baf845315 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -107,44 +107,32 @@ typedef int BOOL; #define DOS_OPEN_FCB 0xF /* define shifts and masks for share and open modes. */ -#define OPEN_MODE_MASK 0xF -#define SHARE_MODE_SHIFT 4 -#define SHARE_MODE_MASK 0x7 -#define GET_OPEN_MODE(x) ((x) & OPEN_MODE_MASK) -#define SET_OPEN_MODE(x) ((x) & OPEN_MODE_MASK) -#define GET_DENY_MODE(x) (((x)>>SHARE_MODE_SHIFT) & SHARE_MODE_MASK) -#define SET_DENY_MODE(x) (((x) & SHARE_MODE_MASK) <<SHARE_MODE_SHIFT) +#define OPENX_MODE_MASK 0xF +#define DENY_MODE_SHIFT 4 +#define DENY_MODE_MASK 0x7 +#define GET_OPENX_MODE(x) ((x) & OPENX_MODE_MASK) +#define SET_OPENX_MODE(x) ((x) & OPENX_MODE_MASK) +#define GET_DENY_MODE(x) (((x)>>DENY_MODE_SHIFT) & DENY_MODE_MASK) +#define SET_DENY_MODE(x) (((x) & DENY_MODE_MASK) <<DENY_MODE_SHIFT) /* Sync on open file (not sure if used anymore... ?) */ #define FILE_SYNC_OPENMODE (1<<14) #define GET_FILE_SYNC_OPENMODE(x) (((x) & FILE_SYNC_OPENMODE) ? True : False) -/* allow delete on open file mode (used by NT SMB's). */ -#define ALLOW_SHARE_DELETE (1<<15) -#define GET_ALLOW_SHARE_DELETE(x) (((x) & ALLOW_SHARE_DELETE) ? True : False) -#define SET_ALLOW_SHARE_DELETE(x) ((x) ? ALLOW_SHARE_DELETE : 0) - -/* delete on close flag (used by NT SMB's). */ -#define DELETE_ON_CLOSE_FLAG (1<<16) -#define GET_DELETE_ON_CLOSE_FLAG(x) (((x) & DELETE_ON_CLOSE_FLAG) ? True : False) -#define SET_DELETE_ON_CLOSE_FLAG(x) ((x) ? DELETE_ON_CLOSE_FLAG : 0) - /* open disposition values */ -#define FILE_EXISTS_FAIL 0 -#define FILE_EXISTS_OPEN 1 -#define FILE_EXISTS_TRUNCATE 2 +#define OPENX_FILE_EXISTS_FAIL 0 +#define OPENX_FILE_EXISTS_OPEN 1 +#define OPENX_FILE_EXISTS_TRUNCATE 2 /* mask for open disposition. */ -#define FILE_OPEN_MASK 0x3 +#define OPENX_FILE_OPEN_MASK 0x3 -#define GET_FILE_OPEN_DISPOSITION(x) ((x) & FILE_OPEN_MASK) -#define SET_FILE_OPEN_DISPOSITION(x) ((x) & FILE_OPEN_MASK) +#define GET_FILE_OPENX_DISPOSITION(x) ((x) & FILE_OPEN_MASK) +#define SET_FILE_OPENX_DISPOSITION(x) ((x) & FILE_OPEN_MASK) /* The above can be OR'ed with... */ -#define FILE_CREATE_IF_NOT_EXIST 0x10 -#define FILE_FAIL_IF_NOT_EXIST 0 - -#define GET_FILE_CREATE_DISPOSITION(x) ((x) & (FILE_CREATE_IF_NOT_EXIST|FILE_FAIL_IF_NOT_EXIST)) +#define OPENX_FILE_CREATE_IF_NOT_EXIST 0x10 +#define OPENX_FILE_FAIL_IF_NOT_EXIST 0 /* share types */ #define STYPE_DISKTREE 0 /* Disk drive */ @@ -407,27 +395,38 @@ typedef struct #include "fake_file.h" +struct fd_handle { + size_t ref_count; + int fd; + SMB_BIG_UINT position_information; + SMB_OFF_T pos; + uint32 private_options; /* NT Create options, but we only look at + * NTCREATEX_OPTIONS_PRIVATE_DENY_DOS and + * NTCREATEX_OPTIONS_PRIVATE_DENY_FCB (Except + * for print files *only*, where + * DELETE_ON_CLOSE is not stored in the share + * mode database. + */ +}; + typedef struct files_struct { struct files_struct *next, *prev; int fnum; struct connection_struct *conn; - int fd; + struct fd_handle *fh; unsigned int num_smb_operations; uint16 rap_print_jobid; SMB_DEV_T dev; SMB_INO_T inode; - BOOL delete_on_close; - SMB_OFF_T pos; SMB_BIG_UINT initial_allocation_size; /* Faked up initial allocation on disk. */ - SMB_BIG_UINT position_information; mode_t mode; uint16 file_pid; uint16 vuid; write_bmpx_struct *wbmpx_ptr; write_cache *wcp; struct timeval open_time; - int share_mode; - uint32 desired_access; + uint32 access_mask; /* NTCreateX access bits (FILE_READ_DATA etc.) */ + uint32 share_access; /* NTCreateX share constants (FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE). */ BOOL pending_modtime_owner; time_t pending_modtime; time_t last_write_time; @@ -441,7 +440,7 @@ typedef struct files_struct { BOOL modified; BOOL is_directory; BOOL is_stat; - BOOL directory_delete_on_close; + BOOL aio_write_behind; char *fsp_name; FAKE_FILE_HANDLE *fake_file_handle; } files_struct; @@ -450,11 +449,10 @@ typedef struct files_struct { #include "sysquotas.h" /* used to hold an arbitrary blob of data */ -typedef struct data_blob -{ +typedef struct data_blob_ { uint8 *data; size_t length; - void (*free)(struct data_blob *data_blob); + void (*free)(struct data_blob_ *data_blob); } DATA_BLOB; /* @@ -542,6 +540,7 @@ typedef struct connection_struct name_compare_entry *hide_list; /* Per-share list of files to return as hidden. */ name_compare_entry *veto_list; /* Per-share list of files to veto (never show). */ name_compare_entry *veto_oplock_list; /* Per-share list of files to refuse oplocks on. */ + name_compare_entry *aio_write_behind_list; /* Per-share list of files to use aio write behind on. */ } connection_struct; @@ -638,8 +637,12 @@ typedef struct { pid_t pid; uint16 op_port; uint16 op_type; - int share_mode; - uint32 desired_access; + uint32 access_mask; /* NTCreateX access bits (FILE_READ_DATA etc.) */ + uint32 share_access; /* NTCreateX share constants (FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE). */ + uint32 private_options; /* NT Create options, but we only look at + * NTCREATEX_OPTIONS_PRIVATE_DENY_DOS and + * NTCREATEX_OPTIONS_PRIVATE_DENY_FCB for + * smbstatus and swat */ struct timeval time; SMB_DEV_T dev; SMB_INO_T inode; @@ -747,7 +750,7 @@ struct parm_struct { const char *label; parm_type type; - parm_class class; + parm_class p_class; void *ptr; BOOL (*special)(int snum, const char *, char **); const struct enum_list *enum_list; @@ -1078,18 +1081,18 @@ struct bitmap { #define DESIRED_ACCESS_PIPE 0x2019f /* Generic access masks & rights. */ -#define DELETE_ACCESS (1L<<16) /* 0x00010000 */ -#define READ_CONTROL_ACCESS (1L<<17) /* 0x00020000 */ -#define WRITE_DAC_ACCESS (1L<<18) /* 0x00040000 */ -#define WRITE_OWNER_ACCESS (1L<<19) /* 0x00080000 */ -#define SYNCHRONIZE_ACCESS (1L<<20) /* 0x00100000 */ - -#define SYSTEM_SECURITY_ACCESS (1L<<24) /* 0x01000000 */ -#define MAXIMUM_ALLOWED_ACCESS (1L<<25) /* 0x02000000 */ -#define GENERIC_ALL_ACCESS (1<<28) /* 0x10000000 */ -#define GENERIC_EXECUTE_ACCESS (1<<29) /* 0x20000000 */ -#define GENERIC_WRITE_ACCESS (1<<30) /* 0x40000000 */ -#define GENERIC_READ_ACCESS (((unsigned)1)<<31) /* 0x80000000 */ +#define DELETE_ACCESS 0x00010000 /* (1L<<16) */ +#define READ_CONTROL_ACCESS 0x00020000 /* (1L<<17) */ +#define WRITE_DAC_ACCESS 0x00040000 /* (1L<<18) */ +#define WRITE_OWNER_ACCESS 0x00080000 /* (1L<<19) */ +#define SYNCHRONIZE_ACCESS 0x00100000 /* (1L<<20) */ + +#define SYSTEM_SECURITY_ACCESS 0x01000000 /* (1L<<24) */ +#define MAXIMUM_ALLOWED_ACCESS 0x02000000 /* (1L<<25) */ +#define GENERIC_ALL_ACCESS 0x10000000 /* (1<<28) */ +#define GENERIC_EXECUTE_ACCESS 0x20000000 /* (1<<29) */ +#define GENERIC_WRITE_ACCESS 0x40000000 /* (1<<30) */ +#define GENERIC_READ_ACCESS ((unsigned)0x80000000) /* (((unsigned)1)<<31) */ /* Mapping of generic access rights for files to specific rights. */ @@ -1171,12 +1174,12 @@ struct bitmap { #define FILE_FLAG_POSIX_SEMANTICS 0x01000000L /* CreateDisposition field. */ -#define FILE_SUPERSEDE 0 -#define FILE_OPEN 1 -#define FILE_CREATE 2 -#define FILE_OPEN_IF 3 -#define FILE_OVERWRITE 4 -#define FILE_OVERWRITE_IF 5 +#define FILE_SUPERSEDE 0 /* File exists overwrite/supersede. File not exist create. */ +#define FILE_OPEN 1 /* File exists open. File not exist fail. */ +#define FILE_CREATE 2 /* File exists fail. File not exist create. */ +#define FILE_OPEN_IF 3 /* File exists open. File not exist create. */ +#define FILE_OVERWRITE 4 /* File exists overwrite. File not exist fail. */ +#define FILE_OVERWRITE_IF 5 /* File exists overwrite. File not exist create. */ /* CreateOptions field. */ #define FILE_DIRECTORY_FILE 0x0001 @@ -1189,6 +1192,10 @@ struct bitmap { #define FILE_DELETE_ON_CLOSE 0x1000 #define FILE_OPEN_BY_FILE_ID 0x2000 +/* Private create options used by the ntcreatex processing code. From Samba4. */ +#define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x01000000 +#define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x02000000 + /* Responses when opening a file. */ #define FILE_WAS_SUPERSEDED 0 #define FILE_WAS_OPENED 1 @@ -1334,7 +1341,7 @@ char *strdup(char *s); #define FLAGS2_IS_LONG_NAME 0x0040 #define FLAGS2_EXTENDED_SECURITY 0x0800 #define FLAGS2_DFS_PATHNAMES 0x1000 -#define FLAGS2_READ_PERMIT_NO_EXECUTE 0x2000 +#define FLAGS2_READ_PERMIT_EXECUTE 0x2000 #define FLAGS2_32_BIT_ERROR_CODES 0x4000 #define FLAGS2_UNICODE_STRINGS 0x8000 @@ -1441,36 +1448,36 @@ extern int chain_size; #define LOCKING_ANDX_CANCEL_LOCK 0x8 #define LOCKING_ANDX_LARGE_FILES 0x10 -/* Oplock levels */ -#define OPLOCKLEVEL_NONE 0 -#define OPLOCKLEVEL_II 1 - /* * Bits we test with. */ - + #define NO_OPLOCK 0 #define EXCLUSIVE_OPLOCK 1 #define BATCH_OPLOCK 2 #define LEVEL_II_OPLOCK 4 #define INTERNAL_OPEN_ONLY 8 -#define EXCLUSIVE_OPLOCK_TYPE(lck) ((lck) & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) -#define BATCH_OPLOCK_TYPE(lck) ((lck) & BATCH_OPLOCK) -#define LEVEL_II_OPLOCK_TYPE(lck) ((lck) & LEVEL_II_OPLOCK) - -#define CORE_OPLOCK_GRANTED (1<<5) -#define EXTENDED_OPLOCK_GRANTED (1<<15) +#define EXCLUSIVE_OPLOCK_TYPE(lck) ((lck) & ((unsigned int)EXCLUSIVE_OPLOCK|(unsigned int)BATCH_OPLOCK)) +#define BATCH_OPLOCK_TYPE(lck) ((lck) & (unsigned int)BATCH_OPLOCK) +#define LEVEL_II_OPLOCK_TYPE(lck) ((lck) & (unsigned int)LEVEL_II_OPLOCK) /* - * Return values for oplock types. + * On the wire return values for oplock types. */ +#define CORE_OPLOCK_GRANTED (1<<5) +#define EXTENDED_OPLOCK_GRANTED (1<<15) + #define NO_OPLOCK_RETURN 0 #define EXCLUSIVE_OPLOCK_RETURN 1 #define BATCH_OPLOCK_RETURN 2 #define LEVEL_II_OPLOCK_RETURN 3 +/* Oplock levels */ +#define OPLOCKLEVEL_NONE 0 +#define OPLOCKLEVEL_II 1 + /* * Loopback command offsets. */ @@ -1586,13 +1593,12 @@ struct nmb_name { unsigned int name_type; }; - /* A netbios node status array element. */ -struct node_status { +typedef struct node_status_ { nstring name; unsigned char type; unsigned char flags; -}; +} NODE_STATUS_STRUCT; /* The extra info from a NetBIOS node status query */ struct node_status_extra { diff --git a/source/include/smb_acls.h b/source/include/smb_acls.h index 2bde6caeda1..ec1316e4667 100644 --- a/source/include/smb_acls.h +++ b/source/include/smb_acls.h @@ -257,11 +257,11 @@ struct new_acl_entry{ #define SMB_ACL_OTHER 4 #define SMB_ACL_MASK 5 -typedef struct SMB_ACL_T { +typedef struct SMB_ACL_T_ { int dummy; } *SMB_ACL_T; -typedef struct SMB_ACL_ENTRY_T { +typedef struct SMB_ACL_ENTRY_T_ { int dummy; } *SMB_ACL_ENTRY_T; diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h index b7e27d22667..7a0afdfc192 100644 --- a/source/include/smb_macros.h +++ b/source/include/smb_macros.h @@ -101,15 +101,16 @@ extern struct current_user current_user;\ if (!FNUM_OK(fsp,conn)) \ return(ERROR_DOS(ERRDOS,ERRbadfid)); \ - else if((fsp)->fd == -1) \ + else if((fsp)->fh->fd == -1) \ return(ERROR_DOS(ERRDOS,ERRbadaccess));\ (fsp)->num_smb_operations++;\ } while(0) -#define CHECK_READ(fsp) if (!(fsp)->can_read) \ - return(ERROR_DOS(ERRDOS,ERRbadaccess)) -#define CHECK_WRITE(fsp) if (!(fsp)->can_write) \ - return(ERROR_DOS(ERRDOS,ERRbadaccess)) +#define CHECK_READ(fsp,inbuf) (((fsp)->fh->fd != -1) && ((fsp)->can_read || \ + ((SVAL((inbuf),smb_flg2) & FLAGS2_READ_PERMIT_EXECUTE) && \ + (fsp->access_mask & FILE_EXECUTE)))) + +#define CHECK_WRITE(fsp) ((fsp)->can_write && ((fsp)->fh->fd != -1)) #define ERROR_WAS_LOCK_DENIED(status) (NT_STATUS_EQUAL((status), NT_STATUS_LOCK_NOT_GRANTED) || \ NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT) ) diff --git a/source/include/socket_wrapper.h b/source/include/socket_wrapper.h index 6da5a2980cd..d8815a25757 100644 --- a/source/include/socket_wrapper.h +++ b/source/include/socket_wrapper.h @@ -32,17 +32,17 @@ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const str int swrap_close(int); #ifdef SOCKET_WRAPPER_REPLACE -#define accept swrap_accept -#define connect swrap_connect -#define bind swrap_bind -#define getpeername swrap_getpeername -#define getsockname swrap_getsockname -#define getsockopt swrap_getsockopt -#define setsockopt swrap_setsockopt -#define recvfrom swrap_recvfrom -#define sendto swrap_sendto -#define socket swrap_socket -#define close swrap_close +#define accept(s,addr,addrlen) swrap_accept(s,addr,addrlen) +#define connect(s,serv_addr,addrlen) swrap_connect(s,serv_addr,addrlen) +#define bind(s,myaddr,addrlen) swrap_bind(s,myaddr,addrlen) +#define getpeername(s,name,addrlen) swrap_getpeername(s,name,addrlen) +#define getsockname(s,name,addrlen) swrap_getsockname(s,name,addrlen) +#define getsockopt(s,level,optname,optval,optlen) swrap_getsockopt(s,level,optname,optval,optlen) +#define setsockopt(s,level,optname,optval,optlen) swrap_setsockopt(s,level,optname,optval,optlen) +#define recvfrom(s,buf,len,flags,from,fromlen) swrap_recvfrom(s,buf,len,flags,from,fromlen) +#define sendto(s,buf,len,flags,to,tolen) swrap_sendto(s,buf,len,flags,to,tolen) +#define socket(domain,type,protocol) swrap_socket(domain,type,protocol) +#define close(s) swrap_close(s) #endif #endif /* __SOCKET_WRAPPER_H__ */ diff --git a/source/include/spnego.h b/source/include/spnego.h index b6492ee3c8a..8bb13bd354a 100644 --- a/source/include/spnego.h +++ b/source/include/spnego.h @@ -43,7 +43,7 @@ typedef enum _spnego_negResult { } negResult_t; typedef struct spnego_negTokenInit { - const char **mechTypes; + char **mechTypes; int reqFlags; DATA_BLOB mechToken; DATA_BLOB mechListMIC; @@ -51,7 +51,7 @@ typedef struct spnego_negTokenInit { typedef struct spnego_negTokenTarg { uint8 negResult; - const char *supportedMech; + char *supportedMech; DATA_BLOB responseToken; DATA_BLOB mechListMIC; } negTokenTarg_t; diff --git a/source/include/trans2.h b/source/include/trans2.h index 2f56c640d3c..1d5dfe3678e 100644 --- a/source/include/trans2.h +++ b/source/include/trans2.h @@ -450,11 +450,13 @@ Offset Size Name /* Info level for TRANS2_QFSINFO - returns version of CIFS UNIX extensions, plus 64-bits worth of capability fun :-). + Use the same info level for TRANS2_SETFSINFO */ #define SMB_QUERY_CIFS_UNIX_INFO 0x200 +#define SMB_SET_CIFS_UNIX_INFO 0x200 -/* Returns the following. +/* Returns or sets the following. UINT16 major version number UINT16 minor version number @@ -474,12 +476,6 @@ Offset Size Name (chflags) and lsattr */ #define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x10 /* Use POSIX pathnames on the wire. */ -/* - Info level for TRANSACT2_SETFSINFO - takes 64-bits of capabilies in the data section. -*/ - -#define SMB_SET_CIFS_UNIX_INFO 0x200 - #define SMB_QUERY_POSIX_FS_INFO 0x201 diff --git a/source/include/vfs.h b/source/include/vfs.h index e8c6ff32d55..7f6c94f6e99 100644 --- a/source/include/vfs.h +++ b/source/include/vfs.h @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. VFS structures and parameters - Copyright (C) Jeremy Allison 1999-2004 + Copyright (C) Jeremy Allison 1999-2005 Copyright (C) Tim Potter 1999 Copyright (C) Alexander Bokovoy 2002 Copyright (C) Stefan (metze) Metzmacher 2003 @@ -56,10 +56,13 @@ /* Changed to version 9 to include the get_shadow_data call. --metze */ /* Changed to version 10 to include pread/pwrite calls. */ /* Changed to version 11 to include seekdir/telldir/rewinddir calls. JRA */ -#define SMB_VFS_INTERFACE_VERSION 11 +/* Changed to version 12 to add mask and attributes to opendir(). JRA + Also include aio calls. JRA. */ +/* Changed to version 13 as the internal structure of files_struct has changed. JRA */ +#define SMB_VFS_INTERFACE_VERSION 13 -/* to bug old modules witch are trying to compile with the old functions */ +/* to bug old modules which are trying to compile with the old functions */ #define vfs_init __ERROR_please_port_this_module_to_SMB_VFS_INTERFACE_VERSION_8_donot_use_vfs_init_anymore(void) { __ERROR_please_port_this_module_to_SMB_VFS_INTERFACE_VERSION_8_donot_use_vfs_init_anymore }; #define lp_parm_string __ERROR_please_port_lp_parm_string_to_lp_parm_const_string_or_lp_parm_talloc_string { \ __ERROR_please_port_lp_parm_string_to_lp_parm_const_string_or_lp_parm_talloc_string }; @@ -190,6 +193,15 @@ typedef enum _vfs_op_type { SMB_VFS_OP_LSETXATTR, SMB_VFS_OP_FSETXATTR, + /* aio operations */ + SMB_VFS_OP_AIO_READ, + SMB_VFS_OP_AIO_WRITE, + SMB_VFS_OP_AIO_RETURN, + SMB_VFS_OP_AIO_CANCEL, + SMB_VFS_OP_AIO_ERROR, + SMB_VFS_OP_AIO_FSYNC, + SMB_VFS_OP_AIO_SUSPEND, + /* This should always be last enum value */ SMB_VFS_OP_LAST @@ -202,7 +214,7 @@ struct vfs_ops { struct vfs_fn_pointers { /* Disk operations */ - int (*connect)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *service, const char *user); + int (*connect_fn)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *service, const char *user); void (*disconnect)(struct vfs_handle_struct *handle, struct connection_struct *conn); SMB_BIG_UINT (*disk_free)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize); @@ -212,7 +224,7 @@ struct vfs_ops { /* Directory operations */ - DIR *(*opendir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname); + DIR *(*opendir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, const char *mask, uint32 attributes); SMB_STRUCT_DIRENT *(*readdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp); void (*seekdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp, long offset); long (*telldir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp); @@ -224,14 +236,14 @@ struct vfs_ops { /* File operations */ int (*open)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, int flags, mode_t mode); - int (*close)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd); + int (*close_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd); ssize_t (*read)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n); ssize_t (*pread)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n, SMB_OFF_T offset); ssize_t (*write)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, const void *data, size_t n); ssize_t (*pwrite)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, const void *data, size_t n, SMB_OFF_T offset); SMB_OFF_T (*lseek)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T offset, int whence); ssize_t (*sendfile)(struct vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count); - int (*rename)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *old, const char *new); + int (*rename)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *oldname, const char *newname); int (*fsync)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd); int (*stat)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf); int (*fstat)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf); @@ -301,12 +313,21 @@ struct vfs_ops { int (*lsetxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags); int (*fsetxattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int filedes, const char *name, const void *value, size_t size, int flags); + /* aio operations */ + int (*aio_read)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb); + int (*aio_write)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb); + ssize_t (*aio_return)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb); + int (*aio_cancel)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_AIOCB *aiocb); + int (*aio_error)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb); + int (*aio_fsync)(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb); + int (*aio_suspend)(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *timeout); + } ops; struct vfs_handles_pointers { /* Disk operations */ - struct vfs_handle_struct *connect; + struct vfs_handle_struct *connect_hnd; struct vfs_handle_struct *disconnect; struct vfs_handle_struct *disk_free; struct vfs_handle_struct *get_quota; @@ -327,7 +348,7 @@ struct vfs_ops { /* File operations */ struct vfs_handle_struct *open; - struct vfs_handle_struct *close; + struct vfs_handle_struct *close_hnd; struct vfs_handle_struct *read; struct vfs_handle_struct *pread; struct vfs_handle_struct *write; @@ -404,6 +425,14 @@ struct vfs_ops { struct vfs_handle_struct *lsetxattr; struct vfs_handle_struct *fsetxattr; + /* aio operations */ + struct vfs_handle_struct *aio_read; + struct vfs_handle_struct *aio_write; + struct vfs_handle_struct *aio_return; + struct vfs_handle_struct *aio_cancel; + struct vfs_handle_struct *aio_error; + struct vfs_handle_struct *aio_fsync; + struct vfs_handle_struct *aio_suspend; } handles; }; diff --git a/source/include/vfs_macros.h b/source/include/vfs_macros.h index 7681b443ebd..0647796ea84 100644 --- a/source/include/vfs_macros.h +++ b/source/include/vfs_macros.h @@ -28,7 +28,7 @@ ********************************************************************/ /* Disk operations */ -#define SMB_VFS_CONNECT(conn, service, user) ((conn)->vfs.ops.connect((conn)->vfs.handles.connect, (conn), (service), (user))) +#define SMB_VFS_CONNECT(conn, service, user) ((conn)->vfs.ops.connect_fn((conn)->vfs.handles.connect_hnd, (conn), (service), (user))) #define SMB_VFS_DISCONNECT(conn) ((conn)->vfs.ops.disconnect((conn)->vfs.handles.disconnect, (conn))) #define SMB_VFS_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) ((conn)->vfs.ops.disk_free((conn)->vfs.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize))) #define SMB_VFS_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.get_quota((conn)->vfs.handles.get_quota, (conn), (qtype), (id), (qt))) @@ -36,7 +36,7 @@ #define SMB_VFS_GET_SHADOW_COPY_DATA(fsp,shadow_copy_data,labels) ((fsp)->conn->vfs.ops.get_shadow_copy_data((fsp)->conn->vfs.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels))) /* Directory operations */ -#define SMB_VFS_OPENDIR(conn, fname) ((conn)->vfs.ops.opendir((conn)->vfs.handles.opendir, (conn), (fname))) +#define SMB_VFS_OPENDIR(conn, fname, mask, attr) ((conn)->vfs.ops.opendir((conn)->vfs.handles.opendir, (conn), (fname), (mask), (attr))) #define SMB_VFS_READDIR(conn, dirp) ((conn)->vfs.ops.readdir((conn)->vfs.handles.readdir, (conn), (dirp))) #define SMB_VFS_SEEKDIR(conn, dirp, offset) ((conn)->vfs.ops.seekdir((conn)->vfs.handles.seekdir, (conn), (dirp), (offset))) #define SMB_VFS_TELLDIR(conn, dirp) ((conn)->vfs.ops.telldir((conn)->vfs.handles.telldir, (conn), (dirp))) @@ -47,7 +47,7 @@ /* File operations */ #define SMB_VFS_OPEN(conn, fname, flags, mode) ((conn)->vfs.ops.open((conn)->vfs.handles.open, (conn), (fname), (flags), (mode))) -#define SMB_VFS_CLOSE(fsp, fd) ((fsp)->conn->vfs.ops.close((fsp)->conn->vfs.handles.close, (fsp), (fd))) +#define SMB_VFS_CLOSE(fsp, fd) ((fsp)->conn->vfs.ops.close_fn((fsp)->conn->vfs.handles.close_hnd, (fsp), (fd))) #define SMB_VFS_READ(fsp, fd, data, n) ((fsp)->conn->vfs.ops.read((fsp)->conn->vfs.handles.read, (fsp), (fd), (data), (n))) #define SMB_VFS_PREAD(fsp, fd, data, n, off) ((fsp)->conn->vfs.ops.pread((fsp)->conn->vfs.handles.pread, (fsp), (fd), (data), (n), (off))) #define SMB_VFS_WRITE(fsp, fd, data, n) ((fsp)->conn->vfs.ops.write((fsp)->conn->vfs.handles.write, (fsp), (fd), (data), (n))) @@ -122,6 +122,15 @@ #define SMB_VFS_LSETXATTR(conn,path,name,value,size,flags) ((conn)->vfs.ops.lsetxattr((conn)->vfs.handles.lsetxattr,(conn),(path),(name),(value),(size),(flags))) #define SMB_VFS_FSETXATTR(fsp,fd,name,value,size,flags) ((fsp)->conn->vfs.ops.fsetxattr((fsp)->conn->vfs.handles.fsetxattr,(fsp),(fd),(name),(value),(size),(flags))) +/* AIO operations. */ +#define SMB_VFS_AIO_READ(fsp,aiocb) ((fsp)->conn->vfs.ops.aio_read((fsp)->conn->vfs.handles.aio_read,(fsp),(aiocb))) +#define SMB_VFS_AIO_WRITE(fsp,aiocb) ((fsp)->conn->vfs.ops.aio_write((fsp)->conn->vfs.handles.aio_write,(fsp),(aiocb))) +#define SMB_VFS_AIO_RETURN(fsp,aiocb) ((fsp)->conn->vfs.ops.aio_return((fsp)->conn->vfs.handles.aio_return,(fsp),(aiocb))) +#define SMB_VFS_AIO_CANCEL(fsp,fd,aiocb) ((fsp)->conn->vfs.ops.aio_cancel((fsp)->conn->vfs.handles.aio_cancel,(fsp),(fd),(aiocb))) +#define SMB_VFS_AIO_ERROR(fsp,aiocb) ((fsp)->conn->vfs.ops.aio_error((fsp)->conn->vfs.handles.aio_error,(fsp),(aiocb))) +#define SMB_VFS_AIO_FSYNC(fsp,op,aiocb) ((fsp)->conn->vfs.ops.aio_fsync((fsp)->conn->vfs.handles.aio_fsync,(fsp),(op),(aiocb))) +#define SMB_VFS_AIO_SUSPEND(fsp,aiocb,n,ts) ((fsp)->conn->vfs.ops.aio_suspend((fsp)->conn->vfs.handles.aio_suspend,(fsp),(aiocb),(n),(ts))) + /******************************************************************* Don't access conn->vfs_opaque.ops directly!!! Use this macros! @@ -129,7 +138,7 @@ ********************************************************************/ /* Disk operations */ -#define SMB_VFS_OPAQUE_CONNECT(conn, service, user) ((conn)->vfs_opaque.ops.connect((conn)->vfs_opaque.handles.connect, (conn), (service), (user))) +#define SMB_VFS_OPAQUE_CONNECT(conn, service, user) ((conn)->vfs_opaque.ops.connect_fn((conn)->vfs_opaque.handles.connect_hnd, (conn), (service), (user))) #define SMB_VFS_OPAQUE_DISCONNECT(conn) ((conn)->vfs_opaque.ops.disconnect((conn)->vfs_opaque.handles.disconnect, (conn))) #define SMB_VFS_OPAQUE_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) ((conn)->vfs_opaque.ops.disk_free((conn)->vfs_opaque.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize))) #define SMB_VFS_OPAQUE_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.get_quota((conn)->vfs_opaque.handles.get_quota, (conn), (qtype), (id), (qt))) @@ -137,7 +146,7 @@ #define SMB_VFS_OPAQUE_GET_SHADOW_COPY_DATA(fsp,shadow_copy_data,labels) ((fsp)->conn->vfs_opaque.ops.get_shadow_copy_data((fsp)->conn->vfs_opaque.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels))) /* Directory operations */ -#define SMB_VFS_OPAQUE_OPENDIR(conn, fname) ((conn)->vfs_opaque.ops.opendir((conn)->vfs_opaque.handles.opendir, (conn), (fname))) +#define SMB_VFS_OPAQUE_OPENDIR(conn, fname, mask, attr) ((conn)->vfs_opaque.ops.opendir((conn)->vfs_opaque.handles.opendir, (conn), (fname), (mask), (attr))) #define SMB_VFS_OPAQUE_READDIR(conn, dirp) ((conn)->vfs_opaque.ops.readdir((conn)->vfs_opaque.handles.readdir, (conn), (dirp))) #define SMB_VFS_OPAQUE_SEEKDIR(conn, dirp, offset) ((conn)->vfs_opaque.ops.seekdir((conn)->vfs_opaque.handles.seekdir, (conn), (dirp), (offset))) #define SMB_VFS_OPAQUE_TELLDIR(conn, dirp) ((conn)->vfs_opaque.ops.telldir((conn)->vfs_opaque.handles.telldir, (conn), (dirp))) @@ -148,7 +157,7 @@ /* File operations */ #define SMB_VFS_OPAQUE_OPEN(conn, fname, flags, mode) ((conn)->vfs_opaque.ops.open((conn)->vfs_opaque.handles.open, (conn), (fname), (flags), (mode))) -#define SMB_VFS_OPAQUE_CLOSE(fsp, fd) ((fsp)->conn->vfs_opaque.ops.close((fsp)->conn->vfs_opaque.handles.close, (fsp), (fd))) +#define SMB_VFS_OPAQUE_CLOSE(fsp, fd) ((fsp)->conn->vfs_opaque.ops.close_fn((fsp)->conn->vfs_opaque.handles.close_hnd, (fsp), (fd))) #define SMB_VFS_OPAQUE_READ(fsp, fd, data, n) ((fsp)->conn->vfs_opaque.ops.read((fsp)->conn->vfs_opaque.handles.read, (fsp), (fd), (data), (n))) #define SMB_VFS_OPAQUE_PREAD(fsp, fd, data, n, off) ((fsp)->conn->vfs_opaque.ops.pread((fsp)->conn->vfs_opaque.handles.pread, (fsp), (fd), (data), (n), (off))) #define SMB_VFS_OPAQUE_WRITE(fsp, fd, data, n) ((fsp)->conn->vfs_opaque.ops.write((fsp)->conn->vfs_opaque.handles.write, (fsp), (fd), (data), (n))) @@ -223,6 +232,15 @@ #define SMB_VFS_OPAQUE_LSETXATTR(conn,path,name,value,size,flags) ((conn)->vfs_opaque.ops.lsetxattr((conn)->vfs_opaque.handles.lsetxattr,(conn),(path),(name),(value),(size),(flags))) #define SMB_VFS_OPAQUE_FSETXATTR(fsp,fd,name,value,size,flags) ((fsp)->conn->vfs_opaque.ops.fsetxattr((fsp)->conn->vfs_opaque.handles.fsetxattr,(fsp),(fd),(name),(value),(size),(flags))) +/* AIO operations. */ +#define SMB_VFS_OPAQUE_AIO_READ(fsp,aiocb) ((fsp)->conn->vfs_opaque.ops.aio_read((fsp)->conn->vfs_opaque.handles.aio_read,(fsp),(aiocb))) +#define SMB_VFS_OPAQUE_AIO_WRITE(fsp,aiocb) ((fsp)->conn->vfs_opaque.ops.aio_write((fsp)->conn->vfs_opaque.handles.aio_read,(fsp),(aiocb))) +#define SMB_VFS_OPAQUE_AIO_RETURN(fsp,aiocb) ((fsp)->conn->vfs_opaque.ops.aio_return((fsp)->conn->vfs_opaque.handles.aio_read,(fsp),(aiocb))) +#define SMB_VFS_OPAQUE_AIO_CANCEL(fsp,fd,aiocb) ((fsp)->conn->vfs_opaque.ops.aio_cancel((fsp)->conn->vfs_opaque.handles.aio_read,(fsp),(fd),(aiocb))) +#define SMB_VFS_OPAQUE_AIO_ERROR(fsp,aiocb) ((fsp)->conn->vfs_opaque.ops.aio_error((fsp)->conn->vfs_opaque.handles.aio_read,(fsp),(aiocb))) +#define SMB_VFS_OPAQUE_AIO_FSYNC(fsp,op,aiocb) ((fsp)->conn->vfs_opaque.ops.aio_fsync((fsp)->conn->vfs_opaque.handles.aio_read,(fsp),(op),(aiocb))) +#define SMB_VFS_OPAQUE_AIO_SUSPEND(fsp,aiocb,n,ts) ((fsp)->conn->vfs_opaque.ops.aio_suspend((fsp)->conn->vfs_opaque.handles.aio_suspend,(fsp),(aiocb),(n),(ts))) + /******************************************************************* Don't access handle->vfs_next.ops.* directly!!! Use this macros! @@ -230,7 +248,7 @@ ********************************************************************/ /* Disk operations */ -#define SMB_VFS_NEXT_CONNECT(handle, conn, service, user) ((handle)->vfs_next.ops.connect((handle)->vfs_next.handles.connect, (conn), (service), (user))) +#define SMB_VFS_NEXT_CONNECT(handle, conn, service, user) ((handle)->vfs_next.ops.connect_fn((handle)->vfs_next.handles.connect_hnd, (conn), (service), (user))) #define SMB_VFS_NEXT_DISCONNECT(handle, conn) ((handle)->vfs_next.ops.disconnect((handle)->vfs_next.handles.disconnect, (conn))) #define SMB_VFS_NEXT_DISK_FREE(handle, conn, path, small_query, bsize, dfree ,dsize) ((handle)->vfs_next.ops.disk_free((handle)->vfs_next.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize))) #define SMB_VFS_NEXT_GET_QUOTA(handle, conn, qtype, id, qt) ((handle)->vfs_next.ops.get_quota((handle)->vfs_next.handles.get_quota, (conn), (qtype), (id), (qt))) @@ -238,7 +256,7 @@ #define SMB_VFS_NEXT_GET_SHADOW_COPY_DATA(handle, fsp, shadow_copy_data ,labels) ((handle)->vfs_next.ops.get_shadow_copy_data((handle)->vfs_next.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels))) /* Directory operations */ -#define SMB_VFS_NEXT_OPENDIR(handle, conn, fname) ((handle)->vfs_next.ops.opendir((handle)->vfs_next.handles.opendir, (conn), (fname))) +#define SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr) ((handle)->vfs_next.ops.opendir((handle)->vfs_next.handles.opendir, (conn), (fname), (mask), (attr))) #define SMB_VFS_NEXT_READDIR(handle, conn, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (conn), (dirp))) #define SMB_VFS_NEXT_SEEKDIR(handle, conn, dirp, offset) ((handle)->vfs_next.ops.seekdir((handle)->vfs_next.handles.seekdir, (conn), (dirp), (offset))) #define SMB_VFS_NEXT_TELLDIR(handle, conn, dirp) ((handle)->vfs_next.ops.telldir((handle)->vfs_next.handles.telldir, (conn), (dirp))) @@ -250,7 +268,7 @@ /* File operations */ #define SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode) ((handle)->vfs_next.ops.open((handle)->vfs_next.handles.open, (conn), (fname), (flags), (mode))) -#define SMB_VFS_NEXT_CLOSE(handle, fsp, fd) ((handle)->vfs_next.ops.close((handle)->vfs_next.handles.close, (fsp), (fd))) +#define SMB_VFS_NEXT_CLOSE(handle, fsp, fd) ((handle)->vfs_next.ops.close_fn((handle)->vfs_next.handles.close_hnd, (fsp), (fd))) #define SMB_VFS_NEXT_READ(handle, fsp, fd, data, n) ((handle)->vfs_next.ops.read((handle)->vfs_next.handles.read, (fsp), (fd), (data), (n))) #define SMB_VFS_NEXT_PREAD(handle, fsp, fd, data, n, off) ((handle)->vfs_next.ops.pread((handle)->vfs_next.handles.pread, (fsp), (fd), (data), (n), (off))) #define SMB_VFS_NEXT_WRITE(handle, fsp, fd, data, n) ((handle)->vfs_next.ops.write((handle)->vfs_next.handles.write, (fsp), (fd), (data), (n))) @@ -325,4 +343,13 @@ #define SMB_VFS_NEXT_LSETXATTR(handle,conn,path,name,value,size,flags) ((handle)->vfs_next.ops.lsetxattr((handle)->vfs_next.handles.lsetxattr,(conn),(path),(name),(value),(size),(flags))) #define SMB_VFS_NEXT_FSETXATTR(handle,fsp,fd,name,value,size,flags) ((handle)->vfs_next.ops.fsetxattr((handle)->vfs_next.handles.fsetxattr,(fsp),(fd),(name),(value),(size),(flags))) +/* AIO operations. */ +#define SMB_VFS_NEXT_AIO_READ(handle,fsp,aiocb) ((handle)->vfs_next.ops.aio_read((handle)->vfs_next.handles.aio_read,(fsp),(aiocb))) +#define SMB_VFS_NEXT_AIO_WRITE(handle,fsp,aiocb) ((handle)->vfs_next.ops.aio_write((handle)->vfs_next.handles.aio_read,(fsp),(aiocb))) +#define SMB_VFS_NEXT_AIO_RETURN(handle,fsp,aiocb) ((handle)->vfs_next.ops.aio_return((handle)->vfs_next.handles.aio_read,(fsp),(aiocb))) +#define SMB_VFS_NEXT_AIO_CANCEL(handle,fsp,fd,aiocb) ((handle)->vfs_next.ops.aio_cancel((handle)->vfs_next.handles.aio_read,(fsp),(fd),(aiocb))) +#define SMB_VFS_NEXT_AIO_ERROR(handle,fsp,aiocb) ((handle)->vfs_next.ops.aio_error((handle)->vfs_next.handles.aio_read,(fsp),(aiocb))) +#define SMB_VFS_NEXT_AIO_FSYNC(handle,fsp,op,aiocb) ((handle)->vfs_next.ops.aio_fsync((handle)->vfs_next.handles.aio_read,(fsp),(op),(aiocb))) +#define SMB_VFS_NEXT_AIO_SUSPEND(handle,fsp,aiocb,n,ts) ((handle)->vfs_next.ops.aio_suspend((handle)->vfs_next.handles.aio_suspend,(fsp),(aiocb),(n),(ts))) + #endif /* _VFS_MACROS_H */ diff --git a/source/lib/data_blob.c b/source/lib/data_blob.c index 35805f861c5..161f46a9417 100644 --- a/source/lib/data_blob.c +++ b/source/lib/data_blob.c @@ -35,6 +35,7 @@ static void free_data_blob(DATA_BLOB *d) construct a data blob, must be freed with data_blob_free() you can pass NULL for p and get a blank data blob *******************************************************************/ + DATA_BLOB data_blob(const void *p, size_t length) { DATA_BLOB ret; diff --git a/source/lib/debug.c b/source/lib/debug.c index 43d1f64eb17..d6785f83adf 100644 --- a/source/lib/debug.c +++ b/source/lib/debug.c @@ -166,6 +166,7 @@ static const char *default_classname_table[] = { "acls", /* DBGC_ACLS */ "printerdb", /* DBGC_PRINTERDB */ "locking", /* DBGC_LOCKING */ + "msdfs", /* DBGC_MSDFS */ NULL }; diff --git a/source/lib/privileges.c b/source/lib/privileges.c index ae98d8940ff..05dff33307c 100644 --- a/source/lib/privileges.c +++ b/source/lib/privileges.c @@ -25,8 +25,6 @@ #define PRIVPREFIX "PRIV_" -#define GENERATE_LUID_LOW(x) (x)+1; - static const SE_PRIV se_priv_all = SE_ALL_PRIVS; static const SE_PRIV se_priv_end = SE_END; @@ -43,60 +41,65 @@ const SE_PRIV se_restore = SE_RESTORE; /******************************************************************** This is a list of privileges reported by a WIndows 2000 SP4 AD DC - just for reference purposes: - - SeCreateTokenPrivilege Create a token object - SeAssignPrimaryTokenPrivilege Replace a process level token - SeLockMemoryPrivilege Lock pages in memory - SeIncreaseQuotaPrivilege Increase quotas - SeMachineAccountPrivilege Add workstations to domain - SeTcbPrivilege Act as part of the operating system - SeSecurityPrivilege Manage auditing and security log - SeTakeOwnershipPrivilege Take ownership of files or other objects - SeLoadDriverPrivilege Load and unload device drivers - SeSystemProfilePrivilege Profile system performance - SeSystemtimePrivilege Change the system time - SeProfileSingleProcessPrivilege Profile single process - SeIncreaseBasePriorityPrivilege Increase scheduling priority - SeCreatePagefilePrivilege Create a pagefile - SeCreatePermanentPrivilege Create permanent shared objects - SeBackupPrivilege Back up files and directories - SeRestorePrivilege Restore files and directories - SeShutdownPrivilege Shut down the system - SeDebugPrivilege Debug programs - SeAuditPrivilege Generate security audits - SeSystemEnvironmentPrivilege Modify firmware environment values - SeChangeNotifyPrivilege Bypass traverse checking - SeRemoteShutdownPrivilege Force shutdown from a remote system - SeUndockPrivilege Remove computer from docking station - SeSyncAgentPrivilege Synchronize directory service data - SeEnableDelegationPrivilege Enable computer and user accounts to be trusted for delegation - SeManageVolumePrivilege Perform volume maintenance tasks - SeImpersonatePrivilege Impersonate a client after authentication - SeCreateGlobalPrivilege Create global objects - -********************************************************************/ - - + just for reference purposes (and I know the LUID is not guaranteed + across reboots): + + SeCreateTokenPrivilege Create a token object ( 0x0, 0x2 ) + SeAssignPrimaryTokenPrivilege Replace a process level token ( 0x0, 0x3 ) + SeLockMemoryPrivilege Lock pages in memory ( 0x0, 0x4 ) + SeIncreaseQuotaPrivilege Increase quotas ( 0x0, 0x5 ) + SeMachineAccountPrivilege Add workstations to domain ( 0x0, 0x6 ) + SeTcbPrivilege Act as part of the operating system ( 0x0, 0x7 ) + SeSecurityPrivilege Manage auditing and security log ( 0x0, 0x8 ) + SeTakeOwnershipPrivilege Take ownership of files or other objects ( 0x0, 0x9 ) + SeLoadDriverPrivilege Load and unload device drivers ( 0x0, 0xa ) + SeSystemProfilePrivilege Profile system performance ( 0x0, 0xb ) + SeSystemtimePrivilege Change the system time ( 0x0, 0xc ) + SeProfileSingleProcessPrivilege Profile single process ( 0x0, 0xd ) + SeIncreaseBasePriorityPrivilege Increase scheduling priority ( 0x0, 0xe ) + SeCreatePagefilePrivilege Create a pagefile ( 0x0, 0xf ) + SeCreatePermanentPrivilege Create permanent shared objects ( 0x0, 0x10 ) + SeBackupPrivilege Back up files and directories ( 0x0, 0x11 ) + SeRestorePrivilege Restore files and directories ( 0x0, 0x12 ) + SeShutdownPrivilege Shut down the system ( 0x0, 0x13 ) + SeDebugPrivilege Debug programs ( 0x0, 0x14 ) + SeAuditPrivilege Generate security audits ( 0x0, 0x15 ) + SeSystemEnvironmentPrivilege Modify firmware environment values ( 0x0, 0x16 ) + SeChangeNotifyPrivilege Bypass traverse checking ( 0x0, 0x17 ) + SeRemoteShutdownPrivilege Force shutdown from a remote system ( 0x0, 0x18 ) + SeUndockPrivilege Remove computer from docking station ( 0x0, 0x19 ) + SeSyncAgentPrivilege Synchronize directory service data ( 0x0, 0x1a ) + SeEnableDelegationPrivilege Enable computer and user accounts to be trusted for delegation ( 0x0, 0x1b ) + SeManageVolumePrivilege Perform volume maintenance tasks ( 0x0, 0x1c ) + SeImpersonatePrivilege Impersonate a client after authentication ( 0x0, 0x1d ) + SeCreateGlobalPrivilege Create global objects ( 0x0, 0x1e ) + + ********************************************************************/ + +/* we have to define the LUID here due to a horrible check by printmig.exe + that requires the SeBackupPrivilege match what is in Windows. So match + those that we implement and start Samba privileges at 0x1001 */ + PRIVS privs[] = { #if 0 /* usrmgr will display these twice if you include them. We don't use them but we'll keep the bitmasks reserved in privileges.h anyways */ - {SE_NETWORK_LOGON, "SeNetworkLogonRight", "Access this computer from network"}, - {SE_INTERACTIVE_LOGON, "SeInteractiveLogonRight", "Log on locally"}, - {SE_BATCH_LOGON, "SeBatchLogonRight", "Log on as a batch job"}, - {SE_SERVICE_LOGON, "SeServiceLogonRight", "Log on as a service"}, + {SE_NETWORK_LOGON, "SeNetworkLogonRight", "Access this computer from network", { 0x0, 0x0 }}, + {SE_INTERACTIVE_LOGON, "SeInteractiveLogonRight", "Log on locally", { 0x0, 0x0 }}, + {SE_BATCH_LOGON, "SeBatchLogonRight", "Log on as a batch job", { 0x0, 0x0 }}, + {SE_SERVICE_LOGON, "SeServiceLogonRight", "Log on as a service", { 0x0, 0x0 }}, #endif - {SE_MACHINE_ACCOUNT, "SeMachineAccountPrivilege", "Add machines to domain"}, - {SE_PRINT_OPERATOR, "SePrintOperatorPrivilege", "Manage printers"}, - {SE_ADD_USERS, "SeAddUsersPrivilege", "Add users and groups to the domain"}, - {SE_REMOTE_SHUTDOWN, "SeRemoteShutdownPrivilege", "Force shutdown from a remote system"}, - {SE_DISK_OPERATOR, "SeDiskOperatorPrivilege", "Manage disk shares"}, - {SE_BACKUP, "SeBackupPrivilege", "Back up files and directories"}, - {SE_RESTORE, "SeRestorePrivilege", "Restore files and directories"}, - {SE_TAKE_OWNERSHIP, "SeTakeOwnershipPrivilege", "Take ownership of files or other objects"}, - - {SE_END, "", ""} + {SE_MACHINE_ACCOUNT, "SeMachineAccountPrivilege", "Add machines to domain", { 0x0, 0x0006 }}, + {SE_TAKE_OWNERSHIP, "SeTakeOwnershipPrivilege", "Take ownership of files or other objects",{ 0x0, 0x0009 }}, + {SE_BACKUP, "SeBackupPrivilege", "Back up files and directories", { 0x0, 0x0011 }}, + {SE_RESTORE, "SeRestorePrivilege", "Restore files and directories", { 0x0, 0x0012 }}, + {SE_REMOTE_SHUTDOWN, "SeRemoteShutdownPrivilege", "Force shutdown from a remote system", { 0x0, 0x0018 }}, + + {SE_PRINT_OPERATOR, "SePrintOperatorPrivilege", "Manage printers", { 0x0, 0x1001 }}, + {SE_ADD_USERS, "SeAddUsersPrivilege", "Add users and groups to the domain", { 0x0, 0x1002 }}, + {SE_DISK_OPERATOR, "SeDiskOperatorPrivilege", "Manage disk shares", { 0x0, 0x1003 }}, + + {SE_END, "", "", { 0x0, 0x0 }} }; typedef struct { @@ -109,7 +112,6 @@ typedef struct { SID_LIST sids; } PRIV_SID_LIST; - /*************************************************************************** copy an SE_PRIV structure ****************************************************************************/ @@ -402,7 +404,7 @@ LUID_ATTR get_privilege_luid( SE_PRIV *mask ) for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { if ( se_priv_equal( &privs[i].se_priv, mask ) ) { - priv_luid.luid.low = GENERATE_LUID_LOW(i); + priv_luid.luid = privs[i].luid; break; } } @@ -537,6 +539,9 @@ BOOL grant_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask) { SE_PRIV old_mask, new_mask; + ZERO_STRUCT( old_mask ); + ZERO_STRUCT( new_mask ); + if ( get_privileges( sid, &old_mask ) ) se_priv_copy( &new_mask, &old_mask ); else @@ -746,17 +751,19 @@ BOOL user_has_any_privilege(NT_USER_TOKEN *token, const SE_PRIV *privilege) char* luid_to_privilege_name(const LUID *set) { static fstring name; - int max = count_all_privileges(); + int i; if (set->high != 0) return NULL; - if ( set->low > max ) - return NULL; - - fstrcpy( name, privs[set->low - 1].name ); + for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { + if ( set->low == privs[i].luid.low ) { + fstrcpy( name, privs[set->low - 1].name ); + return name; + } + } - return name; + return NULL; } /******************************************************************* @@ -792,7 +799,7 @@ BOOL se_priv_to_privilege_set( PRIVILEGE_SET *set, SE_PRIV *mask ) if ( !is_privilege_assigned(mask, &privs[i].se_priv) ) continue; - luid.luid.low = GENERATE_LUID_LOW(i); + luid.luid = privs[i].luid; if ( !privilege_set_add( set, luid ) ) return False; diff --git a/source/lib/secace.c b/source/lib/secace.c index c550dcce311..b2cf81d0fd0 100644 --- a/source/lib/secace.c +++ b/source/lib/secace.c @@ -72,25 +72,25 @@ void init_sec_ace(SEC_ACE *t, const DOM_SID *sid, uint8 type, SEC_ACCESS mask, u adds new SID with its permissions to ACE list ********************************************************************/ -NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, unsigned *num, DOM_SID *sid, uint32 mask) +NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **pp_new, SEC_ACE *old, unsigned *num, DOM_SID *sid, uint32 mask) { unsigned int i = 0; - if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER; + if (!ctx || !pp_new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER; *num += 1; - if((new[0] = TALLOC_ZERO_ARRAY(ctx, SEC_ACE, *num )) == 0) + if((pp_new[0] = TALLOC_ZERO_ARRAY(ctx, SEC_ACE, *num )) == 0) return NT_STATUS_NO_MEMORY; for (i = 0; i < *num - 1; i ++) - sec_ace_copy(&(*new)[i], &old[i]); + sec_ace_copy(&(*pp_new)[i], &old[i]); - (*new)[i].type = 0; - (*new)[i].flags = 0; - (*new)[i].size = SEC_ACE_HEADER_SIZE + sid_size(sid); - (*new)[i].info.mask = mask; - sid_copy(&(*new)[i].trustee, sid); + (*pp_new)[i].type = 0; + (*pp_new)[i].flags = 0; + (*pp_new)[i].size = SEC_ACE_HEADER_SIZE + sid_size(sid); + (*pp_new)[i].info.mask = mask; + sid_copy(&(*pp_new)[i].trustee, sid); return NT_STATUS_OK; } @@ -117,19 +117,19 @@ NTSTATUS sec_ace_mod_sid(SEC_ACE *ace, size_t num, DOM_SID *sid, uint32 mask) delete SID from ACL ********************************************************************/ -NTSTATUS sec_ace_del_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, uint32 *num, DOM_SID *sid) +NTSTATUS sec_ace_del_sid(TALLOC_CTX *ctx, SEC_ACE **pp_new, SEC_ACE *old, uint32 *num, DOM_SID *sid) { unsigned int i = 0; unsigned int n_del = 0; - if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER; + if (!ctx || !pp_new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER; - if((new[0] = TALLOC_ZERO_ARRAY(ctx, SEC_ACE, *num )) == 0) + if((pp_new[0] = TALLOC_ZERO_ARRAY(ctx, SEC_ACE, *num )) == 0) return NT_STATUS_NO_MEMORY; for (i = 0; i < *num; i ++) { if (sid_compare(&old[i].trustee, sid) != 0) - sec_ace_copy(&(*new)[i], &old[i]); + sec_ace_copy(&(*pp_new)[i], &old[i]); else n_del ++; } diff --git a/source/lib/smbldap_util.c b/source/lib/smbldap_util.c index 46ea5b7bfcc..798cb3fff74 100644 --- a/source/lib/smbldap_util.c +++ b/source/lib/smbldap_util.c @@ -155,7 +155,7 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state, LDAPMessage ** result, const char *domain_name, BOOL try_add) { - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; pstring filter; int rc; const char **attr_list; @@ -168,7 +168,6 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state, DEBUG(2, ("Searching for:[%s]\n", filter)); - attr_list = get_attr_list( dominfo_attr_list ); rc = smbldap_search_suffix(ldap_state, filter, attr_list , result); free_attr_list( attr_list ); @@ -176,28 +175,44 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state, if (rc != LDAP_SUCCESS) { DEBUG(2,("Problem during LDAPsearch: %s\n", ldap_err2string (rc))); DEBUG(2,("Query was: %s, %s\n", lp_ldap_suffix(), filter)); - } else if (ldap_count_entries(ldap_state->ldap_struct, *result) < 1) { + goto failed; + } + + count = ldap_count_entries(ldap_state->ldap_struct, *result); + + if (count == 1) + return NT_STATUS_OK; + + ldap_msgfree(*result); + *result = NULL; + + if (count < 1) { + DEBUG(3, ("Got no domain info entries for domain\n")); - ldap_msgfree(*result); - *result = NULL; - if ( try_add && NT_STATUS_IS_OK(ret = add_new_domain_info(ldap_state, domain_name)) ) { - return smbldap_search_domain_info(ldap_state, result, domain_name, False); - } - else { + + if (!try_add) + goto failed; + + status = add_new_domain_info(ldap_state, domain_name); + if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Adding domain info for %s failed with %s\n", - domain_name, nt_errstr(ret))); - return ret; + domain_name, nt_errstr(status))); + goto failed; } - } else if ((count = ldap_count_entries(ldap_state->ldap_struct, *result)) > 1) { + + return smbldap_search_domain_info(ldap_state, result, domain_name, False); + + } + + if (count > 1 ) { + DEBUG(0, ("Got too many (%d) domain info entries for domain %s\n", count, domain_name)); - ldap_msgfree(*result); - *result = NULL; - return ret; - } else { - return NT_STATUS_OK; + goto failed; } + +failed: + return status; - return ret; } diff --git a/source/lib/socket_wrapper.c b/source/lib/socket_wrapper.c index cb3911c3582..bb4a4e0a673 100644 --- a/source/lib/socket_wrapper.c +++ b/source/lib/socket_wrapper.c @@ -19,21 +19,20 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifdef _SAMBA_BUILD_ #include "includes.h" -#include "system/network.h" -#else -#include <sys/types.h> -#include <sys/socket.h> -#include <errno.h> -#include <sys/un.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include "dlinklist.h" + +#ifdef SOCKET_WRAPPER_REPLACE +#undef accept +#undef connect +#undef bind +#undef getpeername +#undef getsockname +#undef getsockopt +#undef setsockopt +#undef recvfrom +#undef sendto +#undef socket +#undef close #endif /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support @@ -54,6 +53,10 @@ #define real_close close #endif +#undef malloc +#undef calloc +#undef strdup + static struct sockaddr *sockaddr_dup(const void *data, socklen_t len) { struct sockaddr *ret = (struct sockaddr *)malloc(len); @@ -95,8 +98,8 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, s } in->sin_family = AF_INET; - in->sin_port = 1025; /* Default to 1025 */ - p = strchr(un->sun_path, '/'); + in->sin_port = htons(1025); /* Default to 1025 */ + p = strrchr(un->sun_path, '/'); if (p) p++; else p = un->sun_path; if (sscanf(p, "sock_ip_%d_%u", &type, &prt) == 2) { @@ -107,9 +110,20 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, s return 0; } -static int convert_in_un(int type, const struct sockaddr_in *in, struct sockaddr_un *un) +static int convert_in_un(struct socket_info *si, const struct sockaddr_in *in, struct sockaddr_un *un) { + int type = si->type; uint16_t prt = ntohs(in->sin_port); + if (prt == 0) { + struct stat st; + /* handle auto-allocation of ephemeral ports */ + prt = 5000; + do { + snprintf(un->sun_path, sizeof(un->sun_path), "%s/sock_ip_%d_%u", + getenv("SOCKET_WRAPPER_DIR"), type, ++prt); + } while (stat(un->sun_path, &st) == 0 && prt < 10000); + ((struct sockaddr_in *)si->myname)->sin_port = htons(prt); + } snprintf(un->sun_path, sizeof(un->sun_path), "%s/sock_ip_%d_%u", getenv("SOCKET_WRAPPER_DIR"), type, prt); return 0; @@ -126,7 +140,7 @@ static struct socket_info *find_socket_info(int fd) return NULL; } -static int sockaddr_convert_to_un(const struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len, +static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len, struct sockaddr_un *out_addr) { if (!out_addr) @@ -136,7 +150,7 @@ static int sockaddr_convert_to_un(const struct socket_info *si, const struct soc switch (in_addr->sa_family) { case AF_INET: - return convert_in_un(si->type, (const struct sockaddr_in *)in_addr, out_addr); + return convert_in_un(si, (const struct sockaddr_in *)in_addr, out_addr); case AF_UNIX: memcpy(out_addr, in_addr, sizeof(*out_addr)); return 0; @@ -229,15 +243,58 @@ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) memset(child_si, 0, sizeof(*child_si)); child_si->fd = fd; + child_si->bound = 1; - if (addr && addrlen) { - child_si->myname_len = *addrlen; - child_si->myname = sockaddr_dup(addr, *addrlen); - } + child_si->myname_len = parent_si->myname_len; + child_si->myname = sockaddr_dup(parent_si->myname, parent_si->myname_len); + + child_si->peername_len = *addrlen; + child_si->peername = sockaddr_dup(addr, *addrlen); + + DLIST_ADD(sockets, child_si); return fd; } +/* using sendto() or connect() on an unbound socket would give the + recipient no way to reply, as unlike UDP and TCP, a unix domain + socket can't auto-assign emphemeral port numbers, so we need to + assign it here */ +static int swrap_auto_bind(struct socket_info *si) +{ + struct sockaddr_un un_addr; + struct sockaddr_in in; + int i; + + un_addr.sun_family = AF_UNIX; + + for (i=0;i<1000;i++) { + snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), + "%s/sock_ip_%u_%u", getenv("SOCKET_WRAPPER_DIR"), + SOCK_DGRAM, i + 10000); + if (bind(si->fd, (struct sockaddr *)&un_addr, + sizeof(un_addr)) == 0) { + si->tmp_path = strdup(un_addr.sun_path); + si->bound = 1; + break; + } + } + if (i == 1000) { + return -1; + } + + memset(&in, 0, sizeof(in)); + in.sin_family = AF_INET; + in.sin_port = htons(i); + in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + si->myname_len = sizeof(in); + si->myname = sockaddr_dup(&in, si->myname_len); + si->bound = 1; + return 0; +} + + int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) { int ret; @@ -256,6 +313,11 @@ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) return -1; } + if (si->bound == 0 && si->domain != AF_UNIX) { + ret = swrap_auto_bind(si); + if (ret == -1) return -1; + } + ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr); if (ret == -1) return -1; @@ -280,6 +342,14 @@ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) return real_bind(s, myaddr, addrlen); } + si->myname_len = addrlen; + si->myname = sockaddr_dup(myaddr, addrlen); + + if (myaddr->sa_family == AF_INET && + ((const struct sockaddr_in *)myaddr)->sin_addr.s_addr == 0) { + ((struct sockaddr_in *)si->myname)->sin_addr.s_addr = + htonl(INADDR_LOOPBACK); + } ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr); if (ret == -1) return -1; @@ -289,8 +359,6 @@ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) sizeof(struct sockaddr_un)); if (ret == 0) { - si->myname_len = addrlen; - si->myname = sockaddr_dup(myaddr, addrlen); si->bound = 1; } @@ -402,6 +470,7 @@ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr return ret; } + ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) { struct sockaddr_un un_addr; @@ -412,31 +481,10 @@ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const str return real_sendto(s, buf, len, flags, to, tolen); } - /* using sendto() on an unbound DGRAM socket would give the - recipient no way to reply, as unlike UDP, a unix domain socket - can't auto-assign emphemeral port numbers, so we need to assign - it here */ - if (si->bound == 0 && si->type == SOCK_DGRAM) { - int i; - - un_addr.sun_family = AF_UNIX; - - for (i=0;i<1000;i++) { - snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), - "%s/sock_ip_%u_%u", getenv("SOCKET_WRAPPER_DIR"), - SOCK_DGRAM, i + 10000); - if (bind(si->fd, (struct sockaddr *)&un_addr, - sizeof(un_addr)) == 0) { - si->tmp_path = strdup(un_addr.sun_path); - si->bound = 1; - break; - } - } - if (i == 1000) { - return -1; - } + if (si->bound == 0 && si->domain != AF_UNIX) { + ret = swrap_auto_bind(si); + if (ret == -1) return -1; } - ret = sockaddr_convert_to_un(si, to, tolen, &un_addr); if (ret == -1) return -1; diff --git a/source/lib/system.c b/source/lib/system.c index 6c36544b775..6ac2cdf2433 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -1846,3 +1846,161 @@ uint32 unix_dev_minor(SMB_DEV_T dev) return (uint32)(dev & 0xff); #endif } + +#if defined(WITH_AIO) + +/******************************************************************* + An aio_read wrapper that will deal with 64-bit sizes. +********************************************************************/ + +int sys_aio_read(SMB_STRUCT_AIOCB *aiocb) +{ +#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_READ64) + return aio_read64(aiocb); +#elif defined(HAVE_AIO_READ) + return aio_read(aiocb); +#else + errno = ENOSYS; + return -1; +#endif +} + +/******************************************************************* + An aio_write wrapper that will deal with 64-bit sizes. +********************************************************************/ + +int sys_aio_write(SMB_STRUCT_AIOCB *aiocb) +{ +#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_WRITE64) + return aio_write64(aiocb); +#elif defined(HAVE_AIO_WRITE) + return aio_write(aiocb); +#else + errno = ENOSYS; + return -1; +#endif +} + +/******************************************************************* + An aio_return wrapper that will deal with 64-bit sizes. +********************************************************************/ + +ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb) +{ +#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_RETURN64) + return aio_return64(aiocb); +#elif defined(HAVE_AIO_RETURN) + return aio_return(aiocb); +#else + errno = ENOSYS; + return -1; +#endif +} + +/******************************************************************* + An aio_cancel wrapper that will deal with 64-bit sizes. +********************************************************************/ + +int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb) +{ +#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_CANCEL64) + return aio_cancel64(fd, aiocb); +#elif defined(HAVE_AIO_CANCEL) + return aio_cancel(fd, aiocb); +#else + errno = ENOSYS; + return -1; +#endif +} + +/******************************************************************* + An aio_error wrapper that will deal with 64-bit sizes. +********************************************************************/ + +int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb) +{ +#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_ERROR64) + return aio_error64(aiocb); +#elif defined(HAVE_AIO_ERROR) + return aio_error(aiocb); +#else + errno = ENOSYS; + return -1; +#endif +} + +/******************************************************************* + An aio_fsync wrapper that will deal with 64-bit sizes. +********************************************************************/ + +int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb) +{ +#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_FSYNC64) + return aio_fsync64(op, aiocb); +#elif defined(HAVE_AIO_FSYNC) + return aio_fsync64(op, aiocb); +#else + errno = ENOSYS; + return -1; +#endif +} + +/******************************************************************* + An aio_fsync wrapper that will deal with 64-bit sizes. +********************************************************************/ + +int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout) +{ +#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_SUSPEND64) + return aio_suspend64(cblist, n, timeout); +#elif defined(HAVE_AIO_FSYNC) + return aio_suspend(cblist, n, timeout); +#else + errno = ENOSYS; + return -1; +#endif +} +#else /* !WITH_AIO */ + +int sys_aio_read(SMB_STRUCT_AIOCB *aiocb) +{ + errno = ENOSYS; + return -1; +} + +int sys_aio_write(SMB_STRUCT_AIOCB *aiocb) +{ + errno = ENOSYS; + return -1; +} + +ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb) +{ + errno = ENOSYS; + return -1; +} + +int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb) +{ + errno = ENOSYS; + return -1; +} + +int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb) +{ + errno = ENOSYS; + return -1; +} + +int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb) +{ + errno = ENOSYS; + return -1; +} + +int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout) +{ + errno = ENOSYS; + return -1; +} +#endif /* WITH_AIO */ diff --git a/source/lib/util.c b/source/lib/util.c index 297eeb4d030..de366c604ff 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -2217,14 +2217,14 @@ int set_maxfiles(int requested_max) Possibly replace mkstemp if it is broken. *****************************************************************/ -int smb_mkstemp(char *template) +int smb_mkstemp(char *name_template) { #if HAVE_SECURE_MKSTEMP - return mkstemp(template); + return mkstemp(name_template); #else /* have a reasonable go at emulating it. Hope that the system mktemp() isn't completly hopeless */ - char *p = mktemp(template); + char *p = mktemp(name_template); if (!p) return -1; return open(p, O_CREAT|O_EXCL|O_RDWR, 0600); @@ -2451,6 +2451,12 @@ char *parent_dirname(const char *path) BOOL ms_has_wild(const char *s) { char c; + + if (lp_posix_pathnames()) { + /* With posix pathnames no characters are wild. */ + return False; + } + while ((c = *s++)) { switch (c) { case '*': @@ -2729,3 +2735,25 @@ int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6) return ret; } #endif + +uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options) +{ + switch (share_access) { + case FILE_SHARE_NONE: + return DENY_ALL; + case FILE_SHARE_READ: + return DENY_WRITE; + case FILE_SHARE_WRITE: + return DENY_READ; + case FILE_SHARE_READ|FILE_SHARE_WRITE: + case FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE: + return DENY_NONE; + } + if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) { + return DENY_DOS; + } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) { + return DENY_FCB; + } + + return (uint32)-1; +} diff --git a/source/lib/util_str.c b/source/lib/util_str.c index f600d1704e0..42229f105a1 100644 --- a/source/lib/util_str.c +++ b/source/lib/util_str.c @@ -2194,3 +2194,30 @@ void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len, *len = -1; *string = NULL; } + +/* + Returns the substring from src between the first occurrence of + the char "front" and the first occurence of the char "back". + Mallocs the return string which must be freed. Not for use + with wide character strings. +*/ +char *sstring_sub(const char *src, char front, char back) +{ + char *temp1, *temp2, *temp3; + ptrdiff_t len; + + temp1 = strchr(src, front); + if (temp1 == NULL) return NULL; + temp2 = strchr(src, back); + if (temp2 == NULL) return NULL; + len = temp2 - temp1; + if (len <= 0) return NULL; + temp3 = (char*)SMB_MALLOC(len); + if (temp3 == NULL) { + DEBUG(1,("Malloc failure in sstring_sub\n")); + return NULL; + } + memcpy(temp3, temp1+1, len-1); + temp3[len-1] = '\0'; + return temp3; +} diff --git a/source/libads/ads_ldap.c b/source/libads/ads_ldap.c index 944cb1599cc..ae86ef0b764 100644 --- a/source/libads/ads_ldap.c +++ b/source/libads/ads_ldap.c @@ -24,135 +24,6 @@ #include "includes.h" #ifdef HAVE_LDAP -/* convert a single name to a sid in a domain */ -NTSTATUS ads_name_to_sid(ADS_STRUCT *ads, - const char *name, - DOM_SID *sid, - enum SID_NAME_USE *type) -{ - const char *attrs[] = {"objectSid", "sAMAccountType", NULL}; - int count; - ADS_STATUS rc; - void *res = NULL; - char *ldap_exp; - uint32 t; - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - char *escaped_name = escape_ldap_string_alloc(name); - char *escaped_realm = escape_ldap_string_alloc(ads->config.realm); - - if (!escaped_name || !escaped_realm) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - - if (asprintf(&ldap_exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))", - escaped_name, escaped_name, escaped_realm) == -1) { - DEBUG(1,("ads_name_to_sid: asprintf failed!\n")); - status = NT_STATUS_NO_MEMORY; - goto done; - } - - rc = ads_search_retry(ads, &res, ldap_exp, attrs); - free(ldap_exp); - if (!ADS_ERR_OK(rc)) { - DEBUG(1,("name_to_sid ads_search: %s\n", ads_errstr(rc))); - goto done; - } - - count = ads_count_replies(ads, res); - if (count != 1) { - DEBUG(1,("name_to_sid: %s not found\n", name)); - goto done; - } - - if (!ads_pull_sid(ads, res, "objectSid", sid)) { - DEBUG(1,("No sid for %s !?\n", name)); - goto done; - } - - if (!ads_pull_uint32(ads, res, "sAMAccountType", &t)) { - DEBUG(1,("No sAMAccountType for %s !?\n", name)); - goto done; - } - - *type = ads_atype_map(t); - - status = NT_STATUS_OK; - - DEBUG(3,("ads name_to_sid mapped %s\n", name)); - -done: - if (res) ads_msgfree(ads, res); - - SAFE_FREE(escaped_name); - SAFE_FREE(escaped_realm); - - return status; -} - -/* convert a sid to a user or group name */ -NTSTATUS ads_sid_to_name(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - const DOM_SID *sid, - char **name, - enum SID_NAME_USE *type) -{ - const char *attrs[] = {"userPrincipalName", - "sAMAccountName", - "sAMAccountType", NULL}; - ADS_STATUS rc; - void *msg = NULL; - char *ldap_exp = NULL; - char *sidstr = NULL; - uint32 atype; - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - - if (!(sidstr = sid_binstring(sid))) { - DEBUG(1,("ads_sid_to_name: sid_binstring failed!\n")); - status = NT_STATUS_NO_MEMORY; - goto done; - } - - if (asprintf(&ldap_exp, "(objectSid=%s)", sidstr) == -1) { - DEBUG(1,("ads_sid_to_name: asprintf failed!\n")); - status = NT_STATUS_NO_MEMORY; - goto done; - } - - rc = ads_search_retry(ads, &msg, ldap_exp, attrs); - if (!ADS_ERR_OK(rc)) { - status = ads_ntstatus(rc); - DEBUG(1,("ads_sid_to_name ads_search: %s\n", ads_errstr(rc))); - goto done; - } - - if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype)) { - goto done; - } - - *name = ads_pull_username(ads, mem_ctx, msg); - if (!*name) { - DEBUG(1,("ads_sid_to_name: ads_pull_username retuned NULL!\n")); - status = NT_STATUS_NO_MEMORY; - goto done; - } - - *type = ads_atype_map(atype); - - status = NT_STATUS_OK; - - DEBUG(3,("ads sid_to_name mapped %s\n", *name)); - -done: - if (msg) ads_msgfree(ads, msg); - - SAFE_FREE(ldap_exp); - SAFE_FREE(sidstr); - - return status; -} - - /* convert a sid to a DN */ ADS_STATUS ads_sid_to_dn(ADS_STRUCT *ads, diff --git a/source/libads/ads_struct.c b/source/libads/ads_struct.c index e8546f86f50..d8676d050dd 100644 --- a/source/libads/ads_struct.c +++ b/source/libads/ads_struct.c @@ -132,8 +132,13 @@ void ads_destroy(ADS_STRUCT **ads) SAFE_FREE((*ads)->config.realm); SAFE_FREE((*ads)->config.bind_path); + SAFE_FREE((*ads)->config.schema_path); SAFE_FREE((*ads)->config.ldap_server_name); + SAFE_FREE((*ads)->schema.sfu_uidnumber_attr); + SAFE_FREE((*ads)->schema.sfu_gidnumber_attr); + SAFE_FREE((*ads)->schema.sfu_shell_attr); + SAFE_FREE((*ads)->schema.sfu_homedir_attr); ZERO_STRUCTP(*ads); diff --git a/source/libads/ldap.c b/source/libads/ldap.c index 04754f4e9e1..81afd7f49e3 100644 --- a/source/libads/ldap.c +++ b/source/libads/ldap.c @@ -2388,6 +2388,43 @@ static time_t ads_parse_time(const char *str) } +const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * OID) +{ + ADS_STATUS rc; + int count = 0; + void *res = NULL; + char *expr = NULL; + const char *attrs[] = { "lDAPDisplayName", NULL }; + + if (ads == NULL || mem_ctx == NULL || OID == NULL) { + goto failed; + } + + expr = talloc_asprintf(mem_ctx, "(attributeId=%s)", OID); + if (expr == NULL) { + goto failed; + } + + rc = ads_do_search_retry(ads, ads->config.schema_path, + LDAP_SCOPE_SUBTREE, expr, attrs, &res); + if (!ADS_ERR_OK(rc)) { + goto failed; + } + + count = ads_count_replies(ads, res); + if (count == 0 || !res) { + goto failed; + } + + return ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName"); + +failed: + DEBUG(0,("ads_get_attrname_by_oid: failed to retrieve name for oid: %s\n", + OID)); + + return NULL; +} + /** * Find the servers name and realm - this can be done before authentication * The ldapServiceName field on w2k looks like this: @@ -2397,12 +2434,15 @@ static time_t ads_parse_time(const char *str) **/ ADS_STATUS ads_server_info(ADS_STRUCT *ads) { - const char *attrs[] = {"ldapServiceName", "currentTime", NULL}; + const char *attrs[] = {"ldapServiceName", + "currentTime", + "schemaNamingContext", NULL}; ADS_STATUS status; void *res; char *value; char *p; char *timestr; + char *schema_path; TALLOC_CTX *ctx; if (!(ctx = talloc_init("ads_server_info"))) { @@ -2429,6 +2469,16 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } + schema_path = ads_pull_string(ads, ctx, res, "schemaNamingContext"); + if (!schema_path) { + ads_msgfree(ads, res); + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + SAFE_FREE(ads->config.schema_path); + ads->config.schema_path = SMB_STRDUP(schema_path); + ads_msgfree(ads, res); p = strchr(value, ':'); @@ -2476,6 +2526,50 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) } /** + * Check for "Services for Unix"-Schema and load some attributes into the ADS_STRUCT + * @param ads connection to ads server + * @return BOOL status of search (False if one or more attributes couldn't be + * found in Active Directory) + **/ +BOOL ads_check_sfu_mapping(ADS_STRUCT *ads) +{ + BOOL ret = False; + TALLOC_CTX *ctx = NULL; + const char *gidnumber, *uidnumber, *homedir, *shell; + + ctx = talloc_init("ads_check_sfu_mapping"); + if (ctx == NULL) + goto done; + + gidnumber = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_GIDNUMBER_OID); + if (gidnumber == NULL) + goto done; + ads->schema.sfu_gidnumber_attr = SMB_STRDUP(gidnumber); + + uidnumber = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_UIDNUMBER_OID); + if (uidnumber == NULL) + goto done; + ads->schema.sfu_uidnumber_attr = SMB_STRDUP(uidnumber); + + homedir = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_HOMEDIR_OID); + if (homedir == NULL) + goto done; + ads->schema.sfu_homedir_attr = SMB_STRDUP(homedir); + + shell = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_SHELL_OID); + if (shell == NULL) + goto done; + ads->schema.sfu_shell_attr = SMB_STRDUP(shell); + + ret = True; +done: + if (ctx) + talloc_destroy(ctx); + + return ret; +} + +/** * find the domain sid for our domain * @param ads connection to ads server * @param sid Pointer to domain sid diff --git a/source/libsmb/asn1.c b/source/libsmb/asn1.c index 6db12fc6125..09998407941 100644 --- a/source/libsmb/asn1.c +++ b/source/libsmb/asn1.c @@ -86,7 +86,16 @@ BOOL asn1_pop_tag(ASN1_DATA *data) /* yes, this is ugly. We don't know in advance how many bytes the length of a tag will take, so we assumed 1 byte. If we were wrong then we need to correct our mistake */ - if (len > 255) { + if (len > 0xFFFF) { + data->data[nesting->start] = 0x83; + if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return False; + memmove(data->data+nesting->start+4, data->data+nesting->start+1, len); + data->data[nesting->start+1] = (len>>16) & 0xFF; + data->data[nesting->start+2] = (len>>8) & 0xFF; + data->data[nesting->start+3] = len&0xff; + } else if (len > 255) { data->data[nesting->start] = 0x82; if (!asn1_write_uint8(data, 0)) return False; if (!asn1_write_uint8(data, 0)) return False; diff --git a/source/libsmb/clierror.c b/source/libsmb/clierror.c index ec0ca53a853..a16c1f52419 100644 --- a/source/libsmb/clierror.c +++ b/source/libsmb/clierror.c @@ -153,9 +153,9 @@ NTSTATUS cli_nt_error(struct cli_state *cli) int flgs2 = SVAL(cli->inbuf,smb_flg2); if (!(flgs2 & FLAGS2_32_BIT_ERROR_CODES)) { - int class = CVAL(cli->inbuf,smb_rcls); + int e_class = CVAL(cli->inbuf,smb_rcls); int code = SVAL(cli->inbuf,smb_err); - return dos_to_ntstatus(class, code); + return dos_to_ntstatus(e_class, code); } return NT_STATUS(IVAL(cli->inbuf,smb_rcls)); diff --git a/source/libsmb/clifile.c b/source/libsmb/clifile.c index 90ca98d17eb..87c6f2568b1 100644 --- a/source/libsmb/clifile.c +++ b/source/libsmb/clifile.c @@ -262,7 +262,12 @@ BOOL cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbu sbuf->st_size = IVAL2_TO_SMB_BIG_UINT(rdata,0); /* total size, in bytes */ sbuf->st_blocks = IVAL2_TO_SMB_BIG_UINT(rdata,8); /* number of blocks allocated */ +#if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE) sbuf->st_blocks /= STAT_ST_BLOCKSIZE; +#else + /* assume 512 byte blocks */ + sbuf->st_blocks /= 512; +#endif sbuf->st_ctime = interpret_long_date(rdata + 16); /* time of last change */ sbuf->st_atime = interpret_long_date(rdata + 24); /* time of last access */ sbuf->st_mtime = interpret_long_date(rdata + 32); /* time of last modification */ @@ -700,7 +705,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess) { return cli_nt_create_full(cli, fname, 0, DesiredAccess, 0, - FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0, 0x0); + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0); } /**************************************************************************** diff --git a/source/libsmb/doserr.c b/source/libsmb/doserr.c index 4449c92ab18..ef71a883f7f 100644 --- a/source/libsmb/doserr.c +++ b/source/libsmb/doserr.c @@ -72,6 +72,9 @@ werror_code_struct dos_errs[] = { "WERR_IO_PENDING", WERR_IO_PENDING }, { "WERR_INVALID_SERVICE_CONTROL", WERR_INVALID_SERVICE_CONTROL }, { "WERR_NET_NAME_NOT_FOUND", WERR_NET_NAME_NOT_FOUND }, + { "WERR_REG_CORRUPT", WERR_REG_CORRUPT }, + { "WERR_REG_IO_FAILURE", WERR_REG_IO_FAILURE }, + { "WERR_REG_FILE_INVALID", WERR_REG_FILE_INVALID }, { NULL, W_ERROR(0) } }; diff --git a/source/libsmb/errormap.c b/source/libsmb/errormap.c index c79561bda87..8462fbee877 100644 --- a/source/libsmb/errormap.c +++ b/source/libsmb/errormap.c @@ -124,9 +124,9 @@ static const struct { {ERRHRD, ERRgeneral, NT_STATUS_HANDLE_NOT_WAITABLE}, {ERRDOS, ERRbadfid, NT_STATUS_PORT_DISCONNECTED}, {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_ALREADY_ATTACHED}, - {ERRDOS, 161, NT_STATUS_OBJECT_PATH_INVALID}, + {ERRDOS, ERRinvalidpath, NT_STATUS_OBJECT_PATH_INVALID}, {ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND}, - {ERRDOS, 161, NT_STATUS_OBJECT_PATH_SYNTAX_BAD}, + {ERRDOS, ERRinvalidpath, NT_STATUS_OBJECT_PATH_SYNTAX_BAD}, {ERRHRD, ERRgeneral, NT_STATUS_DATA_OVERRUN}, {ERRHRD, ERRgeneral, NT_STATUS_DATA_LATE_ERROR}, {ERRDOS, 23, NT_STATUS_DATA_ERROR}, diff --git a/source/libsmb/libsmb_cache.c b/source/libsmb/libsmb_cache.c index de9a1656d84..e6033faf50f 100644 --- a/source/libsmb/libsmb_cache.c +++ b/source/libsmb/libsmb_cache.c @@ -46,7 +46,7 @@ struct smbc_server_cache { * Add a new connection to the server cache. * This function is only used if the external cache is not enabled */ -static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new, +static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * newsrv, const char * server, const char * share, const char * workgroup, const char * username) { @@ -60,7 +60,7 @@ static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new, ZERO_STRUCTP(srvcache); - srvcache->server = new; + srvcache->server = newsrv; srvcache->server_name = SMB_STRDUP(server); if (!srvcache->server_name) { diff --git a/source/libsmb/libsmb_compat.c b/source/libsmb/libsmb_compat.c index 3dc60f7240b..f9461f93683 100644 --- a/source/libsmb/libsmb_compat.c +++ b/source/libsmb/libsmb_compat.c @@ -163,7 +163,7 @@ int smbc_open(const char *furl, int flags, mode_t mode) fd = add_fd(file); if (fd == -1) - statcont->close(statcont, file); + statcont->close_fn(statcont, file); return fd; } @@ -180,7 +180,7 @@ int smbc_creat(const char *furl, mode_t mode) fd = add_fd(file); if (fd == -1) { /* Hmm... should we delete the file too ? I guess we could try */ - statcont->close(statcont, file); + statcont->close_fn(statcont, file); statcont->unlink(statcont, furl); } return fd; @@ -209,7 +209,7 @@ int smbc_close(int fd) { SMBCFILE * file = find_fd(fd); del_fd(fd); - return statcont->close(statcont, file); + return statcont->close_fn(statcont, file); } int smbc_unlink(const char *fname) diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c index dac30b934e1..9104a083f53 100644 --- a/source/libsmb/libsmbclient.c +++ b/source/libsmb/libsmbclient.c @@ -3305,7 +3305,7 @@ static BOOL parse_ace(struct cli_state *ipc_cli, /* add an ACE to a list of ACEs in a SEC_ACL */ static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace, TALLOC_CTX *ctx) { - SEC_ACL *new; + SEC_ACL *newacl; SEC_ACE *aces; if (! *the_acl) { (*the_acl) = make_sec_acl(ctx, 3, 1, ace); @@ -3315,9 +3315,9 @@ static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace, TALLOC_CTX *ctx) aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces); memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE)); memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE)); - new = make_sec_acl(ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces); + newacl = make_sec_acl(ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces); SAFE_FREE(aces); - (*the_acl) = new; + (*the_acl) = newacl; return True; } @@ -4953,7 +4953,7 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr if ((int)(fid2 = c_print->open_print_job(c_print, printq)) < 0) { saverr = errno; /* Save errno */ - c_file->close(c_file, fid1); + c_file->close_fn(c_file, fid1); errno = saverr; return -1; @@ -4966,8 +4966,8 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr if ((c_print->write(c_print, fid2, buf, bytes)) < 0) { saverr = errno; - c_file->close(c_file, fid1); - c_print->close(c_print, fid2); + c_file->close_fn(c_file, fid1); + c_print->close_fn(c_print, fid2); errno = saverr; } @@ -4976,8 +4976,8 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr saverr = errno; - c_file->close(c_file, fid1); /* We have to close these anyway */ - c_print->close(c_print, fid2); + c_file->close_fn(c_file, fid1); /* We have to close these anyway */ + c_print->close_fn(c_print, fid2); if (bytes < 0) { @@ -5152,7 +5152,7 @@ SMBCCTX * smbc_new_context(void) context->creat = smbc_creat_ctx; context->read = smbc_read_ctx; context->write = smbc_write_ctx; - context->close = smbc_close_ctx; + context->close_fn = smbc_close_ctx; context->unlink = smbc_unlink_ctx; context->rename = smbc_rename_ctx; context->lseek = smbc_lseek_ctx; @@ -5206,7 +5206,7 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx) f = context->internal->_files; while (f) { - context->close(context, f); + context->close_fn(context, f); f = f->next; } context->internal->_files = NULL; diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c index e6868fb3730..28b89db9087 100644 --- a/source/libsmb/namequery.c +++ b/source/libsmb/namequery.c @@ -45,9 +45,9 @@ static int generate_trn_id(void) Parse a node status response into an array of structures. ****************************************************************************/ -static struct node_status *parse_node_status(char *p, int *num_names, struct node_status_extra *extra) +static NODE_STATUS_STRUCT *parse_node_status(char *p, int *num_names, struct node_status_extra *extra) { - struct node_status *ret; + NODE_STATUS_STRUCT *ret; int i; *num_names = CVAL(p,0); @@ -55,7 +55,7 @@ static struct node_status *parse_node_status(char *p, int *num_names, struct nod if (*num_names == 0) return NULL; - ret = SMB_MALLOC_ARRAY(struct node_status,*num_names); + ret = SMB_MALLOC_ARRAY(NODE_STATUS_STRUCT,*num_names); if (!ret) return NULL; @@ -84,7 +84,7 @@ static struct node_status *parse_node_status(char *p, int *num_names, struct nod structures holding the returned names or NULL if the query failed. **************************************************************************/ -struct node_status *node_status_query(int fd,struct nmb_name *name, +NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name, struct in_addr to_ip, int *num_names, struct node_status_extra *extra) { @@ -95,7 +95,7 @@ struct node_status *node_status_query(int fd,struct nmb_name *name, struct packet_struct p; struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; - struct node_status *ret; + NODE_STATUS_STRUCT *ret; ZERO_STRUCT(p); @@ -173,7 +173,7 @@ struct node_status *node_status_query(int fd,struct nmb_name *name, BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name) { - struct node_status *status = NULL; + NODE_STATUS_STRUCT *status = NULL; struct nmb_name nname; int count, i; int sock; diff --git a/source/libsmb/smberr.c b/source/libsmb/smberr.c index 82efbdb6898..b014fb947e3 100644 --- a/source/libsmb/smberr.c +++ b/source/libsmb/smberr.c @@ -142,7 +142,7 @@ err_code_struct hard_msgs[] = { const struct { int code; - const char *class; + const char *e_class; err_code_struct *err_msgs; } err_classes[] = { {0,"SUCCESS",NULL}, @@ -160,13 +160,13 @@ const struct /**************************************************************************** return a SMB error name from a class and code ****************************************************************************/ -const char *smb_dos_err_name(uint8 class, uint16 num) +const char *smb_dos_err_name(uint8 e_class, uint16 num) { static pstring ret; int i,j; - for (i=0;err_classes[i].class;i++) - if (err_classes[i].code == class) { + for (i=0;err_classes[i].e_class;i++) + if (err_classes[i].code == e_class) { if (err_classes[i].err_msgs) { err_code_struct *err = err_classes[i].err_msgs; for (j=0;err[j].name;j++) @@ -178,7 +178,7 @@ const char *smb_dos_err_name(uint8 class, uint16 num) return ret; } - slprintf(ret, sizeof(ret) - 1, "Error: Unknown error class (%d,%d)",class,num); + slprintf(ret, sizeof(ret) - 1, "Error: Unknown error class (%d,%d)",e_class,num); return(ret); } @@ -196,18 +196,18 @@ const char *get_dos_error_msg(WERROR result) /**************************************************************************** return a SMB error class name as a string. ****************************************************************************/ -const char *smb_dos_err_class(uint8 class) +const char *smb_dos_err_class(uint8 e_class) { static pstring ret; int i; - for (i=0;err_classes[i].class;i++) { - if (err_classes[i].code == class) { - return err_classes[i].class; + for (i=0;err_classes[i].e_class;i++) { + if (err_classes[i].code == e_class) { + return err_classes[i].e_class; } } - slprintf(ret, sizeof(ret) - 1, "Error: Unknown class (%d)",class); + slprintf(ret, sizeof(ret) - 1, "Error: Unknown class (%d)",e_class); return(ret); } @@ -217,32 +217,32 @@ return a SMB string from an SMB buffer char *smb_dos_errstr(char *inbuf) { static pstring ret; - int class = CVAL(inbuf,smb_rcls); + int e_class = CVAL(inbuf,smb_rcls); int num = SVAL(inbuf,smb_err); int i,j; - for (i=0;err_classes[i].class;i++) - if (err_classes[i].code == class) { + for (i=0;err_classes[i].e_class;i++) + if (err_classes[i].code == e_class) { if (err_classes[i].err_msgs) { err_code_struct *err = err_classes[i].err_msgs; for (j=0;err[j].name;j++) if (num == err[j].code) { if (DEBUGLEVEL > 0) slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)", - err_classes[i].class, + err_classes[i].e_class, err[j].name,err[j].message); else slprintf(ret, sizeof(ret) - 1, "%s - %s", - err_classes[i].class,err[j].name); + err_classes[i].e_class,err[j].name); return ret; } } - slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class,num); + slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].e_class,num); return ret; } - slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num); + slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",e_class,num); return(ret); } diff --git a/source/libsmb/spnego.c b/source/libsmb/spnego.c index a0f5565d4f3..2eaec61ed79 100644 --- a/source/libsmb/spnego.c +++ b/source/libsmb/spnego.c @@ -47,7 +47,7 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) 0 < asn1_tag_remaining(asn1); i++) { token->mechTypes = SMB_REALLOC_ARRAY(token->mechTypes, char *, i + 2); - asn1_read_OID(asn1, token->mechTypes + i); + asn1_read_OID(asn1, &token->mechTypes[i]); } token->mechTypes[i] = NULL; diff --git a/source/locking/locking.c b/source/locking/locking.c index 3c5ab63b4ab..5bcf7f2eda8 100644 --- a/source/locking/locking.c +++ b/source/locking/locking.c @@ -3,6 +3,7 @@ Locking functions Copyright (C) Andrew Tridgell 1992-2000 Copyright (C) Jeremy Allison 1992-2000 + Copyright (C) Volker Lendecke 2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -46,7 +47,10 @@ static TDB_CONTEXT *deferred_open_tdb; struct locking_data { union { - int num_share_mode_entries; + struct { + int num_share_mode_entries; + BOOL delete_on_close; + } s; share_mode_entry dummy; /* Needed for alignment. */ } u; /* the following two entries are implicit @@ -432,10 +436,14 @@ char *share_mode_str(int num, share_mode_entry *e) { static pstring share_str; - slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: \ -pid = %lu, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f", - num, (unsigned long)e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id, - (unsigned int)e->dev, (double)e->inode ); + slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: " + "pid = %lu, share_access = 0x%x, private_options = 0x%x, " + "access_mask = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, " + "dev = 0x%x, inode = %.0f", + num, (unsigned long)e->pid, + e->share_access, e->private_options, + e->access_mask, e->op_port, e->op_type, e->share_file_id, + (unsigned int)e->dev, (double)e->inode ); return share_str; } @@ -446,7 +454,7 @@ pid = %lu, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, fi static void print_share_mode_table(struct locking_data *data) { - int num_share_modes = data->u.num_share_mode_entries; + int num_share_modes = data->u.s.num_share_mode_entries; share_mode_entry *shares = (share_mode_entry *)(data + 1); int i; @@ -460,9 +468,9 @@ static void print_share_mode_table(struct locking_data *data) Get all share mode entries for a dev/inode pair. ********************************************************************/ -int get_share_modes(connection_struct *conn, - SMB_DEV_T dev, SMB_INO_T inode, - share_mode_entry **pp_shares) +int get_share_modes(SMB_DEV_T dev, SMB_INO_T inode, + share_mode_entry **pp_shares, + BOOL *delete_on_close) { TDB_DATA dbuf; struct locking_data *data; @@ -470,13 +478,18 @@ int get_share_modes(connection_struct *conn, share_mode_entry *shares = NULL; TDB_DATA key = locking_key(dev, inode); *pp_shares = NULL; + *delete_on_close = False; dbuf = tdb_fetch(tdb, key); if (!dbuf.dptr) return 0; data = (struct locking_data *)dbuf.dptr; - num_share_modes = data->u.num_share_mode_entries; + + *delete_on_close = data->u.s.delete_on_close; + DEBUG(10, ("get_share_modes: delete_on_close: %d\n", + *delete_on_close)); + num_share_modes = data->u.s.num_share_mode_entries; if(num_share_modes) { pstring fname; int i; @@ -515,7 +528,7 @@ int get_share_modes(connection_struct *conn, /* Did we delete any ? If so, re-store in tdb. */ if (del_count) { - data->u.num_share_mode_entries = num_share_modes; + data->u.s.num_share_mode_entries = num_share_modes; if (num_share_modes) { memcpy(dbuf.dptr + sizeof(*data), shares, @@ -527,7 +540,7 @@ int get_share_modes(connection_struct *conn, /* The record has shrunk a bit */ dbuf.dsize -= del_count * sizeof(share_mode_entry); - if (data->u.num_share_mode_entries == 0) { + if (data->u.s.num_share_mode_entries == 0) { if (tdb_delete(tdb, key) == -1) { SAFE_FREE(shares); SAFE_FREE(dbuf.dptr); @@ -548,6 +561,15 @@ int get_share_modes(connection_struct *conn, return num_share_modes; } +BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode) +{ + share_mode_entry *shares; + BOOL result; + get_share_modes(dev, inode, &shares, &result); + SAFE_FREE(shares); + return result; +} + /******************************************************************* Fill a share mode entry. ********************************************************************/ @@ -559,8 +581,9 @@ static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_t memset(e, '\0', sizeof(share_mode_entry)); e->pid = sys_getpid(); - e->share_mode = fsp->share_mode; - e->desired_access = fsp->desired_access; + e->share_access = fsp->share_access; + e->private_options = fsp->fh->private_options; + e->access_mask = fsp->access_mask; e->op_port = port; e->op_type = op_type; memcpy(x, &fsp->open_time, sizeof(struct timeval)); @@ -581,16 +604,17 @@ BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2) e1->share_file_id == e2->share_file_id && e1->dev == e2->dev && e1->inode == e2->inode && - (e1->share_mode & ~DELETE_ON_CLOSE_FLAG) != (e2->share_mode & ~DELETE_ON_CLOSE_FLAG)) { - DEBUG(0,("PANIC: share_modes_identical: share_mode missmatch (e1 = %u, e2 = %u). Logic error.\n", - (unsigned int)(e1->share_mode & ~DELETE_ON_CLOSE_FLAG), - (unsigned int)(e2->share_mode & ~DELETE_ON_CLOSE_FLAG) )); + (e1->share_access) != (e2->share_access)) { + DEBUG(0,("PANIC: share_modes_identical: share_mode " + "mismatch (e1 = 0x%x, e2 = 0x%x). Logic error.\n", + (unsigned int)e1->share_access, + (unsigned int)e2->share_access )); smb_panic("PANIC: share_modes_identical logic error.\n"); } #endif return (e1->pid == e2->pid && - (e1->share_mode & ~DELETE_ON_CLOSE_FLAG) == (e2->share_mode & ~DELETE_ON_CLOSE_FLAG) && + (e1->share_access) == (e2->share_access) && e1->dev == e2->dev && e1->inode == e2->inode && e1->share_file_id == e2->share_file_id ); @@ -602,8 +626,9 @@ BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2) Ignore if no entry deleted. ********************************************************************/ -ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, - share_mode_entry *entry, share_mode_entry **ppse) +ssize_t del_share_entry(SMB_DEV_T dev, SMB_INO_T inode, + share_mode_entry *entry, share_mode_entry **ppse, + BOOL *delete_on_close) { TDB_DATA dbuf; struct locking_data *data; @@ -621,6 +646,7 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, return -1; data = (struct locking_data *)dbuf.dptr; + *delete_on_close = data->u.s.delete_on_close; shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); /* @@ -629,15 +655,15 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, * from the record. */ - DEBUG(10,("del_share_entry: num_share_modes = %d\n", data->u.num_share_mode_entries )); + DEBUG(10,("del_share_entry: num_share_modes = %d\n", data->u.s.num_share_mode_entries )); - for (i=0;i<data->u.num_share_mode_entries;) { + for (i=0;i<data->u.s.num_share_mode_entries;) { if (share_modes_identical(&shares[i], entry)) { DEBUG(10,("del_share_entry: deleted %s\n", share_mode_str(i, &shares[i]) )); if (ppse) *ppse = memdup(&shares[i], sizeof(*shares)); - data->u.num_share_mode_entries--; + data->u.s.num_share_mode_entries--; if ((dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))) > 0) { memmove(&shares[i], &shares[i+1], dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); @@ -655,10 +681,10 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, /* the record may have shrunk a bit */ dbuf.dsize -= del_count * sizeof(*shares); - count = (ssize_t)data->u.num_share_mode_entries; + count = (ssize_t)data->u.s.num_share_mode_entries; /* store it back in the database */ - if (data->u.num_share_mode_entries == 0) { + if (data->u.s.num_share_mode_entries == 0) { if (tdb_delete(tdb, key) == -1) count = -1; } else { @@ -677,7 +703,8 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, of entries left, and a memdup'ed copy of the entry deleted. ********************************************************************/ -ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse) +ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse, + BOOL *delete_on_close) { share_mode_entry entry; @@ -686,7 +713,8 @@ ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse) */ fill_share_mode((char *)&entry, fsp, 0, 0); - return del_share_entry(fsp->dev, fsp->inode, &entry, ppse); + return del_share_entry(fsp->dev, fsp->inode, &entry, ppse, + delete_on_close); } /******************************************************************* @@ -718,7 +746,8 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) if (!p) return False; data = (struct locking_data *)p; - data->u.num_share_mode_entries = 1; + ZERO_STRUCT(data->u); /* Keep valgrind happy */ + data->u.s.num_share_mode_entries = 1; DEBUG(10,("set_share_mode: creating entry for file %s. num_share_modes = 1\n", fsp->fsp_name )); @@ -740,10 +769,10 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) /* we're adding to an existing entry - this is a bit fiddly */ data = (struct locking_data *)dbuf.dptr; - data->u.num_share_mode_entries++; + data->u.s.num_share_mode_entries++; DEBUG(10,("set_share_mode: adding entry for file %s. new num_share_modes = %d\n", - fsp->fsp_name, data->u.num_share_mode_entries )); + fsp->fsp_name, data->u.s.num_share_mode_entries )); size = dbuf.dsize + sizeof(share_mode_entry); p = SMB_MALLOC(size); @@ -790,7 +819,7 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); /* find any with our pid and call the supplied function */ - for (i=0;i<data->u.num_share_mode_entries;i++) { + for (i=0;i<data->u.s.num_share_mode_entries;i++) { if (share_modes_identical(entry, &shares[i])) { mod_fn(&shares[i], dev, inode, param); need_store=True; @@ -799,7 +828,7 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en /* if the mod fn was called then store it back */ if (need_store) { - if (data->u.num_share_mode_entries == 0) { + if (data->u.s.num_share_mode_entries == 0) { if (tdb_delete(tdb, key) == -1) ret = False; } else { @@ -877,8 +906,7 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close) { TDB_DATA dbuf; struct locking_data *data; - int i; - share_mode_entry *shares; + BOOL res; TDB_DATA key = locking_key(dev, inode); /* read in the existing share modes */ @@ -887,25 +915,14 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close) return False; data = (struct locking_data *)dbuf.dptr; - shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); /* Set/Unset the delete on close element. */ - for (i=0;i<data->u.num_share_mode_entries;i++,shares++) { - shares->share_mode = (delete_on_close ? - (shares->share_mode | DELETE_ON_CLOSE_FLAG) : - (shares->share_mode & ~DELETE_ON_CLOSE_FLAG) ); - } + data->u.s.delete_on_close = delete_on_close; - /* store it back */ - if (data->u.num_share_mode_entries) { - if (tdb_store(tdb, key, dbuf, TDB_REPLACE)==-1) { - SAFE_FREE(dbuf.dptr); - return False; - } - } + res = (tdb_store(tdb, key, dbuf, TDB_REPLACE)!=-1); SAFE_FREE(dbuf.dptr); - return True; + return res; } /******************************************************************* @@ -1200,6 +1217,7 @@ BOOL add_deferred_open(uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T if (!p) return False; data = (struct deferred_open_data *)p; + ZERO_STRUCT(data->u.dummy); /* Keep valgrind happy */ data->u.num_deferred_open_entries = 1; DEBUG(10,("add_deferred_open: creating entry for file %s. num_deferred_open_entries = 1\n", @@ -1268,9 +1286,9 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, data = (struct locking_data *)dbuf.dptr; shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); - name = dbuf.dptr + sizeof(*data) + data->u.num_share_mode_entries*sizeof(*shares); + name = dbuf.dptr + sizeof(*data) + data->u.s.num_share_mode_entries*sizeof(*shares); - for (i=0;i<data->u.num_share_mode_entries;i++) { + for (i=0;i<data->u.s.num_share_mode_entries;i++) { traverse_callback(&shares[i], name); } return 0; diff --git a/source/locking/posix.c b/source/locking/posix.c index 5b001b71416..c63992adc59 100644 --- a/source/locking/posix.c +++ b/source/locking/posix.c @@ -102,6 +102,7 @@ static BOOL add_fd_to_close_entry(files_struct *fsp) char *tp; dbuf.dptr = NULL; + dbuf.dsize = 0; dbuf = tdb_fetch(posix_pending_close_tdb, kbuf); @@ -113,7 +114,7 @@ static BOOL add_fd_to_close_entry(files_struct *fsp) } else dbuf.dptr = tp; - memcpy(dbuf.dptr + dbuf.dsize, &fsp->fd, sizeof(int)); + memcpy(dbuf.dptr + dbuf.dsize, &fsp->fh->fd, sizeof(int)); dbuf.dsize += sizeof(int); if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) { @@ -208,8 +209,8 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp) /* * No POSIX to worry about, just close. */ - ret = SMB_VFS_CLOSE(fsp,fsp->fd); - fsp->fd = -1; + ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd); + fsp->fh->fd = -1; return ret; } @@ -226,7 +227,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp) */ for (i = 0; i < count; i++) { - if (entries[i].fd != fsp->fd) { + if (entries[i].fd != fsp->fh->fd) { locks_on_other_fds = True; break; } @@ -236,7 +237,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp) /* * There are outstanding locks on this dev/inode pair on other fds. - * Add our fd to the pending close tdb and set fsp->fd to -1. + * Add our fd to the pending close tdb and set fsp->fh->fd to -1. */ if (!add_fd_to_close_entry(fsp)) { @@ -245,7 +246,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp) } SAFE_FREE(entries); - fsp->fd = -1; + fsp->fh->fd = -1; return 0; } @@ -281,14 +282,14 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp) * Finally close the fd associated with this fsp. */ - ret = SMB_VFS_CLOSE(fsp,fsp->fd); + ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd); if (saved_errno != 0) { errno = saved_errno; ret = -1; } - fsp->fd = -1; + fsp->fh->fd = -1; return ret; } @@ -330,9 +331,9 @@ static BOOL delete_posix_lock_entry_by_index(files_struct *fsp, size_t entry) tdb_delete(posix_lock_tdb, kbuf); } else { if (entry < count-1) { - memmove(&locks[entry], &locks[entry+1], sizeof(*locks)*((count-1) - entry)); + memmove(&locks[entry], &locks[entry+1], sizeof(struct posix_lock)*((count-1) - entry)); } - dbuf.dsize -= sizeof(*locks); + dbuf.dsize -= sizeof(struct posix_lock); tdb_store(posix_lock_tdb, kbuf, dbuf, TDB_REPLACE); } @@ -360,29 +361,30 @@ static BOOL add_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T s char *tp; dbuf.dptr = NULL; + dbuf.dsize = 0; dbuf = tdb_fetch(posix_lock_tdb, kbuf); - *pentry_num = (size_t)(dbuf.dsize / sizeof(pl)); + *pentry_num = (size_t)(dbuf.dsize / sizeof(struct posix_lock)); /* * Add new record. */ - pl.fd = fsp->fd; + pl.fd = fsp->fh->fd; pl.start = start; pl.size = size; pl.lock_type = lock_type; - tp = SMB_REALLOC(dbuf.dptr, dbuf.dsize + sizeof(pl)); + tp = SMB_REALLOC(dbuf.dptr, dbuf.dsize + sizeof(struct posix_lock)); if (!tp) { DEBUG(0,("add_posix_lock_entry: Realloc fail !\n")); goto fail; } else dbuf.dptr = tp; - memcpy(dbuf.dptr + dbuf.dsize, &pl, sizeof(pl)); - dbuf.dsize += sizeof(pl); + memcpy(dbuf.dptr + dbuf.dsize, &pl, sizeof(struct posix_lock)); + dbuf.dsize += sizeof(struct posix_lock); if (tdb_store(posix_lock_tdb, kbuf, dbuf, TDB_REPLACE) == -1) { DEBUG(0,("add_posix_lock: Failed to add lock entry on file %s\n", fsp->fsp_name)); @@ -443,7 +445,7 @@ static int delete_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T /* There are existing locks - find a match. */ locks = (struct posix_lock *)dbuf.dptr; - count = (size_t)(dbuf.dsize / sizeof(*locks)); + count = (size_t)(dbuf.dsize / sizeof(struct posix_lock)); /* * Search for and delete the first record that matches the @@ -453,7 +455,7 @@ static int delete_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T for (i=0; i<count; i++) { struct posix_lock *entry = &locks[i]; - if (entry->fd == fsp->fd && + if (entry->fd == fsp->fh->fd && entry->start == start && entry->size == size) { @@ -466,9 +468,9 @@ static int delete_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T tdb_delete(posix_lock_tdb, kbuf); } else { if (i < count-1) { - memmove(&locks[i], &locks[i+1], sizeof(*locks)*((count-1) - i)); + memmove(&locks[i], &locks[i+1], sizeof(struct posix_lock)*((count-1) - i)); } - dbuf.dsize -= sizeof(*locks); + dbuf.dsize -= sizeof(struct posix_lock); tdb_store(posix_lock_tdb, kbuf, dbuf, TDB_REPLACE); } count--; @@ -488,7 +490,7 @@ static int delete_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T for (i = 0; i < count; i++) { struct posix_lock *entry = &locks[i]; - if (fsp->fd == entry->fd && + if (fsp->fh->fd == entry->fd && does_lock_overlap( start, size, entry->start, entry->size)) num_overlapping_records++; } @@ -522,20 +524,24 @@ static int map_posix_lock_type( files_struct *fsp, enum brl_type lock_type) */ DEBUG(10,("map_posix_lock_type: Downgrading write lock to read due to read-only file.\n")); return F_RDLCK; - } else if((lock_type == READ_LOCK) && !fsp->can_read) { + } +#if 0 + /* We no longer open files write-only. */ + else if((lock_type == READ_LOCK) && !fsp->can_read) { /* * Ditto for read locks on write only files. */ DEBUG(10,("map_posix_lock_type: Changing read lock to write due to write-only file.\n")); return F_WRLCK; } +#endif - /* - * This return should be the most normal, as we attempt - * to always open files read/write. - */ + /* + * This return should be the most normal, as we attempt + * to always open files read/write. + */ - return (lock_type == READ_LOCK) ? F_RDLCK : F_WRLCK; + return (lock_type == READ_LOCK) ? F_RDLCK : F_WRLCK; } /**************************************************************************** @@ -545,7 +551,7 @@ static int map_posix_lock_type( files_struct *fsp, enum brl_type lock_type) ****************************************************************************/ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out, - SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count) + SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count) { SMB_OFF_T offset = (SMB_OFF_T)u_offset; SMB_OFF_T count = (SMB_OFF_T)u_count; @@ -650,9 +656,9 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF { int ret; - DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fd,op,(double)offset,(double)count,type)); + DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fh->fd,op,(double)offset,(double)count,type)); - ret = SMB_VFS_LOCK(fsp,fsp->fd,op,offset,count,type); + ret = SMB_VFS_LOCK(fsp,fsp->fh->fd,op,offset,count,type); if (!ret && ((errno == EFBIG) || (errno == ENOLCK) || (errno == EINVAL))) { @@ -676,7 +682,7 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF DEBUG(0,("Count greater than 31 bits - retrying with 31 bit truncated length.\n")); errno = 0; count &= 0x7fffffff; - ret = SMB_VFS_LOCK(fsp,fsp->fd,op,offset,count,type); + ret = SMB_VFS_LOCK(fsp,fsp->fh->fd,op,offset,count,type); } } @@ -722,10 +728,10 @@ BOOL is_posix_locked(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_co */ struct lock_list { - struct lock_list *next; - struct lock_list *prev; - SMB_OFF_T start; - SMB_OFF_T size; + struct lock_list *next; + struct lock_list *prev; + SMB_OFF_T start; + SMB_OFF_T size; }; /**************************************************************************** @@ -749,7 +755,7 @@ static struct lock_list *posix_lock_list(TALLOC_CTX *ctx, struct lock_list *lhea return lhead; locks = (struct posix_lock *)dbuf.dptr; - num_locks = (size_t)(dbuf.dsize / sizeof(*locks)); + num_locks = (size_t)(dbuf.dsize / sizeof(struct posix_lock)); /* * Check the current lock list on this dev/inode pair. @@ -1128,7 +1134,7 @@ BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u num_overlapped_entries = delete_posix_lock_entry(fsp, offset, count, &deleted_lock); if (num_overlapped_entries == -1) { - smb_panic("release_posix_lock: unable find entry to delete !\n"); + smb_panic("release_posix_lock: unable find entry to delete !\n"); } /* @@ -1245,7 +1251,7 @@ void posix_locking_close_file(files_struct *fsp) } for (i = 0; i < count; i++) { - if (entries[i].fd != fsp->fd ) + if (entries[i].fd != fsp->fh->fd ) break; dump_entry(&entries[i]); @@ -1267,7 +1273,7 @@ void posix_locking_close_file(files_struct *fsp) for (i = 0; i < count; i++) { struct posix_lock *pl = &entries[i]; - if (pl->fd == fsp->fd) + if (pl->fd == fsp->fh->fd) release_posix_lock(fsp, (SMB_BIG_UINT)pl->start, (SMB_BIG_UINT)pl->size ); } SAFE_FREE(entries); diff --git a/source/modules/vfs_afsacl.c b/source/modules/vfs_afsacl.c index 6d6848eb120..731ddfa5836 100644 --- a/source/modules/vfs_afsacl.c +++ b/source/modules/vfs_afsacl.c @@ -31,11 +31,11 @@ #define MAXSIZE 2048 -extern DOM_SID global_sid_World; -extern DOM_SID global_sid_Builtin_Administrators; -extern DOM_SID global_sid_Builtin_Backup_Operators; -extern DOM_SID global_sid_Authenticated_Users; -extern DOM_SID global_sid_NULL; +extern const DOM_SID global_sid_World; +extern const DOM_SID global_sid_Builtin_Administrators; +extern const DOM_SID global_sid_Builtin_Backup_Operators; +extern const DOM_SID global_sid_Authenticated_Users; +extern const DOM_SID global_sid_NULL; static char space_replacement = '%'; @@ -605,13 +605,13 @@ static size_t afs_to_nt_acl(struct afs_acl *afs_acl, struct afs_ace *afs_ace; - if (fsp->is_directory || fsp->fd == -1) { + if (fsp->is_directory || fsp->fh->fd == -1) { /* Get the stat struct for the owner info. */ if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) { return 0; } } else { - if(SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) { + if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) { return 0; } } @@ -619,7 +619,7 @@ static size_t afs_to_nt_acl(struct afs_acl *afs_acl, uid_to_sid(&owner_sid, sbuf.st_uid); gid_to_sid(&group_sid, sbuf.st_gid); - nt_ace_list = SMB_MALLOC_ARRAY(SEC_ACE, afs_acl->num_aces); + nt_ace_list = TALLOC_ARRAY(mem_ctx, SEC_ACE, afs_acl->num_aces); if (nt_ace_list == NULL) return 0; diff --git a/source/modules/vfs_audit.c b/source/modules/vfs_audit.c index 550d918b43c..952cb1eddf6 100644 --- a/source/modules/vfs_audit.c +++ b/source/modules/vfs_audit.c @@ -31,12 +31,12 @@ static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user); static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn); -static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname); +static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr); static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode); static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path); static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode); static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd); -static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new); +static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname); static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path); static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode); static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode); @@ -119,11 +119,11 @@ static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn) return; } -static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) +static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr) { DIR *result; - result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname); + result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr); syslog(audit_syslog_priority(handle), "opendir %s %s%s\n", fname, @@ -190,14 +190,14 @@ static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd) return result; } -static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new) +static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname) { int result; - result = SMB_VFS_NEXT_RENAME(handle, conn, old, new); + result = SMB_VFS_NEXT_RENAME(handle, conn, oldname, newname); syslog(audit_syslog_priority(handle), "rename %s -> %s %s%s\n", - old, new, + oldname, newname, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); diff --git a/source/modules/vfs_cap.c b/source/modules/vfs_cap.c index 18fa04533f0..6ee63a577d1 100644 --- a/source/modules/vfs_cap.c +++ b/source/modules/vfs_cap.c @@ -38,11 +38,11 @@ static SMB_BIG_UINT cap_disk_free(vfs_handle_struct *handle, connection_struct * dfree, dsize); } -static DIR *cap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) +static DIR *cap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr) { pstring capname; capencode(capname, fname); - return SMB_VFS_NEXT_OPENDIR(handle, conn, capname); + return SMB_VFS_NEXT_OPENDIR(handle, conn, capname, mask, attr); } static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp) @@ -79,11 +79,11 @@ static int cap_open(vfs_handle_struct *handle, connection_struct *conn, const ch return SMB_VFS_NEXT_OPEN(handle, conn, capname, flags, mode); } -static int cap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new) +static int cap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname) { pstring capold, capnew; - capencode(capold, old); - capencode(capnew, new); + capencode(capold, oldname); + capencode(capnew, newname); return SMB_VFS_NEXT_RENAME(handle, conn, capold, capnew); } diff --git a/source/modules/vfs_catia.c b/source/modules/vfs_catia.c index f77739b23a4..d4420884ddd 100644 --- a/source/modules/vfs_catia.c +++ b/source/modules/vfs_catia.c @@ -72,13 +72,13 @@ static void to_unix(char *s) } static DIR *catia_opendir(vfs_handle_struct *handle, connection_struct - *conn, const char *fname) + *conn, const char *fname, const char *mask, uint32 attr) { pstring name; pstrcpy(name, fname); to_unix(name); - return SMB_VFS_NEXT_OPENDIR(handle, conn, name); + return SMB_VFS_NEXT_OPENDIR(handle, conn, name, mask, attr); } static SMB_STRUCT_DIRENT *catia_readdir(vfs_handle_struct *handle, @@ -105,13 +105,13 @@ static int catia_open(vfs_handle_struct *handle, connection_struct *conn, } static int catia_rename(vfs_handle_struct *handle, connection_struct *conn, - const char *old, const char *new) + const char *oldname, const char *newname) { pstring oname, nname; - pstrcpy(oname, old); + pstrcpy(oname, oldname); to_unix(oname); - pstrcpy(nname, new); + pstrcpy(nname, newname); to_unix(nname); DEBUG(10, ("converted old name: %s\n", oname)); diff --git a/source/modules/vfs_extd_audit.c b/source/modules/vfs_extd_audit.c index 06cddc78e43..e3b90b293b6 100644 --- a/source/modules/vfs_extd_audit.c +++ b/source/modules/vfs_extd_audit.c @@ -34,12 +34,12 @@ static int vfs_extd_audit_debug_level = DBGC_VFS; static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user); static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn); -static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname); +static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr); static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode); static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path); static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode); static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd); -static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new); +static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname); static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path); static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode); static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode); @@ -125,11 +125,11 @@ static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn) return; } -static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) +static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr) { DIR *result; - result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname); + result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr); syslog(audit_syslog_priority(handle), "opendir %s %s%s\n", fname, @@ -216,18 +216,18 @@ static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd) return result; } -static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new) +static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname) { int result; - result = SMB_VFS_NEXT_RENAME(handle, conn, old, new); + result = SMB_VFS_NEXT_RENAME(handle, conn, oldname, newname); syslog(audit_syslog_priority(handle), "rename %s -> %s %s%s\n", - old, new, + oldname, newname, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); - DEBUG(1, ("vfs_extd_audit: rename old: %s new: %s %s %s\n", - old, new, + DEBUG(1, ("vfs_extd_audit: rename old: %s newname: %s %s %s\n", + oldname, newname, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : "")); diff --git a/source/modules/vfs_full_audit.c b/source/modules/vfs_full_audit.c index 3c0098408ef..aa9e047f0ae 100644 --- a/source/modules/vfs_full_audit.c +++ b/source/modules/vfs_full_audit.c @@ -87,7 +87,7 @@ static int smb_full_audit_get_shadow_copy_data(struct vfs_handle_struct *handle, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels); static DIR *smb_full_audit_opendir(vfs_handle_struct *handle, connection_struct *conn, - const char *fname); + const char *fname, const char *mask, uint32 attr); static SMB_STRUCT_DIRENT *smb_full_audit_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp); static void smb_full_audit_seekdir(vfs_handle_struct *handle, connection_struct *conn, @@ -121,7 +121,7 @@ static ssize_t smb_full_audit_sendfile(vfs_handle_struct *handle, int tofd, const DATA_BLOB *hdr, SMB_OFF_T offset, size_t n); static int smb_full_audit_rename(vfs_handle_struct *handle, connection_struct *conn, - const char *old, const char *new); + const char *oldname, const char *newname); static int smb_full_audit_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd); static int smb_full_audit_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf); @@ -291,6 +291,14 @@ static int smb_full_audit_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, const char *name, const void *value, size_t size, int flags); +static int smb_full_audit_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb); +static int smb_full_audit_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb); +static ssize_t smb_full_audit_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb); +static int smb_full_audit_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_AIOCB *aiocb); +static int smb_full_audit_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb); +static int smb_full_audit_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb); +static int smb_full_audit_aio_suspend(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *ts); + /* VFS operations */ static vfs_op_tuple audit_op_tuples[] = { @@ -477,6 +485,21 @@ static vfs_op_tuple audit_op_tuples[] = { {SMB_VFS_OP(smb_full_audit_fsetxattr), SMB_VFS_OP_FSETXATTR, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_full_audit_aio_read), SMB_VFS_OP_AIO_READ, + SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_full_audit_aio_write), SMB_VFS_OP_AIO_WRITE, + SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_full_audit_aio_return), SMB_VFS_OP_AIO_RETURN, + SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_full_audit_aio_cancel), SMB_VFS_OP_AIO_CANCEL, + SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_full_audit_aio_error), SMB_VFS_OP_AIO_ERROR, + SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_full_audit_aio_fsync), SMB_VFS_OP_AIO_FSYNC, + SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_full_audit_aio_suspend),SMB_VFS_OP_AIO_SUSPEND, + SMB_VFS_LAYER_LOGGER}, + /* Finish VFS operations definition */ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, @@ -571,6 +594,13 @@ static struct { { SMB_VFS_OP_SETXATTR, "setxattr" }, { SMB_VFS_OP_LSETXATTR, "lsetxattr" }, { SMB_VFS_OP_FSETXATTR, "fsetxattr" }, + { SMB_VFS_OP_AIO_READ, "aio_read" }, + { SMB_VFS_OP_AIO_WRITE, "aio_write" }, + { SMB_VFS_OP_AIO_RETURN,"aio_return" }, + { SMB_VFS_OP_AIO_CANCEL,"aio_cancel" }, + { SMB_VFS_OP_AIO_ERROR, "aio_error" }, + { SMB_VFS_OP_AIO_FSYNC, "aio_fsync" }, + { SMB_VFS_OP_AIO_SUSPEND,"aio_suspend" }, { SMB_VFS_OP_LAST, NULL } }; @@ -816,11 +846,11 @@ static int smb_full_audit_get_shadow_copy_data(struct vfs_handle_struct *handle, } static DIR *smb_full_audit_opendir(vfs_handle_struct *handle, connection_struct *conn, - const char *fname) + const char *fname, const char *mask, uint32 attr) { DIR *result; - result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname); + result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr); do_log(SMB_VFS_OP_OPENDIR, (result != NULL), handle, "%s", fname); @@ -1012,13 +1042,13 @@ static ssize_t smb_full_audit_sendfile(vfs_handle_struct *handle, int tofd, } static int smb_full_audit_rename(vfs_handle_struct *handle, connection_struct *conn, - const char *old, const char *new) + const char *oldname, const char *newname) { int result; - result = SMB_VFS_NEXT_RENAME(handle, conn, old, new); + result = SMB_VFS_NEXT_RENAME(handle, conn, oldname, newname); - do_log(SMB_VFS_OP_RENAME, (result >= 0), handle, "%s|%s", old, new); + do_log(SMB_VFS_OP_RENAME, (result >= 0), handle, "%s|%s", oldname, newname); return result; } @@ -1835,6 +1865,84 @@ static int smb_full_audit_fsetxattr(struct vfs_handle_struct *handle, return result; } +static int smb_full_audit_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + int result; + + result = SMB_VFS_NEXT_AIO_READ(handle, fsp, aiocb); + do_log(SMB_VFS_OP_AIO_READ, (result >= 0), handle, + "%s", fsp->fsp_name); + + return result; +} + +static int smb_full_audit_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + int result; + + result = SMB_VFS_NEXT_AIO_WRITE(handle, fsp, aiocb); + do_log(SMB_VFS_OP_AIO_WRITE, (result >= 0), handle, + "%s", fsp->fsp_name); + + return result; +} + +static ssize_t smb_full_audit_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + int result; + + result = SMB_VFS_NEXT_AIO_RETURN(handle, fsp, aiocb); + do_log(SMB_VFS_OP_AIO_RETURN, (result >= 0), handle, + "%s", fsp->fsp_name); + + return result; +} + +static int smb_full_audit_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_AIOCB *aiocb) +{ + int result; + + result = SMB_VFS_NEXT_AIO_CANCEL(handle, fsp, fd, aiocb); + do_log(SMB_VFS_OP_AIO_CANCEL, (result >= 0), handle, + "%s", fsp->fsp_name); + + return result; +} + +static int smb_full_audit_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + int result; + + result = SMB_VFS_NEXT_AIO_ERROR(handle, fsp, aiocb); + do_log(SMB_VFS_OP_AIO_ERROR, (result >= 0), handle, + "%s", fsp->fsp_name); + + return result; +} + +static int smb_full_audit_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb) +{ + int result; + + result = SMB_VFS_NEXT_AIO_FSYNC(handle, fsp, op, aiocb); + do_log(SMB_VFS_OP_AIO_FSYNC, (result >= 0), handle, + "%s", fsp->fsp_name); + + return result; +} + +static int smb_full_audit_aio_suspend(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *ts) +{ + int result; + + result = SMB_VFS_NEXT_AIO_SUSPEND(handle, fsp, aiocb, n, ts); + do_log(SMB_VFS_OP_AIO_SUSPEND, (result >= 0), handle, + "%s", fsp->fsp_name); + + return result; +} + + NTSTATUS vfs_full_audit_init(void) { NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, diff --git a/source/modules/vfs_netatalk.c b/source/modules/vfs_netatalk.c index 1b36914bbea..02ce5300ae7 100644 --- a/source/modules/vfs_netatalk.c +++ b/source/modules/vfs_netatalk.c @@ -172,11 +172,11 @@ static void atalk_rrmdir(TALLOC_CTX *ctx, char *path) /* Directory operations */ -DIR *atalk_opendir(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname) +DIR *atalk_opendir(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, const char *mask, uint32 attr) { DIR *ret = 0; - ret = SMB_VFS_NEXT_OPENDIR(handle, conn, fname); + ret = SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr); /* * when we try to perform delete operation upon file which has fork @@ -223,7 +223,7 @@ exit_rmdir: /* File operations */ -static int atalk_rename(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *old, const char *new) +static int atalk_rename(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *oldname, const char *newname) { int ret = 0; char *adbl_path = 0; @@ -232,14 +232,14 @@ static int atalk_rename(struct vfs_handle_struct *handle, struct connection_stru SMB_STRUCT_STAT orig_info; TALLOC_CTX *ctx; - ret = SMB_VFS_NEXT_RENAME(handle, conn, old, new); + ret = SMB_VFS_NEXT_RENAME(handle, conn, oldname, newname); - if (!conn || !old) return ret; + if (!conn || !oldname) return ret; if (!(ctx = talloc_init("rename_file"))) return ret; - if (atalk_build_paths(ctx, conn->origpath, old, &adbl_path, &orig_path, + if (atalk_build_paths(ctx, conn->origpath, oldname, &adbl_path, &orig_path, &adbl_info, &orig_info) != 0) return ret; @@ -379,7 +379,7 @@ static vfs_op_tuple atalk_ops[] = { /* Directory operations */ - {SMB_VFS_OP(atalk_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(atalk_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(atalk_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT}, /* File operations */ diff --git a/source/modules/vfs_shadow_copy.c b/source/modules/vfs_shadow_copy.c index d957afb9232..005e2f1fbae 100644 --- a/source/modules/vfs_shadow_copy.c +++ b/source/modules/vfs_shadow_copy.c @@ -72,10 +72,10 @@ static BOOL shadow_copy_match_name(const char *name) return False; } -static DIR *shadow_copy_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) +static DIR *shadow_copy_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr) { shadow_copy_Dir *dirp; - DIR *p = SMB_VFS_NEXT_OPENDIR(handle,conn,fname); + DIR *p = SMB_VFS_NEXT_OPENDIR(handle,conn,fname,mask,attr); if (!p) { DEBUG(0,("shadow_copy_opendir: SMB_VFS_NEXT_OPENDIR() failed for [%s]\n",fname)); @@ -166,7 +166,7 @@ int shadow_copy_closedir(vfs_handle_struct *handle, connection_struct *conn, DIR static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels) { - DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fsp->conn,fsp->conn->connectpath); + DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fsp->conn,fsp->conn->connectpath,NULL,0); shadow_copy_data->num_volumes = 0; shadow_copy_data->labels = NULL; diff --git a/source/nsswitch/wb_client.c b/source/nsswitch/wb_client.c index 32ac4319a03..db56cf04441 100644 --- a/source/nsswitch/wb_client.c +++ b/source/nsswitch/wb_client.c @@ -28,7 +28,7 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND -NSS_STATUS winbindd_request(int req_type, +NSS_STATUS winbindd_request_response(int req_type, struct winbindd_request *request, struct winbindd_response *response); @@ -52,7 +52,7 @@ BOOL winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid, fstrcpy(request.data.name.dom_name, dom_name); fstrcpy(request.data.name.name, name); - if ((result = winbindd_request(WINBINDD_LOOKUPNAME, &request, + if ((result = winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response)) == NSS_STATUS_SUCCESS) { if (!string_to_sid(sid, response.data.sid.sid)) return False; @@ -83,7 +83,7 @@ BOOL winbind_lookup_sid(const DOM_SID *sid, /* Make request */ - result = winbindd_request(WINBINDD_LOOKUPSID, &request, &response); + result = winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response); /* Copy out result */ @@ -121,7 +121,7 @@ BOOL winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid) /* Make request */ - result = winbindd_request(WINBINDD_SID_TO_UID, &request, &response); + result = winbindd_request_response(WINBINDD_SID_TO_UID, &request, &response); /* Copy out result */ @@ -152,7 +152,7 @@ BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid) /* Make request */ - result = winbindd_request(WINBINDD_UID_TO_SID, &request, &response); + result = winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response); /* Copy out result */ @@ -188,7 +188,7 @@ BOOL winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid) /* Make request */ - result = winbindd_request(WINBINDD_SID_TO_GID, &request, &response); + result = winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response); /* Copy out result */ @@ -219,7 +219,7 @@ BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid) /* Make request */ - result = winbindd_request(WINBINDD_GID_TO_SID, &request, &response); + result = winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response); /* Copy out result */ @@ -246,7 +246,7 @@ BOOL winbind_allocate_rid(uint32 *rid) /* Make request */ - result = winbindd_request(WINBINDD_ALLOCATE_RID, &request, &response); + result = winbindd_request_response(WINBINDD_ALLOCATE_RID, &request, &response); if (result != NSS_STATUS_SUCCESS) return False; @@ -270,7 +270,7 @@ BOOL winbind_allocate_rid_and_gid(uint32 *rid, gid_t *gid) /* Make request */ - result = winbindd_request(WINBINDD_ALLOCATE_RID_AND_GID, &request, + result = winbindd_request_response(WINBINDD_ALLOCATE_RID_AND_GID, &request, &response); if (result != NSS_STATUS_SUCCESS) @@ -299,7 +299,7 @@ static int wb_getgroups(const char *user, gid_t **groups) ZERO_STRUCT(response); - result = winbindd_request(WINBINDD_GETGROUPS, &request, &response); + result = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response); if (result == NSS_STATUS_SUCCESS) { @@ -415,7 +415,7 @@ BOOL winbind_ping( void ) { NSS_STATUS result; - result = winbindd_request(WINBINDD_PING, NULL, NULL); + result = winbindd_request_response(WINBINDD_PING, NULL, NULL); return result == NSS_STATUS_SUCCESS; } @@ -450,5 +450,5 @@ NSS_STATUS wb_is_trusted_domain(const char *domain) fstrcpy(request.domain_name, domain); - return winbindd_request(WINBINDD_DOMAIN_INFO, &request, &response); + return winbindd_request_response(WINBINDD_DOMAIN_INFO, &request, &response); } diff --git a/source/nsswitch/wb_common.c b/source/nsswitch/wb_common.c index d2e8b9cc6ac..b6f617eb952 100644 --- a/source/nsswitch/wb_common.c +++ b/source/nsswitch/wb_common.c @@ -316,14 +316,14 @@ int winbind_open_pipe_sock(void) /* version-check the socket */ - if ((winbindd_request(WINBINDD_INTERFACE_VERSION, &request, &response) != NSS_STATUS_SUCCESS) || (response.data.interface_version != WINBIND_INTERFACE_VERSION)) { + if ((winbindd_request_response(WINBINDD_INTERFACE_VERSION, &request, &response) != NSS_STATUS_SUCCESS) || (response.data.interface_version != WINBIND_INTERFACE_VERSION)) { close_sock(); return -1; } /* try and get priv pipe */ - if (winbindd_request(WINBINDD_PRIV_PIPE_DIR, &request, &response) == NSS_STATUS_SUCCESS) { + if (winbindd_request_response(WINBINDD_PRIV_PIPE_DIR, &request, &response) == NSS_STATUS_SUCCESS) { int fd; if ((fd = winbind_named_pipe_sock(response.extra_data)) != -1) { close(winbindd_fd); @@ -584,7 +584,7 @@ NSS_STATUS winbindd_get_response(struct winbindd_response *response) /* Handle simple types of requests */ -NSS_STATUS winbindd_request(int req_type, +NSS_STATUS winbindd_request_response(int req_type, struct winbindd_request *request, struct winbindd_response *response) { diff --git a/source/nsswitch/wbinfo.c b/source/nsswitch/wbinfo.c index 8407bb1e3a2..34b2d6c9299 100644 --- a/source/nsswitch/wbinfo.c +++ b/source/nsswitch/wbinfo.c @@ -43,7 +43,7 @@ static char winbind_separator(void) /* Send off request */ - if (winbindd_request(WINBINDD_INFO, NULL, &response) != + if (winbindd_request_response(WINBINDD_INFO, NULL, &response) != NSS_STATUS_SUCCESS) { d_printf("could not obtain winbind separator!\n"); /* HACK: (this module should not call lp_ funtions) */ @@ -71,7 +71,7 @@ static const char *get_winbind_domain(void) /* Send off request */ - if (winbindd_request(WINBINDD_DOMAIN_NAME, NULL, &response) != + if (winbindd_request_response(WINBINDD_DOMAIN_NAME, NULL, &response) != NSS_STATUS_SUCCESS) { d_printf("could not obtain winbind domain name!\n"); @@ -123,7 +123,7 @@ static BOOL wbinfo_get_usergroups(char *user) fstrcpy(request.data.username, user); - result = winbindd_request(WINBINDD_GETGROUPS, &request, &response); + result = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response); if (result != NSS_STATUS_SUCCESS) return False; @@ -151,7 +151,7 @@ static BOOL wbinfo_get_usersids(char *user_sid) /* Send request */ fstrcpy(request.data.sid, user_sid); - result = winbindd_request(WINBINDD_GETUSERSIDS, &request, &response); + result = winbindd_request_response(WINBINDD_GETUSERSIDS, &request, &response); if (result != NSS_STATUS_SUCCESS) return False; @@ -178,7 +178,7 @@ static BOOL wbinfo_get_userdomgroups(const char *user_sid) /* Send request */ fstrcpy(request.data.sid, user_sid); - result = winbindd_request(WINBINDD_GETUSERDOMGROUPS, &request, + result = winbindd_request_response(WINBINDD_GETUSERDOMGROUPS, &request, &response); if (result != NSS_STATUS_SUCCESS) @@ -207,7 +207,7 @@ static BOOL wbinfo_wins_byname(char *name) fstrcpy(request.data.winsreq, name); - if (winbindd_request(WINBINDD_WINS_BYNAME, &request, &response) != + if (winbindd_request_response(WINBINDD_WINS_BYNAME, &request, &response) != NSS_STATUS_SUCCESS) { return False; } @@ -233,7 +233,7 @@ static BOOL wbinfo_wins_byip(char *ip) fstrcpy(request.data.winsreq, ip); - if (winbindd_request(WINBINDD_WINS_BYIP, &request, &response) != + if (winbindd_request_response(WINBINDD_WINS_BYIP, &request, &response) != NSS_STATUS_SUCCESS) { return False; } @@ -255,7 +255,7 @@ static BOOL wbinfo_list_domains(void) /* Send request */ - if (winbindd_request(WINBINDD_LIST_TRUSTDOM, NULL, &response) != + if (winbindd_request_response(WINBINDD_LIST_TRUSTDOM, NULL, &response) != NSS_STATUS_SUCCESS) return False; @@ -298,7 +298,7 @@ static BOOL wbinfo_show_sequence(const char *domain) /* Send request */ - if (winbindd_request(WINBINDD_SHOW_SEQUENCE, &request, &response) != + if (winbindd_request_response(WINBINDD_SHOW_SEQUENCE, &request, &response) != NSS_STATUS_SUCCESS) return False; @@ -327,7 +327,7 @@ static BOOL wbinfo_domain_info(const char *domain_name) /* Send request */ - if (winbindd_request(WINBINDD_DOMAIN_INFO, &request, &response) != + if (winbindd_request_response(WINBINDD_DOMAIN_INFO, &request, &response) != NSS_STATUS_SUCCESS) return False; @@ -364,7 +364,7 @@ static BOOL wbinfo_getdcname(const char *domain_name) /* Send request */ - if (winbindd_request(WINBINDD_GETDCNAME, &request, &response) != + if (winbindd_request_response(WINBINDD_GETDCNAME, &request, &response) != NSS_STATUS_SUCCESS) { d_printf("Could not get dc name for %s\n", domain_name); return False; @@ -386,7 +386,7 @@ static BOOL wbinfo_check_secret(void) ZERO_STRUCT(response); - result = winbindd_request(WINBINDD_CHECK_MACHACC, NULL, &response); + result = winbindd_request_response(WINBINDD_CHECK_MACHACC, NULL, &response); d_printf("checking the trust secret via RPC calls %s\n", (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed"); @@ -413,7 +413,7 @@ static BOOL wbinfo_uid_to_sid(uid_t uid) request.data.uid = uid; - if (winbindd_request(WINBINDD_UID_TO_SID, &request, &response) != + if (winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response) != NSS_STATUS_SUCCESS) return False; @@ -438,7 +438,7 @@ static BOOL wbinfo_gid_to_sid(gid_t gid) request.data.gid = gid; - if (winbindd_request(WINBINDD_GID_TO_SID, &request, &response) != + if (winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response) != NSS_STATUS_SUCCESS) return False; @@ -463,7 +463,7 @@ static BOOL wbinfo_sid_to_uid(char *sid) fstrcpy(request.data.sid, sid); - if (winbindd_request(WINBINDD_SID_TO_UID, &request, &response) != + if (winbindd_request_response(WINBINDD_SID_TO_UID, &request, &response) != NSS_STATUS_SUCCESS) return False; @@ -486,7 +486,7 @@ static BOOL wbinfo_sid_to_gid(char *sid) fstrcpy(request.data.sid, sid); - if (winbindd_request(WINBINDD_SID_TO_GID, &request, &response) != + if (winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response) != NSS_STATUS_SUCCESS) return False; @@ -523,7 +523,7 @@ static BOOL wbinfo_lookupsid(char *sid) fstrcpy(request.data.sid, sid); - if (winbindd_request(WINBINDD_LOOKUPSID, &request, &response) != + if (winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response) != NSS_STATUS_SUCCESS) return False; @@ -551,7 +551,7 @@ static BOOL wbinfo_lookupname(char *name) parse_wbinfo_domain_user(name, request.data.name.dom_name, request.data.name.name); - if (winbindd_request(WINBINDD_LOOKUPNAME, &request, &response) != + if (winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response) != NSS_STATUS_SUCCESS) return False; @@ -586,7 +586,7 @@ static BOOL wbinfo_auth(char *username) } else fstrcpy(request.data.auth.user, username); - result = winbindd_request(WINBINDD_PAM_AUTH, &request, &response); + result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response); /* Display response */ @@ -684,7 +684,7 @@ static BOOL wbinfo_auth_crap(char *username) request.data.auth_crap.nt_resp_len = 24; } - result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response); + result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response); /* Display response */ @@ -728,7 +728,7 @@ static BOOL wbinfo_klog(char *username) request.flags |= WBFLAG_PAM_AFS_TOKEN; - result = winbindd_request(WINBINDD_PAM_AUTH, &request, &response); + result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response); /* Display response */ @@ -780,7 +780,7 @@ static BOOL print_domain_users(const char *domain) fstrcpy( request.domain_name, domain ); } - if (winbindd_request(WINBINDD_LIST_USERS, &request, &response) != + if (winbindd_request_response(WINBINDD_LIST_USERS, &request, &response) != NSS_STATUS_SUCCESS) return False; @@ -818,7 +818,7 @@ static BOOL print_domain_groups(const char *domain) fstrcpy( request.domain_name, domain ); } - if (winbindd_request(WINBINDD_LIST_GROUPS, &request, &response) != + if (winbindd_request_response(WINBINDD_LIST_GROUPS, &request, &response) != NSS_STATUS_SUCCESS) return False; @@ -933,7 +933,7 @@ static BOOL wbinfo_ping(void) { NSS_STATUS result; - result = winbindd_request(WINBINDD_PING, NULL, NULL); + result = winbindd_request_response(WINBINDD_PING, NULL, NULL); /* Display response */ diff --git a/source/nsswitch/winbind_client.h b/source/nsswitch/winbind_client.h index 4de2d57cc7d..ec20cd78ef4 100644 --- a/source/nsswitch/winbind_client.h +++ b/source/nsswitch/winbind_client.h @@ -5,7 +5,7 @@ void init_request(struct winbindd_request *req,int rq_type); NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request *request); NSS_STATUS winbindd_get_response(struct winbindd_response *response); -NSS_STATUS winbindd_request(int req_type, +NSS_STATUS winbindd_request_response(int req_type, struct winbindd_request *request, struct winbindd_response *response); int winbind_open_pipe_sock(void); diff --git a/source/nsswitch/winbind_nss_aix.c b/source/nsswitch/winbind_nss_aix.c index c90dc2f3f10..0a8bef736ca 100644 --- a/source/nsswitch/winbind_nss_aix.c +++ b/source/nsswitch/winbind_nss_aix.c @@ -278,7 +278,7 @@ static struct group *wb_aix_getgrgid(gid_t gid) request.data.gid = gid; - ret = winbindd_request(WINBINDD_GETGRGID, &request, &response); + ret = winbindd_request_response(WINBINDD_GETGRGID, &request, &response); logit("getgrgid ret=%d\n", ret); @@ -310,7 +310,7 @@ static struct group *wb_aix_getgrnam(const char *name) STRCPY_RETNULL(request.data.groupname, name); - ret = winbindd_request(WINBINDD_GETGRNAM, &request, &response); + ret = winbindd_request_response(WINBINDD_GETGRNAM, &request, &response); HANDLE_ERRORS(ret); @@ -366,7 +366,7 @@ static char *wb_aix_getgrset(char *user) free(r_user); } - ret = winbindd_request(WINBINDD_GETGROUPS, &request, &response); + ret = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response); HANDLE_ERRORS(ret); @@ -405,7 +405,7 @@ static struct passwd *wb_aix_getpwuid(uid_t uid) request.data.uid = uid; - ret = winbindd_request(WINBINDD_GETPWUID, &request, &response); + ret = winbindd_request_response(WINBINDD_GETPWUID, &request, &response); HANDLE_ERRORS(ret); @@ -438,7 +438,7 @@ static struct passwd *wb_aix_getpwnam(const char *name) STRCPY_RETNULL(request.data.username, name); - ret = winbindd_request(WINBINDD_GETPWNAM, &request, &response); + ret = winbindd_request_response(WINBINDD_GETPWNAM, &request, &response); HANDLE_ERRORS(ret); @@ -471,7 +471,7 @@ static int wb_aix_lsuser(char *attributes[], attrval_t results[], int size) ZERO_STRUCT(request); ZERO_STRUCT(response); - ret = winbindd_request(WINBINDD_LIST_USERS, &request, &response); + ret = winbindd_request_response(WINBINDD_LIST_USERS, &request, &response); if (ret != 0) { errno = EINVAL; return -1; @@ -519,7 +519,7 @@ static int wb_aix_lsgroup(char *attributes[], attrval_t results[], int size) ZERO_STRUCT(request); ZERO_STRUCT(response); - ret = winbindd_request(WINBINDD_LIST_GROUPS, &request, &response); + ret = winbindd_request_response(WINBINDD_LIST_GROUPS, &request, &response); if (ret != 0) { errno = EINVAL; return -1; @@ -600,7 +600,7 @@ static attrval_t pwd_to_sid(struct passwd *pwd) request.data.uid = pwd->pw_uid; - if (winbindd_request(WINBINDD_UID_TO_SID, &request, &response) != + if (winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response) != NSS_STATUS_SUCCESS) { r.attr_flag = ENOENT; } else { @@ -834,7 +834,7 @@ static int wb_aix_authenticate(char *user, char *pass, free(r_user); } - result = winbindd_request(WINBINDD_PAM_AUTH, &request, &response); + result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response); free_response(&response); @@ -883,7 +883,7 @@ static int wb_aix_chpass(char *user, char *oldpass, char *newpass, char **messag free(r_user); } - result = winbindd_request(WINBINDD_PAM_CHAUTHTOK, &request, &response); + result = winbindd_request_response(WINBINDD_PAM_CHAUTHTOK, &request, &response); free_response(&response); diff --git a/source/nsswitch/winbind_nss_linux.c b/source/nsswitch/winbind_nss_linux.c index d8d4f936769..c0b8bf3a75d 100644 --- a/source/nsswitch/winbind_nss_linux.c +++ b/source/nsswitch/winbind_nss_linux.c @@ -303,7 +303,7 @@ _nss_winbind_setpwent(void) free_response(&getpwent_response); } - return winbindd_request(WINBINDD_SETPWENT, NULL, NULL); + return winbindd_request_response(WINBINDD_SETPWENT, NULL, NULL); } /* Close ntdom password database "file pointer" */ @@ -320,7 +320,7 @@ _nss_winbind_endpwent(void) free_response(&getpwent_response); } - return winbindd_request(WINBINDD_ENDPWENT, NULL, NULL); + return winbindd_request_response(WINBINDD_ENDPWENT, NULL, NULL); } /* Fetch the next password entry from ntdom password database */ @@ -355,7 +355,7 @@ _nss_winbind_getpwent_r(struct passwd *result, char *buffer, request.data.num_entries = MAX_GETPWENT_USERS; - ret = winbindd_request(WINBINDD_GETPWENT, &request, + ret = winbindd_request_response(WINBINDD_GETPWENT, &request, &getpwent_response); if (ret == NSS_STATUS_SUCCESS) { @@ -425,7 +425,7 @@ _nss_winbind_getpwuid_r(uid_t uid, struct passwd *result, char *buffer, request.data.uid = uid; - ret = winbindd_request(WINBINDD_GETPWUID, &request, &response); + ret = winbindd_request_response(WINBINDD_GETPWUID, &request, &response); if (ret == NSS_STATUS_SUCCESS) { ret = fill_pwent(result, &response.data.pw, @@ -487,7 +487,7 @@ _nss_winbind_getpwnam_r(const char *name, struct passwd *result, char *buffer, request.data.username [sizeof(request.data.username) - 1] = '\0'; - ret = winbindd_request(WINBINDD_GETPWNAM, &request, &response); + ret = winbindd_request_response(WINBINDD_GETPWNAM, &request, &response); if (ret == NSS_STATUS_SUCCESS) { ret = fill_pwent(result, &response.data.pw, &buffer, @@ -543,7 +543,7 @@ _nss_winbind_setgrent(void) free_response(&getgrent_response); } - return winbindd_request(WINBINDD_SETGRENT, NULL, NULL); + return winbindd_request_response(WINBINDD_SETGRENT, NULL, NULL); } /* Close "file pointer" for ntdom group database */ @@ -560,7 +560,7 @@ _nss_winbind_endgrent(void) free_response(&getgrent_response); } - return winbindd_request(WINBINDD_ENDGRENT, NULL, NULL); + return winbindd_request_response(WINBINDD_ENDGRENT, NULL, NULL); } /* Get next entry from ntdom group database */ @@ -597,7 +597,7 @@ winbind_getgrent(enum winbindd_cmd cmd, request.data.num_entries = MAX_GETGRENT_USERS; - ret = winbindd_request(cmd, &request, + ret = winbindd_request_response(cmd, &request, &getgrent_response); if (ret == NSS_STATUS_SUCCESS) { @@ -700,7 +700,7 @@ _nss_winbind_getgrnam_r(const char *name, request.data.groupname [sizeof(request.data.groupname) - 1] = '\0'; - ret = winbindd_request(WINBINDD_GETGRNAM, &request, &response); + ret = winbindd_request_response(WINBINDD_GETGRNAM, &request, &response); if (ret == NSS_STATUS_SUCCESS) { ret = fill_grent(result, &response.data.gr, @@ -762,7 +762,7 @@ _nss_winbind_getgrgid_r(gid_t gid, request.data.gid = gid; - ret = winbindd_request(WINBINDD_GETGRGID, &request, &response); + ret = winbindd_request_response(WINBINDD_GETGRGID, &request, &response); if (ret == NSS_STATUS_SUCCESS) { @@ -821,7 +821,7 @@ _nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start, strncpy(request.data.username, user, sizeof(request.data.username) - 1); - ret = winbindd_request(WINBINDD_GETGROUPS, &request, &response); + ret = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response); if (ret == NSS_STATUS_SUCCESS) { int num_gids = response.data.num_entries; @@ -897,7 +897,7 @@ _nss_winbind_getusersids(const char *user_sid, char **group_sids, strncpy(request.data.sid, user_sid,sizeof(request.data.sid) - 1); request.data.sid[sizeof(request.data.sid) - 1] = '\0'; - ret = winbindd_request(WINBINDD_GETUSERSIDS, &request, &response); + ret = winbindd_request_response(WINBINDD_GETUSERSIDS, &request, &response); if (ret != NSS_STATUS_SUCCESS) { goto done; @@ -940,7 +940,7 @@ _nss_winbind_nametosid(const char *name, char **sid, char *buffer, sizeof(request.data.name.name) - 1); request.data.name.name[sizeof(request.data.name.name) - 1] = '\0'; - ret = winbindd_request(WINBINDD_LOOKUPNAME, &request, &response); + ret = winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; @@ -981,7 +981,7 @@ _nss_winbind_sidtoname(const char *sid, char **name, char *buffer, /* we need to fetch the separator first time through */ if (!sep_char) { - ret = winbindd_request(WINBINDD_INFO, &request, &response); + ret = winbindd_request_response(WINBINDD_INFO, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; @@ -996,7 +996,7 @@ _nss_winbind_sidtoname(const char *sid, char **name, char *buffer, sizeof(request.data.sid) - 1); request.data.sid[sizeof(request.data.sid) - 1] = '\0'; - ret = winbindd_request(WINBINDD_LOOKUPSID, &request, &response); + ret = winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; @@ -1043,7 +1043,7 @@ _nss_winbind_sidtouid(const char *sid, uid_t *uid, int *errnop) strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1); request.data.sid[sizeof(request.data.sid) - 1] = '\0'; - ret = winbindd_request(WINBINDD_SID_TO_UID, &request, &response); + ret = winbindd_request_response(WINBINDD_SID_TO_UID, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; @@ -1073,7 +1073,7 @@ _nss_winbind_sidtogid(const char *sid, gid_t *gid, int *errnop) strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1); request.data.sid[sizeof(request.data.sid) - 1] = '\0'; - ret = winbindd_request(WINBINDD_SID_TO_GID, &request, &response); + ret = winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; @@ -1103,7 +1103,7 @@ _nss_winbind_uidtosid(uid_t uid, char **sid, char *buffer, request.data.uid = uid; - ret = winbindd_request(WINBINDD_UID_TO_SID, &request, &response); + ret = winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; @@ -1142,7 +1142,7 @@ _nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer, request.data.gid = gid; - ret = winbindd_request(WINBINDD_GID_TO_SID, &request, &response); + ret = winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; diff --git a/source/nsswitch/winbind_nss_solaris.h b/source/nsswitch/winbind_nss_solaris.h index 567de411aa6..a3ba7629956 100644 --- a/source/nsswitch/winbind_nss_solaris.h +++ b/source/nsswitch/winbind_nss_solaris.h @@ -24,7 +24,33 @@ #ifndef _WINBIND_NSS_SOLARIS_H #define _WINBIND_NSS_SOLARIS_H +/* Solaris has a broken nss_common header file containing C++ reserved names. */ +#ifndef __cplusplus +#undef class +#undef private +#undef public +#undef protected +#undef template +#undef this +#undef new +#undef delete +#undef friend +#endif + #include <nss_common.h> + +#ifndef __cplusplus +#define class #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#define private #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#define public #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#define protected #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#define template #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#define this #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#define new #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#define delete #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#define friend #error DONT_USE_CPLUSPLUS_RESERVED_NAMES +#endif + #include <nss_dbdefs.h> #include <nsswitch.h> diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c index 5e38a84d65b..078aeeb059a 100644 --- a/source/nsswitch/winbindd.c +++ b/source/nsswitch/winbindd.c @@ -392,7 +392,7 @@ static void rw_callback(struct fd_event *event, int flags) if (done <= 0) { event->flags = 0; - event->finished(event->private, False); + event->finished(event->private_data, False); return; } } @@ -404,7 +404,7 @@ static void rw_callback(struct fd_event *event, int flags) if (done <= 0) { event->flags = 0; - event->finished(event->private, False); + event->finished(event->private_data, False); return; } } @@ -413,7 +413,7 @@ static void rw_callback(struct fd_event *event, int flags) if (event->done == event->length) { event->flags = 0; - event->finished(event->private, True); + event->finished(event->private_data, True); } } @@ -423,8 +423,8 @@ static void rw_callback(struct fd_event *event, int flags) */ void setup_async_read(struct fd_event *event, void *data, size_t length, - void (*finished)(void *private, BOOL success), - void *private) + void (*finished)(void *private_data, BOOL success), + void *private_data) { SMB_ASSERT(event->flags == 0); event->data = data; @@ -432,13 +432,13 @@ void setup_async_read(struct fd_event *event, void *data, size_t length, event->done = 0; event->handler = rw_callback; event->finished = finished; - event->private = private; + event->private_data = private_data; event->flags = EVENT_FD_READ; } void setup_async_write(struct fd_event *event, void *data, size_t length, - void (*finished)(void *private, BOOL success), - void *private) + void (*finished)(void *private_data, BOOL success), + void *private_data) { SMB_ASSERT(event->flags == 0); event->data = data; @@ -446,7 +446,7 @@ void setup_async_write(struct fd_event *event, void *data, size_t length, event->done = 0; event->handler = rw_callback; event->finished = finished; - event->private = private; + event->private_data = private_data; event->flags = EVENT_FD_WRITE; } @@ -460,17 +460,17 @@ void setup_async_write(struct fd_event *event, void *data, size_t length, * to call request_finished which schedules sending the response. */ -static void request_len_recv(void *private, BOOL success); -static void request_recv(void *private, BOOL success); +static void request_len_recv(void *private_data, BOOL success); +static void request_recv(void *private_data, BOOL success); static void request_finished(struct winbindd_cli_state *state); -void request_finished_cont(void *private, BOOL success); -static void response_main_sent(void *private, BOOL success); -static void response_extra_sent(void *private, BOOL success); +void request_finished_cont(void *private_data, BOOL success); +static void response_main_sent(void *private_data, BOOL success); +static void response_extra_sent(void *private_data, BOOL success); -static void response_extra_sent(void *private, BOOL success) +static void response_extra_sent(void *private_data, BOOL success) { struct winbindd_cli_state *state = - talloc_get_type_abort(private, struct winbindd_cli_state); + talloc_get_type_abort(private_data, struct winbindd_cli_state); if (state->mem_ctx != NULL) { talloc_destroy(state->mem_ctx); @@ -488,10 +488,10 @@ static void response_extra_sent(void *private, BOOL success) request_len_recv, state); } -static void response_main_sent(void *private, BOOL success) +static void response_main_sent(void *private_data, BOOL success) { struct winbindd_cli_state *state = - talloc_get_type_abort(private, struct winbindd_cli_state); + talloc_get_type_abort(private_data, struct winbindd_cli_state); if (!success) { state->finished = True; @@ -534,10 +534,10 @@ void request_ok(struct winbindd_cli_state *state) request_finished(state); } -void request_finished_cont(void *private, BOOL success) +void request_finished_cont(void *private_data, BOOL success) { struct winbindd_cli_state *state = - talloc_get_type_abort(private, struct winbindd_cli_state); + talloc_get_type_abort(private_data, struct winbindd_cli_state); if (success) request_ok(state); @@ -545,10 +545,10 @@ void request_finished_cont(void *private, BOOL success) request_error(state); } -static void request_recv(void *private, BOOL success) +static void request_recv(void *private_data, BOOL success) { struct winbindd_cli_state *state = - talloc_get_type_abort(private, struct winbindd_cli_state); + talloc_get_type_abort(private_data, struct winbindd_cli_state); if (!success) { state->finished = True; @@ -558,10 +558,10 @@ static void request_recv(void *private, BOOL success) process_request(state); } -static void request_len_recv(void *private, BOOL success) +static void request_len_recv(void *private_data, BOOL success) { struct winbindd_cli_state *state = - talloc_get_type_abort(private, struct winbindd_cli_state); + talloc_get_type_abort(private_data, struct winbindd_cli_state); if (!success) { state->finished = True; diff --git a/source/nsswitch/winbindd.h b/source/nsswitch/winbindd.h index d000168b1f6..3a7728e4a2c 100644 --- a/source/nsswitch/winbindd.h +++ b/source/nsswitch/winbindd.h @@ -43,8 +43,8 @@ struct fd_event { void (*handler)(struct fd_event *fde, int flags); void *data; size_t length, done; - void (*finished)(void *private, BOOL success); - void *private; + void (*finished)(void *private_data, BOOL success); + void *private_data; }; struct winbindd_cli_state { @@ -84,6 +84,8 @@ struct getent_state { struct getpwent_user { fstring name; /* Account name */ fstring gecos; /* User information */ + fstring homedir; /* User Home Directory */ + fstring shell; /* User Login Shell */ DOM_SID user_sid; /* NT user and primary group SIDs */ DOM_SID group_sid; }; @@ -103,6 +105,8 @@ extern struct winbindd_state server_state; /* Server information */ typedef struct { char *acct_name; char *full_name; + char *homedir; + char *shell; DOM_SID user_sid; /* NT user and primary group SIDs */ DOM_SID group_sid; } WINBIND_USERINFO; @@ -163,7 +167,7 @@ struct winbindd_domain { /* Private data for the backends (used for connection cache) */ - void *private; + void *private_data; /* A working DC */ fstring dcname; diff --git a/source/nsswitch/winbindd_ads.c b/source/nsswitch/winbindd_ads.c index 0f4dee4f4ad..3041b736f71 100644 --- a/source/nsswitch/winbindd_ads.c +++ b/source/nsswitch/winbindd_ads.c @@ -39,8 +39,8 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) ADS_STRUCT *ads; ADS_STATUS status; - if (domain->private) { - ads = (ADS_STRUCT *)domain->private; + if (domain->private_data) { + ads = (ADS_STRUCT *)domain->private_data; /* check for a valid structure */ @@ -54,7 +54,7 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) ads->is_mine = True; ads_destroy( &ads ); ads_kdestroy("MEMORY:winbind_ccache"); - domain->private = NULL; + domain->private_data = NULL; } } @@ -95,13 +95,18 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) return NULL; } + if (use_nss_info("sfu") && (!ads_check_sfu_mapping(ads))) { + DEBUG(0,("ads_cached_connection: failed to check sfu attributes\n")); + return NULL; + } + /* set the flag that says we don't own the memory even though we do so that ads_destroy() won't destroy the structure we pass back by reference */ ads->is_mine = False; - domain->private = (void *)ads; + domain->private_data = (void *)ads; return ads; } @@ -116,7 +121,10 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, const char *attrs[] = {"userPrincipalName", "sAMAccountName", "name", "objectSid", "primaryGroupID", - "sAMAccountType", NULL}; + "sAMAccountType", + ADS_ATTR_SFU_HOMEDIR_OID, + ADS_ATTR_SFU_SHELL_OID, + NULL}; int i, count; ADS_STATUS rc; void *res = NULL; @@ -156,6 +164,8 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { char *name, *gecos; + char *homedir = NULL; + char *shell = NULL; uint32 group; uint32 atype; @@ -167,6 +177,11 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, name = ads_pull_username(ads, mem_ctx, msg); gecos = ads_pull_string(ads, mem_ctx, msg, "name"); + if (use_nss_info("sfu")) { + homedir = ads_pull_string(ads, mem_ctx, msg, ads->schema.sfu_homedir_attr); + shell = ads_pull_string(ads, mem_ctx, msg, ads->schema.sfu_shell_attr); + } + if (!ads_pull_sid(ads, msg, "objectSid", &(*info)[i].user_sid)) { DEBUG(1,("No sid for %s !?\n", name)); @@ -179,6 +194,8 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, (*info)[i].acct_name = name; (*info)[i].full_name = gecos; + (*info)[i].homedir = homedir; + (*info)[i].shell = shell; sid_compose(&(*info)[i].group_sid, &domain->sid, group); i++; } @@ -364,7 +381,10 @@ static NTSTATUS query_user(struct winbindd_domain *domain, const char *attrs[] = {"userPrincipalName", "sAMAccountName", "name", - "primaryGroupID", NULL}; + "primaryGroupID", + ADS_ATTR_SFU_HOMEDIR_OID, + ADS_ATTR_SFU_SHELL_OID, + NULL}; ADS_STATUS rc; int count; void *msg = NULL; @@ -403,6 +423,11 @@ static NTSTATUS query_user(struct winbindd_domain *domain, info->acct_name = ads_pull_username(ads, mem_ctx, msg); info->full_name = ads_pull_string(ads, mem_ctx, msg, "name"); + if (use_nss_info("sfu")) { + info->homedir = ads_pull_string(ads, mem_ctx, msg, ads->schema.sfu_homedir_attr); + info->shell = ads_pull_string(ads, mem_ctx, msg, ads->schema.sfu_shell_attr); + } + if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group_rid)) { DEBUG(1,("No primary group for %s !?\n", sid_string_static(sid))); @@ -767,7 +792,7 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) through since ads_USN() has already done that indirectly */ - domain->private = NULL; + domain->private_data = NULL; } return ads_ntstatus(rc); } diff --git a/source/nsswitch/winbindd_async.c b/source/nsswitch/winbindd_async.c index 9ac2acafd01..acae7e7f371 100644 --- a/source/nsswitch/winbindd_async.c +++ b/source/nsswitch/winbindd_async.c @@ -44,32 +44,32 @@ struct do_async_state { void (*cont)(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private); - void *c, *private; + void *c, void *private_data); + void *c, *private_data; }; -static void do_async_recv(void *private, BOOL success) +static void do_async_recv(void *private_data, BOOL success) { struct do_async_state *state = - talloc_get_type_abort(private, struct do_async_state); + talloc_get_type_abort(private_data, struct do_async_state); state->cont(state->mem_ctx, success, &state->response, - state->c, state->private); + state->c, state->private_data); } static void do_async(TALLOC_CTX *mem_ctx, struct winbindd_child *child, const struct winbindd_request *request, void (*cont)(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private), - void *c, void *private) + void *c, void *private_data), + void *c, void *private_data) { struct do_async_state *state; state = TALLOC_P(mem_ctx, struct do_async_state); if (state == NULL) { DEBUG(0, ("talloc failed\n")); - cont(mem_ctx, False, NULL, c, private); + cont(mem_ctx, False, NULL, c, private_data); return; } @@ -78,7 +78,7 @@ static void do_async(TALLOC_CTX *mem_ctx, struct winbindd_child *child, state->request.length = sizeof(state->request); state->cont = cont; state->c = c; - state->private = private; + state->private_data = private_data; async_request(mem_ctx, child, &state->request, &state->response, do_async_recv, state); @@ -88,15 +88,15 @@ static void do_async_domain(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, const struct winbindd_request *request, void (*cont)(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private), - void *c, void *private) + void *c, void *private_data), + void *c, void *private_data) { struct do_async_state *state; state = TALLOC_P(mem_ctx, struct do_async_state); if (state == NULL) { DEBUG(0, ("talloc failed\n")); - cont(mem_ctx, False, NULL, c, private); + cont(mem_ctx, False, NULL, c, private_data); return; } @@ -105,7 +105,7 @@ static void do_async_domain(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, state->request.length = sizeof(state->request); state->cont = cont; state->c = c; - state->private = private; + state->private_data = private_data; async_domain_request(mem_ctx, domain, &state->request, &state->response, do_async_recv, state); @@ -113,29 +113,29 @@ static void do_async_domain(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, static void idmap_set_mapping_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private) + void *c, void *private_data) { void (*cont)(void *priv, BOOL succ) = c; if (!success) { DEBUG(5, ("Could not trigger idmap_set_mapping\n")); - cont(private, False); + cont(private_data, False); return; } if (response->result != WINBINDD_OK) { DEBUG(5, ("idmap_set_mapping returned an error\n")); - cont(private, False); + cont(private_data, False); return; } - cont(private, True); + cont(private_data, True); } void idmap_set_mapping_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, unid_t id, int id_type, - void (*cont)(void *private, BOOL success), - void *private) + void (*cont)(void *private_data, BOOL success), + void *private_data) { struct winbindd_request request; ZERO_STRUCT(request); @@ -148,7 +148,7 @@ void idmap_set_mapping_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, sid_to_string(request.data.dual_idmapset.sid, sid); do_async(mem_ctx, idmap_child(), &request, idmap_set_mapping_recv, - cont, private); + cont, private_data); } enum winbindd_result winbindd_dual_idmapset(struct winbindd_domain *domain, @@ -175,11 +175,11 @@ enum winbindd_result winbindd_dual_idmapset(struct winbindd_domain *domain, static void idmap_sid2uid_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private); + void *c, void *private_data); void idmap_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, BOOL alloc, - void (*cont)(void *private, BOOL success, uid_t uid), - void *private) + void (*cont)(void *private_data, BOOL success, uid_t uid), + void *private_data) { struct winbindd_request request; ZERO_STRUCT(request); @@ -187,7 +187,7 @@ void idmap_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, BOOL alloc, sid_to_string(request.data.dual_sid2id.sid, sid); request.data.dual_sid2id.alloc = alloc; do_async(mem_ctx, idmap_child(), &request, idmap_sid2uid_recv, - cont, private); + cont, private_data); } enum winbindd_result winbindd_dual_sid2uid(struct winbindd_domain *domain, @@ -217,40 +217,40 @@ enum winbindd_result winbindd_dual_sid2uid(struct winbindd_domain *domain, static void idmap_sid2uid_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private) + void *c, void *private_data) { void (*cont)(void *priv, BOOL succ, uid_t uid) = c; if (!success) { DEBUG(5, ("Could not trigger sid2uid\n")); - cont(private, False, 0); + cont(private_data, False, 0); return; } if (response->result != WINBINDD_OK) { DEBUG(5, ("sid2uid returned an error\n")); - cont(private, False, 0); + cont(private_data, False, 0); return; } - cont(private, True, response->data.uid); + cont(private_data, True, response->data.uid); } static void uid2name_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private); + void *c, void *private_data); void winbindd_uid2name_async(TALLOC_CTX *mem_ctx, uid_t uid, - void (*cont)(void *private, BOOL success, + void (*cont)(void *private_data, BOOL success, const char *name), - void *private) + void *private_data) { struct winbindd_request request; ZERO_STRUCT(request); request.cmd = WINBINDD_DUAL_UID2NAME; request.data.uid = uid; do_async(mem_ctx, idmap_child(), &request, uid2name_recv, - cont, private); + cont, private_data); } enum winbindd_result winbindd_dual_uid2name(struct winbindd_domain *domain, @@ -274,40 +274,40 @@ enum winbindd_result winbindd_dual_uid2name(struct winbindd_domain *domain, static void uid2name_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private) + void *c, void *private_data) { void (*cont)(void *priv, BOOL succ, const char *name) = c; if (!success) { DEBUG(5, ("Could not trigger uid2name\n")); - cont(private, False, NULL); + cont(private_data, False, NULL); return; } if (response->result != WINBINDD_OK) { DEBUG(5, ("uid2name returned an error\n")); - cont(private, False, NULL); + cont(private_data, False, NULL); return; } - cont(private, True, response->data.name.name); + cont(private_data, True, response->data.name.name); } static void name2uid_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private); + void *c, void *private_data); static void winbindd_name2uid_async(TALLOC_CTX *mem_ctx, const char *name, - void (*cont)(void *private, BOOL success, + void (*cont)(void *private_data, BOOL success, uid_t uid), - void *private) + void *private_data) { struct winbindd_request request; ZERO_STRUCT(request); request.cmd = WINBINDD_DUAL_NAME2UID; fstrcpy(request.data.username, name); do_async(mem_ctx, idmap_child(), &request, name2uid_recv, - cont, private); + cont, private_data); } enum winbindd_result winbindd_dual_name2uid(struct winbindd_domain *domain, @@ -333,32 +333,32 @@ enum winbindd_result winbindd_dual_name2uid(struct winbindd_domain *domain, static void name2uid_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private) + void *c, void *private_data) { void (*cont)(void *priv, BOOL succ, uid_t uid) = c; if (!success) { DEBUG(5, ("Could not trigger name2uid\n")); - cont(private, False, 0); + cont(private_data, False, 0); return; } if (response->result != WINBINDD_OK) { DEBUG(5, ("name2uid returned an error\n")); - cont(private, False, 0); + cont(private_data, False, 0); return; } - cont(private, True, response->data.uid); + cont(private_data, True, response->data.uid); } static void idmap_sid2gid_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private); + void *c, void *private_data); void idmap_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, BOOL alloc, - void (*cont)(void *private, BOOL success, gid_t gid), - void *private) + void (*cont)(void *private_data, BOOL success, gid_t gid), + void *private_data) { struct winbindd_request request; ZERO_STRUCT(request); @@ -366,7 +366,7 @@ void idmap_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, BOOL alloc, sid_to_string(request.data.dual_sid2id.sid, sid); request.data.dual_sid2id.alloc = alloc; do_async(mem_ctx, idmap_child(), &request, idmap_sid2gid_recv, - cont, private); + cont, private_data); } enum winbindd_result winbindd_dual_sid2gid(struct winbindd_domain *domain, @@ -396,57 +396,57 @@ enum winbindd_result winbindd_dual_sid2gid(struct winbindd_domain *domain, static void idmap_sid2gid_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private) + void *c, void *private_data) { void (*cont)(void *priv, BOOL succ, gid_t gid) = c; if (!success) { DEBUG(5, ("Could not trigger sid2gid\n")); - cont(private, False, 0); + cont(private_data, False, 0); return; } if (response->result != WINBINDD_OK) { DEBUG(5, ("sid2gid returned an error\n")); - cont(private, False, 0); + cont(private_data, False, 0); return; } - cont(private, True, response->data.gid); + cont(private_data, True, response->data.gid); } static void gid2name_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private) + void *c, void *private_data) { void (*cont)(void *priv, BOOL succ, const char *name) = c; if (!success) { DEBUG(5, ("Could not trigger gid2name\n")); - cont(private, False, NULL); + cont(private_data, False, NULL); return; } if (response->result != WINBINDD_OK) { DEBUG(5, ("gid2name returned an error\n")); - cont(private, False, NULL); + cont(private_data, False, NULL); return; } - cont(private, True, response->data.name.name); + cont(private_data, True, response->data.name.name); } void winbindd_gid2name_async(TALLOC_CTX *mem_ctx, gid_t gid, - void (*cont)(void *private, BOOL success, + void (*cont)(void *private_data, BOOL success, const char *name), - void *private) + void *private_data) { struct winbindd_request request; ZERO_STRUCT(request); request.cmd = WINBINDD_DUAL_GID2NAME; request.data.gid = gid; do_async(mem_ctx, idmap_child(), &request, gid2name_recv, - cont, private); + cont, private_data); } enum winbindd_result winbindd_dual_gid2name(struct winbindd_domain *domain, @@ -467,19 +467,19 @@ enum winbindd_result winbindd_dual_gid2name(struct winbindd_domain *domain, static void name2gid_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private); + void *c, void *private_data); static void winbindd_name2gid_async(TALLOC_CTX *mem_ctx, const char *name, - void (*cont)(void *private, BOOL success, + void (*cont)(void *private_data, BOOL success, gid_t gid), - void *private) + void *private_data) { struct winbindd_request request; ZERO_STRUCT(request); request.cmd = WINBINDD_DUAL_NAME2GID; fstrcpy(request.data.groupname, name); do_async(mem_ctx, idmap_child(), &request, name2gid_recv, - cont, private); + cont, private_data); } enum winbindd_result winbindd_dual_name2gid(struct winbindd_domain *domain, @@ -505,55 +505,55 @@ enum winbindd_result winbindd_dual_name2gid(struct winbindd_domain *domain, static void name2gid_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private) + void *c, void *private_data) { void (*cont)(void *priv, BOOL succ, gid_t gid) = c; if (!success) { DEBUG(5, ("Could not trigger name2gid\n")); - cont(private, False, 0); + cont(private_data, False, 0); return; } if (response->result != WINBINDD_OK) { DEBUG(5, ("name2gid returned an error\n")); - cont(private, False, 0); + cont(private_data, False, 0); return; } - cont(private, True, response->data.gid); + cont(private_data, True, response->data.gid); } static void lookupsid_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private) + void *c, void *private_data) { void (*cont)(void *priv, BOOL succ, const char *dom_name, const char *name, enum SID_NAME_USE type) = c; if (!success) { DEBUG(5, ("Could not trigger lookupsid\n")); - cont(private, False, NULL, NULL, SID_NAME_UNKNOWN); + cont(private_data, False, NULL, NULL, SID_NAME_UNKNOWN); return; } if (response->result != WINBINDD_OK) { DEBUG(5, ("lookupsid returned an error\n")); - cont(private, False, NULL, NULL, SID_NAME_UNKNOWN); + cont(private_data, False, NULL, NULL, SID_NAME_UNKNOWN); return; } - cont(private, True, response->data.name.dom_name, + cont(private_data, True, response->data.name.dom_name, response->data.name.name, response->data.name.type); } void winbindd_lookupsid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - void (*cont)(void *private, BOOL success, + void (*cont)(void *private_data, BOOL success, const char *dom_name, const char *name, enum SID_NAME_USE type), - void *private) + void *private_data) { struct winbindd_domain *domain; struct winbindd_request request; @@ -562,7 +562,7 @@ void winbindd_lookupsid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, if (domain == NULL) { DEBUG(5, ("Could not find domain for sid %s\n", sid_string_static(sid))); - cont(private, False, NULL, NULL, SID_NAME_UNKNOWN); + cont(private_data, False, NULL, NULL, SID_NAME_UNKNOWN); return; } @@ -571,7 +571,7 @@ void winbindd_lookupsid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, fstrcpy(request.data.sid, sid_string_static(sid)); do_async_domain(mem_ctx, domain, &request, lookupsid_recv, - cont, private); + cont, private_data); } enum winbindd_result winbindd_dual_lookupsid(struct winbindd_domain *domain, @@ -611,7 +611,7 @@ enum winbindd_result winbindd_dual_lookupsid(struct winbindd_domain *domain, static void lookupname_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private) + void *c, void *private_data) { void (*cont)(void *priv, BOOL succ, const DOM_SID *sid, enum SID_NAME_USE type) = c; @@ -619,32 +619,32 @@ static void lookupname_recv(TALLOC_CTX *mem_ctx, BOOL success, if (!success) { DEBUG(5, ("Could not trigger lookup_name\n")); - cont(private, False, NULL, SID_NAME_UNKNOWN); + cont(private_data, False, NULL, SID_NAME_UNKNOWN); return; } if (response->result != WINBINDD_OK) { DEBUG(5, ("lookup_name returned an error\n")); - cont(private, False, NULL, SID_NAME_UNKNOWN); + cont(private_data, False, NULL, SID_NAME_UNKNOWN); return; } if (!string_to_sid(&sid, response->data.sid.sid)) { DEBUG(0, ("Could not convert string %s to sid\n", response->data.sid.sid)); - cont(private, False, NULL, SID_NAME_UNKNOWN); + cont(private_data, False, NULL, SID_NAME_UNKNOWN); return; } - cont(private, True, &sid, response->data.sid.type); + cont(private_data, True, &sid, response->data.sid.type); } void winbindd_lookupname_async(TALLOC_CTX *mem_ctx, const char *dom_name, const char *name, - void (*cont)(void *private, BOOL success, + void (*cont)(void *private_data, BOOL success, const DOM_SID *sid, enum SID_NAME_USE type), - void *private) + void *private_data) { struct winbindd_request request; struct winbindd_domain *domain; @@ -653,7 +653,7 @@ void winbindd_lookupname_async(TALLOC_CTX *mem_ctx, const char *dom_name, if (domain == NULL) { DEBUG(5, ("Could not find domain for name %s\n", dom_name)); - cont(private, False, NULL, SID_NAME_UNKNOWN); + cont(private_data, False, NULL, SID_NAME_UNKNOWN); return; } @@ -663,7 +663,7 @@ void winbindd_lookupname_async(TALLOC_CTX *mem_ctx, const char *dom_name, fstrcpy(request.data.name.name, name); do_async_domain(mem_ctx, domain, &request, lookupname_recv, - cont, private); + cont, private_data); } enum winbindd_result winbindd_dual_lookupname(struct winbindd_domain *domain, @@ -756,7 +756,7 @@ static BOOL parse_sidlist(TALLOC_CTX *mem_ctx, char *sidstr, static void getsidaliases_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private) + void *c, void *private_data) { void (*cont)(void *priv, BOOL succ, DOM_SID *aliases, int num_aliases) = c; @@ -766,13 +766,13 @@ static void getsidaliases_recv(TALLOC_CTX *mem_ctx, BOOL success, if (!success) { DEBUG(5, ("Could not trigger getsidaliases\n")); - cont(private, success, NULL, 0); + cont(private_data, success, NULL, 0); return; } if (response->result != WINBINDD_OK) { DEBUG(5, ("getsidaliases returned an error\n")); - cont(private, False, NULL, 0); + cont(private_data, False, NULL, 0); return; } @@ -780,47 +780,47 @@ static void getsidaliases_recv(TALLOC_CTX *mem_ctx, BOOL success, if (aliases_str == NULL) { DEBUG(10, ("getsidaliases return 0 SIDs\n")); - cont(private, True, NULL, 0); + cont(private_data, True, NULL, 0); return; } if (!parse_sidlist(mem_ctx, aliases_str, &sids, &num_sids)) { DEBUG(0, ("Could not parse sids\n")); - cont(private, False, NULL, 0); + cont(private_data, False, NULL, 0); return; } SAFE_FREE(response->extra_data); - cont(private, True, sids, num_sids); + cont(private_data, True, sids, num_sids); } void winbindd_getsidaliases_async(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, const DOM_SID *sids, int num_sids, - void (*cont)(void *private, + void (*cont)(void *private_data, BOOL success, const DOM_SID *aliases, int num_aliases), - void *private) + void *private_data) { struct winbindd_request request; char *sidstr = NULL; char *keystr; if (num_sids == 0) { - cont(private, True, NULL, 0); + cont(private_data, True, NULL, 0); return; } if (!print_sidlist(mem_ctx, sids, num_sids, &sidstr)) { - cont(private, False, NULL, 0); + cont(private_data, False, NULL, 0); return; } keystr = cache_store_request_data(mem_ctx, sidstr); if (keystr == NULL) { - cont(private, False, NULL, 0); + cont(private_data, False, NULL, 0); return; } @@ -830,7 +830,7 @@ void winbindd_getsidaliases_async(struct winbindd_domain *domain, fstrcpy(request.data.dual_sidaliases.cache_key, keystr); do_async_domain(mem_ctx, domain, &request, getsidaliases_recv, - cont, private); + cont, private_data); } enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain, @@ -912,22 +912,22 @@ struct gettoken_state { struct winbindd_domain *builtin_domain; DOM_SID *sids; int num_sids; - void (*cont)(void *private, BOOL success, DOM_SID *sids, int num_sids); - void *private; + void (*cont)(void *private_data, BOOL success, DOM_SID *sids, int num_sids); + void *private_data; }; static void gettoken_recvdomgroups(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private); -static void gettoken_recvaliases(void *private, BOOL success, + void *c, void *private_data); +static void gettoken_recvaliases(void *private_data, BOOL success, const DOM_SID *aliases, int num_aliases); void winbindd_gettoken_async(TALLOC_CTX *mem_ctx, const DOM_SID *user_sid, - void (*cont)(void *private, BOOL success, + void (*cont)(void *private_data, BOOL success, DOM_SID *sids, int num_sids), - void *private) + void *private_data) { struct winbindd_domain *domain; struct winbindd_request request; @@ -936,7 +936,7 @@ void winbindd_gettoken_async(TALLOC_CTX *mem_ctx, const DOM_SID *user_sid, state = TALLOC_P(mem_ctx, struct gettoken_state); if (state == NULL) { DEBUG(0, ("talloc failed\n")); - cont(private, False, NULL, 0); + cont(private_data, False, NULL, 0); return; } @@ -945,13 +945,13 @@ void winbindd_gettoken_async(TALLOC_CTX *mem_ctx, const DOM_SID *user_sid, state->alias_domain = find_our_domain(); state->builtin_domain = find_builtin_domain(); state->cont = cont; - state->private = private; + state->private_data = private_data; domain = find_domain_from_sid_noinit(user_sid); if (domain == NULL) { DEBUG(5, ("Could not find domain from SID %s\n", sid_string_static(user_sid))); - cont(private, False, NULL, 0); + cont(private_data, False, NULL, 0); return; } @@ -965,15 +965,15 @@ void winbindd_gettoken_async(TALLOC_CTX *mem_ctx, const DOM_SID *user_sid, static void gettoken_recvdomgroups(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private) + void *c, void *private_data) { struct gettoken_state *state = - talloc_get_type_abort(private, struct gettoken_state); + talloc_get_type_abort(private_data, struct gettoken_state); char *sids_str; if (!success) { DEBUG(10, ("Could not get domain groups\n")); - state->cont(state->private, False, NULL, 0); + state->cont(state->private_data, False, NULL, 0); return; } @@ -981,7 +981,7 @@ static void gettoken_recvdomgroups(TALLOC_CTX *mem_ctx, BOOL success, if (sids_str == NULL) { DEBUG(10, ("Received no domain groups\n")); - state->cont(state->private, True, NULL, 0); + state->cont(state->private_data, True, NULL, 0); return; } @@ -994,7 +994,7 @@ static void gettoken_recvdomgroups(TALLOC_CTX *mem_ctx, BOOL success, if (!parse_sidlist(mem_ctx, sids_str, &state->sids, &state->num_sids)) { DEBUG(0, ("Could not parse sids\n")); - state->cont(state->private, False, NULL, 0); + state->cont(state->private_data, False, NULL, 0); return; } @@ -1002,7 +1002,7 @@ static void gettoken_recvdomgroups(TALLOC_CTX *mem_ctx, BOOL success, if (state->alias_domain == NULL) { DEBUG(10, ("Don't expand domain local groups\n")); - state->cont(state->private, True, state->sids, + state->cont(state->private_data, True, state->sids, state->num_sids); return; } @@ -1012,16 +1012,16 @@ static void gettoken_recvdomgroups(TALLOC_CTX *mem_ctx, BOOL success, gettoken_recvaliases, state); } -static void gettoken_recvaliases(void *private, BOOL success, +static void gettoken_recvaliases(void *private_data, BOOL success, const DOM_SID *aliases, int num_aliases) { - struct gettoken_state *state = private; + struct gettoken_state *state = private_data; int i; if (!success) { DEBUG(10, ("Could not receive domain local groups\n")); - state->cont(state->private, False, NULL, 0); + state->cont(state->private_data, False, NULL, 0); return; } @@ -1039,7 +1039,7 @@ static void gettoken_recvaliases(void *private, BOOL success, return; } - state->cont(state->private, True, state->sids, state->num_sids); + state->cont(state->private_data, True, state->sids, state->num_sids); } struct sid2uid_state { @@ -1047,22 +1047,22 @@ struct sid2uid_state { DOM_SID sid; char *username; uid_t uid; - void (*cont)(void *private, BOOL success, uid_t uid); - void *private; + void (*cont)(void *private_data, BOOL success, uid_t uid); + void *private_data; }; -static void sid2uid_lookup_sid_recv(void *private, BOOL success, +static void sid2uid_lookup_sid_recv(void *private_data, BOOL success, const char *dom_name, const char *name, enum SID_NAME_USE type); -static void sid2uid_noalloc_recv(void *private, BOOL success, uid_t uid); -static void sid2uid_alloc_recv(void *private, BOOL success, uid_t uid); -static void sid2uid_name2uid_recv(void *private, BOOL success, uid_t uid); -static void sid2uid_set_mapping_recv(void *private, BOOL success); +static void sid2uid_noalloc_recv(void *private_data, BOOL success, uid_t uid); +static void sid2uid_alloc_recv(void *private_data, BOOL success, uid_t uid); +static void sid2uid_name2uid_recv(void *private_data, BOOL success, uid_t uid); +static void sid2uid_set_mapping_recv(void *private_data, BOOL success); void winbindd_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - void (*cont)(void *private, BOOL success, + void (*cont)(void *private_data, BOOL success, uid_t uid), - void *private) + void *private_data) { struct sid2uid_state *state; NTSTATUS result; @@ -1070,7 +1070,7 @@ void winbindd_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, if (idmap_proxyonly()) { DEBUG(10, ("idmap proxy only\n")); - cont(private, False, 0); + cont(private_data, False, 0); return; } @@ -1079,43 +1079,43 @@ void winbindd_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, result = idmap_sid_to_uid(sid, &uid, ID_QUERY_ONLY|ID_CACHE_ONLY); if (NT_STATUS_IS_OK(result)) { - cont(private, True, uid); + cont(private_data, True, uid); return; } state = TALLOC_P(mem_ctx, struct sid2uid_state); if (state == NULL) { DEBUG(0, ("talloc failed\n")); - cont(private, False, 0); + cont(private_data, False, 0); return; } state->mem_ctx = mem_ctx; state->sid = *sid; state->cont = cont; - state->private = private; + state->private_data = private_data; /* Let's see if it's really a user before allocating a uid */ winbindd_lookupsid_async(mem_ctx, sid, sid2uid_lookup_sid_recv, state); } -static void sid2uid_lookup_sid_recv(void *private, BOOL success, +static void sid2uid_lookup_sid_recv(void *private_data, BOOL success, const char *dom_name, const char *name, enum SID_NAME_USE type) { struct sid2uid_state *state = - talloc_get_type_abort(private, struct sid2uid_state); + talloc_get_type_abort(private_data, struct sid2uid_state); if (!success) { DEBUG(5, ("Could not trigger lookup_sid\n")); - state->cont(state->private, False, 0); + state->cont(state->private_data, False, 0); return; } if ((type != SID_NAME_USER) && (type != SID_NAME_COMPUTER)) { DEBUG(5, ("SID is not a user\n")); - state->cont(state->private, False, 0); + state->cont(state->private_data, False, 0); return; } @@ -1127,15 +1127,15 @@ static void sid2uid_lookup_sid_recv(void *private, BOOL success, sid2uid_noalloc_recv, state); } -static void sid2uid_noalloc_recv(void *private, BOOL success, uid_t uid) +static void sid2uid_noalloc_recv(void *private_data, BOOL success, uid_t uid) { struct sid2uid_state *state = - talloc_get_type_abort(private, struct sid2uid_state); + talloc_get_type_abort(private_data, struct sid2uid_state); if (success) { DEBUG(10, ("found uid for sid %s in remote backend\n", sid_string_static(&state->sid))); - state->cont(state->private, True, uid); + state->cont(state->private_data, True, uid); return; } @@ -1155,30 +1155,30 @@ static void sid2uid_noalloc_recv(void *private, BOOL success, uid_t uid) sid2uid_alloc_recv, state); } -static void sid2uid_alloc_recv(void *private, BOOL success, uid_t uid) +static void sid2uid_alloc_recv(void *private_data, BOOL success, uid_t uid) { struct sid2uid_state *state = - talloc_get_type_abort(private, struct sid2uid_state); + talloc_get_type_abort(private_data, struct sid2uid_state); if (!success) { DEBUG(5, ("Could not allocate uid\n")); - state->cont(state->private, False, 0); + state->cont(state->private_data, False, 0); return; } - state->cont(state->private, True, uid); + state->cont(state->private_data, True, uid); } -static void sid2uid_name2uid_recv(void *private, BOOL success, uid_t uid) +static void sid2uid_name2uid_recv(void *private_data, BOOL success, uid_t uid) { struct sid2uid_state *state = - talloc_get_type_abort(private, struct sid2uid_state); + talloc_get_type_abort(private_data, struct sid2uid_state); unid_t id; if (!success) { DEBUG(5, ("Could not find uid for name %s\n", state->username)); - state->cont(state->private, False, 0); + state->cont(state->private_data, False, 0); return; } @@ -1189,19 +1189,19 @@ static void sid2uid_name2uid_recv(void *private, BOOL success, uid_t uid) sid2uid_set_mapping_recv, state); } -static void sid2uid_set_mapping_recv(void *private, BOOL success) +static void sid2uid_set_mapping_recv(void *private_data, BOOL success) { struct sid2uid_state *state = - talloc_get_type_abort(private, struct sid2uid_state); + talloc_get_type_abort(private_data, struct sid2uid_state); if (!success) { DEBUG(5, ("Could not set ID mapping for sid %s\n", sid_string_static(&state->sid))); - state->cont(state->private, False, 0); + state->cont(state->private_data, False, 0); return; } - state->cont(state->private, True, state->uid); + state->cont(state->private_data, True, state->uid); } struct sid2gid_state { @@ -1209,22 +1209,22 @@ struct sid2gid_state { DOM_SID sid; char *groupname; gid_t gid; - void (*cont)(void *private, BOOL success, gid_t gid); - void *private; + void (*cont)(void *private_data, BOOL success, gid_t gid); + void *private_data; }; -static void sid2gid_lookup_sid_recv(void *private, BOOL success, +static void sid2gid_lookup_sid_recv(void *private_data, BOOL success, const char *dom_name, const char *name, enum SID_NAME_USE type); -static void sid2gid_noalloc_recv(void *private, BOOL success, gid_t gid); -static void sid2gid_alloc_recv(void *private, BOOL success, gid_t gid); -static void sid2gid_name2gid_recv(void *private, BOOL success, gid_t gid); -static void sid2gid_set_mapping_recv(void *private, BOOL success); +static void sid2gid_noalloc_recv(void *private_data, BOOL success, gid_t gid); +static void sid2gid_alloc_recv(void *private_data, BOOL success, gid_t gid); +static void sid2gid_name2gid_recv(void *private_data, BOOL success, gid_t gid); +static void sid2gid_set_mapping_recv(void *private_data, BOOL success); void winbindd_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - void (*cont)(void *private, BOOL success, + void (*cont)(void *private_data, BOOL success, gid_t gid), - void *private) + void *private_data) { struct sid2gid_state *state; NTSTATUS result; @@ -1232,7 +1232,7 @@ void winbindd_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, if (idmap_proxyonly()) { DEBUG(10, ("idmap proxy only\n")); - cont(private, False, 0); + cont(private_data, False, 0); return; } @@ -1241,44 +1241,44 @@ void winbindd_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, result = idmap_sid_to_gid(sid, &gid, ID_QUERY_ONLY|ID_CACHE_ONLY); if (NT_STATUS_IS_OK(result)) { - cont(private, True, gid); + cont(private_data, True, gid); return; } state = TALLOC_P(mem_ctx, struct sid2gid_state); if (state == NULL) { DEBUG(0, ("talloc failed\n")); - cont(private, False, 0); + cont(private_data, False, 0); return; } state->mem_ctx = mem_ctx; state->sid = *sid; state->cont = cont; - state->private = private; + state->private_data = private_data; /* Let's see if it's really a user before allocating a gid */ winbindd_lookupsid_async(mem_ctx, sid, sid2gid_lookup_sid_recv, state); } -static void sid2gid_lookup_sid_recv(void *private, BOOL success, +static void sid2gid_lookup_sid_recv(void *private_data, BOOL success, const char *dom_name, const char *name, enum SID_NAME_USE type) { struct sid2gid_state *state = - talloc_get_type_abort(private, struct sid2gid_state); + talloc_get_type_abort(private_data, struct sid2gid_state); if (!success) { DEBUG(5, ("Could not trigger lookup_sid\n")); - state->cont(state->private, False, 0); + state->cont(state->private_data, False, 0); return; } if (((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) && (type != SID_NAME_WKN_GRP))) { DEBUG(5, ("SID is not a group\n")); - state->cont(state->private, False, 0); + state->cont(state->private_data, False, 0); return; } @@ -1290,15 +1290,15 @@ static void sid2gid_lookup_sid_recv(void *private, BOOL success, sid2gid_noalloc_recv, state); } -static void sid2gid_noalloc_recv(void *private, BOOL success, gid_t gid) +static void sid2gid_noalloc_recv(void *private_data, BOOL success, gid_t gid) { struct sid2gid_state *state = - talloc_get_type_abort(private, struct sid2gid_state); + talloc_get_type_abort(private_data, struct sid2gid_state); if (success) { DEBUG(10, ("found gid for sid %s in remote backend\n", sid_string_static(&state->sid))); - state->cont(state->private, True, gid); + state->cont(state->private_data, True, gid); return; } @@ -1318,30 +1318,30 @@ static void sid2gid_noalloc_recv(void *private, BOOL success, gid_t gid) sid2gid_alloc_recv, state); } -static void sid2gid_alloc_recv(void *private, BOOL success, gid_t gid) +static void sid2gid_alloc_recv(void *private_data, BOOL success, gid_t gid) { struct sid2gid_state *state = - talloc_get_type_abort(private, struct sid2gid_state); + talloc_get_type_abort(private_data, struct sid2gid_state); if (!success) { DEBUG(5, ("Could not allocate gid\n")); - state->cont(state->private, False, 0); + state->cont(state->private_data, False, 0); return; } - state->cont(state->private, True, gid); + state->cont(state->private_data, True, gid); } -static void sid2gid_name2gid_recv(void *private, BOOL success, gid_t gid) +static void sid2gid_name2gid_recv(void *private_data, BOOL success, gid_t gid) { struct sid2gid_state *state = - talloc_get_type_abort(private, struct sid2gid_state); + talloc_get_type_abort(private_data, struct sid2gid_state); unid_t id; if (!success) { DEBUG(5, ("Could not find gid for name %s\n", state->groupname)); - state->cont(state->private, False, 0); + state->cont(state->private_data, False, 0); return; } @@ -1352,52 +1352,56 @@ static void sid2gid_name2gid_recv(void *private, BOOL success, gid_t gid) sid2gid_set_mapping_recv, state); } -static void sid2gid_set_mapping_recv(void *private, BOOL success) +static void sid2gid_set_mapping_recv(void *private_data, BOOL success) { struct sid2gid_state *state = - talloc_get_type_abort(private, struct sid2gid_state); + talloc_get_type_abort(private_data, struct sid2gid_state); if (!success) { DEBUG(5, ("Could not set ID mapping for sid %s\n", sid_string_static(&state->sid))); - state->cont(state->private, False, 0); + state->cont(state->private_data, False, 0); return; } - state->cont(state->private, True, state->gid); + state->cont(state->private_data, True, state->gid); } static void query_user_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, - void *c, void *private) + void *c, void *private_data) { void (*cont)(void *priv, BOOL succ, const char *acct_name, - const char *full_name, uint32 group_rid) = c; + const char *full_name, const char *homedir, + const char *shell, uint32 group_rid) = c; if (!success) { DEBUG(5, ("Could not trigger query_user\n")); - cont(private, False, NULL, NULL, -1); + cont(private_data, False, NULL, NULL, NULL, NULL, -1); return; } - cont(private, True, response->data.user_info.acct_name, + cont(private_data, True, response->data.user_info.acct_name, response->data.user_info.full_name, + response->data.user_info.homedir, + response->data.user_info.shell, response->data.user_info.group_rid); } void query_user_async(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, const DOM_SID *sid, - void (*cont)(void *private, BOOL success, + void (*cont)(void *private_data, BOOL success, const char *acct_name, const char *full_name, + const char *homedir, + const char *shell, uint32 group_rid), - void *private) + void *private_data) { struct winbindd_request request; ZERO_STRUCT(request); request.cmd = WINBINDD_DUAL_USERINFO; sid_to_string(request.data.sid, sid); do_async_domain(mem_ctx, domain, &request, query_user_recv, - cont, private); + cont, private_data); } - diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c index 90ccb43a6ec..730da7a9b52 100644 --- a/source/nsswitch/winbindd_cache.c +++ b/source/nsswitch/winbindd_cache.c @@ -652,6 +652,8 @@ static void wcache_save_user(struct winbindd_domain *domain, NTSTATUS status, WI return; centry_put_string(centry, info->acct_name); centry_put_string(centry, info->full_name); + centry_put_string(centry, info->homedir); + centry_put_string(centry, info->shell); centry_put_sid(centry, &info->user_sid); centry_put_sid(centry, &info->group_sid); centry_end(centry, "U/%s", sid_to_string(sid_string, &info->user_sid)); @@ -689,6 +691,8 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, for (i=0; i<(*num_entries); i++) { (*info)[i].acct_name = centry_string(centry, mem_ctx); (*info)[i].full_name = centry_string(centry, mem_ctx); + (*info)[i].homedir = centry_string(centry, mem_ctx); + (*info)[i].shell = centry_string(centry, mem_ctx); centry_sid(centry, &(*info)[i].user_sid); centry_sid(centry, &(*info)[i].group_sid); } @@ -747,6 +751,8 @@ do_query: for (i=0; i<(*num_entries); i++) { centry_put_string(centry, (*info)[i].acct_name); centry_put_string(centry, (*info)[i].full_name); + centry_put_string(centry, (*info)[i].homedir); + centry_put_string(centry, (*info)[i].shell); centry_put_sid(centry, &(*info)[i].user_sid); centry_put_sid(centry, &(*info)[i].group_sid); if (domain->backend->consistent) { @@ -1082,6 +1088,8 @@ static NTSTATUS query_user(struct winbindd_domain *domain, info->acct_name = centry_string(centry, mem_ctx); info->full_name = centry_string(centry, mem_ctx); + info->homedir = centry_string(centry, mem_ctx); + info->shell = centry_string(centry, mem_ctx); centry_sid(centry, &info->user_sid); centry_sid(centry, &info->group_sid); status = centry->status; diff --git a/source/nsswitch/winbindd_dual.c b/source/nsswitch/winbindd_dual.c index 2b0ce8c14d3..46b3ce2258b 100644 --- a/source/nsswitch/winbindd_dual.c +++ b/source/nsswitch/winbindd_dual.c @@ -259,19 +259,19 @@ struct winbindd_async_request { struct winbindd_child *child; struct winbindd_request *request; struct winbindd_response *response; - void (*continuation)(void *private, BOOL success); - void *private; + void (*continuation)(void *private_data, BOOL success); + void *private_data; }; -static void async_request_sent(void *private, BOOL success); -static void async_reply_recv(void *private, BOOL success); +static void async_request_sent(void *private_data, BOOL success); +static void async_reply_recv(void *private_data, BOOL success); static void schedule_async_request(struct winbindd_child *child); void async_request(TALLOC_CTX *mem_ctx, struct winbindd_child *child, struct winbindd_request *request, struct winbindd_response *response, - void (*continuation)(void *private, BOOL success), - void *private) + void (*continuation)(void *private_data, BOOL success), + void *private_data) { struct winbindd_async_request *state, *tmp; @@ -281,7 +281,7 @@ void async_request(TALLOC_CTX *mem_ctx, struct winbindd_child *child, if (state == NULL) { DEBUG(0, ("talloc failed\n")); - continuation(private, False); + continuation(private_data, False); return; } @@ -290,7 +290,7 @@ void async_request(TALLOC_CTX *mem_ctx, struct winbindd_child *child, state->request = request; state->response = response; state->continuation = continuation; - state->private = private; + state->private_data = private_data; DLIST_ADD_END(child->requests, state, tmp); @@ -299,17 +299,17 @@ void async_request(TALLOC_CTX *mem_ctx, struct winbindd_child *child, return; } -static void async_request_sent(void *private, BOOL success) +static void async_request_sent(void *private_data, BOOL success) { struct winbindd_async_request *state = - talloc_get_type_abort(private, struct winbindd_async_request); + talloc_get_type_abort(private_data, struct winbindd_async_request); if (!success) { DEBUG(5, ("Could not send async request\n")); state->response->length = sizeof(struct winbindd_response); state->response->result = WINBINDD_ERROR; - state->continuation(state->private, False); + state->continuation(state->private_data, False); return; } @@ -321,10 +321,10 @@ static void async_request_sent(void *private, BOOL success) async_reply_recv, state); } -static void async_reply_recv(void *private, BOOL success) +static void async_reply_recv(void *private_data, BOOL success) { struct winbindd_async_request *state = - talloc_get_type_abort(private, struct winbindd_async_request); + talloc_get_type_abort(private_data, struct winbindd_async_request); struct winbindd_child *child = state->child; state->response->length = sizeof(struct winbindd_response); @@ -343,7 +343,7 @@ static void async_reply_recv(void *private, BOOL success) schedule_async_request(child); - state->continuation(state->private, True); + state->continuation(state->private_data, True); } static BOOL fork_domain_child(struct winbindd_child *child); @@ -366,7 +366,7 @@ static void schedule_async_request(struct winbindd_child *child) while (request != NULL) { /* request might be free'd in the continuation */ struct winbindd_async_request *next = request->next; - request->continuation(request->private, False); + request->continuation(request->private_data, False); request = next; } return; @@ -383,31 +383,31 @@ struct domain_request_state { struct winbindd_domain *domain; struct winbindd_request *request; struct winbindd_response *response; - void (*continuation)(void *private, BOOL success); - void *private; + void (*continuation)(void *private_data, BOOL success); + void *private_data; }; -static void domain_init_recv(void *private, BOOL success); +static void domain_init_recv(void *private_data, BOOL success); void async_domain_request(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, struct winbindd_request *request, struct winbindd_response *response, - void (*continuation)(void *private, BOOL success), - void *private) + void (*continuation)(void *private_data, BOOL success), + void *private_data) { struct domain_request_state *state; if (domain->initialized) { async_request(mem_ctx, &domain->child, request, response, - continuation, private); + continuation, private_data); return; } state = TALLOC_P(mem_ctx, struct domain_request_state); if (state == NULL) { DEBUG(0, ("talloc failed\n")); - continuation(private, False); + continuation(private_data, False); return; } @@ -416,15 +416,15 @@ void async_domain_request(TALLOC_CTX *mem_ctx, state->request = request; state->response = response; state->continuation = continuation; - state->private = private; + state->private_data = private_data; init_child_connection(domain, domain_init_recv, state); } -static void recvfrom_child(void *private, BOOL success) +static void recvfrom_child(void *private_data, BOOL success) { struct winbindd_cli_state *state = - talloc_get_type_abort(private, struct winbindd_cli_state); + talloc_get_type_abort(private_data, struct winbindd_cli_state); enum winbindd_result result = state->response.result; /* This is an optimization: The child has written directly to the @@ -456,20 +456,20 @@ void sendto_domain(struct winbindd_cli_state *state, recvfrom_child, state); } -static void domain_init_recv(void *private, BOOL success) +static void domain_init_recv(void *private_data, BOOL success) { struct domain_request_state *state = - talloc_get_type_abort(private, struct domain_request_state); + talloc_get_type_abort(private_data, struct domain_request_state); if (!success) { DEBUG(5, ("Domain init returned an error\n")); - state->continuation(state->private, False); + state->continuation(state->private_data, False); return; } async_request(state->mem_ctx, &state->domain->child, state->request, state->response, - state->continuation, state->private); + state->continuation, state->private_data); } struct winbindd_child_dispatch_table { diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c index 2751f06815f..eb2adde98bd 100644 --- a/source/nsswitch/winbindd_group.c +++ b/source/nsswitch/winbindd_group.c @@ -375,7 +375,7 @@ void winbindd_getgrgid(struct winbindd_cli_state *state) /* "Rewind" file pointer for group database enumeration */ -void winbindd_setgrent(struct winbindd_cli_state *state) +static BOOL winbindd_setgrent_internal(struct winbindd_cli_state *state) { struct winbindd_domain *domain; @@ -384,8 +384,7 @@ void winbindd_setgrent(struct winbindd_cli_state *state) /* Check user has enabled this */ if (!lp_winbind_enum_groups()) { - request_error(state); - return; + return False; } /* Free old static data if it exists */ @@ -413,8 +412,7 @@ void winbindd_setgrent(struct winbindd_cli_state *state) if ((domain_state = SMB_MALLOC_P(struct getent_state)) == NULL) { DEBUG(1, ("winbindd_setgrent: malloc failed for domain_state!\n")); - request_error(state); - return; + return False; } ZERO_STRUCTP(domain_state); @@ -427,7 +425,16 @@ void winbindd_setgrent(struct winbindd_cli_state *state) } state->getgrent_initialized = True; - request_ok(state); + return True; +} + +void winbindd_setgrent(struct winbindd_cli_state *state) +{ + if (winbindd_setgrent_internal(state)) { + request_ok(state); + } else { + request_error(state); + } } /* Close file pointer to ntdom group database */ @@ -592,7 +599,7 @@ void winbindd_getgrent(struct winbindd_cli_state *state) group_list = (struct winbindd_gr *)state->response.extra_data; if (!state->getgrent_initialized) - winbindd_setgrent(state); + winbindd_setgrent_internal(state); if (!(ent = state->getgrent_state)) { request_error(state); @@ -898,11 +905,11 @@ struct getgroups_state { int num_token_gids; }; -static void getgroups_usersid_recv(void *private, BOOL success, +static void getgroups_usersid_recv(void *private_data, BOOL success, const DOM_SID *sid, enum SID_NAME_USE type); -static void getgroups_tokensids_recv(void *private, BOOL success, +static void getgroups_tokensids_recv(void *private_data, BOOL success, DOM_SID *token_sids, int num_token_sids); -static void getgroups_sid2gid_recv(void *private, BOOL success, gid_t gid); +static void getgroups_sid2gid_recv(void *private_data, BOOL success, gid_t gid); void winbindd_getgroups(struct winbindd_cli_state *state) { @@ -960,10 +967,10 @@ void winbindd_getgroups(struct winbindd_cli_state *state) getgroups_usersid_recv, s); } -static void getgroups_usersid_recv(void *private, BOOL success, +static void getgroups_usersid_recv(void *private_data, BOOL success, const DOM_SID *sid, enum SID_NAME_USE type) { - struct getgroups_state *s = private; + struct getgroups_state *s = private_data; if ((!success) || ((type != SID_NAME_USER) && (type != SID_NAME_COMPUTER))) { @@ -977,10 +984,10 @@ static void getgroups_usersid_recv(void *private, BOOL success, getgroups_tokensids_recv, s); } -static void getgroups_tokensids_recv(void *private, BOOL success, +static void getgroups_tokensids_recv(void *private_data, BOOL success, DOM_SID *token_sids, int num_token_sids) { - struct getgroups_state *s = private; + struct getgroups_state *s = private_data; /* We need at least the user sid and the primary group in the token, * otherwise it's an error */ @@ -1000,9 +1007,9 @@ static void getgroups_tokensids_recv(void *private, BOOL success, getgroups_sid2gid_recv(s, False, 0); } -static void getgroups_sid2gid_recv(void *private, BOOL success, gid_t gid) +static void getgroups_sid2gid_recv(void *private_data, BOOL success, gid_t gid) { - struct getgroups_state *s = private; + struct getgroups_state *s = private_data; if (success) add_gid_to_array_unique(NULL, gid, @@ -1041,7 +1048,7 @@ static void getgroups_sid2gid_recv(void *private, BOOL success, gid_t gid) results. */ -static void getusersids_recv(void *private, BOOL success, DOM_SID *sids, +static void getusersids_recv(void *private_data, BOOL success, DOM_SID *sids, int num_sids); void winbindd_getusersids(struct winbindd_cli_state *state) @@ -1069,10 +1076,10 @@ void winbindd_getusersids(struct winbindd_cli_state *state) state); } -static void getusersids_recv(void *private, BOOL success, DOM_SID *sids, +static void getusersids_recv(void *private_data, BOOL success, DOM_SID *sids, int num_sids) { - struct winbindd_cli_state *state = private; + struct winbindd_cli_state *state = private_data; char *ret = NULL; unsigned ofs, ret_size = 0; int i; diff --git a/source/nsswitch/winbindd_misc.c b/source/nsswitch/winbindd_misc.c index 7a02c8f6293..6f72a0e2c63 100644 --- a/source/nsswitch/winbindd_misc.c +++ b/source/nsswitch/winbindd_misc.c @@ -219,7 +219,7 @@ struct sequence_state { char *extra_data; }; -static void sequence_recv(void *private, BOOL success); +static void sequence_recv(void *private_data, BOOL success); void winbindd_show_sequence(struct winbindd_cli_state *state) { @@ -279,9 +279,9 @@ void winbindd_show_sequence(struct winbindd_cli_state *state) sequence_recv, seq); } -static void sequence_recv(void *private, BOOL success) +static void sequence_recv(void *private_data, BOOL success) { - struct sequence_state *state = private; + struct sequence_state *state = private_data; uint32 seq = DOM_SEQUENCE_NONE; if ((success) && (state->response->result == WINBINDD_OK)) @@ -345,7 +345,7 @@ struct domain_info_state { struct winbindd_cli_state *cli_state; }; -static void domain_info_init_recv(void *private, BOOL success); +static void domain_info_init_recv(void *private_data, BOOL success); void winbindd_domain_info(struct winbindd_cli_state *state) { @@ -400,9 +400,9 @@ void winbindd_domain_info(struct winbindd_cli_state *state) request_ok(state); } -static void domain_info_init_recv(void *private, BOOL success) +static void domain_info_init_recv(void *private_data, BOOL success) { - struct domain_info_state *istate = private; + struct domain_info_state *istate = private_data; struct winbindd_cli_state *state = istate->cli_state; struct winbindd_domain *domain = istate->domain; diff --git a/source/nsswitch/winbindd_nss.h b/source/nsswitch/winbindd_nss.h index b249b62d69e..cf0fae74a06 100644 --- a/source/nsswitch/winbindd_nss.h +++ b/source/nsswitch/winbindd_nss.h @@ -322,6 +322,8 @@ struct winbindd_response { struct { fstring acct_name; fstring full_name; + fstring homedir; + fstring shell; uint32 group_rid; } user_info; } data; diff --git a/source/nsswitch/winbindd_rpc.c b/source/nsswitch/winbindd_rpc.c index 2b4c020d889..63e24877008 100644 --- a/source/nsswitch/winbindd_rpc.c +++ b/source/nsswitch/winbindd_rpc.c @@ -101,6 +101,8 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, (*info)[i].acct_name = talloc_strdup(mem_ctx, username ); (*info)[i].full_name = talloc_strdup(mem_ctx, fullname ); + (*info)[i].homedir = NULL; + (*info)[i].shell = NULL; sid_compose(&(*info)[i].user_sid, &domain->sid, rid); /* For the moment we set the primary group for @@ -352,7 +354,10 @@ static NTSTATUS query_user(struct winbindd_domain *domain, &user->uni_user_name); user_info->full_name = unistr2_tdup(mem_ctx, &user->uni_full_name); - + + user_info->homedir = NULL; + user_info->shell = NULL; + SAFE_FREE(user); return NT_STATUS_OK; @@ -388,6 +393,8 @@ static NTSTATUS query_user(struct winbindd_domain *domain, &ctr->info.id21->uni_user_name); user_info->full_name = unistr2_tdup(mem_ctx, &ctr->info.id21->uni_full_name); + user_info->homedir = NULL; + user_info->shell = NULL; return NT_STATUS_OK; } diff --git a/source/nsswitch/winbindd_sid.c b/source/nsswitch/winbindd_sid.c index 9bad2a6d414..2685e98555c 100644 --- a/source/nsswitch/winbindd_sid.c +++ b/source/nsswitch/winbindd_sid.c @@ -28,7 +28,7 @@ /* Convert a string */ -static void lookupsid_recv(void *private, BOOL success, +static void lookupsid_recv(void *private_data, BOOL success, const char *dom_name, const char *name, enum SID_NAME_USE type); @@ -51,12 +51,12 @@ void winbindd_lookupsid(struct winbindd_cli_state *state) winbindd_lookupsid_async(state->mem_ctx, &sid, lookupsid_recv, state); } -static void lookupsid_recv(void *private, BOOL success, +static void lookupsid_recv(void *private_data, BOOL success, const char *dom_name, const char *name, enum SID_NAME_USE type) { struct winbindd_cli_state *state = - talloc_get_type_abort(private, struct winbindd_cli_state); + talloc_get_type_abort(private_data, struct winbindd_cli_state); if (!success) { DEBUG(5, ("lookupsid returned an error\n")); @@ -74,7 +74,7 @@ static void lookupsid_recv(void *private, BOOL success, * Look up the SID for a qualified name. **/ -static void lookupname_recv(void *private, BOOL success, +static void lookupname_recv(void *private_data, BOOL success, const DOM_SID *sid, enum SID_NAME_USE type); void winbindd_lookupname(struct winbindd_cli_state *state) @@ -106,11 +106,11 @@ void winbindd_lookupname(struct winbindd_cli_state *state) lookupname_recv, state); } -static void lookupname_recv(void *private, BOOL success, +static void lookupname_recv(void *private_data, BOOL success, const DOM_SID *sid, enum SID_NAME_USE type) { struct winbindd_cli_state *state = - talloc_get_type_abort(private, struct winbindd_cli_state); + talloc_get_type_abort(private_data, struct winbindd_cli_state); if (!success) { DEBUG(5, ("lookupname returned an error\n")); @@ -139,7 +139,7 @@ struct winbindd_child *idmap_child(void) /* Convert a sid to a uid. We assume we only have one rid attached to the sid. */ -static void sid2uid_recv(void *private, BOOL success, uid_t uid); +static void sid2uid_recv(void *private_data, BOOL success, uid_t uid); void winbindd_sid_to_uid(struct winbindd_cli_state *state) { @@ -178,10 +178,10 @@ void winbindd_sid_to_uid(struct winbindd_cli_state *state) winbindd_sid2uid_async(state->mem_ctx, &sid, sid2uid_recv, state); } -static void sid2uid_recv(void *private, BOOL success, uid_t uid) +static void sid2uid_recv(void *private_data, BOOL success, uid_t uid) { struct winbindd_cli_state *state = - talloc_get_type_abort(private, struct winbindd_cli_state); + talloc_get_type_abort(private_data, struct winbindd_cli_state); if (!success) { DEBUG(5, ("Could not convert sid %s\n", @@ -197,7 +197,7 @@ static void sid2uid_recv(void *private, BOOL success, uid_t uid) /* Convert a sid to a gid. We assume we only have one rid attached to the sid.*/ -static void sid2gid_recv(void *private, BOOL success, gid_t gid); +static void sid2gid_recv(void *private_data, BOOL success, gid_t gid); void winbindd_sid_to_gid(struct winbindd_cli_state *state) { @@ -236,10 +236,10 @@ void winbindd_sid_to_gid(struct winbindd_cli_state *state) winbindd_sid2gid_async(state->mem_ctx, &sid, sid2gid_recv, state); } -static void sid2gid_recv(void *private, BOOL success, gid_t gid) +static void sid2gid_recv(void *private_data, BOOL success, gid_t gid) { struct winbindd_cli_state *state = - talloc_get_type_abort(private, struct winbindd_cli_state); + talloc_get_type_abort(private_data, struct winbindd_cli_state); if (!success) { DEBUG(5, ("Could not convert sid %s\n", @@ -262,12 +262,12 @@ struct uid2sid_state { enum SID_NAME_USE type; }; -static void uid2sid_uid2name_recv(void *private, BOOL success, +static void uid2sid_uid2name_recv(void *private_data, BOOL success, const char *username); -static void uid2sid_lookupname_recv(void *private, BOOL success, +static void uid2sid_lookupname_recv(void *private_data, BOOL success, const DOM_SID *sid, enum SID_NAME_USE type); -static void uid2sid_idmap_set_mapping_recv(void *private, BOOL success); +static void uid2sid_idmap_set_mapping_recv(void *private_data, BOOL success); void winbindd_uid_to_sid(struct winbindd_cli_state *state) { @@ -326,11 +326,11 @@ void winbindd_uid_to_sid(struct winbindd_cli_state *state) uid2sid_uid2name_recv, uid2sid_state); } -static void uid2sid_uid2name_recv(void *private, BOOL success, +static void uid2sid_uid2name_recv(void *private_data, BOOL success, const char *username) { struct uid2sid_state *state = - talloc_get_type_abort(private, struct uid2sid_state); + talloc_get_type_abort(private_data, struct uid2sid_state); DEBUG(10, ("uid2sid: uid %lu has name %s\n", (unsigned long)state->uid, username)); @@ -347,11 +347,11 @@ static void uid2sid_uid2name_recv(void *private, BOOL success, uid2sid_lookupname_recv, state); } -static void uid2sid_lookupname_recv(void *private, BOOL success, +static void uid2sid_lookupname_recv(void *private_data, BOOL success, const DOM_SID *sid, enum SID_NAME_USE type) { struct uid2sid_state *state = - talloc_get_type_abort(private, struct uid2sid_state); + talloc_get_type_abort(private_data, struct uid2sid_state); unid_t id; if ((!success) || (type != SID_NAME_USER)) { @@ -367,10 +367,10 @@ static void uid2sid_lookupname_recv(void *private, BOOL success, uid2sid_idmap_set_mapping_recv, state ); } -static void uid2sid_idmap_set_mapping_recv(void *private, BOOL success) +static void uid2sid_idmap_set_mapping_recv(void *private_data, BOOL success) { struct uid2sid_state *state = - talloc_get_type_abort(private, struct uid2sid_state); + talloc_get_type_abort(private_data, struct uid2sid_state); /* don't fail if we can't store it */ @@ -389,12 +389,12 @@ struct gid2sid_state { enum SID_NAME_USE type; }; -static void gid2sid_gid2name_recv(void *private, BOOL success, +static void gid2sid_gid2name_recv(void *private_data, BOOL success, const char *groupname); -static void gid2sid_lookupname_recv(void *private, BOOL success, +static void gid2sid_lookupname_recv(void *private_data, BOOL success, const DOM_SID *sid, enum SID_NAME_USE type); -static void gid2sid_idmap_set_mapping_recv(void *private, BOOL success); +static void gid2sid_idmap_set_mapping_recv(void *private_data, BOOL success); void winbindd_gid_to_sid(struct winbindd_cli_state *state) { @@ -453,11 +453,11 @@ void winbindd_gid_to_sid(struct winbindd_cli_state *state) gid2sid_gid2name_recv, gid2sid_state); } -static void gid2sid_gid2name_recv(void *private, BOOL success, +static void gid2sid_gid2name_recv(void *private_data, BOOL success, const char *username) { struct gid2sid_state *state = - talloc_get_type_abort(private, struct gid2sid_state); + talloc_get_type_abort(private_data, struct gid2sid_state); DEBUG(10, ("gid2sid: gid %lu has name %s\n", (unsigned long)state->gid, username)); @@ -474,11 +474,11 @@ static void gid2sid_gid2name_recv(void *private, BOOL success, gid2sid_lookupname_recv, state); } -static void gid2sid_lookupname_recv(void *private, BOOL success, +static void gid2sid_lookupname_recv(void *private_data, BOOL success, const DOM_SID *sid, enum SID_NAME_USE type) { struct gid2sid_state *state = - talloc_get_type_abort(private, struct gid2sid_state); + talloc_get_type_abort(private_data, struct gid2sid_state); unid_t id; if ((!success) || @@ -495,9 +495,9 @@ static void gid2sid_lookupname_recv(void *private, BOOL success, gid2sid_idmap_set_mapping_recv, state ); } -static void gid2sid_idmap_set_mapping_recv(void *private, BOOL success) +static void gid2sid_idmap_set_mapping_recv(void *private_data, BOOL success) { - struct gid2sid_state *state = private; + struct gid2sid_state *state = private_data; /* don't fail if we can't store it */ diff --git a/source/nsswitch/winbindd_user.c b/source/nsswitch/winbindd_user.c index 55b63a81827..ab5da3edd06 100644 --- a/source/nsswitch/winbindd_user.c +++ b/source/nsswitch/winbindd_user.c @@ -30,15 +30,50 @@ extern userdom_struct current_user_info; +static BOOL fillup_pw_field(const char *lp_template, + const char *username, + const char *domname, + uid_t uid, + gid_t gid, + const char *in, + fstring out) +{ + char *templ; + + if (out == NULL) + return False; + + if (in && !strequal(in,"") && lp_security() == SEC_ADS && use_nss_info("sfu")) { + safe_strcpy(out, in, sizeof(fstring) - 1); + return True; + } + + /* Home directory and shell - use template config parameters. The + defaults are /tmp for the home directory and /bin/false for + shell. */ + + /* The substitution of %U and %D in the 'template homedir' is done + by alloc_sub_specified() below. */ + + templ = alloc_sub_specified(lp_template, username, domname, uid, gid); + + if (!templ) + return False; + + safe_strcpy(out, templ, sizeof(fstring) - 1); + SAFE_FREE(templ); + + return True; + +} /* Fill a pwent structure with information we have obtained */ static BOOL winbindd_fill_pwent(char *dom_name, char *user_name, DOM_SID *user_sid, DOM_SID *group_sid, - char *full_name, struct winbindd_pw *pw) + char *full_name, char *homedir, char *shell, + struct winbindd_pw *pw) { fstring output_username; - char *homedir; - char *shell; fstring sid_string; if (!pw || !dom_name || !user_name) @@ -79,25 +114,14 @@ static BOOL winbindd_fill_pwent(char *dom_name, char *user_name, fstrcpy(current_user_info.domain, dom_name); - homedir = alloc_sub_specified(lp_template_homedir(), user_name, dom_name, pw->pw_uid, pw->pw_gid); - - if (!homedir) + if (!fillup_pw_field(lp_template_homedir(), user_name, dom_name, + pw->pw_uid, pw->pw_gid, homedir, pw->pw_dir)) return False; - - safe_strcpy(pw->pw_dir, homedir, sizeof(pw->pw_dir) - 1); - - SAFE_FREE(homedir); - - shell = alloc_sub_specified(lp_template_shell(), user_name, dom_name, pw->pw_uid, pw->pw_gid); - if (!shell) + if (!fillup_pw_field(lp_template_shell(), user_name, dom_name, + pw->pw_uid, pw->pw_gid, shell, pw->pw_shell)) return False; - safe_strcpy(pw->pw_shell, shell, - sizeof(pw->pw_shell) - 1); - - SAFE_FREE(shell); - /* Password - set to "x" as we can't generate anything useful here. Authentication can be done using the pam_winbind module. */ @@ -136,6 +160,8 @@ enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain, fstrcpy(state->response.data.user_info.acct_name, user_info.acct_name); fstrcpy(state->response.data.user_info.full_name, user_info.full_name); + fstrcpy(state->response.data.user_info.homedir, user_info.homedir); + fstrcpy(state->response.data.user_info.shell, user_info.shell); if (!sid_peek_check_rid(&domain->sid, &user_info.group_sid, &state->response.data.user_info.group_rid)) { DEBUG(1, ("Could not extract group rid out of %s\n", @@ -151,17 +177,22 @@ struct getpwsid_state { struct winbindd_domain *domain; char *username; char *fullname; + char *homedir; + char *shell; DOM_SID user_sid; uid_t uid; DOM_SID group_sid; gid_t gid; }; -static void getpwsid_queryuser_recv(void *private, BOOL success, +static void getpwsid_queryuser_recv(void *private_data, BOOL success, const char *acct_name, - const char *full_name, uint32 group_rid); -static void getpwsid_sid2uid_recv(void *private, BOOL success, uid_t uid); -static void getpwsid_sid2gid_recv(void *private, BOOL success, gid_t gid); + const char *full_name, + const char *homedir, + const char *shell, + uint32 group_rid); +static void getpwsid_sid2uid_recv(void *private_data, BOOL success, uid_t uid); +static void getpwsid_sid2gid_recv(void *private_data, BOOL success, gid_t gid); static void winbindd_getpwsid(struct winbindd_cli_state *state, const DOM_SID *sid) @@ -192,12 +223,15 @@ static void winbindd_getpwsid(struct winbindd_cli_state *state, request_error(state); } -static void getpwsid_queryuser_recv(void *private, BOOL success, +static void getpwsid_queryuser_recv(void *private_data, BOOL success, const char *acct_name, - const char *full_name, uint32 group_rid) + const char *full_name, + const char *homedir, + const char *shell, + uint32 group_rid) { struct getpwsid_state *s = - talloc_get_type_abort(private, struct getpwsid_state); + talloc_get_type_abort(private_data, struct getpwsid_state); if (!success) { DEBUG(5, ("Could not query user %s\\%s\n", s->domain->name, @@ -208,6 +242,8 @@ static void getpwsid_queryuser_recv(void *private, BOOL success, s->username = talloc_strdup(s->state->mem_ctx, acct_name); s->fullname = talloc_strdup(s->state->mem_ctx, full_name); + s->homedir = talloc_strdup(s->state->mem_ctx, homedir); + s->shell = talloc_strdup(s->state->mem_ctx, shell); sid_copy(&s->group_sid, &s->domain->sid); sid_append_rid(&s->group_sid, group_rid); @@ -215,10 +251,10 @@ static void getpwsid_queryuser_recv(void *private, BOOL success, getpwsid_sid2uid_recv, s); } -static void getpwsid_sid2uid_recv(void *private, BOOL success, uid_t uid) +static void getpwsid_sid2uid_recv(void *private_data, BOOL success, uid_t uid) { struct getpwsid_state *s = - talloc_get_type_abort(private, struct getpwsid_state); + talloc_get_type_abort(private_data, struct getpwsid_state); if (!success) { DEBUG(5, ("Could not query user's %s\\%s uid\n", @@ -232,14 +268,12 @@ static void getpwsid_sid2uid_recv(void *private, BOOL success, uid_t uid) getpwsid_sid2gid_recv, s); } -static void getpwsid_sid2gid_recv(void *private, BOOL success, gid_t gid) +static void getpwsid_sid2gid_recv(void *private_data, BOOL success, gid_t gid) { struct getpwsid_state *s = - talloc_get_type_abort(private, struct getpwsid_state); + talloc_get_type_abort(private_data, struct getpwsid_state); struct winbindd_pw *pw; fstring output_username; - char *homedir; - char *shell; if (!success) { DEBUG(5, ("Could not query user's %s\\%s\n gid", @@ -256,32 +290,19 @@ static void getpwsid_sid2gid_recv(void *private, BOOL success, gid_t gid) safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1); safe_strcpy(pw->pw_gecos, s->fullname, sizeof(pw->pw_gecos) - 1); - /* Home directory and shell - use template config parameters. The - defaults are /tmp for the home directory and /bin/false for - shell. */ - - /* The substitution of %U and %D in the 'template homedir' is done - by alloc_sub_specified() below. */ - fstrcpy(current_user_info.domain, s->domain->name); - homedir = alloc_sub_specified(lp_template_homedir(), s->username, - s->domain->name, pw->pw_uid, pw->pw_gid); - if (homedir == NULL) { + if (!fillup_pw_field(lp_template_homedir(), s->username, s->domain->name, + pw->pw_uid, pw->pw_gid, s->homedir, pw->pw_dir)) { DEBUG(5, ("Could not compose homedir\n")); goto failed; } - safe_strcpy(pw->pw_dir, homedir, sizeof(pw->pw_dir) - 1); - SAFE_FREE(homedir); - - shell = alloc_sub_specified(lp_template_shell(), s->username, - s->domain->name, pw->pw_uid, pw->pw_gid); - if (shell == NULL) { + + if (!fillup_pw_field(lp_template_shell(), s->username, s->domain->name, + pw->pw_uid, pw->pw_gid, s->shell, pw->pw_shell)) { DEBUG(5, ("Could not compose shell\n")); goto failed; } - safe_strcpy(pw->pw_shell, shell, sizeof(pw->pw_shell) - 1); - SAFE_FREE(shell); /* Password - set to "x" as we can't generate anything useful here. Authentication can be done using the pam_winbind module. */ @@ -297,7 +318,7 @@ static void getpwsid_sid2gid_recv(void *private, BOOL success, gid_t gid) /* Return a password structure from a username. */ -static void getpwnam_name2sid_recv(void *private, BOOL success, +static void getpwnam_name2sid_recv(void *private_data, BOOL success, const DOM_SID *sid, enum SID_NAME_USE type); void winbindd_getpwnam(struct winbindd_cli_state *state) @@ -343,10 +364,10 @@ void winbindd_getpwnam(struct winbindd_cli_state *state) getpwnam_name2sid_recv, state); } -static void getpwnam_name2sid_recv(void *private, BOOL success, +static void getpwnam_name2sid_recv(void *private_data, BOOL success, const DOM_SID *sid, enum SID_NAME_USE type) { - struct winbindd_cli_state *state = private; + struct winbindd_cli_state *state = private_data; if (!success) { DEBUG(5, ("Could not lookup name for user %s\n", @@ -401,7 +422,7 @@ void winbindd_getpwuid(struct winbindd_cli_state *state) /* Rewind file pointer for ntdom passwd database */ -void winbindd_setpwent(struct winbindd_cli_state *state) +static BOOL winbindd_setpwent_internal(struct winbindd_cli_state *state) { struct winbindd_domain *domain; @@ -410,8 +431,7 @@ void winbindd_setpwent(struct winbindd_cli_state *state) /* Check user has enabled this */ if (!lp_winbind_enum_users()) { - request_error(state); - return; + return False; } /* Free old static data if it exists */ @@ -425,7 +445,7 @@ void winbindd_setpwent(struct winbindd_cli_state *state) /* add any local users we have */ if ( (domain_state = (struct getent_state *)malloc(sizeof(struct getent_state))) == NULL ) - return WINBINDD_ERROR; + return False; ZERO_STRUCTP(domain_state); @@ -453,8 +473,7 @@ void winbindd_setpwent(struct winbindd_cli_state *state) if ((domain_state = SMB_MALLOC_P(struct getent_state)) == NULL) { DEBUG(0, ("malloc failed\n")); - request_error(state); - return; + return False; } ZERO_STRUCTP(domain_state); @@ -467,7 +486,16 @@ void winbindd_setpwent(struct winbindd_cli_state *state) } state->getpwent_initialized = True; - request_ok(state); + return True; +} + +void winbindd_setpwent(struct winbindd_cli_state *state) +{ + if (winbindd_setpwent_internal(state)) { + request_ok(state); + } else { + request_error(state); + } } /* Close file pointer to ntdom passwd database */ @@ -548,7 +576,20 @@ static BOOL get_sam_user_entries(struct getent_state *ent, TALLOC_CTX *mem_ctx) fstrcpy(name_list[ent->num_sam_entries + i].gecos, info[i].full_name); } - + if (!info[i].homedir) { + fstrcpy(name_list[ent->num_sam_entries + i].homedir, ""); + } else { + fstrcpy(name_list[ent->num_sam_entries + i].homedir, + info[i].homedir); + } + if (!info[i].shell) { + fstrcpy(name_list[ent->num_sam_entries + i].shell, ""); + } else { + fstrcpy(name_list[ent->num_sam_entries + i].shell, + info[i].shell); + } + + /* User and group ids */ sid_copy(&name_list[ent->num_sam_entries+i].user_sid, &info[i].user_sid); @@ -603,7 +644,7 @@ void winbindd_getpwent(struct winbindd_cli_state *state) user_list = (struct winbindd_pw *)state->response.extra_data; if (!state->getpwent_initialized) - winbindd_setpwent(state); + winbindd_setpwent_internal(state); if (!(ent = state->getpwent_state)) { request_error(state); @@ -651,6 +692,8 @@ void winbindd_getpwent(struct winbindd_cli_state *state) &name_list[ent->sam_entry_index].user_sid, &name_list[ent->sam_entry_index].group_sid, name_list[ent->sam_entry_index].gecos, + name_list[ent->sam_entry_index].homedir, + name_list[ent->sam_entry_index].shell, &user_list[user_list_ndx]); ent->sam_entry_index++; diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c index 21ae4611c25..2be1520250a 100644 --- a/source/nsswitch/winbindd_util.c +++ b/source/nsswitch/winbindd_util.c @@ -177,7 +177,7 @@ struct trustdom_state { struct winbindd_response *response; }; -static void trustdom_recv(void *private, BOOL success); +static void trustdom_recv(void *private_data, BOOL success); static void add_trusted_domains( struct winbindd_domain *domain ) { @@ -213,11 +213,11 @@ static void add_trusted_domains( struct winbindd_domain *domain ) trustdom_recv, state); } -static void trustdom_recv(void *private, BOOL success) +static void trustdom_recv(void *private_data, BOOL success) { extern struct winbindd_methods cache_methods; struct trustdom_state *state = - talloc_get_type_abort(private, struct trustdom_state); + talloc_get_type_abort(private_data, struct trustdom_state); struct winbindd_response *response = state->response; char *p; @@ -311,17 +311,17 @@ struct init_child_state { struct winbindd_domain *domain; struct winbindd_request *request; struct winbindd_response *response; - void (*continuation)(void *private, BOOL success); - void *private; + void (*continuation)(void *private_data, BOOL success); + void *private_data; }; -static void init_child_recv(void *private, BOOL success); -static void init_child_getdc_recv(void *private, BOOL success); +static void init_child_recv(void *private_data, BOOL success); +static void init_child_getdc_recv(void *private_data, BOOL success); enum winbindd_result init_child_connection(struct winbindd_domain *domain, - void (*continuation)(void *private, + void (*continuation)(void *private_data, BOOL success), - void *private) + void *private_data) { TALLOC_CTX *mem_ctx; struct winbindd_request *request; @@ -340,7 +340,7 @@ enum winbindd_result init_child_connection(struct winbindd_domain *domain, if ((request == NULL) || (response == NULL) || (state == NULL)) { DEBUG(0, ("talloc failed\n")); - continuation(private, False); + continuation(private_data, False); return WINBINDD_ERROR; } @@ -351,7 +351,7 @@ enum winbindd_result init_child_connection(struct winbindd_domain *domain, state->request = request; state->response = response; state->continuation = continuation; - state->private = private; + state->private_data = private_data; if (domain->primary) { /* The primary domain has to find the DC name itself */ @@ -376,10 +376,10 @@ enum winbindd_result init_child_connection(struct winbindd_domain *domain, return WINBINDD_PENDING; } -static void init_child_getdc_recv(void *private, BOOL success) +static void init_child_getdc_recv(void *private_data, BOOL success) { struct init_child_state *state = - talloc_get_type_abort(private, struct init_child_state); + talloc_get_type_abort(private_data, struct init_child_state); const char *dcname = ""; DEBUG(10, ("Received getdcname response\n")); @@ -398,17 +398,17 @@ static void init_child_getdc_recv(void *private, BOOL success) init_child_recv, state); } -static void init_child_recv(void *private, BOOL success) +static void init_child_recv(void *private_data, BOOL success) { struct init_child_state *state = - talloc_get_type_abort(private, struct init_child_state); + talloc_get_type_abort(private_data, struct init_child_state); DEBUG(5, ("Received child initialization response for domain %s\n", state->domain->name)); if ((!success) || (state->response->result != WINBINDD_OK)) { DEBUG(3, ("Could not init child\n")); - state->continuation(state->private, False); + state->continuation(state->private_data, False); talloc_destroy(state->mem_ctx); return; } @@ -429,7 +429,7 @@ static void init_child_recv(void *private, BOOL success) state->domain->initialized = 1; if (state->continuation != NULL) - state->continuation(state->private, True); + state->continuation(state->private_data, True); talloc_destroy(state->mem_ctx); } diff --git a/source/nsswitch/winbindd_wins.c b/source/nsswitch/winbindd_wins.c index 2e03becd5af..2cb835b3733 100644 --- a/source/nsswitch/winbindd_wins.c +++ b/source/nsswitch/winbindd_wins.c @@ -65,12 +65,12 @@ static int wins_lookup_open_socket_in(void) } -static struct node_status *lookup_byaddr_backend(char *addr, int *count) +static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count) { int fd; struct in_addr ip; struct nmb_name nname; - struct node_status *status; + NODE_STATUS_STRUCT *status; fd = wins_lookup_open_socket_in(); if (fd == -1) @@ -136,7 +136,7 @@ void winbindd_wins_byip(struct winbindd_cli_state *state) { fstring response; int i, count, maxlen, size; - struct node_status *status; + NODE_STATUS_STRUCT *status; /* Ensure null termination */ state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0'; diff --git a/source/nsswitch/wins.c b/source/nsswitch/wins.c index 8d26fc52971..6d4f6cfa264 100644 --- a/source/nsswitch/wins.c +++ b/source/nsswitch/wins.c @@ -128,12 +128,12 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count) #ifdef HAVE_NS_API_H -static struct node_status *lookup_byaddr_backend(char *addr, int *count) +static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count) { int fd; struct in_addr ip; struct nmb_name nname; - struct node_status *status; + NODE_STATUS_STRUCT *status; if (!initialised) { nss_wins_init(); @@ -166,7 +166,7 @@ int lookup(nsd_file_t *rq) char *key; char *addr; struct in_addr *ip_list; - struct node_status *status; + NODE_STATUS_STRUCT *status; int i, count, len, size; char response[1024]; BOOL found = False; diff --git a/source/pam_smbpass/support.c b/source/pam_smbpass/support.c index f5682480eba..82d51103d26 100644 --- a/source/pam_smbpass/support.c +++ b/source/pam_smbpass/support.c @@ -232,23 +232,23 @@ void _cleanup( pam_handle_t * pamh, void *x, int error_status ) */ char * smbpXstrDup( const char *x ) { - register char *new = NULL; + register char *newstr = NULL; if (x != NULL) { register int i; for (i = 0; x[i]; ++i); /* length of string */ - if ((new = SMB_MALLOC_ARRAY(char, ++i)) == NULL) { + if ((newstr = SMB_MALLOC_ARRAY(char, ++i)) == NULL) { i = 0; _log_err( LOG_CRIT, "out of memory in smbpXstrDup" ); } else { while (i-- > 0) { - new[i] = x[i]; + newstr[i] = x[i]; } } x = NULL; } - return new; /* return the duplicate or NULL on error */ + return newstr; /* return the duplicate or NULL on error */ } /* ************************************************************** * @@ -374,21 +374,21 @@ int _smb_verify_password( pam_handle_t * pamh, SAM_ACCOUNT *sampass, pam_get_item( pamh, PAM_SERVICE, (const void **)&service ); if (data_name != NULL) { - struct _pam_failed_auth *new = NULL; + struct _pam_failed_auth *newauth = NULL; const struct _pam_failed_auth *old = NULL; /* get a failure recorder */ - new = SMB_MALLOC_P( struct _pam_failed_auth ); + newauth = SMB_MALLOC_P( struct _pam_failed_auth ); - if (new != NULL) { + if (newauth != NULL) { /* any previous failures for this user ? */ pam_get_data(pamh, data_name, (const void **) &old); if (old != NULL) { - new->count = old->count + 1; - if (new->count >= SMB_MAX_RETRIES) { + newauth->count = old->count + 1; + if (newauth->count >= SMB_MAX_RETRIES) { retval = PAM_MAXTRIES; } } else { @@ -396,17 +396,17 @@ int _smb_verify_password( pam_handle_t * pamh, SAM_ACCOUNT *sampass, "failed auth request by %s for service %s as %s", uidtoname(getuid()), service ? service : "**unknown**", name); - new->count = 1; + newauth->count = 1; } - if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sampass), &(new->id)))) { + if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sampass), &(newauth->id)))) { _log_err(LOG_NOTICE, "failed auth request by %s for service %s as %s", uidtoname(getuid()), service ? service : "**unknown**", name); } - new->user = smbpXstrDup( name ); - new->agent = smbpXstrDup( uidtoname( getuid() ) ); - pam_set_data( pamh, data_name, new, _cleanup_failures ); + newauth->user = smbpXstrDup( name ); + newauth->agent = smbpXstrDup( uidtoname( getuid() ) ); + pam_set_data( pamh, data_name, newauth, _cleanup_failures ); } else { _log_err( LOG_CRIT, "no memory for failure recorder" ); diff --git a/source/param/loadparm.c b/source/param/loadparm.c index 0083b508208..a1dcf284910 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -177,7 +177,6 @@ typedef struct BOOL bWinbindUseDefaultDomain; BOOL bWinbindTrustedDomainsOnly; BOOL bWinbindNestedGroups; - char *szWinbindBackend; char **szIdmapBackend; char *szAddShareCommand; char *szChangeShareCommand; @@ -226,6 +225,7 @@ typedef struct int oplock_break_wait_time; int winbind_cache_time; int winbind_max_idle_children; + char **szWinbindNssInfo; int iLockSpinCount; int iLockSpinTime; char *szLdapMachineSuffix; @@ -360,6 +360,7 @@ typedef struct char *fstype; char **szVfsObjects; char *szMSDfsProxy; + char *szAioWriteBehind; int iMinPrintSpace; int iMaxPrintJobs; int iMaxReportedPrintJobs; @@ -436,7 +437,10 @@ typedef struct BOOL bAfs_Share; BOOL bEASupport; BOOL bAclCheckPermissions; + BOOL bAclMapFullControl; int iallocation_roundup_size; + int iAioReadSize; + int iAioWriteSize; param_opt_struct *param_opt; char dummy[3]; /* for alignment */ @@ -488,6 +492,7 @@ static service sDefault = { NULL, /* fstype */ NULL, /* vfs objects */ NULL, /* szMSDfsProxy */ + NULL, /* szAioWriteBehind */ 0, /* iMinPrintSpace */ 1000, /* iMaxPrintJobs */ 0, /* iMaxReportedPrintJobs */ @@ -564,7 +569,10 @@ static service sDefault = { False, /* bAfs_Share */ False, /* bEASupport */ True, /* bAclCheckPermissions */ + True, /* bAclMapFullControl */ SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */ + 0, /* iAioReadSize */ + 0, /* iAioWriteSize */ NULL, /* Parametric options */ @@ -868,6 +876,7 @@ static struct parm_struct parm_table[] = { {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, {"acl check permissions", P_BOOL, P_LOCAL, &sDefault.bAclCheckPermissions, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, + {"acl map full control", P_BOOL, P_LOCAL, &sDefault.bAclMapFullControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE}, {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, @@ -914,6 +923,9 @@ static struct parm_struct parm_table[] = { {N_("Protocol Options"), P_SEP, P_SEPARATOR}, {"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED}, + {"aio read size", P_INTEGER, P_LOCAL, &sDefault.iAioReadSize, NULL, NULL, FLAG_ADVANCED}, + {"aio write size", P_INTEGER, P_LOCAL, &sDefault.iAioWriteSize, NULL, NULL, FLAG_ADVANCED}, + {"aio write behind", P_STRING, P_LOCAL, &sDefault.szAioWriteBehind, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED}, {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED}, {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED}, @@ -1225,6 +1237,7 @@ static struct parm_struct parm_table[] = { {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED}, {"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED}, {"winbind max idle children", P_INTEGER, P_GLOBAL, &Globals.winbind_max_idle_children, NULL, NULL, FLAG_ADVANCED}, + {"winbind nss info", P_LIST, P_GLOBAL, &Globals.szWinbindNssInfo, NULL, NULL, FLAG_ADVANCED}, {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0} }; @@ -1338,7 +1351,7 @@ static void init_globals(void) if ((parm_table[i].type == P_STRING || parm_table[i].type == P_USTRING) && parm_table[i].ptr) - string_set(parm_table[i].ptr, ""); + string_set((char **)parm_table[i].ptr, ""); string_set(&sDefault.fstype, FSTYPE_STRING); @@ -1570,6 +1583,7 @@ static void init_globals(void) Globals.bWinbindTrustedDomainsOnly = False; Globals.bWinbindNestedGroups = False; Globals.winbind_max_idle_children = 3; + Globals.szWinbindNssInfo = str_list_make("template", NULL); Globals.bEnableRidAlgorithm = True; @@ -1914,6 +1928,7 @@ FN_LOCAL_STRING(lp_veto_files, szVetoFiles) FN_LOCAL_STRING(lp_hide_files, szHideFiles) FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles) FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot) +FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind) FN_LOCAL_BOOL(lp_autoloaded, autoloaded) FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose) FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose) @@ -1969,6 +1984,7 @@ FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls) FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit) FN_LOCAL_BOOL(lp_afs_share, bAfs_Share) FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions) +FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl) FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask) FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode) FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask) @@ -1987,9 +2003,12 @@ FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy) FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize) FN_LOCAL_INTEGER(lp_block_size, iBlock_size) FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size); +FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize); +FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize); FN_LOCAL_CHAR(lp_magicchar, magic_char) FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time) FN_GLOBAL_INTEGER(lp_winbind_max_idle_children, &Globals.winbind_max_idle_children) +FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo) FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase) FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout) FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing) @@ -2272,12 +2291,12 @@ static void free_service(service *pservice) for (i = 0; parm_table[i].label; i++) { if ((parm_table[i].type == P_STRING || parm_table[i].type == P_USTRING) && - parm_table[i].class == P_LOCAL) + parm_table[i].p_class == P_LOCAL) string_free((char **) (((char *)pservice) + PTR_DIFF(parm_table[i].ptr, &sDefault))); else if (parm_table[i].type == P_LIST && - parm_table[i].class == P_LOCAL) + parm_table[i].p_class == P_LOCAL) str_list_free((char ***) (((char *)pservice) + PTR_DIFF(parm_table[i].ptr, &sDefault))); @@ -2541,7 +2560,7 @@ void show_parameter_list(void) for ( classIndex=0; section_names[classIndex]; classIndex++) { printf("[%s]\n", section_names[classIndex]); for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) { - if (parm_table[parmIndex].class == classIndex) { + if (parm_table[parmIndex].p_class == classIndex) { printf("%s=%s", parm_table[parmIndex].label, type[parm_table[parmIndex].type]); @@ -2632,7 +2651,7 @@ static void copy_service(service * pserviceDest, service * pserviceSource, BOOL BOOL not_added; for (i = 0; parm_table[i].label; i++) - if (parm_table[i].ptr && parm_table[i].class == P_LOCAL && + if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL && (bcopyall || pcopymapDest[i])) { void *def_ptr = parm_table[i].ptr; void *src_ptr = @@ -2659,12 +2678,12 @@ static void copy_service(service * pserviceDest, service * pserviceSource, BOOL break; case P_STRING: - string_set(dest_ptr, + string_set((char **)dest_ptr, *(char **)src_ptr); break; case P_USTRING: - string_set(dest_ptr, + string_set((char **)dest_ptr, *(char **)src_ptr); strupper_m(*(char **)dest_ptr); break; @@ -3268,7 +3287,7 @@ BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue if (snum < 0) { parm_ptr = def_ptr; } else { - if (parm_table[parmnum].class == P_GLOBAL) { + if (parm_table[parmnum].p_class == P_GLOBAL) { DEBUG(0, ("Global parameter %s found in service section!\n", pszParmName)); @@ -3300,11 +3319,11 @@ BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue switch (parm_table[parmnum].type) { case P_BOOL: - set_boolean(parm_ptr, pszParmValue); + set_boolean((BOOL *)parm_ptr, pszParmValue); break; case P_BOOLREV: - set_boolean(parm_ptr, pszParmValue); + set_boolean((BOOL *)parm_ptr, pszParmValue); *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr; break; @@ -3321,16 +3340,16 @@ BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue break; case P_LIST: - str_list_free(parm_ptr); + str_list_free((char ***)parm_ptr); *(char ***)parm_ptr = str_list_make(pszParmValue, NULL); break; case P_STRING: - string_set(parm_ptr, pszParmValue); + string_set((char **)parm_ptr, pszParmValue); break; case P_USTRING: - string_set(parm_ptr, pszParmValue); + string_set((char **)parm_ptr, pszParmValue); strupper_m(*(char **)parm_ptr); break; @@ -3598,7 +3617,7 @@ static void dump_globals(FILE *f) fprintf(f, "[global]\n"); for (i = 0; parm_table[i].label; i++) - if (parm_table[i].class == P_GLOBAL && + if (parm_table[i].p_class == P_GLOBAL && parm_table[i].ptr && (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) { if (defaults_saved && is_default(i)) @@ -3644,7 +3663,7 @@ static void dump_a_service(service * pService, FILE * f) for (i = 0; parm_table[i].label; i++) { - if (parm_table[i].class == P_LOCAL && + if (parm_table[i].p_class == P_LOCAL && parm_table[i].ptr && (*parm_table[i].label != '-') && (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) @@ -3688,18 +3707,18 @@ BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal) { service * pService = ServicePtrs[snum]; int i, result = False; - parm_class class; + parm_class p_class; unsigned flag = 0; if (isGlobal) { - class = P_GLOBAL; + p_class = P_GLOBAL; flag = FLAG_GLOBAL; } else - class = P_LOCAL; + p_class = P_LOCAL; for (i = 0; parm_table[i].label; i++) { if (strwicmp(parm_table[i].label, parm_name) == 0 && - (parm_table[i].class == class || parm_table[i].flags & flag) && + (parm_table[i].p_class == p_class || parm_table[i].flags & flag) && parm_table[i].ptr && (*parm_table[i].label != '-') && (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) @@ -3733,7 +3752,7 @@ struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters) if (snum < 0) { /* do the globals */ for (; parm_table[*i].label; (*i)++) { - if (parm_table[*i].class == P_SEPARATOR) + if (parm_table[*i].p_class == P_SEPARATOR) return &parm_table[(*i)++]; if (!parm_table[*i].ptr @@ -3751,10 +3770,10 @@ struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters) service *pService = ServicePtrs[snum]; for (; parm_table[*i].label; (*i)++) { - if (parm_table[*i].class == P_SEPARATOR) + if (parm_table[*i].p_class == P_SEPARATOR) return &parm_table[(*i)++]; - if (parm_table[*i].class == P_LOCAL && + if (parm_table[*i].p_class == P_LOCAL && parm_table[*i].ptr && (*parm_table[*i].label != '-') && ((*i) == 0 || @@ -3795,7 +3814,7 @@ static void dump_copy_map(BOOL *pcopymap) printf("\n\tNon-Copied parameters:\n"); for (i = 0; parm_table[i].label; i++) - if (parm_table[i].class == P_LOCAL && + if (parm_table[i].p_class == P_LOCAL && parm_table[i].ptr && !pcopymap[i] && (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) { @@ -4523,3 +4542,29 @@ void set_store_dos_attributes(int snum, BOOL val) return; ServicePtrs[(snum)]->bStoreDosAttributes = val; } + +void lp_set_mangling_method(const char *new_method) +{ + string_set(&Globals.szManglingMethod, new_method); +} + +/******************************************************************* + Global state for POSIX pathname processing. +********************************************************************/ + +static BOOL posix_pathnames; + +BOOL lp_posix_pathnames(void) +{ + return posix_pathnames; +} + +/******************************************************************* + Change everything needed to ensure POSIX pathname processing (currently + not much). +********************************************************************/ + +void lp_set_posix_pathnames(void) +{ + posix_pathnames = True; +} diff --git a/source/param/params.c b/source/param/params.c index 3b736113bef..2a6c8b3e650 100644 --- a/source/param/params.c +++ b/source/param/params.c @@ -264,7 +264,7 @@ static BOOL Section( myFILE *InFile, BOOL (*sfunc)(const char *) ) if( i > (bSize - 2) ) { char *tb; - tb = SMB_REALLOC( bufr, bSize +BUFR_INC ); + tb = (char *)SMB_REALLOC( bufr, bSize +BUFR_INC ); if( NULL == tb ) { DEBUG(0, ("%s Memory re-allocation failure.", func) ); return False; @@ -356,7 +356,7 @@ static BOOL Parameter( myFILE *InFile, BOOL (*pfunc)(const char *, const char *) /* Loop until we've found the start of the value. */ if( i > (bSize - 2) ) { /* Ensure there's space for next char. */ - char *tb = SMB_REALLOC( bufr, bSize + BUFR_INC ); + char *tb = (char *)SMB_REALLOC( bufr, bSize + BUFR_INC ); if( NULL == tb ) { DEBUG(0, ("%s Memory re-allocation failure.", func) ); return False; @@ -414,7 +414,7 @@ static BOOL Parameter( myFILE *InFile, BOOL (*pfunc)(const char *, const char *) while( (EOF !=c) && (c > 0) ) { if( i > (bSize - 2) ) { /* Make sure there's enough room. */ - char *tb = SMB_REALLOC( bufr, bSize + BUFR_INC ); + char *tb = (char *)SMB_REALLOC( bufr, bSize + BUFR_INC ); if( NULL == tb ) { DEBUG(0, ("%s Memory re-allocation failure.", func)); return False; diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c index 1dd8893c1ca..283eb7f1c16 100644 --- a/source/passdb/passdb.c +++ b/source/passdb/passdb.c @@ -52,7 +52,7 @@ const char *get_default_sam_name(void) void pdb_fill_default_sam(SAM_ACCOUNT *user) { - ZERO_STRUCT(user->private); /* Don't touch the talloc context */ + ZERO_STRUCT(user->private_u); /* Don't touch the talloc context */ /* no initial methods */ user->methods = NULL; @@ -60,36 +60,36 @@ void pdb_fill_default_sam(SAM_ACCOUNT *user) /* Don't change these timestamp settings without a good reason. They are important for NT member server compatibility. */ - user->private.logon_time = (time_t)0; - user->private.pass_last_set_time = (time_t)0; - user->private.pass_can_change_time = (time_t)0; - user->private.logoff_time = - user->private.kickoff_time = - user->private.pass_must_change_time = get_time_t_max(); - user->private.fields_present = 0x00ffffff; - user->private.logon_divs = 168; /* hours per week */ - user->private.hours_len = 21; /* 21 times 8 bits = 168 */ - memset(user->private.hours, 0xff, user->private.hours_len); /* available at all hours */ - user->private.bad_password_count = 0; - user->private.logon_count = 0; - user->private.unknown_6 = 0x000004ec; /* don't know */ + user->private_u.logon_time = (time_t)0; + user->private_u.pass_last_set_time = (time_t)0; + user->private_u.pass_can_change_time = (time_t)0; + user->private_u.logoff_time = + user->private_u.kickoff_time = + user->private_u.pass_must_change_time = get_time_t_max(); + user->private_u.fields_present = 0x00ffffff; + user->private_u.logon_divs = 168; /* hours per week */ + user->private_u.hours_len = 21; /* 21 times 8 bits = 168 */ + memset(user->private_u.hours, 0xff, user->private_u.hours_len); /* available at all hours */ + user->private_u.bad_password_count = 0; + user->private_u.logon_count = 0; + user->private_u.unknown_6 = 0x000004ec; /* don't know */ /* Some parts of samba strlen their pdb_get...() returns, so this keeps the interface unchanged for now. */ - user->private.username = ""; - user->private.domain = ""; - user->private.nt_username = ""; - user->private.full_name = ""; - user->private.home_dir = ""; - user->private.logon_script = ""; - user->private.profile_path = ""; - user->private.acct_desc = ""; - user->private.workstations = ""; - user->private.unknown_str = ""; - user->private.munged_dial = ""; - - user->private.plaintext_pw = NULL; + user->private_u.username = ""; + user->private_u.domain = ""; + user->private_u.nt_username = ""; + user->private_u.full_name = ""; + user->private_u.home_dir = ""; + user->private_u.logon_script = ""; + user->private_u.profile_path = ""; + user->private_u.acct_desc = ""; + user->private_u.workstations = ""; + user->private_u.unknown_str = ""; + user->private_u.munged_dial = ""; + + user->private_u.plaintext_pw = NULL; /* Unless we know otherwise have a Account Control Bit @@ -97,17 +97,17 @@ void pdb_fill_default_sam(SAM_ACCOUNT *user) asks for a filtered list of users. */ - user->private.acct_ctrl = ACB_NORMAL; + user->private_u.acct_ctrl = ACB_NORMAL; } static void destroy_pdb_talloc(SAM_ACCOUNT **user) { if (*user) { - data_blob_clear_free(&((*user)->private.lm_pw)); - data_blob_clear_free(&((*user)->private.nt_pw)); + data_blob_clear_free(&((*user)->private_u.lm_pw)); + data_blob_clear_free(&((*user)->private_u.nt_pw)); - if((*user)->private.plaintext_pw!=NULL) - memset((*user)->private.plaintext_pw,'\0',strlen((*user)->private.plaintext_pw)); + if((*user)->private_u.plaintext_pw!=NULL) + memset((*user)->private_u.plaintext_pw,'\0',strlen((*user)->private_u.plaintext_pw)); talloc_destroy((*user)->mem_ctx); *user = NULL; } @@ -396,13 +396,13 @@ static void pdb_free_sam_contents(SAM_ACCOUNT *user) /* Kill off sensitive data. Free()ed by the talloc mechinism */ - data_blob_clear_free(&(user->private.lm_pw)); - data_blob_clear_free(&(user->private.nt_pw)); - if (user->private.plaintext_pw!=NULL) - memset(user->private.plaintext_pw,'\0',strlen(user->private.plaintext_pw)); + data_blob_clear_free(&(user->private_u.lm_pw)); + data_blob_clear_free(&(user->private_u.nt_pw)); + if (user->private_u.plaintext_pw!=NULL) + memset(user->private_u.plaintext_pw,'\0',strlen(user->private_u.plaintext_pw)); - if (user->private.backend_private_data && user->private.backend_private_data_free_fn) { - user->private.backend_private_data_free_fn(&user->private.backend_private_data); + if (user->private_u.backend_private_data && user->private_u.backend_private_data_free_fn) { + user->private_u.backend_private_data_free_fn(&user->private_u.backend_private_data); } } diff --git a/source/passdb/pdb_get_set.c b/source/passdb/pdb_get_set.c index 99afac133ac..12e8bcc9cf9 100644 --- a/source/passdb/pdb_get_set.c +++ b/source/passdb/pdb_get_set.c @@ -43,7 +43,7 @@ uint16 pdb_get_acct_ctrl (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.acct_ctrl); + return (sampass->private_u.acct_ctrl); else return (ACB_DISABLED); } @@ -51,7 +51,7 @@ uint16 pdb_get_acct_ctrl (const SAM_ACCOUNT *sampass) time_t pdb_get_logon_time (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.logon_time); + return (sampass->private_u.logon_time); else return (0); } @@ -59,7 +59,7 @@ time_t pdb_get_logon_time (const SAM_ACCOUNT *sampass) time_t pdb_get_logoff_time (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.logoff_time); + return (sampass->private_u.logoff_time); else return (-1); } @@ -67,7 +67,7 @@ time_t pdb_get_logoff_time (const SAM_ACCOUNT *sampass) time_t pdb_get_kickoff_time (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.kickoff_time); + return (sampass->private_u.kickoff_time); else return (-1); } @@ -75,7 +75,7 @@ time_t pdb_get_kickoff_time (const SAM_ACCOUNT *sampass) time_t pdb_get_bad_password_time (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.bad_password_time); + return (sampass->private_u.bad_password_time); else return (-1); } @@ -83,7 +83,7 @@ time_t pdb_get_bad_password_time (const SAM_ACCOUNT *sampass) time_t pdb_get_pass_last_set_time (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.pass_last_set_time); + return (sampass->private_u.pass_last_set_time); else return (-1); } @@ -91,7 +91,7 @@ time_t pdb_get_pass_last_set_time (const SAM_ACCOUNT *sampass) time_t pdb_get_pass_can_change_time (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.pass_can_change_time); + return (sampass->private_u.pass_can_change_time); else return (-1); } @@ -99,7 +99,7 @@ time_t pdb_get_pass_can_change_time (const SAM_ACCOUNT *sampass) time_t pdb_get_pass_must_change_time (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.pass_must_change_time); + return (sampass->private_u.pass_must_change_time); else return (-1); } @@ -107,7 +107,7 @@ time_t pdb_get_pass_must_change_time (const SAM_ACCOUNT *sampass) uint16 pdb_get_logon_divs (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.logon_divs); + return (sampass->private_u.logon_divs); else return (-1); } @@ -115,7 +115,7 @@ uint16 pdb_get_logon_divs (const SAM_ACCOUNT *sampass) uint32 pdb_get_hours_len (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.hours_len); + return (sampass->private_u.hours_len); else return (-1); } @@ -123,7 +123,7 @@ uint32 pdb_get_hours_len (const SAM_ACCOUNT *sampass) const uint8* pdb_get_hours (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.hours); + return (sampass->private_u.hours); else return (NULL); } @@ -131,9 +131,9 @@ const uint8* pdb_get_hours (const SAM_ACCOUNT *sampass) const uint8* pdb_get_nt_passwd (const SAM_ACCOUNT *sampass) { if (sampass) { - SMB_ASSERT((!sampass->private.nt_pw.data) - || sampass->private.nt_pw.length == NT_HASH_LEN); - return ((uint8*)sampass->private.nt_pw.data); + SMB_ASSERT((!sampass->private_u.nt_pw.data) + || sampass->private_u.nt_pw.length == NT_HASH_LEN); + return ((uint8*)sampass->private_u.nt_pw.data); } else return (NULL); @@ -142,9 +142,9 @@ const uint8* pdb_get_nt_passwd (const SAM_ACCOUNT *sampass) const uint8* pdb_get_lanman_passwd (const SAM_ACCOUNT *sampass) { if (sampass) { - SMB_ASSERT((!sampass->private.lm_pw.data) - || sampass->private.lm_pw.length == LM_HASH_LEN); - return ((uint8*)sampass->private.lm_pw.data); + SMB_ASSERT((!sampass->private_u.lm_pw.data) + || sampass->private_u.lm_pw.length == LM_HASH_LEN); + return ((uint8*)sampass->private_u.lm_pw.data); } else return (NULL); @@ -153,10 +153,10 @@ const uint8* pdb_get_lanman_passwd (const SAM_ACCOUNT *sampass) const uint8* pdb_get_pw_history (const SAM_ACCOUNT *sampass, uint32 *current_hist_len) { if (sampass) { - SMB_ASSERT((!sampass->private.nt_pw_his.data) - || ((sampass->private.nt_pw_his.length % PW_HISTORY_ENTRY_LEN) == 0)); - *current_hist_len = sampass->private.nt_pw_his.length / PW_HISTORY_ENTRY_LEN; - return ((uint8*)sampass->private.nt_pw_his.data); + SMB_ASSERT((!sampass->private_u.nt_pw_his.data) + || ((sampass->private_u.nt_pw_his.length % PW_HISTORY_ENTRY_LEN) == 0)); + *current_hist_len = sampass->private_u.nt_pw_his.length / PW_HISTORY_ENTRY_LEN; + return ((uint8*)sampass->private_u.nt_pw_his.data); } else { *current_hist_len = 0; return (NULL); @@ -172,7 +172,7 @@ const uint8* pdb_get_pw_history (const SAM_ACCOUNT *sampass, uint32 *current_his const char* pdb_get_plaintext_passwd (const SAM_ACCOUNT *sampass) { if (sampass) { - return (sampass->private.plaintext_pw); + return (sampass->private_u.plaintext_pw); } else return (NULL); @@ -180,7 +180,7 @@ const char* pdb_get_plaintext_passwd (const SAM_ACCOUNT *sampass) const DOM_SID *pdb_get_user_sid(const SAM_ACCOUNT *sampass) { if (sampass) - return &sampass->private.user_sid; + return &sampass->private_u.user_sid; else return (NULL); } @@ -188,7 +188,7 @@ const DOM_SID *pdb_get_user_sid(const SAM_ACCOUNT *sampass) const DOM_SID *pdb_get_group_sid(const SAM_ACCOUNT *sampass) { if (sampass) - return &sampass->private.group_sid; + return &sampass->private_u.group_sid; else return (NULL); } @@ -203,15 +203,15 @@ enum pdb_value_state pdb_get_init_flags (const SAM_ACCOUNT *sampass, enum pdb_el { enum pdb_value_state ret = PDB_DEFAULT; - if (!sampass || !sampass->private.change_flags || !sampass->private.set_flags) + if (!sampass || !sampass->private_u.change_flags || !sampass->private_u.set_flags) return ret; - if (bitmap_query(sampass->private.set_flags, element)) { + if (bitmap_query(sampass->private_u.set_flags, element)) { DEBUG(11, ("element %d: SET\n", element)); ret = PDB_SET; } - if (bitmap_query(sampass->private.change_flags, element)) { + if (bitmap_query(sampass->private_u.change_flags, element)) { DEBUG(11, ("element %d: CHANGED\n", element)); ret = PDB_CHANGED; } @@ -226,7 +226,7 @@ enum pdb_value_state pdb_get_init_flags (const SAM_ACCOUNT *sampass, enum pdb_el const char* pdb_get_username (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.username); + return (sampass->private_u.username); else return (NULL); } @@ -234,7 +234,7 @@ const char* pdb_get_username (const SAM_ACCOUNT *sampass) const char* pdb_get_domain (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.domain); + return (sampass->private_u.domain); else return (NULL); } @@ -242,7 +242,7 @@ const char* pdb_get_domain (const SAM_ACCOUNT *sampass) const char* pdb_get_nt_username (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.nt_username); + return (sampass->private_u.nt_username); else return (NULL); } @@ -250,7 +250,7 @@ const char* pdb_get_nt_username (const SAM_ACCOUNT *sampass) const char* pdb_get_fullname (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.full_name); + return (sampass->private_u.full_name); else return (NULL); } @@ -258,7 +258,7 @@ const char* pdb_get_fullname (const SAM_ACCOUNT *sampass) const char* pdb_get_homedir (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.home_dir); + return (sampass->private_u.home_dir); else return (NULL); } @@ -266,7 +266,7 @@ const char* pdb_get_homedir (const SAM_ACCOUNT *sampass) const char* pdb_get_unix_homedir (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.unix_home_dir); + return (sampass->private_u.unix_home_dir); else return (NULL); } @@ -274,7 +274,7 @@ const char* pdb_get_unix_homedir (const SAM_ACCOUNT *sampass) const char* pdb_get_dir_drive (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.dir_drive); + return (sampass->private_u.dir_drive); else return (NULL); } @@ -282,7 +282,7 @@ const char* pdb_get_dir_drive (const SAM_ACCOUNT *sampass) const char* pdb_get_logon_script (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.logon_script); + return (sampass->private_u.logon_script); else return (NULL); } @@ -290,7 +290,7 @@ const char* pdb_get_logon_script (const SAM_ACCOUNT *sampass) const char* pdb_get_profile_path (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.profile_path); + return (sampass->private_u.profile_path); else return (NULL); } @@ -298,7 +298,7 @@ const char* pdb_get_profile_path (const SAM_ACCOUNT *sampass) const char* pdb_get_acct_desc (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.acct_desc); + return (sampass->private_u.acct_desc); else return (NULL); } @@ -306,7 +306,7 @@ const char* pdb_get_acct_desc (const SAM_ACCOUNT *sampass) const char* pdb_get_workstations (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.workstations); + return (sampass->private_u.workstations); else return (NULL); } @@ -314,7 +314,7 @@ const char* pdb_get_workstations (const SAM_ACCOUNT *sampass) const char* pdb_get_unknown_str (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.unknown_str); + return (sampass->private_u.unknown_str); else return (NULL); } @@ -322,7 +322,7 @@ const char* pdb_get_unknown_str (const SAM_ACCOUNT *sampass) const char* pdb_get_munged_dial (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.munged_dial); + return (sampass->private_u.munged_dial); else return (NULL); } @@ -330,7 +330,7 @@ const char* pdb_get_munged_dial (const SAM_ACCOUNT *sampass) uint16 pdb_get_bad_password_count(const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.bad_password_count); + return (sampass->private_u.bad_password_count); else return 0; } @@ -338,7 +338,7 @@ uint16 pdb_get_bad_password_count(const SAM_ACCOUNT *sampass) uint16 pdb_get_logon_count(const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.logon_count); + return (sampass->private_u.logon_count); else return 0; } @@ -346,15 +346,15 @@ uint16 pdb_get_logon_count(const SAM_ACCOUNT *sampass) uint32 pdb_get_unknown_6 (const SAM_ACCOUNT *sampass) { if (sampass) - return (sampass->private.unknown_6); + return (sampass->private_u.unknown_6); else return (-1); } void *pdb_get_backend_private_data (const SAM_ACCOUNT *sampass, const struct pdb_methods *my_methods) { - if (sampass && my_methods == sampass->private.backend_private_methods) - return sampass->private.backend_private_data; + if (sampass && my_methods == sampass->private_u.backend_private_methods) + return sampass->private_u.backend_private_data; else return NULL; } @@ -368,7 +368,7 @@ BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 acct_ctrl, enum pdb_value_s if (!sampass) return False; - sampass->private.acct_ctrl = acct_ctrl; + sampass->private_u.acct_ctrl = acct_ctrl; return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag); } @@ -378,7 +378,7 @@ BOOL pdb_set_logon_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_sta if (!sampass) return False; - sampass->private.logon_time = mytime; + sampass->private_u.logon_time = mytime; return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag); } @@ -388,7 +388,7 @@ BOOL pdb_set_logoff_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_st if (!sampass) return False; - sampass->private.logoff_time = mytime; + sampass->private_u.logoff_time = mytime; return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag); } @@ -398,7 +398,7 @@ BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_s if (!sampass) return False; - sampass->private.kickoff_time = mytime; + sampass->private_u.kickoff_time = mytime; return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag); } @@ -409,7 +409,7 @@ BOOL pdb_set_bad_password_time (SAM_ACCOUNT *sampass, time_t mytime, if (!sampass) return False; - sampass->private.bad_password_time = mytime; + sampass->private_u.bad_password_time = mytime; return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_TIME, flag); } @@ -419,7 +419,7 @@ BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb if (!sampass) return False; - sampass->private.pass_can_change_time = mytime; + sampass->private_u.pass_can_change_time = mytime; return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag); } @@ -429,7 +429,7 @@ BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t mytime, enum pd if (!sampass) return False; - sampass->private.pass_must_change_time = mytime; + sampass->private_u.pass_must_change_time = mytime; return pdb_set_init_flags(sampass, PDB_MUSTCHANGETIME, flag); } @@ -439,7 +439,7 @@ BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_v if (!sampass) return False; - sampass->private.pass_last_set_time = mytime; + sampass->private_u.pass_last_set_time = mytime; return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag); } @@ -449,7 +449,7 @@ BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len, enum pdb_value_state f if (!sampass) return False; - sampass->private.hours_len = len; + sampass->private_u.hours_len = len; return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag); } @@ -459,7 +459,7 @@ BOOL pdb_set_logon_divs (SAM_ACCOUNT *sampass, uint16 hours, enum pdb_value_stat if (!sampass) return False; - sampass->private.logon_divs = hours; + sampass->private_u.logon_divs = hours; return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag); } @@ -476,16 +476,16 @@ BOOL pdb_set_init_flags (SAM_ACCOUNT *sampass, enum pdb_elements element, enum p if (!sampass || !sampass->mem_ctx) return False; - if (!sampass->private.set_flags) { - if ((sampass->private.set_flags = + if (!sampass->private_u.set_flags) { + if ((sampass->private_u.set_flags = bitmap_talloc(sampass->mem_ctx, PDB_COUNT))==NULL) { DEBUG(0,("bitmap_talloc failed\n")); return False; } } - if (!sampass->private.change_flags) { - if ((sampass->private.change_flags = + if (!sampass->private_u.change_flags) { + if ((sampass->private_u.change_flags = bitmap_talloc(sampass->mem_ctx, PDB_COUNT))==NULL) { DEBUG(0,("bitmap_talloc failed\n")); @@ -495,22 +495,22 @@ BOOL pdb_set_init_flags (SAM_ACCOUNT *sampass, enum pdb_elements element, enum p switch(value_flag) { case PDB_CHANGED: - if (!bitmap_set(sampass->private.change_flags, element)) { + if (!bitmap_set(sampass->private_u.change_flags, element)) { DEBUG(0,("Can't set flag: %d in change_flags.\n",element)); return False; } - if (!bitmap_set(sampass->private.set_flags, element)) { + if (!bitmap_set(sampass->private_u.set_flags, element)) { DEBUG(0,("Can't set flag: %d in set_flags.\n",element)); return False; } DEBUG(11, ("element %d -> now CHANGED\n", element)); break; case PDB_SET: - if (!bitmap_clear(sampass->private.change_flags, element)) { + if (!bitmap_clear(sampass->private_u.change_flags, element)) { DEBUG(0,("Can't set flag: %d in change_flags.\n",element)); return False; } - if (!bitmap_set(sampass->private.set_flags, element)) { + if (!bitmap_set(sampass->private_u.set_flags, element)) { DEBUG(0,("Can't set flag: %d in set_flags.\n",element)); return False; } @@ -518,11 +518,11 @@ BOOL pdb_set_init_flags (SAM_ACCOUNT *sampass, enum pdb_elements element, enum p break; case PDB_DEFAULT: default: - if (!bitmap_clear(sampass->private.change_flags, element)) { + if (!bitmap_clear(sampass->private_u.change_flags, element)) { DEBUG(0,("Can't set flag: %d in change_flags.\n",element)); return False; } - if (!bitmap_clear(sampass->private.set_flags, element)) { + if (!bitmap_clear(sampass->private_u.set_flags, element)) { DEBUG(0,("Can't set flag: %d in set_flags.\n",element)); return False; } @@ -538,10 +538,10 @@ BOOL pdb_set_user_sid (SAM_ACCOUNT *sampass, const DOM_SID *u_sid, enum pdb_valu if (!sampass || !u_sid) return False; - sid_copy(&sampass->private.user_sid, u_sid); + sid_copy(&sampass->private_u.user_sid, u_sid); DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n", - sid_string_static(&sampass->private.user_sid))); + sid_string_static(&sampass->private_u.user_sid))); return pdb_set_init_flags(sampass, PDB_USERSID, flag); } @@ -574,10 +574,10 @@ BOOL pdb_set_group_sid (SAM_ACCOUNT *sampass, const DOM_SID *g_sid, enum pdb_val if (!sampass || !g_sid) return False; - sid_copy(&sampass->private.group_sid, g_sid); + sid_copy(&sampass->private_u.group_sid, g_sid); DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n", - sid_string_static(&sampass->private.group_sid))); + sid_string_static(&sampass->private_u.group_sid))); return pdb_set_init_flags(sampass, PDB_GROUPSID, flag); } @@ -614,17 +614,17 @@ BOOL pdb_set_username(SAM_ACCOUNT *sampass, const char *username, enum pdb_value if (username) { DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username, - (sampass->private.username)?(sampass->private.username):"NULL")); + (sampass->private_u.username)?(sampass->private_u.username):"NULL")); - sampass->private.username = talloc_strdup(sampass->mem_ctx, username); + sampass->private_u.username = talloc_strdup(sampass->mem_ctx, username); - if (!sampass->private.username) { + if (!sampass->private_u.username) { DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n")); return False; } } else { - sampass->private.username = PDB_NOT_QUITE_NULL; + sampass->private_u.username = PDB_NOT_QUITE_NULL; } return pdb_set_init_flags(sampass, PDB_USERNAME, flag); @@ -641,17 +641,17 @@ BOOL pdb_set_domain(SAM_ACCOUNT *sampass, const char *domain, enum pdb_value_sta if (domain) { DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain, - (sampass->private.domain)?(sampass->private.domain):"NULL")); + (sampass->private_u.domain)?(sampass->private_u.domain):"NULL")); - sampass->private.domain = talloc_strdup(sampass->mem_ctx, domain); + sampass->private_u.domain = talloc_strdup(sampass->mem_ctx, domain); - if (!sampass->private.domain) { + if (!sampass->private_u.domain) { DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n")); return False; } } else { - sampass->private.domain = PDB_NOT_QUITE_NULL; + sampass->private_u.domain = PDB_NOT_QUITE_NULL; } return pdb_set_init_flags(sampass, PDB_DOMAIN, flag); @@ -668,17 +668,17 @@ BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, const char *nt_username, enum pdb if (nt_username) { DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username, - (sampass->private.nt_username)?(sampass->private.nt_username):"NULL")); + (sampass->private_u.nt_username)?(sampass->private_u.nt_username):"NULL")); - sampass->private.nt_username = talloc_strdup(sampass->mem_ctx, nt_username); + sampass->private_u.nt_username = talloc_strdup(sampass->mem_ctx, nt_username); - if (!sampass->private.nt_username) { + if (!sampass->private_u.nt_username) { DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n")); return False; } } else { - sampass->private.nt_username = PDB_NOT_QUITE_NULL; + sampass->private_u.nt_username = PDB_NOT_QUITE_NULL; } return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag); @@ -695,17 +695,17 @@ BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, const char *full_name, enum pdb_valu if (full_name) { DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name, - (sampass->private.full_name)?(sampass->private.full_name):"NULL")); + (sampass->private_u.full_name)?(sampass->private_u.full_name):"NULL")); - sampass->private.full_name = talloc_strdup(sampass->mem_ctx, full_name); + sampass->private_u.full_name = talloc_strdup(sampass->mem_ctx, full_name); - if (!sampass->private.full_name) { + if (!sampass->private_u.full_name) { DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n")); return False; } } else { - sampass->private.full_name = PDB_NOT_QUITE_NULL; + sampass->private_u.full_name = PDB_NOT_QUITE_NULL; } return pdb_set_init_flags(sampass, PDB_FULLNAME, flag); @@ -722,17 +722,17 @@ BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, const char *logon_script, enum p if (logon_script) { DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script, - (sampass->private.logon_script)?(sampass->private.logon_script):"NULL")); + (sampass->private_u.logon_script)?(sampass->private_u.logon_script):"NULL")); - sampass->private.logon_script = talloc_strdup(sampass->mem_ctx, logon_script); + sampass->private_u.logon_script = talloc_strdup(sampass->mem_ctx, logon_script); - if (!sampass->private.logon_script) { + if (!sampass->private_u.logon_script) { DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n")); return False; } } else { - sampass->private.logon_script = PDB_NOT_QUITE_NULL; + sampass->private_u.logon_script = PDB_NOT_QUITE_NULL; } return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag); @@ -749,17 +749,17 @@ BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, const char *profile_path, enum if (profile_path) { DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path, - (sampass->private.profile_path)?(sampass->private.profile_path):"NULL")); + (sampass->private_u.profile_path)?(sampass->private_u.profile_path):"NULL")); - sampass->private.profile_path = talloc_strdup(sampass->mem_ctx, profile_path); + sampass->private_u.profile_path = talloc_strdup(sampass->mem_ctx, profile_path); - if (!sampass->private.profile_path) { + if (!sampass->private_u.profile_path) { DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n")); return False; } } else { - sampass->private.profile_path = PDB_NOT_QUITE_NULL; + sampass->private_u.profile_path = PDB_NOT_QUITE_NULL; } return pdb_set_init_flags(sampass, PDB_PROFILE, flag); @@ -776,17 +776,17 @@ BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, const char *dir_drive, enum pdb_va if (dir_drive) { DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive, - (sampass->private.dir_drive)?(sampass->private.dir_drive):"NULL")); + (sampass->private_u.dir_drive)?(sampass->private_u.dir_drive):"NULL")); - sampass->private.dir_drive = talloc_strdup(sampass->mem_ctx, dir_drive); + sampass->private_u.dir_drive = talloc_strdup(sampass->mem_ctx, dir_drive); - if (!sampass->private.dir_drive) { + if (!sampass->private_u.dir_drive) { DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n")); return False; } } else { - sampass->private.dir_drive = PDB_NOT_QUITE_NULL; + sampass->private_u.dir_drive = PDB_NOT_QUITE_NULL; } return pdb_set_init_flags(sampass, PDB_DRIVE, flag); @@ -803,17 +803,17 @@ BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, const char *home_dir, enum pdb_value if (home_dir) { DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir, - (sampass->private.home_dir)?(sampass->private.home_dir):"NULL")); + (sampass->private_u.home_dir)?(sampass->private_u.home_dir):"NULL")); - sampass->private.home_dir = talloc_strdup(sampass->mem_ctx, home_dir); + sampass->private_u.home_dir = talloc_strdup(sampass->mem_ctx, home_dir); - if (!sampass->private.home_dir) { + if (!sampass->private_u.home_dir) { DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n")); return False; } } else { - sampass->private.home_dir = PDB_NOT_QUITE_NULL; + sampass->private_u.home_dir = PDB_NOT_QUITE_NULL; } return pdb_set_init_flags(sampass, PDB_SMBHOME, flag); @@ -830,18 +830,18 @@ BOOL pdb_set_unix_homedir (SAM_ACCOUNT *sampass, const char *unix_home_dir, enum if (unix_home_dir) { DEBUG(10, ("pdb_set_unix_homedir: setting home dir %s, was %s\n", unix_home_dir, - (sampass->private.unix_home_dir)?(sampass->private.unix_home_dir):"NULL")); + (sampass->private_u.unix_home_dir)?(sampass->private_u.unix_home_dir):"NULL")); - sampass->private.unix_home_dir = talloc_strdup(sampass->mem_ctx, + sampass->private_u.unix_home_dir = talloc_strdup(sampass->mem_ctx, unix_home_dir); - if (!sampass->private.unix_home_dir) { + if (!sampass->private_u.unix_home_dir) { DEBUG(0, ("pdb_set_unix_home_dir: talloc_strdup() failed!\n")); return False; } } else { - sampass->private.unix_home_dir = PDB_NOT_QUITE_NULL; + sampass->private_u.unix_home_dir = PDB_NOT_QUITE_NULL; } return pdb_set_init_flags(sampass, PDB_UNIXHOMEDIR, flag); @@ -857,15 +857,15 @@ BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, const char *acct_desc, enum pdb_va return False; if (acct_desc) { - sampass->private.acct_desc = talloc_strdup(sampass->mem_ctx, acct_desc); + sampass->private_u.acct_desc = talloc_strdup(sampass->mem_ctx, acct_desc); - if (!sampass->private.acct_desc) { + if (!sampass->private_u.acct_desc) { DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n")); return False; } } else { - sampass->private.acct_desc = PDB_NOT_QUITE_NULL; + sampass->private_u.acct_desc = PDB_NOT_QUITE_NULL; } return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag); @@ -882,17 +882,17 @@ BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, const char *workstations, enum if (workstations) { DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations, - (sampass->private.workstations)?(sampass->private.workstations):"NULL")); + (sampass->private_u.workstations)?(sampass->private_u.workstations):"NULL")); - sampass->private.workstations = talloc_strdup(sampass->mem_ctx, workstations); + sampass->private_u.workstations = talloc_strdup(sampass->mem_ctx, workstations); - if (!sampass->private.workstations) { + if (!sampass->private_u.workstations) { DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n")); return False; } } else { - sampass->private.workstations = PDB_NOT_QUITE_NULL; + sampass->private_u.workstations = PDB_NOT_QUITE_NULL; } return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag); @@ -908,15 +908,15 @@ BOOL pdb_set_unknown_str (SAM_ACCOUNT *sampass, const char *unknown_str, enum pd return False; if (unknown_str) { - sampass->private.unknown_str = talloc_strdup(sampass->mem_ctx, unknown_str); + sampass->private_u.unknown_str = talloc_strdup(sampass->mem_ctx, unknown_str); - if (!sampass->private.unknown_str) { + if (!sampass->private_u.unknown_str) { DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n")); return False; } } else { - sampass->private.unknown_str = PDB_NOT_QUITE_NULL; + sampass->private_u.unknown_str = PDB_NOT_QUITE_NULL; } return pdb_set_init_flags(sampass, PDB_UNKNOWNSTR, flag); @@ -932,15 +932,15 @@ BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, const char *munged_dial, enum pd return False; if (munged_dial) { - sampass->private.munged_dial = talloc_strdup(sampass->mem_ctx, munged_dial); + sampass->private_u.munged_dial = talloc_strdup(sampass->mem_ctx, munged_dial); - if (!sampass->private.munged_dial) { + if (!sampass->private_u.munged_dial) { DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n")); return False; } } else { - sampass->private.munged_dial = PDB_NOT_QUITE_NULL; + sampass->private_u.munged_dial = PDB_NOT_QUITE_NULL; } return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag); @@ -955,12 +955,12 @@ BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[NT_HASH_LEN], enum if (!sampass) return False; - data_blob_clear_free(&sampass->private.nt_pw); + data_blob_clear_free(&sampass->private_u.nt_pw); if (pwd) { - sampass->private.nt_pw = data_blob(pwd, NT_HASH_LEN); + sampass->private_u.nt_pw = data_blob(pwd, NT_HASH_LEN); } else { - sampass->private.nt_pw = data_blob(NULL, 0); + sampass->private_u.nt_pw = data_blob(NULL, 0); } return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag); @@ -975,12 +975,12 @@ BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[LM_HASH_LEN], if (!sampass) return False; - data_blob_clear_free(&sampass->private.lm_pw); + data_blob_clear_free(&sampass->private_u.lm_pw); if (pwd) { - sampass->private.lm_pw = data_blob(pwd, LM_HASH_LEN); + sampass->private_u.lm_pw = data_blob(pwd, LM_HASH_LEN); } else { - sampass->private.lm_pw = data_blob(NULL, 0); + sampass->private_u.lm_pw = data_blob(NULL, 0); } return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag); @@ -999,14 +999,14 @@ BOOL pdb_set_pw_history (SAM_ACCOUNT *sampass, const uint8 *pwd, uint32 historyL return False; if (historyLen && pwd){ - sampass->private.nt_pw_his = data_blob_talloc(sampass->mem_ctx, + sampass->private_u.nt_pw_his = data_blob_talloc(sampass->mem_ctx, pwd, historyLen*PW_HISTORY_ENTRY_LEN); - if (!sampass->private.nt_pw_his.length) { + if (!sampass->private_u.nt_pw_his.length) { DEBUG(0, ("pdb_set_pw_history: data_blob_talloc() failed!\n")); return False; } } else { - sampass->private.nt_pw_his = data_blob_talloc(sampass->mem_ctx, NULL, 0); + sampass->private_u.nt_pw_his = data_blob_talloc(sampass->mem_ctx, NULL, 0); } return pdb_set_init_flags(sampass, PDB_PWHISTORY, flag); @@ -1023,18 +1023,18 @@ BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const char *password, enum return False; if (password) { - if (sampass->private.plaintext_pw!=NULL) - memset(sampass->private.plaintext_pw,'\0',strlen(sampass->private.plaintext_pw)+1); + if (sampass->private_u.plaintext_pw!=NULL) + memset(sampass->private_u.plaintext_pw,'\0',strlen(sampass->private_u.plaintext_pw)+1); - sampass->private.plaintext_pw = talloc_strdup(sampass->mem_ctx, password); + sampass->private_u.plaintext_pw = talloc_strdup(sampass->mem_ctx, password); - if (!sampass->private.plaintext_pw) { + if (!sampass->private_u.plaintext_pw) { DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n")); return False; } } else { - sampass->private.plaintext_pw = NULL; + sampass->private_u.plaintext_pw = NULL; } return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag); @@ -1045,7 +1045,7 @@ BOOL pdb_set_bad_password_count(SAM_ACCOUNT *sampass, uint16 bad_password_count, if (!sampass) return False; - sampass->private.bad_password_count = bad_password_count; + sampass->private_u.bad_password_count = bad_password_count; return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_COUNT, flag); } @@ -1055,7 +1055,7 @@ BOOL pdb_set_logon_count(SAM_ACCOUNT *sampass, uint16 logon_count, enum pdb_valu if (!sampass) return False; - sampass->private.logon_count = logon_count; + sampass->private_u.logon_count = logon_count; return pdb_set_init_flags(sampass, PDB_LOGON_COUNT, flag); } @@ -1065,7 +1065,7 @@ BOOL pdb_set_unknown_6 (SAM_ACCOUNT *sampass, uint32 unkn, enum pdb_value_state if (!sampass) return False; - sampass->private.unknown_6 = unkn; + sampass->private_u.unknown_6 = unkn; return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag); } @@ -1076,11 +1076,11 @@ BOOL pdb_set_hours (SAM_ACCOUNT *sampass, const uint8 *hours, enum pdb_value_sta return False; if (!hours) { - memset ((char *)sampass->private.hours, 0, MAX_HOURS_LEN); + memset ((char *)sampass->private_u.hours, 0, MAX_HOURS_LEN); return True; } - memcpy (sampass->private.hours, hours, MAX_HOURS_LEN); + memcpy (sampass->private_u.hours, hours, MAX_HOURS_LEN); return pdb_set_init_flags(sampass, PDB_HOURS, flag); } @@ -1093,13 +1093,13 @@ BOOL pdb_set_backend_private_data (SAM_ACCOUNT *sampass, void *private_data, if (!sampass) return False; - if (sampass->private.backend_private_data && sampass->private.backend_private_data_free_fn) { - sampass->private.backend_private_data_free_fn(&sampass->private.backend_private_data); + if (sampass->private_u.backend_private_data && sampass->private_u.backend_private_data_free_fn) { + sampass->private_u.backend_private_data_free_fn(&sampass->private_u.backend_private_data); } - sampass->private.backend_private_data = private_data; - sampass->private.backend_private_data_free_fn = free_fn; - sampass->private.backend_private_methods = my_methods; + sampass->private_u.backend_private_data = private_data; + sampass->private_u.backend_private_data_free_fn = free_fn; + sampass->private_u.backend_private_methods = my_methods; return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag); } diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c index c6880b1d50b..d4407492c21 100644 --- a/source/passdb/pdb_interface.c +++ b/source/passdb/pdb_interface.c @@ -1614,7 +1614,7 @@ struct user_search { static BOOL next_entry_users(struct pdb_search *s, struct samr_displayentry *entry) { - struct user_search *state = s->private; + struct user_search *state = s->private_data; SAM_ACCOUNT *user = NULL; NTSTATUS status; @@ -1677,7 +1677,7 @@ static BOOL pdb_default_search_users(struct pdb_methods *methods, state->acct_flags = acct_flags; - search->private = state; + search->private_data = state; search->next_entry = next_entry_users; search->search_end = search_end_users; return True; @@ -1691,7 +1691,7 @@ struct group_search { static BOOL next_entry_groups(struct pdb_search *s, struct samr_displayentry *entry) { - struct group_search *state = s->private; + struct group_search *state = s->private_data; uint32 rid; GROUP_MAP *map = &state->groups[state->current_group]; @@ -1709,7 +1709,7 @@ static BOOL next_entry_groups(struct pdb_search *s, static void search_end_groups(struct pdb_search *search) { - struct group_search *state = search->private; + struct group_search *state = search->private_data; SAFE_FREE(state->groups); } @@ -1731,7 +1731,7 @@ static BOOL pdb_search_grouptype(struct pdb_search *search, } state->current_group = 0; - search->private = state; + search->private_data = state; search->next_entry = next_entry_groups; search->search_end = search_end_groups; return True; diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c index d688a04dc44..002ec70464b 100644 --- a/source/passdb/pdb_ldap.c +++ b/source/passdb/pdb_ldap.c @@ -3387,7 +3387,7 @@ struct ldap_search_state { static BOOL ldapsam_search_firstpage(struct pdb_search *search) { - struct ldap_search_state *state = search->private; + struct ldap_search_state *state = search->private_data; LDAP *ld; int rc = LDAP_OPERATIONS_ERROR; @@ -3439,7 +3439,7 @@ static BOOL ldapsam_search_firstpage(struct pdb_search *search) static BOOL ldapsam_search_nextpage(struct pdb_search *search) { - struct ldap_search_state *state = search->private; + struct ldap_search_state *state = search->private_data; LDAP *ld = state->connection->ldap_struct; int rc; @@ -3470,7 +3470,7 @@ static BOOL ldapsam_search_nextpage(struct pdb_search *search) static BOOL ldapsam_search_next_entry(struct pdb_search *search, struct samr_displayentry *entry) { - struct ldap_search_state *state = search->private; + struct ldap_search_state *state = search->private_data; LDAP *ld = state->connection->ldap_struct; BOOL result; @@ -3506,7 +3506,7 @@ static BOOL ldapsam_search_next_entry(struct pdb_search *search, static void ldapsam_search_end(struct pdb_search *search) { - struct ldap_search_state *state = search->private; + struct ldap_search_state *state = search->private_data; int rc; if (state->pagedresults_cookie == NULL) @@ -3657,7 +3657,7 @@ static BOOL ldapsam_search_users(struct pdb_methods *methods, return False; } - search->private = state; + search->private_data = state; search->next_entry = ldapsam_search_next_entry; search->search_end = ldapsam_search_end; @@ -3764,7 +3764,7 @@ static BOOL ldapsam_search_grouptype(struct pdb_methods *methods, return False; } - search->private = state; + search->private_data = state; search->next_entry = ldapsam_search_next_entry; search->search_end = ldapsam_search_end; diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c index 2146448ae3c..25083002c31 100644 --- a/source/printing/nt_printing.c +++ b/source/printing/nt_printing.c @@ -922,7 +922,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 } /* Skip OEM header (if any) and the DOS stub to start of Windows header */ - if (SMB_VFS_LSEEK(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) { + if (SMB_VFS_LSEEK(fsp, fsp->fh->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) { DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n", fname, errno)); /* Assume this isn't an error... the file just looks sort of like a PE/NE file */ @@ -988,7 +988,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 } /* Seek to the start of the .rsrc section info */ - if (SMB_VFS_LSEEK(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) { + if (SMB_VFS_LSEEK(fsp, fsp->fh->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) { DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n", fname, errno)); goto error_exit; @@ -1084,7 +1084,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 * twice, as it is simpler to read the code. */ if (strcmp(&buf[i], VS_SIGNATURE) == 0) { /* Compute skip alignment to next long address */ - int skip = -(SMB_VFS_LSEEK(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) + + int skip = -(SMB_VFS_LSEEK(fsp, fsp->fh->fd, 0, SEEK_CUR) - (byte_count - i) + sizeof(VS_SIGNATURE)) & 3; if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue; @@ -1142,8 +1142,6 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr uint32 old_minor; time_t old_create_time; - int access_mode; - int action; files_struct *fsp = NULL; SMB_STRUCT_STAT st; SMB_STRUCT_STAT stat_buf; @@ -1159,10 +1157,15 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf); - fsp = open_file_shared(conn, filepath, &stat_buf, - SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY), - (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), - FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, &access_mode, &action); + fsp = open_file_ntcreate(conn, filepath, &stat_buf, + FILE_GENERIC_READ, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, + 0, + FILE_ATTRIBUTE_NORMAL, + INTERNAL_OPEN_ONLY, + NULL); + if (!fsp) { /* Old file not found, so by definition new file is in fact newer */ DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n", @@ -1171,13 +1174,15 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr } else { int ret = get_file_version(fsp, old_file, &old_major, &old_minor); - if (ret == -1) goto error_exit; + if (ret == -1) { + goto error_exit; + } if (!ret) { DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n", old_file)); use_version = False; - if (SMB_VFS_FSTAT(fsp, fsp->fd, &st) == -1) goto error_exit; + if (SMB_VFS_FSTAT(fsp, fsp->fh->fd, &st) == -1) goto error_exit; old_create_time = st.st_mtime; DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time)); } @@ -1188,10 +1193,15 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr pstrcpy(filepath, new_file); driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf); - fsp = open_file_shared(conn, filepath, &stat_buf, - SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY), - (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), - FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, &access_mode, &action); + fsp = open_file_ntcreate(conn, filepath, &stat_buf, + FILE_GENERIC_READ, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, + 0, + FILE_ATTRIBUTE_NORMAL, + INTERNAL_OPEN_ONLY, + NULL); + if (!fsp) { /* New file not found, this shouldn't occur if the caller did its job */ DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n", @@ -1200,13 +1210,15 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr } else { int ret = get_file_version(fsp, new_file, &new_major, &new_minor); - if (ret == -1) goto error_exit; + if (ret == -1) { + goto error_exit; + } if (!ret) { DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n", new_file)); use_version = False; - if (SMB_VFS_FSTAT(fsp, fsp->fd, &st) == -1) goto error_exit; + if (SMB_VFS_FSTAT(fsp, fsp->fh->fd, &st) == -1) goto error_exit; new_create_time = st.st_mtime; DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time)); } @@ -1251,8 +1263,6 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_ struct current_user *user, WERROR *perr) { int cversion; - int access_mode; - int action; NTSTATUS nt_status; pstring driverpath; DATA_BLOB null_pw; @@ -1309,18 +1319,21 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_ goto error_exit; } - fsp = open_file_shared(conn, driverpath, &st, - SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY), - (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), - FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, &access_mode, &action); + fsp = open_file_ntcreate(conn, driverpath, &st, + FILE_GENERIC_READ, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, + 0, + FILE_ATTRIBUTE_NORMAL, + INTERNAL_OPEN_ONLY, + NULL); if (!fsp) { DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n", driverpath, errno)); *perr = WERR_ACCESS_DENIED; goto error_exit; - } - else { + } else { uint32 major; uint32 minor; int ret = get_file_version(fsp, driverpath, &major, &minor); @@ -1659,12 +1672,12 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath); slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath); if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) { - NTSTATUS status; driver_unix_convert(new_name, conn, NULL, &bad_path, &st); - if ( !copy_file(new_name, old_name, conn, FILE_EXISTS_TRUNCATE|FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) { + if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE| + OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) { DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n", new_name, old_name)); - *perr = ntstatus_to_werror(status); + *perr = WERR_ACCESS_DENIED; ver = -1; } } @@ -1675,12 +1688,12 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile); slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile); if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) { - NTSTATUS status; driver_unix_convert(new_name, conn, NULL, &bad_path, &st); - if ( !copy_file(new_name, old_name, conn, FILE_EXISTS_TRUNCATE|FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) { + if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE| + OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) { DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n", new_name, old_name)); - *perr = ntstatus_to_werror(status); + *perr = WERR_ACCESS_DENIED; ver = -1; } } @@ -1693,12 +1706,12 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile); slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile); if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) { - NTSTATUS status; driver_unix_convert(new_name, conn, NULL, &bad_path, &st); - if ( !copy_file(new_name, old_name, conn, FILE_EXISTS_TRUNCATE|FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) { + if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE| + OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) { DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n", new_name, old_name)); - *perr = ntstatus_to_werror(status); + *perr = WERR_ACCESS_DENIED; ver = -1; } } @@ -1712,12 +1725,12 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile); slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile); if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) { - NTSTATUS status; driver_unix_convert(new_name, conn, NULL, &bad_path, &st); - if ( !copy_file(new_name, old_name, conn, FILE_EXISTS_TRUNCATE|FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) { + if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE| + OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) { DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n", new_name, old_name)); - *perr = ntstatus_to_werror(status); + *perr = WERR_ACCESS_DENIED; ver = -1; } } @@ -1740,12 +1753,13 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]); slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]); if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) { - NTSTATUS status; driver_unix_convert(new_name, conn, NULL, &bad_path, &st); - if ( !copy_file(new_name, old_name, conn, FILE_EXISTS_TRUNCATE|FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) { + if ( !copy_file(new_name, old_name, conn, + OPENX_FILE_EXISTS_TRUNCATE| + OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) { DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n", new_name, old_name)); - *perr = ntstatus_to_werror(status); + *perr = WERR_ACCESS_DENIED; ver = -1; } } @@ -2095,13 +2109,13 @@ int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen) nt_devmode->reserved2, nt_devmode->panningwidth, nt_devmode->panningheight, - nt_devmode->private); + nt_devmode->nt_dev_private); - if (nt_devmode->private) { + if (nt_devmode->nt_dev_private) { len += tdb_pack(buf+len, buflen-len, "B", nt_devmode->driverextra, - nt_devmode->private); + nt_devmode->nt_dev_private); } DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname)); @@ -2130,8 +2144,17 @@ static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen) for ( i=0; i<data->num_keys; i++ ) { val_ctr = &data->keys[i].values; num_values = regval_ctr_numvals( val_ctr ); + + /* pack the keyname followed by a empty value */ + + len += tdb_pack(buf+len, buflen-len, "pPdB", + &data->keys[i].name, + data->keys[i].name, + REG_NONE, + 0, + NULL); - /* loop over all values */ + /* now loop over all values */ for ( j=0; j<num_values; j++ ) { /* pathname should be stored as <key>\<value> */ @@ -2198,6 +2221,7 @@ uint32 del_a_printer(const char *sharename) static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info) { pstring key; + fstring norm_sharename; char *buf; int buflen, len; WERROR ret; @@ -2279,6 +2303,11 @@ static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info) } + /* normalize the key */ + + fstrcpy( norm_sharename, info->sharename ); + strlower_m( norm_sharename ); + slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, info->sharename); kbuf.dptr = key; @@ -2360,7 +2389,7 @@ NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename) nt_devmode->panningwidth = 0; nt_devmode->panningheight = 0; - nt_devmode->private = NULL; + nt_devmode->nt_dev_private = NULL; return nt_devmode; } @@ -2380,9 +2409,9 @@ NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode) return NULL; } - new_nt_devicemode->private = NULL; - if (nt_devicemode->private != NULL) { - if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) { + new_nt_devicemode->nt_dev_private = NULL; + if (nt_devicemode->nt_dev_private != NULL) { + if ((new_nt_devicemode->nt_dev_private = memdup(nt_devicemode->nt_dev_private, nt_devicemode->driverextra)) == NULL) { SAFE_FREE(new_nt_devicemode); DEBUG(0,("dup_nt_devicemode: malloc fail.\n")); return NULL; @@ -2405,7 +2434,7 @@ void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr) DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n")); - SAFE_FREE(nt_devmode->private); + SAFE_FREE(nt_devmode->nt_dev_private); SAFE_FREE(*devmode_ptr); } @@ -2491,25 +2520,25 @@ int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen) &devmode.reserved2, &devmode.panningwidth, &devmode.panningheight, - &devmode.private); + &devmode.nt_dev_private); - if (devmode.private) { + if (devmode.nt_dev_private) { /* the len in tdb_unpack is an int value and * devmode.driverextra is only a short */ - len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private); + len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.nt_dev_private); devmode.driverextra=(uint16)extra_len; /* check to catch an invalid TDB entry so we don't segfault */ if (devmode.driverextra == 0) { - devmode.private = NULL; + devmode.nt_dev_private = NULL; } } *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode)); DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname)); - if (devmode.private) + if (devmode.nt_dev_private) DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra)); return len; @@ -2519,7 +2548,7 @@ int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen) Allocate and initialize a new slot. ***************************************************************************/ -static int add_new_printer_key( NT_PRINTER_DATA *data, const char *name ) +int add_new_printer_key( NT_PRINTER_DATA *data, const char *name ) { NT_PRINTER_KEY *d; int key_index; @@ -2529,9 +2558,12 @@ static int add_new_printer_key( NT_PRINTER_DATA *data, const char *name ) /* allocate another slot in the NT_PRINTER_KEY array */ - d = SMB_REALLOC_ARRAY( data->keys, NT_PRINTER_KEY, data->num_keys+1); - if ( d ) - data->keys = d; + if ( !(d = SMB_REALLOC_ARRAY( data->keys, NT_PRINTER_KEY, data->num_keys+1)) ) { + DEBUG(0,("add_new_printer_key: Realloc() failed!\n")); + return -1; + } + + data->keys = d; key_index = data->num_keys; @@ -2550,6 +2582,38 @@ static int add_new_printer_key( NT_PRINTER_DATA *data, const char *name ) /**************************************************************************** search for a registry key name in the existing printer data ***************************************************************************/ + +int delete_printer_key( NT_PRINTER_DATA *data, const char *name ) +{ + int i; + NT_PRINTER_KEY *printer_key; + + for ( i=0; i<data->num_keys; i++ ) { + if ( strequal( data->keys[i].name, name ) ) { + + /* cleanup memory */ + + printer_key = &data->keys[i]; + SAFE_FREE( printer_key->name ); + regval_ctr_destroy( &printer_key->values ); + + /* if not the end of the array, move remaining elements down one slot */ + + data->num_keys--; + if ( data->num_keys && (i < data->num_keys) ) + memmove( &data->keys[i], &data->keys[i+1], sizeof(NT_PRINTER_KEY)*(data->num_keys-i) ); + + break; + } + } + + + return data->num_keys; +} + +/**************************************************************************** + search for a registry key name in the existing printer data + ***************************************************************************/ int lookup_printerkey( NT_PRINTER_DATA *data, const char *name ) { @@ -2578,7 +2642,7 @@ int lookup_printerkey( NT_PRINTER_DATA *data, const char *name ) /**************************************************************************** ***************************************************************************/ -uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys ) +int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys ) { int i, j; int key_len; @@ -2589,14 +2653,42 @@ uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **su if ( !data ) return 0; + + if ( !key ) + return -1; + + /* special case of asking for the top level printer data registry key names */ + + if ( strlen(key) == 0 ) { + for ( i=0; i<data->num_keys; i++ ) { + /* found a match, so allocate space and copy the name */ + + if ( !(ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) { + DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n", + num_subkeys+1)); + SAFE_FREE( subkeys ); + return -1; + } + + subkeys_ptr = ptr; + fstrcpy( subkeys_ptr[num_subkeys], data->keys[i].name ); + num_subkeys++; + } + + goto done; + } + + /* asking for the subkeys of some key */ + /* subkey paths are stored in the key name using '\' as the delimiter */ + for ( i=0; i<data->num_keys; i++ ) { if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) { - /* match sure it is a subkey and not the key itself */ + /* if we found the exact key, then break */ key_len = strlen( key ); if ( strlen(data->keys[i].name) == key_len ) - continue; + break; /* get subkey path */ @@ -2633,7 +2725,13 @@ uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **su } - /* tag of the end */ + /* return error if the key was not found */ + + if ( i == data->num_keys ) + return -1; + +done: + /* tag off the end */ if (num_subkeys) fstrcpy(subkeys_ptr[num_subkeys], "" ); @@ -3274,6 +3372,15 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen) &type, &size, &data_p); + + /* lookup for subkey names which have a type of REG_NONE */ + /* there's no data with this entry */ + + if ( type == REG_NONE ) { + if ( (key_index=lookup_printerkey( printer_data, string)) == -1 ) + add_new_printer_key( printer_data, string ); + continue; + } /* * break of the keyname from the value name. @@ -3495,17 +3602,22 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *se TDB_DATA kbuf, dbuf; fstring printername; char adevice[MAXDEVICENAME]; + fstring norm_sharename; ZERO_STRUCT(info); - slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename); + /* normalize case */ + fstrcpy( norm_sharename, sharename ); + strlower_m( norm_sharename ); + + slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, norm_sharename); kbuf.dptr = key; kbuf.dsize = strlen(key)+1; dbuf = tdb_fetch(tdb_printers, kbuf); if (!dbuf.dptr) - return get_a_printer_2_default(info_ptr, servername, sharename); + return get_a_printer_2_default(info_ptr, servername, norm_sharename); len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff", &info.attributes, @@ -3539,7 +3651,7 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *se slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", servername); if ( lp_force_printername(snum) ) - slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, sharename ); + slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, norm_sharename ); else slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, info.printername); @@ -4872,7 +4984,7 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur Store a security desc for a printer. ****************************************************************************/ -WERROR nt_printing_setsec(const char *printername, SEC_DESC_BUF *secdesc_ctr) +WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr) { SEC_DESC_BUF *new_secdesc_ctr = NULL; SEC_DESC_BUF *old_secdesc_ctr = NULL; @@ -4880,6 +4992,10 @@ WERROR nt_printing_setsec(const char *printername, SEC_DESC_BUF *secdesc_ctr) TALLOC_CTX *mem_ctx = NULL; fstring key; WERROR status; + fstring norm_sharename; + + fstrcpy( norm_sharename, sharename ); + strlower_m( norm_sharename ); mem_ctx = talloc_init("nt_printing_setsec"); if (mem_ctx == NULL) @@ -4896,7 +5012,7 @@ WERROR nt_printing_setsec(const char *printername, SEC_DESC_BUF *secdesc_ctr) SEC_DESC *psd = NULL; size_t size; - nt_printing_getsec(mem_ctx, printername, &old_secdesc_ctr); + nt_printing_getsec(mem_ctx, norm_sharename, &old_secdesc_ctr); /* Pick out correct owner and group sids */ @@ -4942,12 +5058,12 @@ WERROR nt_printing_setsec(const char *printername, SEC_DESC_BUF *secdesc_ctr) goto out; } - slprintf(key, sizeof(key)-1, "SECDESC/%s", printername); + slprintf(key, sizeof(key)-1, "SECDESC/%s", norm_sharename); if (tdb_prs_store(tdb_printers, key, &ps)==0) { status = WERR_OK; } else { - DEBUG(1,("Failed to store secdesc for %s\n", printername)); + DEBUG(1,("Failed to store secdesc for %s\n", norm_sharename)); status = WERR_BADFUNC; } @@ -5049,24 +5165,28 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx) Get a security desc for a printer. ****************************************************************************/ -BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *printername, SEC_DESC_BUF **secdesc_ctr) +BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **secdesc_ctr) { prs_struct ps; fstring key; char *temp; + fstring norm_sharename; - if (strlen(printername) > 2 && (temp = strchr(printername + 2, '\\'))) { - printername = temp + 1; + if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) { + sharename = temp + 1; } /* Fetch security descriptor from tdb */ - slprintf(key, sizeof(key)-1, "SECDESC/%s", printername); + fstrcpy( norm_sharename, sharename ); + strlower_m( norm_sharename ); + + slprintf(key, sizeof(key)-1, "SECDESC/%s", norm_sharename); if (tdb_prs_fetch(tdb_printers, key, &ps, ctx)!=0 || !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) { - DEBUG(4,("using default secdesc for %s\n", printername)); + DEBUG(4,("using default secdesc for %s\n", norm_sharename)); if (!(*secdesc_ctr = construct_default_printer_sdb(ctx))) { return False; @@ -5118,7 +5238,7 @@ BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *printername, SEC_DESC_BUF * /* Set it */ - nt_printing_setsec(printername, *secdesc_ctr); + nt_printing_setsec(norm_sharename, *secdesc_ctr); } } @@ -5127,7 +5247,7 @@ BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *printername, SEC_DESC_BUF * int i; DEBUG(10, ("secdesc_ctr for %s has %d aces:\n", - printername, the_acl->num_aces)); + norm_sharename, the_acl->num_aces)); for (i = 0; i < the_acl->num_aces; i++) { fstring sid_str; diff --git a/source/printing/printfsp.c b/source/printing/printfsp.c index 863de9624e7..eb81dc4536f 100644 --- a/source/printing/printfsp.c +++ b/source/printing/printfsp.c @@ -28,7 +28,7 @@ open a print file and setup a fsp for it. This is a wrapper around print_job_start(). ***************************************************************************/ -files_struct *print_fsp_open(connection_struct *conn, char *fname) +files_struct *print_fsp_open(connection_struct *conn, const char *fname) { int jobid; SMB_STRUCT_STAT sbuf; @@ -40,10 +40,11 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname) fstrcpy( name, "Remote Downlevel Document"); if (fname) { - char *p = strrchr(fname, '/'); + const char *p = strrchr(fname, '/'); fstrcat(name, " "); - if (!p) + if (!p) { p = fname; + } fstrcat(name, p); } @@ -63,24 +64,23 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname) } /* setup a full fsp */ - fsp->fd = print_job_fd(lp_const_servicename(SNUM(conn)),jobid); + fsp->fh->fd = print_job_fd(lp_const_servicename(SNUM(conn)),jobid); GetTimeOfDay(&fsp->open_time); fsp->vuid = current_user.vuid; - fsp->pos = -1; + fsp->fh->pos = -1; fsp->can_lock = True; fsp->can_read = False; + fsp->access_mask = FILE_GENERIC_WRITE; fsp->can_write = True; - fsp->share_mode = 0; fsp->print_file = True; fsp->modified = False; fsp->oplock_type = NO_OPLOCK; fsp->sent_oplock_break = NO_BREAK_SENT; fsp->is_directory = False; - fsp->directory_delete_on_close = False; string_set(&fsp->fsp_name,print_job_fname(lp_const_servicename(SNUM(conn)),jobid)); fsp->wbmpx_ptr = NULL; fsp->wcp = NULL; - SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf); + SMB_VFS_FSTAT(fsp,fsp->fh->fd, &sbuf); fsp->mode = sbuf.st_mode; fsp->inode = sbuf.st_ino; fsp->dev = sbuf.st_dev; @@ -91,19 +91,20 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname) } /**************************************************************************** -print a file - called on closing the file + Print a file - called on closing the file. ****************************************************************************/ + void print_fsp_end(files_struct *fsp, BOOL normal_close) { uint32 jobid; fstring sharename; - if (fsp->share_mode == FILE_DELETE_ON_CLOSE) { + if (fsp->fh->private_options & FILE_DELETE_ON_CLOSE) { /* * Truncate the job. print_job_end will take * care of deleting it for us. JRA. */ - sys_ftruncate(fsp->fd, 0); + sys_ftruncate(fsp->fh->fd, 0); } if (fsp->fsp_name) { diff --git a/source/printing/printing.c b/source/printing/printing.c index ab86db53f38..0737cf00d1d 100644 --- a/source/printing/printing.c +++ b/source/printing/printing.c @@ -2094,6 +2094,8 @@ int print_queue_length(int snum, print_status_struct *pstatus) const char* sharename = lp_const_servicename( snum ); print_status_struct status; int len; + + ZERO_STRUCT( status ); /* make sure the database is up to date */ if (print_cache_expired(lp_const_servicename(snum), True)) diff --git a/source/python/py_spoolss_printers.c b/source/python/py_spoolss_printers.c index a8efda16012..7446e2d2828 100644 --- a/source/python/py_spoolss_printers.c +++ b/source/python/py_spoolss_printers.c @@ -43,7 +43,7 @@ PyObject *spoolss_openprinter(PyObject *self, PyObject *args, PyObject *kw) return NULL; } - server = SMB_XSTRDUP(unc_name + 2); + server = SMB_STRDUP(unc_name + 2); if (strchr(server, '\\')) { char *c = strchr(server, '\\'); diff --git a/source/python/py_srvsvc.c b/source/python/py_srvsvc.c index 1fa7ca89c23..823dbb334ac 100644 --- a/source/python/py_srvsvc.c +++ b/source/python/py_srvsvc.c @@ -93,7 +93,7 @@ PyObject *srvsvc_netservergetinfo(PyObject *self, PyObject *args, return NULL; } - server = SMB_XSTRDUP(unc_name + 2); + server = SMB_STRDUP(unc_name + 2); if (strchr(server, '\\')) { char *c = strchr(server, '\\'); diff --git a/source/python/py_winbind.c b/source/python/py_winbind.c index 6482a5b9e33..2f22649bfbf 100644 --- a/source/python/py_winbind.c +++ b/source/python/py_winbind.c @@ -30,7 +30,7 @@ PyObject *winbind_error; /* A winbind call returned WINBINDD_ERROR */ /* Prototypes from common.h */ -NSS_STATUS winbindd_request(int req_type, +NSS_STATUS winbindd_request_response(int req_type, struct winbindd_request *request, struct winbindd_response *response); @@ -66,7 +66,7 @@ static PyObject *py_name_to_sid(PyObject *self, PyObject *args) fstrcpy(request.data.name.name, name); } - if (winbindd_request(WINBINDD_LOOKUPNAME, &request, &response) + if (winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response) != NSS_STATUS_SUCCESS) { PyErr_SetString(winbind_error, "lookup failed"); return NULL; @@ -94,7 +94,7 @@ static PyObject *py_sid_to_name(PyObject *self, PyObject *args) fstrcpy(request.data.sid, sid); - if (winbindd_request(WINBINDD_LOOKUPSID, &request, &response) + if (winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response) != NSS_STATUS_SUCCESS) { PyErr_SetString(winbind_error, "lookup failed"); return NULL; @@ -126,7 +126,7 @@ static PyObject *py_enum_domain_users(PyObject *self, PyObject *args) ZERO_STRUCT(response); - if (winbindd_request(WINBINDD_LIST_USERS, NULL, &response) + if (winbindd_request_response(WINBINDD_LIST_USERS, NULL, &response) != NSS_STATUS_SUCCESS) { PyErr_SetString(winbind_error, "lookup failed"); return NULL; @@ -157,7 +157,7 @@ static PyObject *py_enum_domain_groups(PyObject *self, PyObject *args) ZERO_STRUCT(response); - if (winbindd_request(WINBINDD_LIST_GROUPS, NULL, &response) + if (winbindd_request_response(WINBINDD_LIST_GROUPS, NULL, &response) != NSS_STATUS_SUCCESS) { PyErr_SetString(winbind_error, "lookup failed"); return NULL; @@ -192,7 +192,7 @@ static PyObject *py_enum_trust_dom(PyObject *self, PyObject *args) ZERO_STRUCT(response); - if (winbindd_request(WINBINDD_LIST_TRUSTDOM, NULL, &response) + if (winbindd_request_response(WINBINDD_LIST_TRUSTDOM, NULL, &response) != NSS_STATUS_SUCCESS) { PyErr_SetString(winbind_error, "lookup failed"); return NULL; @@ -222,7 +222,7 @@ static PyObject *py_check_secret(PyObject *self, PyObject *args) ZERO_STRUCT(response); - if (winbindd_request(WINBINDD_CHECK_MACHACC, NULL, &response) + if (winbindd_request_response(WINBINDD_CHECK_MACHACC, NULL, &response) != NSS_STATUS_SUCCESS) { PyErr_SetString(winbind_error, "lookup failed"); return NULL; @@ -294,7 +294,7 @@ static PyObject *py_uid_to_sid(PyObject *self, PyObject *args) request.data.uid = id; - if (winbindd_request(WINBINDD_UID_TO_SID, &request, &response) + if (winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response) != NSS_STATUS_SUCCESS) { PyErr_SetString(winbind_error, "lookup failed"); return NULL; @@ -319,7 +319,7 @@ static PyObject *py_gid_to_sid(PyObject *self, PyObject *args) request.data.gid = id; - if (winbindd_request(WINBINDD_GID_TO_SID, &request, &response) + if (winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response) != NSS_STATUS_SUCCESS) { PyErr_SetString(winbind_error, "lookup failed"); return NULL; @@ -344,7 +344,7 @@ static PyObject *py_sid_to_uid(PyObject *self, PyObject *args) fstrcpy(request.data.sid, sid); - if (winbindd_request(WINBINDD_SID_TO_UID, &request, &response) + if (winbindd_request_response(WINBINDD_SID_TO_UID, &request, &response) != NSS_STATUS_SUCCESS) { PyErr_SetString(winbind_error, "lookup failed"); return NULL; @@ -369,7 +369,7 @@ static PyObject *py_sid_to_gid(PyObject *self, PyObject *args) fstrcpy(request.data.sid, sid); - if (winbindd_request(WINBINDD_SID_TO_GID, &request, &response) + if (winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response) != NSS_STATUS_SUCCESS) { PyErr_SetString(winbind_error, "lookup failed"); return NULL; @@ -399,7 +399,7 @@ static PyObject *py_auth_plaintext(PyObject *self, PyObject *args) fstrcpy(request.data.auth.user, username); fstrcpy(request.data.auth.pass, password); - if (winbindd_request(WINBINDD_PAM_AUTH, &request, &response) + if (winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response) != NSS_STATUS_SUCCESS) { PyErr_SetString(winbind_error, "lookup failed"); return NULL; @@ -446,7 +446,7 @@ static PyObject *py_auth_crap(PyObject *self, PyObject *args, PyObject *kw) request.data.auth_crap.nt_resp_len = 24; } - if (winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response) + if (winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response) != NSS_STATUS_SUCCESS) { PyErr_SetString(winbind_error, "lookup failed"); return NULL; @@ -506,7 +506,7 @@ static PyObject *py_auth_smbd(PyObject *self, PyObject *args, PyObject *kw) - if (winbindd_request(WINBINDD_SMBD_AUTH_CRAP, &request, &response) + if (winbindd_request_response(WINBINDD_SMBD_AUTH_CRAP, &request, &response) != NSS_STATUS_SUCCESS) { PyErr_SetString(winbind_error, "lookup failed"); return NULL; @@ -534,7 +534,7 @@ static PyObject *py_getpwnam(PyObject *self, PyObject *args) fstrcpy(request.data.username, username); - if (winbindd_request(WINBINDD_GETPWNAM, &request, &response) + if (winbindd_request_response(WINBINDD_GETPWNAM, &request, &response) != NSS_STATUS_SUCCESS) { PyErr_SetString(winbind_error, "lookup failed"); return NULL; @@ -565,7 +565,7 @@ static PyObject *py_getpwuid(PyObject *self, PyObject *args) request.data.uid = uid; - if (winbindd_request(WINBINDD_GETPWUID, &request, &response) + if (winbindd_request_response(WINBINDD_GETPWUID, &request, &response) != NSS_STATUS_SUCCESS) { PyErr_SetString(winbind_error, "lookup failed"); return NULL; diff --git a/source/registry/reg_db.c b/source/registry/reg_db.c index 1ae1d6be54d..bd17303a702 100644 --- a/source/registry/reg_db.c +++ b/source/registry/reg_db.c @@ -27,11 +27,7 @@ static TDB_CONTEXT *tdb_reg; - -static BOOL regdb_store_reg_keys( char *keyname, REGSUBKEY_CTR *ctr ); -static int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr ); - - +#define VALUE_PREFIX "SAMBA_REGVAL" /* List the deepest path into the registry. All part components will be created.*/ @@ -44,18 +40,39 @@ static int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr ); KEY_PRINTING_2K in include/rpc_reg.h) --jerry */ static const char *builtin_registry_paths[] = { - "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print", - "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Ports", - "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print", + KEY_PRINTING_2K, + KEY_PRINTING_PORTS, + KEY_PRINTING, + KEY_SHARES, + KEY_EVENTLOG, + "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors", "HKLM\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions", - "HKLM\\SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Shares", - "HKLM\\SYSTEM\\CurrentControlSet\\Services\\EventLog", "HKLM\\SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters", "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Netlogon\\Parameters", "HKU", "HKCR", NULL }; +struct builtin_regkey_value { + const char *path; + const char *valuename; + uint32 type; + union { + const char *string; + uint32 dw_value; + } data; +}; + +static struct builtin_regkey_value builtin_registry_values[] = { + { "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", + "SystemRoot", REG_SZ, { "c:\\Windows" } }, + { "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Ports", + SAMBA_PRINTER_PORT_NAME, REG_SZ, { "" } }, + { "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers", + "DefaultSpoolDirectory", REG_SZ, { "C:\\Windows\\System32\\Spool\\Printers" } }, + { NULL, NULL, 0, { NULL } } +}; + #define REGVER_V1 1 /* first db version with write support */ /*********************************************************************** @@ -67,8 +84,10 @@ static BOOL init_registry_data( void ) pstring path, base, remaining; fstring keyname, subkeyname; REGSUBKEY_CTR subkeys; + REGVAL_CTR values; int i; const char *p, *p2; + UNISTR2 data; /* loop over all of the predefined paths and add each component */ @@ -108,16 +127,49 @@ static BOOL init_registry_data( void ) regsubkey_ctr_init( &subkeys ); - regdb_fetch_reg_keys( base, &subkeys ); + regdb_fetch_keys( base, &subkeys ); if ( *subkeyname ) regsubkey_ctr_addkey( &subkeys, subkeyname ); - if ( !regdb_store_reg_keys( base, &subkeys )) + if ( !regdb_store_keys( base, &subkeys )) return False; regsubkey_ctr_destroy( &subkeys ); } } + /* loop over all of the predefined values and add each component */ + + for ( i=0; builtin_registry_values[i].path != NULL; i++ ) { + regval_ctr_init( &values ); + + regdb_fetch_values( builtin_registry_values[i].path, &values ); + switch( builtin_registry_values[i].type ) { + case REG_DWORD: + regval_ctr_addvalue( &values, + builtin_registry_values[i].valuename, + REG_DWORD, + (char*)&builtin_registry_values[i].data.dw_value, + sizeof(uint32) ); + break; + + case REG_SZ: + init_unistr2( &data, builtin_registry_values[i].data.string, UNI_STR_TERMINATE); + regval_ctr_addvalue( &values, + builtin_registry_values[i].valuename, + REG_SZ, + (char*)data.buffer, + data.uni_str_len*sizeof(uint16) ); + break; + + default: + DEBUG(0,("init_registry_data: invalid value type in builtin_registry_values [%d]\n", + builtin_registry_values[i].type)); + } + regdb_store_values( builtin_registry_values[i].path, &values ); + + regval_ctr_destroy( &values ); + } + return True; } @@ -163,25 +215,13 @@ BOOL init_registry_db( void ) return True; } -/********************************************************************** - The full path to the registry key is used as database after the - \'s are converted to /'s. Key string is also normalized to UPPER - case. -**********************************************************************/ - -static void normalize_reg_path( pstring keyname ) -{ - pstring_sub( keyname, "\\", "/" ); - strupper_m( keyname ); -} - /*********************************************************************** Add subkey strings to the registry tdb under a defined key fmt is the same format as tdb_pack except this function only supports fstrings ***********************************************************************/ -static BOOL regdb_store_reg_keys_internal( char *key, REGSUBKEY_CTR *ctr ) +static BOOL regdb_store_keys_internal( const char *key, REGSUBKEY_CTR *ctr ) { TDB_DATA kbuf, dbuf; char *buffer, *tmpbuf; @@ -214,7 +254,7 @@ static BOOL regdb_store_reg_keys_internal( char *key, REGSUBKEY_CTR *ctr ) if ( len > buflen ) { /* allocate some extra space */ if ((tmpbuf = SMB_REALLOC( buffer, len*2 )) == NULL) { - DEBUG(0,("regdb_store_reg_keys: Failed to realloc memory of size [%d]\n", len*2)); + DEBUG(0,("regdb_store_keys: Failed to realloc memory of size [%d]\n", len*2)); ret = False; goto done; } @@ -247,22 +287,22 @@ done: do not currently exist ***********************************************************************/ -static BOOL regdb_store_reg_keys( char *key, REGSUBKEY_CTR *ctr ) +BOOL regdb_store_keys( const char *key, REGSUBKEY_CTR *ctr ) { int num_subkeys, i; pstring path; REGSUBKEY_CTR subkeys, old_subkeys; char *oldkeyname; - /* fetch a list of the old subkeys so we can difure out if any were deleted */ + /* fetch a list of the old subkeys so we can determine if any were deleted */ regsubkey_ctr_init( &old_subkeys ); - regdb_fetch_reg_keys( key, &old_subkeys ); + regdb_fetch_keys( key, &old_subkeys ); /* store the subkey list for the parent */ - if ( !regdb_store_reg_keys_internal( key, ctr ) ) { - DEBUG(0,("regdb_store_reg_keys: Failed to store new subkey list for parent [%s}\n", key )); + if ( !regdb_store_keys_internal( key, ctr ) ) { + DEBUG(0,("regdb_store_keys: Failed to store new subkey list for parent [%s}\n", key )); return False; } @@ -277,6 +317,8 @@ static BOOL regdb_store_reg_keys( char *key, REGSUBKEY_CTR *ctr ) tdb_delete_bystring( tdb_reg, path ); } } + + regsubkey_ctr_destroy( &old_subkeys ); /* now create records for any subkeys that don't already exist */ @@ -284,10 +326,10 @@ static BOOL regdb_store_reg_keys( char *key, REGSUBKEY_CTR *ctr ) for ( i=0; i<num_subkeys; i++ ) { pstr_sprintf( path, "%s%c%s", key, '/', regsubkey_ctr_specific_key( ctr, i ) ); regsubkey_ctr_init( &subkeys ); - if ( regdb_fetch_reg_keys( path, &subkeys ) == -1 ) { + if ( regdb_fetch_keys( path, &subkeys ) == -1 ) { /* create a record with 0 subkeys */ - if ( !regdb_store_reg_keys_internal( path, &subkeys ) ) { - DEBUG(0,("regdb_store_reg_keys: Failed to store new record for key [%s}\n", path )); + if ( !regdb_store_keys_internal( path, &subkeys ) ) { + DEBUG(0,("regdb_store_keys: Failed to store new record for key [%s}\n", path )); regsubkey_ctr_destroy( &subkeys ); return False; } @@ -301,11 +343,10 @@ static BOOL regdb_store_reg_keys( char *key, REGSUBKEY_CTR *ctr ) /*********************************************************************** Retrieve an array of strings containing subkeys. Memory should be - released by the caller. The subkeys are stored in a catenated string - of null terminated character strings + released by the caller. ***********************************************************************/ -static int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr ) +int regdb_fetch_keys( const char* key, REGSUBKEY_CTR *ctr ) { pstring path; uint32 num_items; @@ -315,7 +356,7 @@ static int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr ) int i; fstring subkeyname; - DEBUG(10,("regdb_fetch_reg_keys: Enter key => [%s]\n", key ? key : "NULL")); + DEBUG(10,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL")); pstrcpy( path, key ); @@ -329,7 +370,7 @@ static int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr ) buflen = dbuf.dsize; if ( !buf ) { - DEBUG(5,("regdb_fetch_reg_keys: tdb lookup failed to locate key [%s]\n", key)); + DEBUG(5,("regdb_fetch_keys: tdb lookup failed to locate key [%s]\n", key)); return -1; } @@ -342,53 +383,116 @@ static int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr ) SAFE_FREE( dbuf.dptr ); - DEBUG(10,("regdb_fetch_reg_keys: Exit [%d] items\n", num_items)); + DEBUG(10,("regdb_fetch_keys: Exit [%d] items\n", num_items)); return num_items; } +/**************************************************************************** + Unpack a list of registry values frem the TDB + ***************************************************************************/ + +static int regdb_unpack_values(REGVAL_CTR *values, char *buf, int buflen) +{ + int len = 0; + uint32 type; + pstring valuename; + uint32 size; + uint8 *data_p; + uint32 num_values = 0; + int i; + + + + /* loop and unpack the rest of the registry values */ + + len += tdb_unpack(buf+len, buflen-len, "d", &num_values); + + for ( i=0; i<num_values; i++ ) { + /* unpack the next regval */ + + type = REG_NONE; + size = 0; + data_p = NULL; + len += tdb_unpack(buf+len, buflen-len, "fdB", + valuename, + &type, + &size, + &data_p); + + /* add the new value. Paranoid protective code -- make sure data_p is valid */ -/*********************************************************************** - Retrieve an array of strings containing subkeys. Memory should be - released by the caller. The subkeys are stored in a catenated string - of null terminated character strings - ***********************************************************************/ + if ( size && data_p ) { + regval_ctr_addvalue( values, valuename, type, (const char *)data_p, size ); + SAFE_FREE(data_p); /* 'B' option to tdb_unpack does a malloc() */ + } + + DEBUG(8,("specific: [%s], len: %d\n", valuename, size)); + } + + return len; +} -static int regdb_fetch_reg_values( char* key, REGVAL_CTR *val ) +/**************************************************************************** + Pack all values in all printer keys + ***************************************************************************/ + +static int regdb_pack_values(REGVAL_CTR *values, char *buf, int buflen) { - UNISTR2 data; - int num_vals; - char *hname; - fstring mydomainname; - - DEBUG(10,("regdb_fetch_reg_values: Looking for value of key [%s] \n", key)); - - num_vals = 0; - - if ( strequal(key, "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion" ) ) { - DEBUG(10,("regdb_fetch_reg_values: Supplying SystemRoot \n")); - init_unistr2( &data, "c:\\Windows", UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "SystemRoot",REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - num_vals = 1; - } else if ( strequal(key, "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" ) ) { - DEBUG(10,("regdb_fetch_reg_values: Supplying ProductType \n")); - init_unistr2( &data, "WinNT", UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "ProductType",REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - num_vals = 1; - } else if ( strequal(key, "HKLM\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters" ) ) { - DEBUG(10,("regdb_fetch_reg_values: Supplying Hostname & Domain Name\n")); - hname = SMB_STRDUP(myhostname()); - get_mydnsdomname(mydomainname); - init_unistr2( &data, hname, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Hostname",REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - init_unistr2( &data, mydomainname, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Domain",REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - num_vals = 2; + int len = 0; + int i; + REGISTRY_VALUE *val; + int num_values = regval_ctr_numvals( values ); + + if ( !values ) + return 0; + + /* pack the number of values first */ + + len += tdb_pack( buf+len, buflen-len, "d", num_values ); + + /* loop over all values */ + + for ( i=0; i<num_values; i++ ) { + val = regval_ctr_specific_value( values, i ); + len += tdb_pack(buf+len, buflen-len, "fdB", + regval_name(val), + regval_type(val), + regval_size(val), + regval_data_p(val) ); } + return len; +} +/*********************************************************************** + Retrieve an array of strings containing subkeys. Memory should be + released by the caller. + ***********************************************************************/ - return num_vals; +int regdb_fetch_values( const char* key, REGVAL_CTR *values ) +{ + TDB_DATA data; + pstring keystr; + int len; + + DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key)); + + pstr_sprintf( keystr, "%s/%s", VALUE_PREFIX, key ); + normalize_reg_path( keystr ); + + data = tdb_fetch_bystring( tdb_reg, keystr ); + + if ( !data.dptr ) { + /* all keys have zero values by default */ + return 0; + } + + len = regdb_unpack_values( values, data.dptr, data.dsize ); + + SAFE_FREE( data.dptr ); + + return regval_ctr_numvals(values); } /*********************************************************************** @@ -396,9 +500,37 @@ static int regdb_fetch_reg_values( char* key, REGVAL_CTR *val ) values in the registry.tdb ***********************************************************************/ -static BOOL regdb_store_reg_values( char *key, REGVAL_CTR *val ) +BOOL regdb_store_values( const char *key, REGVAL_CTR *values ) { - return False; + TDB_DATA data; + pstring keystr; + int len, ret; + + DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key)); + + ZERO_STRUCT( data ); + + len = regdb_pack_values( values, data.dptr, data.dsize ); + if ( len <= 0 ) { + DEBUG(0,("regdb_store_values: unable to pack values. len <= 0\n")); + return False; + } + + data.dptr = SMB_MALLOC_ARRAY( char, len ); + data.dsize = len; + + len = regdb_pack_values( values, data.dptr, data.dsize ); + + SMB_ASSERT( len == data.dsize ); + + pstr_sprintf( keystr, "%s/%s", VALUE_PREFIX, key ); + normalize_reg_path( keystr ); + + ret = tdb_store_bystring(tdb_reg, keystr, data, TDB_REPLACE); + + SAFE_FREE( data.dptr ); + + return ret != -1 ; } @@ -407,10 +539,10 @@ static BOOL regdb_store_reg_values( char *key, REGVAL_CTR *val ) */ REGISTRY_OPS regdb_ops = { - regdb_fetch_reg_keys, - regdb_fetch_reg_values, - regdb_store_reg_keys, - regdb_store_reg_values, + regdb_fetch_keys, + regdb_fetch_values, + regdb_store_keys, + regdb_store_values, NULL }; diff --git a/source/registry/reg_eventlog.c b/source/registry/reg_eventlog.c index 4c3f144980e..b20eb046db8 100644 --- a/source/registry/reg_eventlog.c +++ b/source/registry/reg_eventlog.c @@ -154,9 +154,9 @@ static int eventlog_subkey_values( char *key, REGVAL_CTR *val ) the memory allocated here. **********************************************************************/ -static char* trim_eventlog_reg_path( char *path ) +static char* trim_eventlog_reg_path( const char *path ) { - char *p; + const char *p; uint16 key_len = strlen(KEY_EVENTLOG); /* @@ -186,7 +186,7 @@ static char* trim_eventlog_reg_path( char *path ) Enumerate registry subkey names given a registry path. Caller is responsible for freeing memory to **subkeys *********************************************************************/ -static int eventlog_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr ) +static int eventlog_subkey_info( const char *key, REGSUBKEY_CTR *subkey_ctr ) { char *path; BOOL top_level = False; @@ -251,7 +251,7 @@ static int eventlog_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr ) Caller is responsible for freeing memory *********************************************************************/ -static int eventlog_value_info( char *key, REGVAL_CTR *val ) +static int eventlog_value_info( const char *key, REGVAL_CTR *val ) { char *path; BOOL top_level = False; @@ -280,7 +280,7 @@ static int eventlog_value_info( char *key, REGVAL_CTR *val ) people storing eventlog information directly via registry calls (for now at least) *********************************************************************/ -static BOOL eventlog_store_subkey( char *key, REGSUBKEY_CTR *subkeys ) +static BOOL eventlog_store_subkey( const char *key, REGSUBKEY_CTR *subkeys ) { return False; } @@ -290,7 +290,7 @@ static BOOL eventlog_store_subkey( char *key, REGSUBKEY_CTR *subkeys ) people storing eventlog information directly via registry calls (for now at least) *********************************************************************/ -static BOOL eventlog_store_value( char *key, REGVAL_CTR *val ) +static BOOL eventlog_store_value( const char *key, REGVAL_CTR *val ) { return False; } diff --git a/source/registry/reg_frontend.c b/source/registry/reg_frontend.c index 9c7420ef863..51ad23b4984 100644 --- a/source/registry/reg_frontend.c +++ b/source/registry/reg_frontend.c @@ -31,13 +31,16 @@ extern REGISTRY_OPS shares_reg_ops; extern REGISTRY_OPS regdb_ops; /* these are the default */ /* array of REGISTRY_HOOK's which are read into a tree for easy access */ +/* #define REG_TDB_ONLY 1 */ REGISTRY_HOOK reg_hooks[] = { +#ifndef REG_TDB_ONLY { KEY_PRINTING, &printing_ops }, { KEY_PRINTING_2K, &printing_ops }, { KEY_PRINTING_PORTS, &printing_ops }, { KEY_EVENTLOG, &eventlog_ops }, { KEY_SHARES, &shares_reg_ops }, +#endif { NULL, NULL } }; @@ -70,9 +73,6 @@ BOOL init_registry( void ) return True; } - - - /*********************************************************************** High level wrapper function for storing registry subkeys ***********************************************************************/ @@ -81,8 +81,8 @@ BOOL store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys ) { if ( key->hook && key->hook->ops && key->hook->ops->store_subkeys ) return key->hook->ops->store_subkeys( key->name, subkeys ); - else - return False; + + return False; } @@ -92,10 +92,13 @@ BOOL store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys ) BOOL store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) { + if ( check_dynamic_reg_values( key ) ) + return False; + if ( key->hook && key->hook->ops && key->hook->ops->store_values ) return key->hook->ops->store_values( key->name, val ); - else - return False; + + return False; } @@ -165,10 +168,8 @@ BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index return True; } - /*********************************************************************** High level wrapper function for enumerating registry values - Initialize the TALLOC_CTX if necessary ***********************************************************************/ int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) @@ -177,7 +178,15 @@ int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) if ( key->hook && key->hook->ops && key->hook->ops->fetch_values ) result = key->hook->ops->fetch_values( key->name, val ); + + /* if the backend lookup returned no data, try the dynamic overlay */ + + if ( result == 0 ) { + result = fetch_dynamic_reg_values( key, val ); + return ( result != -1 ) ? result : 0; + } + return result; } @@ -211,7 +220,7 @@ BOOL fetch_reg_values_specific( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32 ctr_init = True; } /* clear the cache when val_index == 0 or the path has changed */ - else if ( !val_index || StrCaseCmp(save_path, key->name) ) { + else if ( !val_index || !strequal(save_path, key->name) ) { DEBUG(8,("fetch_reg_values_specific: Updating cache of values for [%s]\n", key->name)); diff --git a/source/registry/reg_objects.c b/source/registry/reg_objects.c index 582a696529f..d6482e698b0 100644 --- a/source/registry/reg_objects.c +++ b/source/registry/reg_objects.c @@ -94,7 +94,7 @@ int regsubkey_ctr_delkey( REGSUBKEY_CTR *ctr, const char *keyname ) /* update if we have any keys left */ ctr->num_subkeys--; - if ( ctr->num_subkeys ) + if ( i < ctr->num_subkeys ) memmove( &ctr->subkeys[i], &ctr->subkeys[i+1], sizeof(char*) * (ctr->num_subkeys-i) ); return ctr->num_subkeys; @@ -114,7 +114,6 @@ BOOL regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname ) } return False; - } /*********************************************************************** @@ -233,7 +232,7 @@ uint8* regval_data_p( REGISTRY_VALUE *val ) /********************************************************************** *********************************************************************/ -int regval_size( REGISTRY_VALUE *val ) +uint32 regval_size( REGISTRY_VALUE *val ) { return val->size; } @@ -276,10 +275,24 @@ TALLOC_CTX* regval_ctr_getctx( REGVAL_CTR *val ) if ( !val ) return NULL; - return val->ctx; -} + return val->ctx; } /*********************************************************************** + Check for the existance of a value + **********************************************************************/ + +BOOL regval_ctr_key_exists( REGVAL_CTR *ctr, const char *value ) +{ + int i; + + for ( i=0; i<ctr->num_values; i++ ) { + if ( strequal( ctr->values[i]->valuename, value) ) + return True; + } + + return False; +} +/*********************************************************************** Add a new registry value to the array **********************************************************************/ @@ -291,6 +304,10 @@ int regval_ctr_addvalue( REGVAL_CTR *ctr, const char *name, uint16 type, if ( !name ) return ctr->num_values; + /* Delete the current value (if it exists) and add the new one */ + + regval_ctr_delvalue( ctr, name ); + /* allocate a slot in the array of pointers */ if ( ctr->num_values == 0 ) @@ -361,12 +378,8 @@ int regval_ctr_delvalue( REGVAL_CTR *ctr, const char *name ) { int i; - /* search for the value */ - if (!(ctr->num_values)) - return 0; - for ( i=0; i<ctr->num_values; i++ ) { - if ( strcmp( ctr->values[i]->valuename, name ) == 0) + if ( strequal( ctr->values[i]->valuename, name ) ) break; } @@ -375,16 +388,10 @@ int regval_ctr_delvalue( REGVAL_CTR *ctr, const char *name ) if ( i == ctr->num_values ) return ctr->num_values; - /* just shift everything down one */ - - for ( /* use previous i */; i<(ctr->num_values-1); i++ ) - memcpy( ctr->values[i], ctr->values[i+1], sizeof(REGISTRY_VALUE) ); - - /* paranoia */ - - ZERO_STRUCTP( ctr->values[i] ); - + /* If 'i' was not the last element, just shift everything down one */ ctr->num_values--; + if ( i < ctr->num_values ) + memmove( &ctr->values[i], &ctr->values[i+1], sizeof(REGISTRY_VALUE*)*(ctr->num_values-i) ); return ctr->num_values; } diff --git a/source/registry/reg_printing.c b/source/registry/reg_printing.c index b0fb4ab9d90..c1f7d3925f8 100644 --- a/source/registry/reg_printing.c +++ b/source/registry/reg_printing.c @@ -25,115 +25,716 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV -#define MAX_TOP_LEVEL_KEYS 3 +/* registrt paths used in the print_registry[] */ + +#define KEY_MONITORS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/MONITORS" +#define KEY_FORMS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS" +#define KEY_CONTROL_PRINTERS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS" +#define KEY_ENVIRONMENTS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/ENVIRONMENTS" +#define KEY_CONTROL_PRINT "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT" +#define KEY_WINNT_PRINTERS "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS" +#define KEY_WINNT_PRINT "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT" +#define KEY_PORTS "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PORTS" + +/* callback table for various registry paths below the ones we service in this module */ + +struct reg_dyn_tree { + /* full key path in normalized form */ + const char *path; + + /* callbscks for fetch/store operations */ + int ( *fetch_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys ); + BOOL (*store_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys ); + int (*fetch_values) ( const char *path, REGVAL_CTR *values ); + BOOL (*store_values) ( const char *path, REGVAL_CTR *values ); +}; -/* some symbolic indexes into the top_level_keys */ +/********************************************************************* + ********************************************************************* + ** Utility Functions + ********************************************************************* + *********************************************************************/ -#define KEY_INDEX_ENVIR 0 -#define KEY_INDEX_FORMS 1 -#define KEY_INDEX_PRINTER 2 +/********************************************************************** + move to next non-delimter character +*********************************************************************/ -static const char *top_level_keys[MAX_TOP_LEVEL_KEYS] = { - "Environments", - "Forms", - "Printers" -}; +static char* remaining_path( const char *key ) +{ + static pstring new_path; + char *p; + if ( !key || !*key ) + return NULL; -/********************************************************************** - It is safe to assume that every registry path passed into on of - the exported functions here begins with KEY_PRINTING else - these functions would have never been called. This is a small utility - function to strip the beginning of the path and make a copy that the - caller can modify. Note that the caller is responsible for releasing - the memory allocated here. - **********************************************************************/ + pstrcpy( new_path, key ); + /* normalize_reg_path( new_path ); */ + + if ( !(p = strchr( new_path, '\\' )) ) + { + if ( !(p = strchr( new_path, '/' )) ) + p = new_path; + else + p++; + } + else + p++; + + return p; +} -static char* trim_reg_path( char *path ) +/*********************************************************************** + simple function to prune a pathname down to the basename of a file + **********************************************************************/ + +static char* dos_basename ( char *path ) { char *p; - uint16 key_len = strlen(path); - uint16 base_key_len; + + if ( !(p = strrchr( path, '\\' )) ) + p = path; + else + p++; + + return p; +} - int key_printing_len = strlen( KEY_PRINTING ); - int key_printing2k_len = strlen( KEY_PRINTING_2K ); - int key_printing_ports_len = strlen( KEY_PRINTING_PORTS ); +/********************************************************************* + ********************************************************************* + ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS" + ********************************************************************* + *********************************************************************/ +static int key_forms_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ) +{ + char *p = remaining_path( key + strlen(KEY_FORMS) ); + + /* no keys below Forms */ + + if ( p ) + return -1; + + return 0; +} +/********************************************************************** + *********************************************************************/ + +static int key_forms_fetch_values( const char *key, REGVAL_CTR *values ) +{ + uint32 data[8]; + int i, num_values, form_index = 1; + nt_forms_struct *forms_list = NULL; + nt_forms_struct *form; + + DEBUG(10,("print_values_forms: key=>[%s]\n", key ? key : "NULL" )); + + num_values = get_ntforms( &forms_list ); + + DEBUG(10,("hive_forms_fetch_values: [%d] user defined forms returned\n", + num_values)); + + /* handle user defined forms */ + + for ( i=0; i<num_values; i++ ) { + form = &forms_list[i]; + + data[0] = form->width; + data[1] = form->length; + data[2] = form->left; + data[3] = form->top; + data[4] = form->right; + data[5] = form->bottom; + data[6] = form_index++; + data[7] = form->flag; + + regval_ctr_addvalue( values, form->name, REG_BINARY, (char*)data, sizeof(data) ); + } + + SAFE_FREE( forms_list ); + forms_list = NULL; + + /* handle built-on forms */ + + num_values = get_builtin_ntforms( &forms_list ); + + DEBUG(10,("print_subpath_values_forms: [%d] built-in forms returned\n", + num_values)); + + for ( i=0; i<num_values; i++ ) { + form = &forms_list[i]; + + data[0] = form->width; + data[1] = form->length; + data[2] = form->left; + data[3] = form->top; + data[4] = form->right; + data[5] = form->bottom; + data[6] = form_index++; + data[7] = form->flag; + + regval_ctr_addvalue( values, form->name, REG_BINARY, (char*)data, sizeof(data) ); + } + + SAFE_FREE( forms_list ); + + return regval_ctr_numvals( values ); +} + +/********************************************************************* + ********************************************************************* + ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS" + ** "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS" + ********************************************************************* + *********************************************************************/ + +/********************************************************************* + strip off prefix for printers key. DOes return a pointer to static + memory. + *********************************************************************/ + +static char* strip_printers_prefix( const char *key ) +{ + char *subkeypath; + pstring path; + + pstrcpy( path, key ); + normalize_reg_path( path ); + + /* normalizing the path does not change length, just key delimiters and case */ + + if ( strncmp( path, KEY_WINNT_PRINTERS, strlen(KEY_WINNT_PRINTERS) ) == 0 ) + subkeypath = remaining_path( key + strlen(KEY_WINNT_PRINTERS) ); + else + subkeypath = remaining_path( key + strlen(KEY_CONTROL_PRINTERS) ); + + return subkeypath; +} + +/********************************************************************* + *********************************************************************/ + +static int key_printers_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ) +{ + int n_services = lp_numservices(); + int snum; + fstring sname; + int i; + int num_subkeys = 0; + char *printers_key; + char *printername, *printerdatakey; + NT_PRINTER_INFO_LEVEL *printer = NULL; + fstring *subkey_names = NULL; - /* - * sanity check...this really should never be True. - * It is only here to prevent us from accessing outside - * the path buffer in the extreme case. - */ + DEBUG(10,("key_printers_fetch_keys: key=>[%s]\n", key ? key : "NULL" )); - if ( (key_len < key_printing_len) - && (key_len < key_printing2k_len) - && (key_len < key_printing_ports_len) ) + printers_key = strip_printers_prefix( key ); + + if ( !printers_key ) { + /* enumerate all printers */ + + for (snum=0; snum<n_services; snum++) { + if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) ) + continue; + + /* don't report the [printers] share */ + + if ( strequal( lp_servicename(snum), PRINTERS_NAME ) ) + continue; + + fstrcpy( sname, lp_servicename(snum) ); + + regsubkey_ctr_addkey( subkeys, sname ); + } + + num_subkeys = regsubkey_ctr_numkeys( subkeys ); + goto done; + } + + /* get information for a specific printer */ + + reg_split_path( printers_key, &printername, &printerdatakey ); + + if ( find_service(printername) == -1 + || !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) { - DEBUG(0,("trim_reg_path: Registry path too short! [%s]\n", path)); - return NULL; + return -1; } - base_key_len = 0; - if ( StrnCaseCmp( KEY_PRINTING, path, key_printing_len ) == 0 ) { - base_key_len = key_printing_len; + num_subkeys = get_printer_subkeys( &printer->info_2->data, printerdatakey?printerdatakey:"", &subkey_names ); + + for ( i=0; i<num_subkeys; i++ ) + regsubkey_ctr_addkey( subkeys, subkey_names[i] ); + + free_a_printer( &printer, 2 ); + + /* no other subkeys below here */ + +done: + SAFE_FREE( subkey_names ); + + return num_subkeys; +} + +/********************************************************************** + Take a list of names and call add_printer_hook() if necessary + Note that we do this a little differently from Windows since the + keyname is the sharename and not the printer name. + *********************************************************************/ + +static BOOL add_printers_by_registry( REGSUBKEY_CTR *subkeys ) +{ + int i, num_keys, snum; + char *printername; + NT_PRINTER_INFO_LEVEL_2 info2; + NT_PRINTER_INFO_LEVEL printer; + + ZERO_STRUCT( info2 ); + printer.info_2 = &info2; + + num_keys = regsubkey_ctr_numkeys( subkeys ); + + become_root(); + for ( i=0; i<num_keys; i++ ) { + printername = regsubkey_ctr_specific_key( subkeys, i ); + snum = find_service( printername ); + + /* just verify a valied snum for now */ + if ( snum == -1 ) { + fstrcpy( info2.printername, printername ); + fstrcpy( info2.sharename, printername ); + if ( !add_printer_hook( NULL, &printer ) ) { + DEBUG(0,("add_printers_by_registry: Failed to add printer [%s]\n", + printername)); + } + } + } + unbecome_root(); + + return True; +} + +/********************************************************************** + *********************************************************************/ + +static BOOL key_printers_store_keys( const char *key, REGSUBKEY_CTR *subkeys ) +{ + char *printers_key; + char *printername, *printerdatakey; + NT_PRINTER_INFO_LEVEL *printer = NULL; + int i, num_subkeys, num_existing_keys; + char *subkeyname; + fstring *existing_subkeys = NULL; + + printers_key = strip_printers_prefix( key ); + + if ( !printers_key ) { + /* have to deal with some new or deleted printer */ + return add_printers_by_registry( subkeys ); } - else if ( StrnCaseCmp( KEY_PRINTING_2K, path, key_printing2k_len ) == 0 ) { - base_key_len = key_printing2k_len; + + reg_split_path( printers_key, &printername, &printerdatakey ); + + /* lookup the printer */ + + if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, printername)) ) { + DEBUG(0,("key_printers_store_keys: Tried to store subkey for bad printername %s\n", + printername)); + return False; } - else if ( StrnCaseCmp( KEY_PRINTING_PORTS, path, key_printing2k_len ) == 0 ) { - base_key_len = key_printing_ports_len; + + /* get the top level printer keys */ + + num_existing_keys = get_printer_subkeys( &printer->info_2->data, "", &existing_subkeys ); + + for ( i=0; i<num_existing_keys; i++ ) { + + /* remove the key if it has been deleted */ + + if ( !regsubkey_ctr_key_exists( subkeys, existing_subkeys[i] ) ) { + DEBUG(5,("key_printers_store_keys: deleting key %s\n", + existing_subkeys[i])); + delete_printer_key( &printer->info_2->data, existing_subkeys[i] ); + } } - else { - DEBUG(0,("trim_reg_path: invalid path [%s]\n", path )); - return NULL; + + num_subkeys = regsubkey_ctr_numkeys( subkeys ); + for ( i=0; i<num_subkeys; i++ ) { + subkeyname = regsubkey_ctr_specific_key(subkeys, i); + /* add any missing printer keys */ + if ( lookup_printerkey(&printer->info_2->data, subkeyname) == -1 ) { + DEBUG(5,("key_printers_store_keys: adding key %s\n", + existing_subkeys[i])); + if ( add_new_printer_key( &printer->info_2->data, subkeyname ) == -1 ) + return False; + } } - p = path + base_key_len; + /* write back to disk */ - if ( *p == '\\' ) - p++; + mod_a_printer( printer, 2 ); - if ( *p ) - return SMB_STRDUP(p); - else - return NULL; + /* cleanup */ + + if ( printer ) + free_a_printer( &printer, 2 ); + + return True; } /********************************************************************** *********************************************************************/ - -static int fill_ports_values( REGVAL_CTR *values ) + +static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *values ) { - int numlines, i; - char **lines; - UNISTR2 data; - WERROR result; + DEVICEMODE *devmode; + prs_struct prs; + uint32 offset; + UNISTR2 data; + char *p; + uint32 printer_status = PRINTER_STATUS_OK; + int snum; + + regval_ctr_addvalue( values, "Attributes", REG_DWORD, (char*)&info2->attributes, sizeof(info2->attributes) ); + regval_ctr_addvalue( values, "Priority", REG_DWORD, (char*)&info2->priority, sizeof(info2->attributes) ); + regval_ctr_addvalue( values, "ChangeID", REG_DWORD, (char*)&info2->changeid, sizeof(info2->changeid) ); + regval_ctr_addvalue( values, "Default Priority", REG_DWORD, (char*)&info2->default_priority, sizeof(info2->default_priority) ); + + /* lie and say everything is ok since we don't want to call print_queue_length() to get the real status */ + regval_ctr_addvalue( values, "Status", REG_DWORD, (char*)&printer_status, sizeof(info2->status) ); + + regval_ctr_addvalue( values, "StartTime", REG_DWORD, (char*)&info2->starttime, sizeof(info2->starttime) ); + regval_ctr_addvalue( values, "UntilTime", REG_DWORD, (char*)&info2->untiltime, sizeof(info2->untiltime) ); - result = enumports_hook( &numlines, &lines ); + /* strip the \\server\ from this string */ + if ( !(p = strrchr( info2->printername, '\\' ) ) ) + p = info2->printername; + else + p++; + init_unistr2( &data, p, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - if ( !W_ERROR_IS_OK(result) ) + init_unistr2( &data, info2->location, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Location", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, info2->comment, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Description", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, info2->parameters, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Parameters", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, info2->portname, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Port", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, info2->sharename, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Share Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, info2->drivername, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Printer Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, info2->sepfile, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Separator File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, "WinPrint", UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Print Processor", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, "RAW", UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Datatype", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + + /* use a prs_struct for converting the devmode and security + descriptor to REG_BINARY */ + + prs_init( &prs, MAX_PDU_FRAG_LEN, regval_ctr_getctx(values), MARSHALL); + + /* stream the device mode */ + + snum = lp_servicenumber(info2->sharename); + if ( (devmode = construct_dev_mode( snum )) != NULL ) { + if ( spoolss_io_devmode( "devmode", &prs, 0, devmode ) ) { + offset = prs_offset( &prs ); + regval_ctr_addvalue( values, "Default Devmode", REG_BINARY, prs_data_p(&prs), offset ); + } + } + + prs_mem_clear( &prs ); + prs_set_offset( &prs, 0 ); + + /* stream the printer security descriptor */ + + if ( info2->secdesc_buf && info2->secdesc_buf->len ) { + if ( sec_io_desc("sec_desc", &info2->secdesc_buf->sec, &prs, 0 ) ) { + offset = prs_offset( &prs ); + regval_ctr_addvalue( values, "Security", REG_BINARY, prs_data_p(&prs), offset ); + } + } + + prs_mem_free( &prs ); + + return; +} + +/********************************************************************** + *********************************************************************/ + +static int key_printers_fetch_values( const char *key, REGVAL_CTR *values ) +{ + int num_values; + char *printers_key; + char *printername, *printerdatakey; + NT_PRINTER_INFO_LEVEL *printer = NULL; + NT_PRINTER_DATA *p_data; + int i, key_index; + + printers_key = strip_printers_prefix( key ); + + /* top level key values stored in the registry has no values */ + + if ( !printers_key ) { + /* normalize to the 'HKLM\SOFTWARE\...\Print\Printers' ket */ + return regdb_fetch_values( KEY_WINNT_PRINTERS, values ); + } + + /* lookup the printer object */ + + reg_split_path( printers_key, &printername, &printerdatakey ); + if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) + goto done; + + if ( !printerdatakey ) { + fill_in_printer_values( printer->info_2, values ); + goto done; + } + + /* iterate over all printer data keys and fill the regval container */ + + p_data = &printer->info_2->data; + if ( (key_index = lookup_printerkey( p_data, printerdatakey )) == -1 ) { + /* failure....should never happen if the client has a valid open handle first */ + DEBUG(10,("key_printers_fetch_values: Unknown keyname [%s]\n", printerdatakey)); + if ( printer ) + free_a_printer( &printer, 2 ); return -1; + } + + num_values = regval_ctr_numvals( &p_data->keys[key_index].values ); + for ( i=0; i<num_values; i++ ) + regval_ctr_copyvalue( values, regval_ctr_specific_value(&p_data->keys[key_index].values, i) ); + + +done: + if ( printer ) + free_a_printer( &printer, 2 ); + + return regval_ctr_numvals( values ); +} + +/********************************************************************** + *********************************************************************/ + +#define REG_IDX_ATTRIBUTES 1 +#define REG_IDX_PRIORITY 2 +#define REG_IDX_DEFAULT_PRIORITY 3 +#define REG_IDX_CHANGEID 4 +#define REG_IDX_STATUS 5 +#define REG_IDX_STARTTIME 6 +#define REG_IDX_NAME 7 +#define REG_IDX_LOCATION 8 +#define REG_IDX_DESCRIPTION 9 +#define REG_IDX_PARAMETERS 10 +#define REG_IDX_PORT 12 +#define REG_IDX_SHARENAME 13 +#define REG_IDX_DRIVER 14 +#define REG_IDX_SEP_FILE 15 +#define REG_IDX_PRINTPROC 16 +#define REG_IDX_DATATYPE 17 +#define REG_IDX_DEVMODE 18 +#define REG_IDX_SECDESC 19 +#define REG_IDX_UNTILTIME 20 + +struct { + const char *name; + int index; +} printer_values_map[] = { + { "Attributes", REG_IDX_ATTRIBUTES }, + { "Priority", REG_IDX_PRIORITY }, + { "Default Priority", REG_IDX_DEFAULT_PRIORITY }, + { "ChangeID", REG_IDX_CHANGEID }, + { "Status", REG_IDX_STATUS }, + { "StartTime", REG_IDX_STARTTIME }, + { "UntilTime", REG_IDX_UNTILTIME }, + { "Name", REG_IDX_NAME }, + { "Location", REG_IDX_LOCATION }, + { "Descrioption", REG_IDX_DESCRIPTION }, + { "Parameters", REG_IDX_PARAMETERS }, + { "Port", REG_IDX_PORT }, + { "Share Name", REG_IDX_SHARENAME }, + { "Printer Driver", REG_IDX_DRIVER }, + { "Separator File", REG_IDX_SEP_FILE }, + { "Print Processor", REG_IDX_PRINTPROC }, + { "Datatype", REG_IDX_DATATYPE }, + { "Default Devmode", REG_IDX_DEVMODE }, + { "Security", REG_IDX_SECDESC }, + { NULL, -1 } +}; - init_unistr2( &data, "", UNI_STR_TERMINATE); - for ( i=0; i<numlines; i++ ) - regval_ctr_addvalue( values, lines[i], REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - return numlines; +static int find_valuename_index( const char *valuename ) +{ + int i; + + for ( i=0; printer_values_map[i].name; i++ ) { + if ( strequal( valuename, printer_values_map[i].name ) ) + return printer_values_map[i].index; + } + + return -1; } - /********************************************************************** - handle enumeration of subkeys below KEY_PRINTING\Environments - Environments\$ARCH\Print Processors - Environments\$ARCH\Drivers\{0,2,3} *********************************************************************/ - -#define ENVIRONMENT_DRIVERS 1 -#define ENVIRONMENT_PRINTPROC 2 -static int print_subpath_environments( char *key, REGSUBKEY_CTR *subkeys ) +static void convert_values_to_printer_info_2( NT_PRINTER_INFO_LEVEL_2 *printer2, REGVAL_CTR *values ) +{ + int num_values = regval_ctr_numvals( values ); + uint32 value_index; + REGISTRY_VALUE *val; + int i; + + for ( i=0; i<num_values; i++ ) { + val = regval_ctr_specific_value( values, i ); + value_index = find_valuename_index( regval_name( val ) ); + + switch( value_index ) { + case REG_IDX_ATTRIBUTES: + printer2->attributes = (uint32)(*regval_data_p(val)); + break; + case REG_IDX_PRIORITY: + printer2->priority = (uint32)(*regval_data_p(val)); + break; + case REG_IDX_DEFAULT_PRIORITY: + printer2->default_priority = (uint32)(*regval_data_p(val)); + break; + case REG_IDX_CHANGEID: + printer2->changeid = (uint32)(*regval_data_p(val)); + break; + case REG_IDX_STARTTIME: + printer2->starttime = (uint32)(*regval_data_p(val)); + break; + case REG_IDX_UNTILTIME: + printer2->untiltime = (uint32)(*regval_data_p(val)); + break; + case REG_IDX_NAME: + rpcstr_pull( printer2->printername, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_LOCATION: + rpcstr_pull( printer2->location, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_DESCRIPTION: + rpcstr_pull( printer2->comment, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_PARAMETERS: + rpcstr_pull( printer2->parameters, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_PORT: + rpcstr_pull( printer2->portname, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_SHARENAME: + rpcstr_pull( printer2->sharename, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_DRIVER: + rpcstr_pull( printer2->drivername, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_SEP_FILE: + rpcstr_pull( printer2->sepfile, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_PRINTPROC: + rpcstr_pull( printer2->printprocessor, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_DATATYPE: + rpcstr_pull( printer2->datatype, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_DEVMODE: + break; + case REG_IDX_SECDESC: + break; + default: + /* unsupported value...throw away */ + DEBUG(8,("convert_values_to_printer_info_2: Unsupported registry value [%s]\n", + regval_name( val ) )); + } + } + + return; +} + +/********************************************************************** + *********************************************************************/ + +static BOOL key_printers_store_values( const char *key, REGVAL_CTR *values ) +{ + char *printers_key; + char *printername, *keyname; + NT_PRINTER_INFO_LEVEL *printer = NULL; + WERROR result; + + printers_key = strip_printers_prefix( key ); + + /* values in the top level key get stored in the registry */ + + if ( !printers_key ) { + /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */ + return regdb_store_values( KEY_WINNT_PRINTERS, values ); + } + + reg_split_path( printers_key, &printername, &keyname ); + + if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, printername) ) ) + return False; + + /* deal with setting values directly under the printername */ + + if ( !keyname ) { + convert_values_to_printer_info_2( printer->info_2, values ); + } + else { + int num_values = regval_ctr_numvals( values ); + int i; + REGISTRY_VALUE *val; + + delete_printer_key( &printer->info_2->data, keyname ); + + /* deal with any subkeys */ + for ( i=0; i<num_values; i++ ) { + val = regval_ctr_specific_value( values, i ); + result = set_printer_dataex( printer, keyname, + regval_name( val ), + regval_type( val ), + regval_data_p( val ), + regval_size( val ) ); + if ( !W_ERROR_IS_OK(result) ) { + DEBUG(0,("key_printers_store_values: failed to set printer data [%s]!\n", + keyname)); + free_a_printer( &printer, 2 ); + return False; + } + } + } + + result = mod_a_printer( printer, 2 ); + + free_a_printer( &printer, 2 ); + + return W_ERROR_IS_OK(result); +} + +/********************************************************************* + ********************************************************************* + ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/ENVIRONMENTS" + ********************************************************************* + *********************************************************************/ + +static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ) { const char *environments[] = { "Windows 4.0", @@ -149,14 +750,15 @@ static int print_subpath_environments( char *key, REGSUBKEY_CTR *subkeys ) char *keystr, *base, *subkeypath; pstring key2; int num_subkeys = -1; - int env_subkey_type = 0; int version; - DEBUG(10,("print_subpath_environments: key=>[%s]\n", key ? key : "NULL" )); + DEBUG(10,("key_driver_fetch_keys key=>[%s]\n", key ? key : "NULL" )); + + keystr = remaining_path( key + strlen(KEY_ENVIRONMENTS) ); /* list all possible architectures */ - if ( !key ) { + if ( !keystr ) { for ( num_subkeys=0; environments[num_subkeys]; num_subkeys++ ) regsubkey_ctr_addkey( subkeys, environments[num_subkeys] ); @@ -165,7 +767,7 @@ static int print_subpath_environments( char *key, REGSUBKEY_CTR *subkeys ) /* we are dealing with a subkey of "Environments */ - pstrcpy( key2, key ); + pstrcpy( key2, keystr ); keystr = key2; reg_split_path( keystr, &base, &subkeypath ); @@ -194,17 +796,8 @@ static int print_subpath_environments( char *key, REGSUBKEY_CTR *subkeys ) /* ...\Print\Environements\...\Drivers\ */ - if ( strequal(base, "Drivers") ) - env_subkey_type = ENVIRONMENT_DRIVERS; - else if ( strequal(base, "Print Processors") ) - env_subkey_type = ENVIRONMENT_PRINTPROC; - else - /* invalid path */ - return -1; - if ( !subkeypath ) { - switch ( env_subkey_type ) { - case ENVIRONMENT_DRIVERS: + if ( strequal(base, "Drivers") ) { switch ( env_index ) { case 0: /* Win9x */ regsubkey_ctr_addkey( subkeys, "Version-0" ); @@ -216,29 +809,37 @@ static int print_subpath_environments( char *key, REGSUBKEY_CTR *subkeys ) } return regsubkey_ctr_numkeys( subkeys ); - - case ENVIRONMENT_PRINTPROC: + } else if ( strequal(base, "Print Processors") ) { if ( env_index == 1 || env_index == 5 || env_index == 6 ) regsubkey_ctr_addkey( subkeys, "winprint" ); return regsubkey_ctr_numkeys( subkeys ); - } + } else + return -1; /* bad path */ } /* we finally get to enumerate the drivers */ - keystr = subkeypath; - reg_split_path( keystr, &base, &subkeypath ); + /* only one possible subkey below PrintProc key */ + + if ( strequal(base, "Print Processors") ) { + keystr = subkeypath; + reg_split_path( keystr, &base, &subkeypath ); - /* get thr print processors key out of the way */ - if ( env_subkey_type == ENVIRONMENT_PRINTPROC ) { - if ( !strequal( base, "winprint" ) ) + /* no subkeys below this point */ + + if ( subkeypath ) return -1; - return !subkeypath ? 0 : -1; + + /* only allow one keyname here -- 'winprint' */ + + return strequal( base, "winprint" ) ? 0 : -1; } /* only dealing with drivers from here on out */ - + + keystr = subkeypath; + reg_split_path( keystr, &base, &subkeypath ); version = atoi(&base[strlen(base)-1]); switch (env_index) { @@ -263,133 +864,51 @@ static int print_subpath_environments( char *key, REGSUBKEY_CTR *subkeys ) /* if anything else left, just say if has no subkeys */ - DEBUG(1,("print_subpath_environments: unhandled key [%s] (subkey == %s\n", + DEBUG(1,("key_driver_fetch_keys unhandled key [%s] (subkey == %s\n", key, subkeypath )); return 0; } -/*********************************************************************** - simple function to prune a pathname down to the basename of a file - **********************************************************************/ - -static char* dos_basename ( char *path ) -{ - char *p; - - p = strrchr( path, '\\' ); - if ( p ) - p++; - else - p = path; - - return p; -} /********************************************************************** - handle enumeration of values below - KEY_PRINTING\Environments\<arch>\<version>\<drivername> *********************************************************************/ - -static int print_subpath_values_environments( char *key, REGVAL_CTR *val ) -{ - char *keystr, *base, *subkeypath; - pstring key2; - fstring arch_environment; - fstring driver; - int version; - NT_PRINTER_DRIVER_INFO_LEVEL driver_ctr; - NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3; - WERROR w_result; - char *buffer = NULL; - char *buffer2 = NULL; - int buffer_size = 0; - int i, length; - char *filename; - UNISTR2 data; - int env_subkey_type = 0; - - - DEBUG(8,("print_subpath_values_environments: Enter key => [%s]\n", key ? key : "NULL")); - - if ( !key ) - return 0; - - /* The only keys below KEY_PRINTING\Environments is the - specific printer driver info */ - - /* environment */ - - pstrcpy( key2, key ); - keystr = key2; - reg_split_path( keystr, &base, &subkeypath ); - if ( !subkeypath ) - return 0; - fstrcpy( arch_environment, base ); - - /* Driver */ - - keystr = subkeypath; - reg_split_path( keystr, &base, &subkeypath ); - if ( strequal(base, "Drivers") ) - env_subkey_type = ENVIRONMENT_DRIVERS; - else if ( strequal(base, "Print Processors") ) - env_subkey_type = ENVIRONMENT_PRINTPROC; - else - /* invalid path */ - return -1; - - if ( !subkeypath ) - return 0; - - /* for now bail out if we are seeing anything other than the drivers key */ - - if ( env_subkey_type == ENVIRONMENT_PRINTPROC ) - return 0; - - keystr = subkeypath; - reg_split_path( keystr, &base, &subkeypath ); - - version = atoi(&base[strlen(base)-1]); - - /* printer driver name */ - - keystr = subkeypath; - reg_split_path( keystr, &base, &subkeypath ); - /* don't go any deeper for now */ - if ( subkeypath ) - return 0; - fstrcpy( driver, base ); - - w_result = get_a_printer_driver( &driver_ctr, 3, driver, arch_environment, version ); - - if ( !W_ERROR_IS_OK(w_result) ) - return -1; - - /* build the values out of the driver information */ - info3 = driver_ctr.info_3; +static void fill_in_driver_values( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3, REGVAL_CTR *values ) +{ + char *buffer = NULL; + char *buffer2 = NULL; + int buffer_size = 0; + int i, length; + char *filename; + UNISTR2 data; filename = dos_basename( info3->driverpath ); init_unistr2( &data, filename, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + regval_ctr_addvalue( values, "Driver", REG_SZ, (char*)data.buffer, + data.uni_str_len*sizeof(uint16) ); filename = dos_basename( info3->configfile ); init_unistr2( &data, filename, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Configuration File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + regval_ctr_addvalue( values, "Configuration File", REG_SZ, (char*)data.buffer, + data.uni_str_len*sizeof(uint16) ); filename = dos_basename( info3->datafile ); init_unistr2( &data, filename, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Data File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + regval_ctr_addvalue( values, "Data File", REG_SZ, (char*)data.buffer, + data.uni_str_len*sizeof(uint16) ); filename = dos_basename( info3->helpfile ); init_unistr2( &data, filename, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Help File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + regval_ctr_addvalue( values, "Help File", REG_SZ, (char*)data.buffer, + data.uni_str_len*sizeof(uint16) ); init_unistr2( &data, info3->defaultdatatype, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Data Type", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + regval_ctr_addvalue( values, "Data Type", REG_SZ, (char*)data.buffer, + data.uni_str_len*sizeof(uint16) ); - regval_ctr_addvalue( val, "Version", REG_DWORD, (char*)&info3->cversion, sizeof(info3->cversion) ); + regval_ctr_addvalue( values, "Version", REG_DWORD, (char*)&info3->cversion, + sizeof(info3->cversion) ); if ( info3->dependentfiles ) { /* place the list of dependent files in a single @@ -427,497 +946,282 @@ static int print_subpath_values_environments( char *key, REGVAL_CTR *val ) } } - regval_ctr_addvalue( val, "Dependent Files", REG_MULTI_SZ, buffer, buffer_size ); - - free_a_printer_driver( driver_ctr, 3 ); - - SAFE_FREE( buffer ); + regval_ctr_addvalue( values, "Dependent Files", REG_MULTI_SZ, buffer, buffer_size ); - DEBUG(8,("print_subpath_values_environments: Exit\n")); + SAFE_FREE( buffer ); - return regval_ctr_numvals( val ); + return; } - /********************************************************************** - handle enumeration of subkeys below KEY_PRINTING\Forms - Really just a stub function, but left here in case it needs to - be expanded later on *********************************************************************/ - -static int print_subpath_forms( char *key, REGSUBKEY_CTR *subkeys ) -{ - DEBUG(10,("print_subpath_forms: key=>[%s]\n", key ? key : "NULL" )); - - /* there are no subkeys */ - - if ( key ) - return -1; - - return 0; -} -/********************************************************************** - handle enumeration of values below KEY_PRINTING\Forms - *********************************************************************/ - -static int print_subpath_values_forms( char *key, REGVAL_CTR *val ) +static int driver_arch_fetch_values( char *key, REGVAL_CTR *values ) { - int num_values = 0; - uint32 data[8]; - int form_index = 1; - - DEBUG(10,("print_values_forms: key=>[%s]\n", key ? key : "NULL" )); + char *keystr, *base, *subkeypath; + fstring arch_environment; + fstring driver; + int version; + NT_PRINTER_DRIVER_INFO_LEVEL driver_ctr; + WERROR w_result; + + reg_split_path( key, &base, &subkeypath ); - /* handle ..\Forms\ */ + /* no values in 'Environments\Drivers\Windows NT x86' */ - if ( !key ) - { - nt_forms_struct *forms_list = NULL; - nt_forms_struct *form = NULL; - int i; - - if ( (num_values = get_ntforms( &forms_list )) == 0 ) - return 0; + if ( !subkeypath ) + return 0; - DEBUG(10,("print_subpath_values_forms: [%d] user defined forms returned\n", - num_values)); + /* We have the Architecture string and some subkey name: + Currently we only support + * Drivers + * Print Processors + Anything else is an error. + */ - /* handle user defined forms */ - - for ( i=0; i<num_values; i++ ) - { - form = &forms_list[i]; - - data[0] = form->width; - data[1] = form->length; - data[2] = form->left; - data[3] = form->top; - data[4] = form->right; - data[5] = form->bottom; - data[6] = form_index++; - data[7] = form->flag; - - regval_ctr_addvalue( val, form->name, REG_BINARY, (char*)data, sizeof(data) ); - - } - - SAFE_FREE( forms_list ); - forms_list = NULL; - - /* handle built-on forms */ - - if ( (num_values = get_builtin_ntforms( &forms_list )) == 0 ) - return 0; - - DEBUG(10,("print_subpath_values_forms: [%d] built-in forms returned\n", - num_values)); - - for ( i=0; i<num_values; i++ ) - { - form = &forms_list[i]; - - data[0] = form->width; - data[1] = form->length; - data[2] = form->left; - data[3] = form->top; - data[4] = form->right; - data[5] = form->bottom; - data[6] = form_index++; - data[7] = form->flag; - - regval_ctr_addvalue( val, form->name, REG_BINARY, (char*)data, sizeof(data) ); - } - - SAFE_FREE( forms_list ); - } + fstrcpy( arch_environment, base ); - return num_values; -} + keystr = subkeypath; + reg_split_path( keystr, &base, &subkeypath ); -/********************************************************************** - handle enumeration of subkeys below KEY_PRINTING\Printers - *********************************************************************/ - -static int print_subpath_printers( char *key, REGSUBKEY_CTR *subkeys ) -{ - int n_services = lp_numservices(); - int snum; - fstring sname; - int i; - int num_subkeys = 0; - char *keystr, *key2 = NULL; - char *base, *new_path; - NT_PRINTER_INFO_LEVEL *printer = NULL; - fstring *subkey_names = NULL; + if ( strequal(base, "Print Processors") ) + return 0; + + /* only Drivers key can be left */ + + if ( !strequal(base, "Drivers") ) + return -1; + + if ( !subkeypath ) + return 0; - DEBUG(10,("print_subpath_printers: key=>[%s]\n", key ? key : "NULL" )); + /* We know that we have Architechure\Drivers with some subkey name + The subkey name has to be Version-XX */ - if ( !key ) - { - /* enumerate all printers */ - - for (snum=0; snum<n_services; snum++) { - if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) ) - continue; - - /* don't report the [printers] share */ + keystr = subkeypath; + reg_split_path( keystr, &base, &subkeypath ); - if ( strequal( lp_servicename(snum), PRINTERS_NAME ) ) - continue; - - fstrcpy( sname, lp_servicename(snum) ); - - regsubkey_ctr_addkey( subkeys, sname ); - } + if ( !subkeypath ) + return 0; - num_subkeys = regsubkey_ctr_numkeys( subkeys ); - goto done; - } + version = atoi(&base[strlen(base)-1]); - /* get information for a specific printer */ + /* BEGIN PRINTER DRIVER NAME BLOCK */ - key2 = SMB_STRDUP( key ); - keystr = key2; - reg_split_path( keystr, &base, &new_path ); - - if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, base) ) ) - goto done; - - num_subkeys = get_printer_subkeys( &printer->info_2->data, new_path?new_path:"", &subkey_names ); + keystr = subkeypath; + reg_split_path( keystr, &base, &subkeypath ); - for ( i=0; i<num_subkeys; i++ ) - regsubkey_ctr_addkey( subkeys, subkey_names[i] ); + /* don't go any deeper for now */ - free_a_printer( &printer, 2 ); - - /* no other subkeys below here */ + fstrcpy( driver, base ); + + w_result = get_a_printer_driver( &driver_ctr, 3, driver, arch_environment, version ); -done: - SAFE_FREE( key2 ); - SAFE_FREE( subkey_names ); + if ( !W_ERROR_IS_OK(w_result) ) + return -1; + + fill_in_driver_values( driver_ctr.info_3, values ); - return num_subkeys; + free_a_printer_driver( driver_ctr, 3 ); + + /* END PRINTER DRIVER NAME BLOCK */ + + + DEBUG(8,("key_driver_fetch_values: Exit\n")); + + return regval_ctr_numvals( values ); } /********************************************************************** - handle enumeration of values below KEY_PRINTING\Printers *********************************************************************/ - -static int print_subpath_values_printers( char *key, REGVAL_CTR *val ) + +static int key_driver_fetch_values( const char *key, REGVAL_CTR *values ) { - int num_values = 0; - char *keystr, *key2 = NULL; - char *base, *new_path; - NT_PRINTER_INFO_LEVEL *printer = NULL; - NT_PRINTER_INFO_LEVEL_2 *info2; - DEVICEMODE *devmode; - prs_struct prs; - uint32 offset; - int snum; - fstring printername; - NT_PRINTER_DATA *p_data; - int i, key_index; - UNISTR2 data; + char *keystr; + pstring subkey; - /* - * Theres are tw cases to deal with here - * (1) enumeration of printer_info_2 values - * (2) enumeration of the PrinterDriverData subney - */ - - if ( !key ) { - /* top level key has no values */ - goto done; - } + DEBUG(8,("key_driver_fetch_values: Enter key => [%s]\n", key ? key : "NULL")); + + /* no values in the Environments key */ - key2 = SMB_STRDUP( key ); - keystr = key2; - reg_split_path( keystr, &base, &new_path ); + if ( !(keystr = remaining_path( key + strlen(KEY_ENVIRONMENTS) )) ) + return 0; - fstrcpy( printername, base ); + pstrcpy( subkey, keystr); - if ( !new_path ) { - char *p; - - /* we are dealing with the printer itself */ - - if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) - goto done; - - info2 = printer->info_2; - - - regval_ctr_addvalue( val, "Attributes", REG_DWORD, (char*)&info2->attributes, sizeof(info2->attributes) ); - regval_ctr_addvalue( val, "Priority", REG_DWORD, (char*)&info2->priority, sizeof(info2->attributes) ); - regval_ctr_addvalue( val, "ChangeID", REG_DWORD, (char*)&info2->changeid, sizeof(info2->changeid) ); - regval_ctr_addvalue( val, "Default Priority", REG_DWORD, (char*)&info2->default_priority, sizeof(info2->default_priority) ); - regval_ctr_addvalue( val, "Status", REG_DWORD, (char*)&info2->status, sizeof(info2->status) ); - regval_ctr_addvalue( val, "StartTime", REG_DWORD, (char*)&info2->starttime, sizeof(info2->starttime) ); - regval_ctr_addvalue( val, "UntilTime", REG_DWORD, (char*)&info2->untiltime, sizeof(info2->untiltime) ); - - /* strip the \\server\ from this string */ - if ( !(p = strrchr( info2->printername, '\\' ) ) ) - p = info2->printername; - else - p++; - init_unistr2( &data, p, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, info2->location, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Location", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, info2->comment, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Description", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, info2->parameters, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Parameters", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, info2->portname, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Port", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, info2->sharename, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Share Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, info2->drivername, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Printer Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, info2->sepfile, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Separator File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, "WinPrint", UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Print Processor", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, "RAW", UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Datatype", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - - /* use a prs_struct for converting the devmode and security - descriptor to REG_BINARY */ - - prs_init( &prs, MAX_PDU_FRAG_LEN, regval_ctr_getctx(val), MARSHALL); + /* pass off to handle subkeys */ + + return driver_arch_fetch_values( subkey, values ); +} - /* stream the device mode */ - - snum = lp_servicenumber(info2->sharename); - if ( (devmode = construct_dev_mode( snum )) != NULL ) - { - if ( spoolss_io_devmode( "devmode", &prs, 0, devmode ) ) { - - offset = prs_offset( &prs ); - - regval_ctr_addvalue( val, "Default Devmode", REG_BINARY, prs_data_p(&prs), offset ); - } - - - } - - prs_mem_clear( &prs ); - prs_set_offset( &prs, 0 ); - - if ( info2->secdesc_buf && info2->secdesc_buf->len ) - { - if ( sec_io_desc("sec_desc", &info2->secdesc_buf->sec, &prs, 0 ) ) { - - offset = prs_offset( &prs ); - - regval_ctr_addvalue( val, "Security", REG_BINARY, prs_data_p(&prs), offset ); - } - } +/********************************************************************* + ********************************************************************* + ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT" + ********************************************************************* + *********************************************************************/ - prs_mem_free( &prs ); - - num_values = regval_ctr_numvals( val ); - - goto done; - - } - - /* now enumerate the key */ +static int key_print_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ) +{ + int key_len = strlen(key); - if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) - goto done; - - /* iterate over all printer data and fill the regval container */ - - p_data = &printer->info_2->data; - if ( (key_index = lookup_printerkey( p_data, new_path )) == -1 ) { - DEBUG(10,("print_subpath_values_printer: Unknown keyname [%s]\n", new_path)); - goto done; - } - - num_values = regval_ctr_numvals( &p_data->keys[key_index].values ); + /* no keys below 'Print' handled here */ - for ( i=0; i<num_values; i++ ) - regval_ctr_copyvalue( val, regval_ctr_specific_value(&p_data->keys[key_index].values, i) ); - + if ( (key_len != strlen(KEY_CONTROL_PRINT)) && (key_len != strlen(KEY_WINNT_PRINT)) ) + return -1; -done: - if ( printer ) - free_a_printer( &printer, 2 ); - - SAFE_FREE( key2 ); + regsubkey_ctr_addkey( subkeys, "Environments" ); + regsubkey_ctr_addkey( subkeys, "Monitors" ); + regsubkey_ctr_addkey( subkeys, "Forms" ); + regsubkey_ctr_addkey( subkeys, "Printers" ); - return num_values; + return regsubkey_ctr_numkeys( subkeys ); } /********************************************************************** - Routine to handle enumeration of subkeys and values - below KEY_PRINTING (depending on whether or not subkeys/val are - valid pointers. + ********************************************************************* + ** Structure to hold dispatch table of ops for various printer keys. + ** Make sure to always store deeper keys along the same path first so + ** we ge a more specific match. + ********************************************************************* *********************************************************************/ - -static int handle_printing_subpath( char *key, REGSUBKEY_CTR *subkeys, REGVAL_CTR *val ) + +static struct reg_dyn_tree print_registry[] = { +/* just pass the monitor onto the registry tdb */ +{ KEY_MONITORS, + ®db_fetch_keys, + ®db_store_keys, + ®db_fetch_values, + ®db_store_values }, +{ KEY_FORMS, + &key_forms_fetch_keys, + NULL, + &key_forms_fetch_values, + NULL }, +{ KEY_CONTROL_PRINTERS, + &key_printers_fetch_keys, + &key_printers_store_keys, + &key_printers_fetch_values, + &key_printers_store_values }, +{ KEY_ENVIRONMENTS, + &key_driver_fetch_keys, + NULL, + &key_driver_fetch_values, + NULL }, +{ KEY_CONTROL_PRINT, + &key_print_fetch_keys, + NULL, + NULL, + NULL }, +{ KEY_WINNT_PRINTERS, + &key_printers_fetch_keys, + &key_printers_store_keys, + &key_printers_fetch_values, + &key_printers_store_values }, +{ KEY_PORTS, + ®db_fetch_keys, + ®db_store_keys, + ®db_fetch_values, + ®db_store_values }, + +{ NULL, NULL, NULL, NULL, NULL } +}; + + +/********************************************************************** + ********************************************************************* + ** Main reg_printing interface functions + ********************************************************************* + *********************************************************************/ + +/*********************************************************************** + Lookup a key in the print_registry table, returning its index. + -1 on failure + **********************************************************************/ + +static int match_registry_path( const char *key ) { - int result = 0; - char *p, *base; int i; + pstring path; - DEBUG(10,("handle_printing_subpath: key=>[%s]\n", key )); - - /* - * break off the first part of the path - * topmost base **must** be one of the strings - * in top_level_keys[] - */ - - reg_split_path( key, &base, &p); - - for ( i=0; i<MAX_TOP_LEVEL_KEYS; i++ ) { - if ( StrCaseCmp( top_level_keys[i], base ) == 0 ) - break; - } - - DEBUG(10,("handle_printing_subpath: base=>[%s], i==[%d]\n", base, i)); - - if ( !(i < MAX_TOP_LEVEL_KEYS) ) + if ( !key ) return -1; - - /* Call routine to handle each top level key */ - switch ( i ) - { - case KEY_INDEX_ENVIR: - if ( subkeys ) - print_subpath_environments( p, subkeys ); - if ( val ) - print_subpath_values_environments( p, val ); - break; - - case KEY_INDEX_FORMS: - if ( subkeys ) - print_subpath_forms( p, subkeys ); - if ( val ) - print_subpath_values_forms( p, val ); - break; - - case KEY_INDEX_PRINTER: - if ( subkeys ) - print_subpath_printers( p, subkeys ); - if ( val ) - print_subpath_values_printers( p, val ); - break; + + pstrcpy( path, key ); + normalize_reg_path( path ); - /* default case for top level key that has no handler */ - - default: - break; + for ( i=0; print_registry[i].path; i++ ) { + if ( strncmp( path, print_registry[i].path, strlen(print_registry[i].path) ) == 0 ) + return i; } - - - return result; - + return -1; } -/********************************************************************** - Enumerate registry subkey names given a registry path. - Caller is responsible for freeing memory to **subkeys - *********************************************************************/ - -static int printing_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr ) + +/*********************************************************************** + **********************************************************************/ + +static int regprint_fetch_reg_keys( const char *key, REGSUBKEY_CTR *subkeys ) { - char *path; - BOOL top_level = False; - int num_subkeys = 0; - - DEBUG(10,("printing_subkey_info: key=>[%s]\n", key)); + int i = match_registry_path( key ); - path = trim_reg_path( key ); - - /* check to see if we are dealing with the top level key */ - - if ( !path ) - top_level = True; + if ( i == -1 ) + return -1; - if ( top_level ) { - /* check between the two top level keys here */ + if ( !print_registry[i].fetch_subkeys ) + return -1; - if ( strequal( KEY_PRINTING, key ) ) { - regsubkey_ctr_addkey( subkey_ctr, "Environments" ); - regsubkey_ctr_addkey( subkey_ctr, "Forms" ); - } - else if ( strequal( KEY_PRINTING_2K, key ) ) { - regsubkey_ctr_addkey( subkey_ctr, "Printers" ); - } - } - else - num_subkeys = handle_printing_subpath( path, subkey_ctr, NULL ); - - SAFE_FREE( path ); - - return num_subkeys; + return print_registry[i].fetch_subkeys( key, subkeys ); } /********************************************************************** - Enumerate registry values given a registry path. - Caller is responsible for freeing memory *********************************************************************/ -static int printing_value_info( char *key, REGVAL_CTR *val ) +static BOOL regprint_store_reg_keys( const char *key, REGSUBKEY_CTR *subkeys ) { - char *path; - BOOL top_level = False; - int num_values = 0; - - DEBUG(10,("printing_value_info: key=>[%s]\n", key)); - - path = trim_reg_path( key ); + int i = match_registry_path( key ); - /* check to see if we are dealing with the top level key */ + if ( i == -1 ) + return False; - if ( !path ) - top_level = True; - - /* fill in values from the getprinterdata_printer_server() */ - if ( top_level ) { - if ( strequal( key, KEY_PRINTING_PORTS ) ) - num_values = fill_ports_values( val ); - } else - num_values = handle_printing_subpath( path, NULL, val ); + if ( !print_registry[i].store_subkeys ) + return False; - - return num_values; + return print_registry[i].store_subkeys( key, subkeys ); } /********************************************************************** - Stub function which always returns failure since we don't want - people storing printing information directly via regostry calls - (for now at least) *********************************************************************/ -static BOOL printing_store_subkey( char *key, REGSUBKEY_CTR *subkeys ) +static int regprint_fetch_reg_values( const char *key, REGVAL_CTR *values ) { - return True; + int i = match_registry_path( key ); + + if ( i == -1 ) + return -1; + + /* return 0 values by default since we know the key had + to exist because the client opened a handle */ + + if ( !print_registry[i].fetch_values ) + return 0; + + return print_registry[i].fetch_values( key, values ); } /********************************************************************** - Stub function which always returns failure since we don't want - people storing printing information directly via regostry calls - (for now at least) *********************************************************************/ -static BOOL printing_store_value( char *key, REGVAL_CTR *val ) +static BOOL regprint_store_reg_values( const char *key, REGVAL_CTR *values ) { - return True; + int i = match_registry_path( key ); + + if ( i == -1 ) + return False; + + if ( !print_registry[i].store_values ) + return False; + + return print_registry[i].store_values( key, values ); } /* @@ -925,10 +1229,10 @@ static BOOL printing_store_value( char *key, REGVAL_CTR *val ) */ REGISTRY_OPS printing_ops = { - printing_subkey_info, - printing_value_info, - printing_store_subkey, - printing_store_value, + regprint_fetch_reg_keys, + regprint_fetch_reg_values, + regprint_store_reg_keys, + regprint_store_reg_values, NULL }; diff --git a/source/registry/reg_shares.c b/source/registry/reg_shares.c index 4531327d948..85ac812101a 100644 --- a/source/registry/reg_shares.c +++ b/source/registry/reg_shares.c @@ -34,9 +34,9 @@ the memory allocated here. **********************************************************************/ -static char* trim_reg_path( char *path ) +static char* trim_reg_path( const char *path ) { - char *p; + const char *p; uint16 key_len = strlen(KEY_SHARES); /* @@ -67,7 +67,7 @@ static char* trim_reg_path( char *path ) Caller is responsible for freeing memory to **subkeys *********************************************************************/ -static int shares_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr ) +static int shares_subkey_info( const char *key, REGSUBKEY_CTR *subkey_ctr ) { char *path; BOOL top_level = False; @@ -101,7 +101,7 @@ static int shares_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr ) Caller is responsible for freeing memory *********************************************************************/ -static int shares_value_info( char *key, REGVAL_CTR *val ) +static int shares_value_info( const char *key, REGVAL_CTR *val ) { char *path; BOOL top_level = False; @@ -134,7 +134,7 @@ static int shares_value_info( char *key, REGVAL_CTR *val ) (for now at least) *********************************************************************/ -static BOOL shares_store_subkey( char *key, REGSUBKEY_CTR *subkeys ) +static BOOL shares_store_subkey( const char *key, REGSUBKEY_CTR *subkeys ) { return False; } @@ -145,7 +145,7 @@ static BOOL shares_store_subkey( char *key, REGSUBKEY_CTR *subkeys ) (for now at least) *********************************************************************/ -static BOOL shares_store_value( char *key, REGVAL_CTR *val ) +static BOOL shares_store_value( const char *key, REGVAL_CTR *val ) { return False; } diff --git a/source/registry/reg_util.c b/source/registry/reg_util.c index 9120ce0e0a4..165292cf2fe 100644 --- a/source/registry/reg_util.c +++ b/source/registry/reg_util.c @@ -85,4 +85,15 @@ BOOL reg_split_key( char *path, char **base, char **key ) } +/********************************************************************** + The full path to the registry key is used as database after the + \'s are converted to /'s. Key string is also normalized to UPPER + case. +**********************************************************************/ + +void normalize_reg_path( pstring keyname ) +{ + pstring_sub( keyname, "\\", "/" ); + strupper_m( keyname ); +} diff --git a/source/rpc_client/cli_reg.c b/source/rpc_client/cli_reg.c index ca4b63c2822..97ae8b29e7d 100644 --- a/source/rpc_client/cli_reg.c +++ b/source/rpc_client/cli_reg.c @@ -214,7 +214,7 @@ WERROR cli_reg_query_key(struct cli_state *cli, TALLOC_CTX *mem_ctx, if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) { ZERO_STRUCT (in); - *class_len = out.class.string->uni_max_len; + *class_len = out.key_class.string->uni_max_len; if ( *class_len > saved_class_len ) return out.status; @@ -238,8 +238,8 @@ WERROR cli_reg_query_key(struct cli_state *cli, TALLOC_CTX *mem_ctx, if ( !W_ERROR_IS_OK( out.status ) ) return out.status; - *class_len = out.class.string->uni_max_len; - unistr2_to_ascii(key_class, out.class.string, saved_class_len-1); + *class_len = out.key_class.string->uni_max_len; + unistr2_to_ascii(key_class, out.key_class.string, saved_class_len-1); *num_subkeys = out.num_subkeys ; *max_subkeylen = out.max_subkeylen ; *num_values = out.num_values ; @@ -286,24 +286,24 @@ WERROR cli_reg_getversion(struct cli_state *cli, TALLOC_CTX *mem_ctx, /**************************************************************************** do a REG Query Info ****************************************************************************/ -WERROR cli_reg_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, +WERROR cli_reg_query_value(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, const char *val_name, uint32 *type, REGVAL_BUFFER *buffer) { - REG_Q_INFO in; - REG_R_INFO out; + REG_Q_QUERY_VALUE in; + REG_R_QUERY_VALUE out; prs_struct qbuf, rbuf; ZERO_STRUCT (in); ZERO_STRUCT (out); - init_reg_q_info(&in, hnd, val_name, buffer); + init_reg_q_query_value(&in, hnd, val_name, buffer); - CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_QUERY_KEY, + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_QUERY_VALUE, in, out, qbuf, rbuf, - reg_io_q_info, - reg_io_r_info, + reg_io_q_query_value, + reg_io_r_query_value, WERR_GENERAL_FAILURE ); @@ -438,12 +438,12 @@ WERROR cli_reg_delete_key(struct cli_state *cli, TALLOC_CTX *mem_ctx, /**************************************************************************** do a REG Create Key ****************************************************************************/ -WERROR cli_reg_create_key(struct cli_state *cli, TALLOC_CTX *mem_ctx, +WERROR cli_reg_create_key_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, char *key_name, char *key_class, uint32 access_desired, POLICY_HND *key) { - REG_Q_CREATE_KEY in; - REG_R_CREATE_KEY out; + REG_Q_CREATE_KEY_EX in; + REG_R_CREATE_KEY_EX out; prs_struct qbuf, rbuf; SEC_DESC *sec; SEC_DESC_BUF *sec_buf; @@ -461,13 +461,13 @@ WERROR cli_reg_create_key(struct cli_state *cli, TALLOC_CTX *mem_ctx, if ( !(sec_buf = make_sec_desc_buf(mem_ctx, sec_len, sec)) ) return WERR_GENERAL_FAILURE; - init_reg_q_create_key(&in, hnd, key_name, key_class, access_desired, sec_buf); + init_reg_q_create_key_ex(&in, hnd, key_name, key_class, access_desired, sec_buf); - CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_CREATE_KEY, + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_CREATE_KEY_EX, in, out, qbuf, rbuf, - reg_io_q_create_key, - reg_io_r_create_key, + reg_io_q_create_key_ex, + reg_io_r_create_key_ex, WERR_GENERAL_FAILURE ); diff --git a/source/rpc_parse/parse_eventlog.c b/source/rpc_parse/parse_eventlog.c index d27761ad0ff..734f52fffb3 100644 --- a/source/rpc_parse/parse_eventlog.c +++ b/source/rpc_parse/parse_eventlog.c @@ -33,7 +33,7 @@ BOOL eventlog_io_q_open_eventlog(const char *desc, EVENTLOG_Q_OPEN_EVENTLOG *q_u if(q_u == NULL) return False; - /* Data format seems to be: + /** Data format seems to be: UNKNOWN structure uint32 unknown uint16 unknown @@ -258,7 +258,7 @@ BOOL eventlog_io_q_read_eventlog(const char *desc, EVENTLOG_Q_READ_EVENTLOG *q_u return True; } -/* Structure of response seems to be: +/** Structure of response seems to be: DWORD num_bytes_in_resp -- MUST be the same as q_u->max_read_size for i=0..n EVENTLOGRECORD record @@ -397,7 +397,7 @@ BOOL eventlog_io_r_read_eventlog(const char *desc, return True; } -/* The windows client seems to be doing something funny with the file name +/** The windows client seems to be doing something funny with the file name A call like ClearEventLog(handle, "backup_file") on the client side will result in the backup file name looking like this on the diff --git a/source/rpc_parse/parse_reg.c b/source/rpc_parse/parse_reg.c index 5cc4d06f4fb..c46eef13003 100644 --- a/source/rpc_parse/parse_reg.c +++ b/source/rpc_parse/parse_reg.c @@ -206,8 +206,8 @@ static BOOL reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR *hdr_sec, Inits a registry key create request ********************************************************************/ -void init_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd, - char *name, char *class, uint32 access_desired, +void init_reg_q_create_key_ex(REG_Q_CREATE_KEY_EX *q_c, POLICY_HND *hnd, + char *name, char *key_class, uint32 access_desired, SEC_DESC_BUF *sec_buf) { ZERO_STRUCTP(q_c); @@ -216,7 +216,7 @@ void init_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd, init_unistr4( &q_c->name, name, UNI_STR_TERMINATE ); - init_unistr4( &q_c->class, class, UNI_STR_TERMINATE ); + init_unistr4( &q_c->key_class, key_class, UNI_STR_TERMINATE ); q_c->access = access_desired; @@ -234,13 +234,13 @@ void init_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd, Marshalls a registry key create request ********************************************************************/ -BOOL reg_io_q_create_key(const char *desc, REG_Q_CREATE_KEY *q_u, +BOOL reg_io_q_create_key_ex(const char *desc, REG_Q_CREATE_KEY_EX *q_u, prs_struct *ps, int depth) { if ( !q_u ) return False; - prs_debug(ps, depth, desc, "reg_io_q_create_key"); + prs_debug(ps, depth, desc, "reg_io_q_create_key_ex"); depth++; if(!prs_align(ps)) @@ -254,7 +254,7 @@ BOOL reg_io_q_create_key(const char *desc, REG_Q_CREATE_KEY *q_u, if(!prs_align(ps)) return False; - if(!prs_unistr4 ("class", ps, depth, &q_u->class)) + if(!prs_unistr4 ("key_class", ps, depth, &q_u->key_class)) return False; if(!prs_align(ps)) return False; @@ -285,13 +285,13 @@ BOOL reg_io_q_create_key(const char *desc, REG_Q_CREATE_KEY *q_u, Unmarshalls a registry key create response ********************************************************************/ -BOOL reg_io_r_create_key(const char *desc, REG_R_CREATE_KEY *r_u, +BOOL reg_io_r_create_key_ex(const char *desc, REG_R_CREATE_KEY_EX *r_u, prs_struct *ps, int depth) { if ( !r_u ) return False; - prs_debug(ps, depth, desc, "reg_io_r_create_key"); + prs_debug(ps, depth, desc, "reg_io_r_create_key_ex"); depth++; if(!prs_align(ps)) @@ -299,7 +299,7 @@ BOOL reg_io_r_create_key(const char *desc, REG_R_CREATE_KEY *r_u, if(!smb_io_pol_hnd("", &r_u->handle, ps, depth)) return False; - if(!prs_uint32("unknown", ps, depth, &r_u->unknown)) + if(!prs_uint32("disposition", ps, depth, &r_u->disposition)) return False; if(!prs_werror("status", ps, depth, &r_u->status)) @@ -343,8 +343,6 @@ BOOL reg_io_q_delete_value(const char *desc, REG_Q_DELETE_VALUE *q_u, if(!prs_unistr4("name", ps, depth, &q_u->name)) return False; - if(!prs_align(ps)) - return False; return True; } @@ -436,12 +434,12 @@ BOOL reg_io_r_delete_key(const char *desc, REG_R_DELETE_KEY *r_u, prs_struct *p Inits a structure. ********************************************************************/ -void init_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd, const char *class) +void init_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd, const char *key_class) { ZERO_STRUCTP(q_o); memcpy(&q_o->pol, hnd, sizeof(q_o->pol)); - init_unistr4(&q_o->class, class, UNI_STR_TERMINATE); + init_unistr4(&q_o->key_class, key_class, UNI_STR_TERMINATE); } /******************************************************************* @@ -461,10 +459,7 @@ BOOL reg_io_q_query_key(const char *desc, REG_Q_QUERY_KEY *q_u, prs_struct *ps, if(!smb_io_pol_hnd("", &q_u->pol, ps, depth)) return False; - if(!prs_unistr4("class", ps, depth, &q_u->class)) - return False; - - if(!prs_align(ps)) + if(!prs_unistr4("key_class", ps, depth, &q_u->key_class)) return False; return True; @@ -486,7 +481,7 @@ BOOL reg_io_r_query_key(const char *desc, REG_R_QUERY_KEY *r_u, prs_struct *ps, if(!prs_align(ps)) return False; - if(!prs_unistr4("class", ps, depth, &r_u->class)) + if(!prs_unistr4("key_class", ps, depth, &r_u->key_class)) return False; if(!prs_align(ps)) @@ -745,7 +740,7 @@ makes a structure. void init_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_u, POLICY_HND *pol, uint32 sec_info, SEC_DESC_BUF *sec_desc_buf) { - memcpy(&q_u->pol, pol, sizeof(q_u->pol)); + memcpy(&q_u->handle, pol, sizeof(q_u->handle)); q_u->sec_info = sec_info; @@ -769,7 +764,7 @@ BOOL reg_io_q_set_key_sec(const char *desc, REG_Q_SET_KEY_SEC *q_u, prs_struct if(!prs_align(ps)) return False; - if(!smb_io_pol_hnd("", &q_u->pol, ps, depth)) + if(!smb_io_pol_hnd("", &q_u->handle, ps, depth)) return False; if(!prs_uint32("sec_info", ps, depth, &q_u->sec_info)) @@ -813,7 +808,7 @@ void init_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_u, POLICY_HND *pol, uint32 sec_info, uint32 sec_buf_size, SEC_DESC_BUF *psdb) { - memcpy(&q_u->pol, pol, sizeof(q_u->pol)); + memcpy(&q_u->handle, pol, sizeof(q_u->handle)); q_u->sec_info = sec_info; @@ -838,7 +833,7 @@ BOOL reg_io_q_get_key_sec(const char *desc, REG_Q_GET_KEY_SEC *q_u, prs_struct if(!prs_align(ps)) return False; - if(!smb_io_pol_hnd("", &q_u->pol, ps, depth)) + if(!smb_io_pol_hnd("", &q_u->handle, ps, depth)) return False; if(!prs_uint32("sec_info", ps, depth, &q_u->sec_info)) @@ -905,7 +900,7 @@ BOOL reg_io_r_get_key_sec(const char *desc, REG_R_GET_KEY_SEC *q_u, prs_struct makes a structure. ********************************************************************/ -BOOL init_reg_q_info(REG_Q_INFO *q_u, POLICY_HND *pol, const char *val_name, +BOOL init_reg_q_query_value(REG_Q_QUERY_VALUE *q_u, POLICY_HND *pol, const char *val_name, REGVAL_BUFFER *value_output) { if (q_u == NULL) @@ -936,12 +931,12 @@ BOOL init_reg_q_info(REG_Q_INFO *q_u, POLICY_HND *pol, const char *val_name, reads or writes a structure. ********************************************************************/ -BOOL reg_io_q_info(const char *desc, REG_Q_INFO *q_u, prs_struct *ps, int depth) +BOOL reg_io_q_query_value(const char *desc, REG_Q_QUERY_VALUE *q_u, prs_struct *ps, int depth) { if ( !q_u ) return False; - prs_debug(ps, depth, desc, "reg_io_q_info"); + prs_debug(ps, depth, desc, "reg_io_q_query_value"); depth++; if(!prs_align(ps)) @@ -990,10 +985,10 @@ BOOL reg_io_q_info(const char *desc, REG_Q_INFO *q_u, prs_struct *ps, int depth /******************************************************************* Inits a structure. - New version to replace older init_reg_r_info() + New version to replace older init_reg_r_query_value() ********************************************************************/ -BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_u, +BOOL init_reg_r_query_value(uint32 include_keyval, REG_R_QUERY_VALUE *r_u, REGISTRY_VALUE *val, WERROR status) { uint32 buf_len = 0; @@ -1031,12 +1026,12 @@ BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_u, reads or writes a structure. ********************************************************************/ -BOOL reg_io_r_info(const char *desc, REG_R_INFO *r_u, prs_struct *ps, int depth) +BOOL reg_io_r_query_value(const char *desc, REG_R_QUERY_VALUE *r_u, prs_struct *ps, int depth) { if ( !r_u ) return False; - prs_debug(ps, depth, desc, "reg_io_r_info"); + prs_debug(ps, depth, desc, "reg_io_r_query_value"); depth++; if(!prs_align(ps)) diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c index 6c2d6b49785..34e3f8fe355 100644 --- a/source/rpc_parse/parse_spoolss.c +++ b/source/rpc_parse/parse_spoolss.c @@ -774,15 +774,15 @@ BOOL spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE if (devmode->driverextra!=0) { if (UNMARSHALLING(ps)) { - devmode->private=PRS_ALLOC_MEM(ps, uint8, devmode->driverextra); - if(devmode->private == NULL) + devmode->dev_private=PRS_ALLOC_MEM(ps, uint8, devmode->driverextra); + if(devmode->dev_private == NULL) return False; - DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for private\n",devmode->driverextra)); + DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for dev_private\n",devmode->driverextra)); } - DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of private\n",devmode->driverextra)); - if (!prs_uint8s(False, "private", ps, depth, - devmode->private, devmode->driverextra)) + DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of dev_private\n",devmode->driverextra)); + if (!prs_uint8s(False, "dev_private", ps, depth, + devmode->dev_private, devmode->driverextra)) return False; } @@ -6188,7 +6188,7 @@ BOOL spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, void free_devmode(DEVICEMODE *devmode) { if (devmode!=NULL) { - SAFE_FREE(devmode->private); + SAFE_FREE(devmode->dev_private); SAFE_FREE(devmode); } } @@ -6350,7 +6350,7 @@ BOOL spoolss_io_q_routerreplyprinter (const char *desc, SPOOL_Q_ROUTERREPLYPRINT if (!prs_uint32("change_id", ps, depth, &q_u->change_id)) return False; - if (!prs_uint8s(False, "private", ps, depth, q_u->unknown2, 5)) + if (!prs_uint8s(False, "dev_private", ps, depth, q_u->unknown2, 5)) return False; return True; diff --git a/source/rpc_parse/parse_svcctl.c b/source/rpc_parse/parse_svcctl.c index 1f21cb2aab9..85889d58890 100644 --- a/source/rpc_parse/parse_svcctl.c +++ b/source/rpc_parse/parse_svcctl.c @@ -109,7 +109,6 @@ BOOL svcctl_io_service_description( const char *desc, UNISTR2 *svcdesc, prs_stru prs_debug(ps, depth, desc, "svcctl_io_service_description"); depth++; - //DEBUG(10, ("_svcctl_io_service_description: descrption is [%s]\n",svcdesc)); if (!prs_io_unistr2("", ps, depth, svcdesc)) return False; diff --git a/source/rpc_server/srv_dfs.c b/source/rpc_server/srv_dfs.c index 6c35917e618..42be7c5a357 100644 --- a/source/rpc_server/srv_dfs.c +++ b/source/rpc_server/srv_dfs.c @@ -27,10 +27,8 @@ #include "includes.h" #include "nterr.h" -#define MAX_MSDFS_JUNCTIONS 256 - #undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV +#define DBGC_CLASS DBGC_MSDFS /********************************************************************** api_dfs_exist diff --git a/source/rpc_server/srv_dfs_nt.c b/source/rpc_server/srv_dfs_nt.c index 7334eef85be..938b01540f4 100644 --- a/source/rpc_server/srv_dfs_nt.c +++ b/source/rpc_server/srv_dfs_nt.c @@ -27,9 +27,7 @@ #include "nterr.h" #undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -#define MAX_MSDFS_JUNCTIONS 256 +#define DBGC_CLASS DBGC_MSDFS /* This function does not return a WERROR or NTSTATUS code but rather 1 if dfs exists, or 0 otherwise. */ @@ -321,7 +319,7 @@ WERROR _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u) struct junction_map jn[MAX_MSDFS_JUNCTIONS]; int num_jn = 0; - num_jn = enum_msdfs_links(jn); + num_jn = enum_msdfs_links(jn, ARRAY_SIZE(jn)); vfs_ChDir(p->conn,p->conn->connectpath); DEBUG(5,("make_reply_dfs_enum: %d junctions found in Dfs, doing level %d\n", num_jn, level)); diff --git a/source/rpc_server/srv_eventlog.c b/source/rpc_server/srv_eventlog.c index 07aebcd2faa..65b10e8fe40 100644 --- a/source/rpc_server/srv_eventlog.c +++ b/source/rpc_server/srv_eventlog.c @@ -185,7 +185,7 @@ static BOOL api_eventlog_clear_eventlog(pipes_struct *p) struct api_struct api_eventlog_cmds[] = { {"EVENTLOG_OPENEVENTLOG", EVENTLOG_OPENEVENTLOG, api_eventlog_open_eventlog }, - {"EVENTLOG_CLOSEVENTLOG", EVENTLOG_CLOSEEVENTLOG, api_eventlog_close_eventlog }, + {"EVENTLOG_CLOSEEVENTLOG", EVENTLOG_CLOSEEVENTLOG, api_eventlog_close_eventlog }, {"EVENTLOG_GETNUMRECORDS", EVENTLOG_GETNUMRECORDS, api_eventlog_get_num_records }, {"EVENTLOG_GETOLDESTENTRY", EVENTLOG_GETOLDESTENTRY, api_eventlog_get_oldest_entry }, {"EVENTLOG_READEVENTLOG", EVENTLOG_READEVENTLOG, api_eventlog_read_eventlog }, diff --git a/source/rpc_server/srv_eventlog_nt.c b/source/rpc_server/srv_eventlog_nt.c index ea7512b58da..a9b0c9bed80 100644 --- a/source/rpc_server/srv_eventlog_nt.c +++ b/source/rpc_server/srv_eventlog_nt.c @@ -169,12 +169,18 @@ WERROR _eventlog_open_eventlog(pipes_struct *p, DEBUG(10, ("_eventlog_open_eventlog: Using [%s] as the source log file.\n", info->source_log_file_name)); if(!create_policy_hnd(p, &(r_u->handle), free_eventlog_info, (void *)info)) + { + free_eventlog_info(info); return WERR_NOMEM; + } policy_handle_to_string(&r_u->handle, &info->handle_string); if(!(_eventlog_open_eventlog_hook(info))) + { + close_policy_hnd(p, &r_u->handle); return WERR_BADFILE; + } return WERR_OK; } @@ -707,10 +713,10 @@ static Eventlog_entry *_eventlog_read_package_entry(prs_struct *ps, Eventlog_entry *entry) { uint8 *offset; - Eventlog_entry *new = NULL; + Eventlog_entry *ee_new = NULL; - new = PRS_ALLOC_MEM(ps, Eventlog_entry, 1); - if(new == NULL) + ee_new = PRS_ALLOC_MEM(ps, Eventlog_entry, 1); + if(ee_new == NULL) return NULL; entry->data_record.sid_padding = ((4 - ((entry->data_record.source_name_len @@ -761,14 +767,14 @@ static Eventlog_entry *_eventlog_read_package_entry(prs_struct *ps, memcpy(offset, &(entry->data_record.user_data), entry->data_record.user_data_len); offset += entry->data_record.user_data_len; - memcpy(&(new->record), &entry->record, sizeof(Eventlog_record)); - memcpy(&(new->data_record), &entry->data_record, sizeof(Eventlog_data_record)); - new->data = entry->data; + memcpy(&(ee_new->record), &entry->record, sizeof(Eventlog_record)); + memcpy(&(ee_new->data_record), &entry->data_record, sizeof(Eventlog_data_record)); + ee_new->data = entry->data; - return new; + return ee_new; } -static BOOL _eventlog_add_record_to_resp(EVENTLOG_R_READ_EVENTLOG *r_u, Eventlog_entry *new) +static BOOL _eventlog_add_record_to_resp(EVENTLOG_R_READ_EVENTLOG *r_u, Eventlog_entry *ee_new) { Eventlog_entry *insert_point; @@ -776,8 +782,8 @@ static BOOL _eventlog_add_record_to_resp(EVENTLOG_R_READ_EVENTLOG *r_u, Eventlog if (NULL == insert_point) { - r_u->entry = new; - new->next = NULL; + r_u->entry = ee_new; + ee_new->next = NULL; } else { @@ -785,11 +791,11 @@ static BOOL _eventlog_add_record_to_resp(EVENTLOG_R_READ_EVENTLOG *r_u, Eventlog { insert_point=insert_point->next; } - new->next = NULL; - insert_point->next = new; + ee_new->next = NULL; + insert_point->next = ee_new; } r_u->num_records++; - r_u->num_bytes_in_resp += new->record.length; + r_u->num_bytes_in_resp += ee_new->record.length; return True; } @@ -800,7 +806,7 @@ WERROR _eventlog_read_eventlog(pipes_struct *p, { Eventlog_info *info = NULL; POLICY_HND *handle; - Eventlog_entry entry, *new; + Eventlog_entry entry, *ee_new; BOOL eof = False, eor = False; const char *direction = ""; uint32 num_records_read = 0; @@ -848,20 +854,20 @@ WERROR _eventlog_read_eventlog(pipes_struct *p, _eventlog_read_parse_line(buffer[i], &entry, &eor); if(eor == True) { - /* package new entry */ - if((new = _eventlog_read_package_entry(ps, q_u, r_u, &entry)) == NULL) + /* package ee_new entry */ + if((ee_new = _eventlog_read_package_entry(ps, q_u, r_u, &entry)) == NULL) { free(buffer); return WERR_NOMEM; } /* Now see if there is enough room to add */ - if(r_u->num_bytes_in_resp + new->record.length > q_u->max_read_size) + if(r_u->num_bytes_in_resp + ee_new->record.length > q_u->max_read_size) { - r_u->bytes_in_next_record = new->record.length; + r_u->bytes_in_next_record = ee_new->record.length; /* response would be too big to fit in client-size buffer */ break; } - _eventlog_add_record_to_resp(r_u, new); + _eventlog_add_record_to_resp(r_u, ee_new); ZERO_STRUCT(entry); eor=False; num_records_read = r_u->num_records - num_records_read; diff --git a/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c index b724508e0b3..15d420538ef 100644 --- a/source/rpc_server/srv_lsa_nt.c +++ b/source/rpc_server/srv_lsa_nt.c @@ -1544,7 +1544,7 @@ NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, L unistr2_to_ascii(name, &q_u->privname.unistring, sizeof(name)); - DEBUG(10,("_lsa_priv_get_dispname: name = %s\n", name)); + DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name)); if ( !se_priv_from_name( name, &mask ) ) return NT_STATUS_NO_SUCH_PRIVILEGE; diff --git a/source/rpc_server/srv_reg.c b/source/rpc_server/srv_reg.c index c0abc2a9c23..871b1a9f121 100644 --- a/source/rpc_server/srv_reg.c +++ b/source/rpc_server/srv_reg.c @@ -164,13 +164,13 @@ static BOOL api_reg_open_entry(pipes_struct *p) } /******************************************************************* - api_reg_info + api_reg_query_value ********************************************************************/ -static BOOL api_reg_info(pipes_struct *p) +static BOOL api_reg_query_value(pipes_struct *p) { - REG_Q_INFO q_u; - REG_R_INFO r_u; + REG_Q_QUERY_VALUE q_u; + REG_R_QUERY_VALUE r_u; prs_struct *data = &p->in_data.data; prs_struct *rdata = &p->out_data.rdata; @@ -178,12 +178,12 @@ static BOOL api_reg_info(pipes_struct *p) ZERO_STRUCT(r_u); /* grab the reg unknown 0x11*/ - if(!reg_io_q_info("", &q_u, data, 0)) + if(!reg_io_q_query_value("", &q_u, data, 0)) return False; - r_u.status = _reg_info(p, &q_u, &r_u); + r_u.status = _reg_query_value(p, &q_u, &r_u); - if(!reg_io_r_info("", &r_u, rdata, 0)) + if(!reg_io_r_query_value("", &r_u, rdata, 0)) return False; return True; @@ -419,22 +419,22 @@ static BOOL api_reg_save_key(pipes_struct *p) /******************************************************************* ******************************************************************/ -static BOOL api_reg_create_key(pipes_struct *p) +static BOOL api_reg_create_key_ex(pipes_struct *p) { - REG_Q_CREATE_KEY q_u; - REG_R_CREATE_KEY r_u; + REG_Q_CREATE_KEY_EX q_u; + REG_R_CREATE_KEY_EX r_u; prs_struct *data = &p->in_data.data; prs_struct *rdata = &p->out_data.rdata; ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - if(!reg_io_q_create_key("", &q_u, data, 0)) + if(!reg_io_q_create_key_ex("", &q_u, data, 0)) return False; - r_u.status = _reg_create_key(p, &q_u, &r_u); + r_u.status = _reg_create_key_ex(p, &q_u, &r_u); - if(!reg_io_r_create_key("", &r_u, rdata, 0)) + if(!reg_io_r_create_key_ex("", &r_u, rdata, 0)) return False; return True; @@ -512,6 +512,57 @@ static BOOL api_reg_delete_value(pipes_struct *p) return True; } + +/******************************************************************* + ******************************************************************/ + +static BOOL api_reg_get_key_sec(pipes_struct *p) +{ + REG_Q_GET_KEY_SEC q_u; + REG_R_GET_KEY_SEC r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!reg_io_q_get_key_sec("", &q_u, data, 0)) + return False; + + r_u.status = _reg_get_key_sec(p, &q_u, &r_u); + + if(!reg_io_r_get_key_sec("", &r_u, rdata, 0)) + return False; + + return True; +} + + +/******************************************************************* + ******************************************************************/ + +static BOOL api_reg_set_key_sec(pipes_struct *p) +{ + REG_Q_SET_KEY_SEC q_u; + REG_R_SET_KEY_SEC r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!reg_io_q_set_key_sec("", &q_u, data, 0)) + return False; + + r_u.status = _reg_set_key_sec(p, &q_u, &r_u); + + if(!reg_io_r_set_key_sec("", &r_u, rdata, 0)) + return False; + + return True; +} + + /******************************************************************* array of \PIPE\reg operations ********************************************************************/ @@ -526,17 +577,19 @@ static struct api_struct api_reg_cmds[] = { "REG_ENUM_KEY" , REG_ENUM_KEY , api_reg_enum_key }, { "REG_ENUM_VALUE" , REG_ENUM_VALUE , api_reg_enum_value }, { "REG_QUERY_KEY" , REG_QUERY_KEY , api_reg_query_key }, - { "REG_INFO" , REG_INFO , api_reg_info }, + { "REG_QUERY_VALUE" , REG_QUERY_VALUE , api_reg_query_value }, { "REG_SHUTDOWN" , REG_SHUTDOWN , api_reg_shutdown }, { "REG_SHUTDOWN_EX" , REG_SHUTDOWN_EX , api_reg_shutdown_ex }, { "REG_ABORT_SHUTDOWN" , REG_ABORT_SHUTDOWN , api_reg_abort_shutdown }, { "REG_GETVERSION" , REG_GETVERSION , api_reg_getversion }, { "REG_SAVE_KEY" , REG_SAVE_KEY , api_reg_save_key }, { "REG_RESTORE_KEY" , REG_RESTORE_KEY , api_reg_restore_key }, - { "REG_CREATE_KEY" , REG_CREATE_KEY , api_reg_create_key }, + { "REG_CREATE_KEY_EX" , REG_CREATE_KEY_EX , api_reg_create_key_ex }, { "REG_SET_VALUE" , REG_SET_VALUE , api_reg_set_value }, { "REG_DELETE_KEY" , REG_DELETE_KEY , api_reg_delete_key }, - { "REG_DELETE_VALUE" , REG_DELETE_VALUE , api_reg_delete_value } + { "REG_DELETE_VALUE" , REG_DELETE_VALUE , api_reg_delete_value }, + { "REG_GET_KEY_SEC" , REG_GET_KEY_SEC , api_reg_get_key_sec }, + { "REG_SET_KEY_SEC" , REG_SET_KEY_SEC , api_reg_set_key_sec } }; void reg_get_pipe_fns( struct api_struct **fns, int *n_fns ) diff --git a/source/rpc_server/srv_reg_nt.c b/source/rpc_server/srv_reg_nt.c index a3ab63d06ec..db199634c50 100644 --- a/source/rpc_server/srv_reg_nt.c +++ b/source/rpc_server/srv_reg_nt.c @@ -30,18 +30,11 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV -#define REGSTR_PRODUCTTYPE "ProductType" -#define REG_PT_WINNT "WinNT" -#define REG_PT_LANMANNT "LanmanNT" -#define REG_PT_SERVERNT "ServerNT" - #define OUR_HANDLE(hnd) (((hnd)==NULL)?"NULL":(IVAL((hnd)->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER")), \ ((unsigned int)IVAL((hnd)->data5,4)),((unsigned int)sys_getpid()) -/* no idea if this is correct, just use the file access bits for now */ - -struct generic_mapping reg_map = { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL }; +static struct generic_mapping reg_generic_map = { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL }; /******************************************************************** ********************************************************************/ @@ -51,6 +44,7 @@ NTSTATUS registry_access_check( SEC_DESC *sec_desc, NT_USER_TOKEN *token, { NTSTATUS result; + se_map_generic( &access_desired, ®_generic_map ); se_access_check( sec_desc, token, access_desired, access_granted, &result ); return result; @@ -185,12 +179,12 @@ static WERROR open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY * result = WERR_BADFILE; goto done; } - + if ( !create_policy_hnd( p, hnd, free_regkey_info, regkey ) ) { - result = WERR_BADFILE; + result = WERR_BADFILE; goto done; } - + /* save the access mask */ regkey->access_granted = access_granted; @@ -265,9 +259,7 @@ static BOOL get_subkey_information( REGISTRY_KEY *key, uint32 *maxnum, uint32 *m } /******************************************************************** - retrieve information about the values. We don't store values - here. The registry tdb is intended to be a frontend to oether - Samba tdb's (such as ntdrivers.tdb). + retrieve information about the values. *******************************************************************/ static BOOL get_value_information( REGISTRY_KEY *key, uint32 *maxnum, @@ -293,7 +285,7 @@ static BOOL get_value_information( REGISTRY_KEY *key, uint32 *maxnum, for ( i=0; i<num_values && val; i++ ) { - lenmax = MAX(lenmax, strlen(val->valuename)+1 ); + lenmax = MAX(lenmax, val->valuename ? strlen(val->valuename)+1 : 0 ); sizemax = MAX(sizemax, val->size ); val = regval_ctr_specific_value( &values, i ); @@ -317,7 +309,7 @@ WERROR _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u) { /* close the policy handle */ - if ( !close_registry_key(p, &q_u->pol) ) + if (!close_registry_key(p, &q_u->pol)) return WERR_BADFID; return WERR_OK; @@ -405,14 +397,14 @@ WERROR _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY if ( !parent ) return WERR_BADFID; - + rpcstr_pull( name, q_u->name.string->buffer, sizeof(name), q_u->name.string->uni_str_len*2, 0 ); /* check granted access first; what is the correct mask here? */ if ( !(parent->access_granted & (SEC_RIGHTS_ENUM_SUBKEYS|SEC_RIGHTS_CREATE_SUBKEY)) ) return WERR_ACCESS_DENIED; - + /* open the key first to get the appropriate REGISTRY_HOOK and then check the premissions */ @@ -439,13 +431,10 @@ WERROR _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY reg_reply_info ********************************************************************/ -WERROR _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u) +WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VALUE *r_u) { WERROR status = WERR_BADFILE; fstring name; - const char *value_ascii = ""; - fstring value; - int value_length; REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol ); REGISTRY_VALUE *val = NULL; REGVAL_CTR regvals; @@ -463,66 +452,11 @@ WERROR _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u) DEBUG(5,("reg_info: looking up value: [%s]\n", name)); regval_ctr_init( ®vals ); - - /* couple of hard coded registry values */ - - if ( strequal(name, "RefusePasswordChange") ) { - uint32 dwValue; - - if ( (val = SMB_MALLOC_P(REGISTRY_VALUE)) == NULL ) { - DEBUG(0,("_reg_info: malloc() failed!\n")); - return WERR_NOMEM; - } - - if (!account_policy_get(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue)) - dwValue = 0; - regval_ctr_addvalue(®vals, "RefusePasswordChange", - REG_DWORD, - (const char*)&dwValue, sizeof(dwValue)); - val = dup_registry_value( - regval_ctr_specific_value( ®vals, 0 ) ); - - status = WERR_OK; - - goto out; - } - - if ( strequal(name, REGSTR_PRODUCTTYPE) ) { - /* This makes the server look like a member server to clients */ - /* which tells clients that we have our own local user and */ - /* group databases and helps with ACL support. */ - - switch (lp_server_role()) { - case ROLE_DOMAIN_PDC: - case ROLE_DOMAIN_BDC: - value_ascii = REG_PT_LANMANNT; - break; - case ROLE_STANDALONE: - value_ascii = REG_PT_SERVERNT; - break; - case ROLE_DOMAIN_MEMBER: - value_ascii = REG_PT_WINNT; - break; - } - value_length = push_ucs2(value, value, value_ascii, - sizeof(value), - STR_TERMINATE|STR_NOALIGN); - regval_ctr_addvalue(®vals, REGSTR_PRODUCTTYPE, REG_SZ, - value, value_length); - - val = dup_registry_value( regval_ctr_specific_value( ®vals, 0 ) ); - - status = WERR_OK; - - goto out; - } - - /* else fall back to actually looking up the value */ for ( i=0; fetch_reg_values_specific(regkey, &val, i); i++ ) { DEBUG(10,("_reg_info: Testing value [%s]\n", val->valuename)); - if ( StrCaseCmp( val->valuename, name ) == 0 ) { + if ( strequal( val->valuename, name ) ) { DEBUG(10,("_reg_info: Found match for value [%s]\n", name)); status = WERR_OK; break; @@ -531,9 +465,7 @@ WERROR _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u) free_registry_value( val ); } - -out: - init_reg_r_info(q_u->ptr_buf, r_u, val, status); + init_reg_r_query_value(q_u->ptr_buf, r_u, val, status); regval_ctr_destroy( ®vals ); free_registry_value( val ); @@ -558,11 +490,15 @@ WERROR _reg_query_key(pipes_struct *p, REG_Q_QUERY_KEY *q_u, REG_R_QUERY_KEY *r_ if ( !regkey ) return WERR_BADFID; - if ( !get_subkey_information( regkey, &r_u->num_subkeys, &r_u->max_subkeylen ) ) + if ( !get_subkey_information( regkey, &r_u->num_subkeys, &r_u->max_subkeylen ) ) { + DEBUG(0,("_reg_query_key: get_subkey_information() failed!\n")); return WERR_ACCESS_DENIED; + } - if ( !get_value_information( regkey, &r_u->num_values, &r_u->max_valnamelen, &r_u->max_valbufsize ) ) + if ( !get_value_information( regkey, &r_u->num_values, &r_u->max_valnamelen, &r_u->max_valbufsize ) ) { + DEBUG(0,("_reg_query_key: get_value_information() failed!\n")); return WERR_ACCESS_DENIED; + } r_u->sec_desc = 0x00000078; /* size for key's sec_desc */ @@ -852,7 +788,7 @@ static int validate_reg_filename( pstring fname ) } /******************************************************************* - Note: topkeypaty is the *full* path that this *key will be + Note: topkeypat is the *full* path that this *key will be loaded into (including the name of the key) ********************************************************************/ @@ -1080,12 +1016,12 @@ static WERROR make_default_reg_sd( TALLOC_CTX *ctx, SEC_DESC **psd ) /* basic access for Everyone */ - init_sec_access(&mask, reg_map.generic_execute | reg_map.generic_read ); + init_sec_access(&mask, reg_generic_map.generic_execute | reg_generic_map.generic_read ); init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); /* add Full Access 'BUILTIN\Administrators' */ - init_sec_access(&mask, reg_map.generic_all); + init_sec_access(&mask, reg_generic_map.generic_all); sid_copy(&adm_sid, &global_sid_Builtin); sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS); init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); @@ -1165,7 +1101,7 @@ WERROR _reg_save_key(pipes_struct *p, REG_Q_SAVE_KEY *q_u, REG_R_SAVE_KEY *r_u) /******************************************************************* ********************************************************************/ -WERROR _reg_create_key(pipes_struct *p, REG_Q_CREATE_KEY *q_u, REG_R_CREATE_KEY *r_u) +WERROR _reg_create_key_ex(pipes_struct *p, REG_Q_CREATE_KEY_EX *q_u, REG_R_CREATE_KEY_EX *r_u) { REGISTRY_KEY *parent = find_regkey_index_by_hnd(p, &q_u->handle); REGISTRY_KEY *newparent; @@ -1270,6 +1206,7 @@ WERROR _reg_set_value(pipes_struct *p, REG_Q_SET_VALUE *q_u, REG_R_SET_VALUE *r REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle); REGVAL_CTR values; BOOL write_result; + fstring valuename; if ( !key ) return WERR_BADFID; @@ -1279,12 +1216,22 @@ WERROR _reg_set_value(pipes_struct *p, REG_Q_SET_VALUE *q_u, REG_R_SET_VALUE *r if ( !(key->access_granted & SEC_RIGHTS_SET_VALUE) ) return WERR_ACCESS_DENIED; + rpcstr_pull( valuename, q_u->name.string->buffer, sizeof(valuename), q_u->name.string->uni_str_len*2, 0 ); + + /* verify the name */ + + if ( !*valuename ) + return WERR_INVALID_PARAM; + + DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n", key->name, valuename)); + regval_ctr_init( &values ); /* lookup the current values and add the new one */ fetch_reg_values( key, &values ); - /* FIXME!!!! regval_ctr_addvalue( &values, .... ); */ + + regval_ctr_addvalue( &values, valuename, q_u->type, q_u->value.buffer, q_u->value.buf_len ); /* now write to the registry backend */ @@ -1378,6 +1325,8 @@ WERROR _reg_delete_key(pipes_struct *p, REG_Q_DELETE_KEY *q_u, REG_R_DELETE_KEY write_result = store_reg_keys( newparent, &subkeys ); regsubkey_ctr_destroy( &subkeys ); + + result = write_result ? WERR_OK : WERR_REG_IO_FAILURE; done: /* close any intermediate key handles */ @@ -1385,9 +1334,7 @@ done: if ( newparent != parent ) close_registry_key( p, &newparent_handle ); - /* rpc_reg.h says there is a POLICY_HDN in the reply...no idea if that is correct */ - - return write_result ? WERR_OK : WERR_REG_IO_FAILURE; + return result; } @@ -1399,7 +1346,8 @@ WERROR _reg_delete_value(pipes_struct *p, REG_Q_DELETE_VALUE *q_u, REG_R_DELETE REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle); REGVAL_CTR values; BOOL write_result; - + fstring valuename; + if ( !key ) return WERR_BADFID; @@ -1407,13 +1355,21 @@ WERROR _reg_delete_value(pipes_struct *p, REG_Q_DELETE_VALUE *q_u, REG_R_DELETE if ( !(key->access_granted & SEC_RIGHTS_SET_VALUE) ) return WERR_ACCESS_DENIED; - + + rpcstr_pull( valuename, q_u->name.string->buffer, sizeof(valuename), q_u->name.string->uni_str_len*2, 0 ); + + if ( !*valuename ) + return WERR_INVALID_PARAM; + + DEBUG(8,("_reg_delete_value: Setting value for [%s:%s]\n", key->name, valuename)); + regval_ctr_init( &values ); /* lookup the current values and add the new one */ fetch_reg_values( key, &values ); - /* FIXME!!!! regval_ctr_delval( &values, .... ); */ + + regval_ctr_delvalue( &values, valuename ); /* now write to the registry backend */ @@ -1427,3 +1383,40 @@ WERROR _reg_delete_value(pipes_struct *p, REG_Q_DELETE_VALUE *q_u, REG_R_DELETE return WERR_OK; } +/******************************************************************* + ********************************************************************/ + +WERROR _reg_get_key_sec(pipes_struct *p, REG_Q_GET_KEY_SEC *q_u, REG_R_GET_KEY_SEC *r_u) +{ + REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle); + + if ( !key ) + return WERR_BADFID; + + /* access checks first */ + + if ( !(key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) ) + return WERR_ACCESS_DENIED; + + return WERR_ACCESS_DENIED; +} + +/******************************************************************* + ********************************************************************/ + +WERROR _reg_set_key_sec(pipes_struct *p, REG_Q_SET_KEY_SEC *q_u, REG_R_SET_KEY_SEC *r_u) +{ + REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle); + + if ( !key ) + return WERR_BADFID; + + /* access checks first */ + + if ( !(key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) ) + return WERR_ACCESS_DENIED; + + return WERR_ACCESS_DENIED; +} + + diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c index e510f69cc8e..9b98d4cb168 100644 --- a/source/rpc_server/srv_samr_nt.c +++ b/source/rpc_server/srv_samr_nt.c @@ -45,11 +45,14 @@ extern rid_name domain_alias_rids[]; extern rid_name builtin_alias_rids[]; typedef struct disp_info { - struct pdb_search *users; - struct pdb_search *machines; - struct pdb_search *groups; - struct pdb_search *aliases; - struct pdb_search *builtins; + struct pdb_search *users; /* querydispinfo 1 and 4 */ + struct pdb_search *machines; /* querydispinfo 2 */ + struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */ + struct pdb_search *aliases; /* enumaliases */ + struct pdb_search *builtins; /* enumaliases */ + + uint16 enum_acb_mask; + struct pdb_search *enum_users; /* enumusers with a mask */ } DISP_INFO; struct samr_info { @@ -264,6 +267,8 @@ static void free_samr_db(struct samr_info *info) info->disp_info.aliases = NULL; pdb_search_destroy(info->disp_info.builtins); info->disp_info.builtins = NULL; + pdb_search_destroy(info->disp_info.enum_users); + info->disp_info.enum_users = NULL; } static void free_samr_info(void *ptr) @@ -590,11 +595,19 @@ NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__)); become_root(); - if (info->disp_info.users == NULL) - info->disp_info.users = pdb_search_users(q_u->acb_mask); - if (info->disp_info.users == NULL) + if ((info->disp_info.enum_users != NULL) && + (info->disp_info.enum_acb_mask != q_u->acb_mask)) { + pdb_search_destroy(info->disp_info.enum_users); + info->disp_info.enum_users = NULL; + } + + if (info->disp_info.enum_users == NULL) { + info->disp_info.enum_users = pdb_search_users(q_u->acb_mask); + info->disp_info.enum_acb_mask = q_u->acb_mask; + } + if (info->disp_info.enum_users == NULL) return NT_STATUS_ACCESS_DENIED; - num_account = pdb_search_entries(info->disp_info.users, + num_account = pdb_search_entries(info->disp_info.enum_users, enum_context, max_entries, &entries); unbecome_root(); diff --git a/source/rpc_server/srv_samr_util.c b/source/rpc_server/srv_samr_util.c index 61160ccaa02..66cf1cc46dc 100644 --- a/source/rpc_server/srv_samr_util.c +++ b/source/rpc_server/srv_samr_util.c @@ -251,7 +251,7 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) } if (from->fields_present & ACCT_LOGON_HOURS) { - pstring old, new; + pstring oldstr, newstr; DEBUG(15,("INFO_21 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs)); if (from->logon_divs != pdb_get_logon_divs(to)) { pdb_set_logon_divs(to, from->logon_divs, PDB_CHANGED); @@ -263,9 +263,9 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) } DEBUG(15,("INFO_21 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours)); - pdb_sethexhours(old, pdb_get_hours(to)); - pdb_sethexhours(new, from->logon_hrs.hours); - if (!strequal(old, new)) { + pdb_sethexhours(oldstr, pdb_get_hours(to)); + pdb_sethexhours(newstr, from->logon_hrs.hours); + if (!strequal(oldstr, newstr)) { pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED); } } diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c index 972f6e97302..5fbb6d91b00 100644 --- a/source/rpc_server/srv_spoolss_nt.c +++ b/source/rpc_server/srv_spoolss_nt.c @@ -348,6 +348,58 @@ static BOOL close_printer_handle(pipes_struct *p, POLICY_HND *hnd) /**************************************************************************** Delete a printer given a handle. ****************************************************************************/ +WERROR delete_printer_hook( NT_USER_TOKEN *token, const char *sharename ) +{ + char *cmd = lp_deleteprinter_cmd(); + pstring command; + int ret; + SE_PRIV se_printop = SE_PRINT_OPERATOR; + BOOL is_print_op = False; + + /* can't fail if we don't try */ + + if ( !*cmd ) + return WERR_OK; + + pstr_sprintf(command, "%s \"%s\"", cmd, sharename); + + if ( token ) + is_print_op = user_has_privileges( token, &se_printop ); + + DEBUG(10,("Running [%s]\n", command)); + + /********** BEGIN SePrintOperatorPrivlege BLOCK **********/ + + if ( is_print_op ) + become_root(); + + if ( (ret = smbrun(command, NULL)) == 0 ) { + /* Tell everyone we updated smb.conf. */ + message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL); + } + + if ( is_print_op ) + unbecome_root(); + + /********** END SePrintOperatorPrivlege BLOCK **********/ + + DEBUGADD(10,("returned [%d]\n", ret)); + + if (ret != 0) + return WERR_BADFID; /* What to return here? */ + + /* go ahead and re-read the services immediately */ + reload_services( False ); + + if ( lp_servicenumber( sharename ) < 0 ) + return WERR_ACCESS_DENIED; + + return WERR_OK; +} + +/**************************************************************************** + Delete a printer given a handle. +****************************************************************************/ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd) { @@ -369,18 +421,6 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd) DEBUG(3, ("delete_printer_handle: denied by handle\n")); return WERR_ACCESS_DENIED; } - -#if 0 - /* Check calling user has permission to delete printer. Note that - since we set the snum parameter to -1 only administrators can - delete the printer. This stops people with the Full Control - permission from deleting the printer. */ - - if (!print_access_check(NULL, -1, PRINTER_ACCESS_ADMINISTER)) { - DEBUG(3, ("printer delete denied by security descriptor\n")); - return WERR_ACCESS_DENIED; - } -#endif /* this does not need a become root since the access check has been done on the handle already */ @@ -390,50 +430,7 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd) return WERR_BADFID; } - /* the delete printer script shoudl be run as root if the user has perms */ - - if (*lp_deleteprinter_cmd()) { - - char *cmd = lp_deleteprinter_cmd(); - pstring command; - int ret; - SE_PRIV se_printop = SE_PRINT_OPERATOR; - BOOL is_print_op; - - pstr_sprintf(command, "%s \"%s\"", cmd, Printer->sharename); - - is_print_op = user_has_privileges( p->pipe_user.nt_user_token, &se_printop ); - - DEBUG(10,("Running [%s]\n", command)); - - /********** BEGIN SePrintOperatorPrivlege BLOCK **********/ - - if ( is_print_op ) - become_root(); - - if ( (ret = smbrun(command, NULL)) == 0 ) { - /* Tell everyone we updated smb.conf. */ - message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL); - } - - if ( is_print_op ) - unbecome_root(); - - /********** END SePrintOperatorPrivlege BLOCK **********/ - - DEBUGADD(10,("returned [%d]\n", ret)); - - if (ret != 0) - return WERR_BADFID; /* What to return here? */ - - /* go ahead and re-read the services immediately */ - reload_services( False ); - - if ( lp_servicenumber( Printer->sharename ) < 0 ) - return WERR_ACCESS_DENIED; - } - - return WERR_OK; + return delete_printer_hook( p->pipe_user.nt_user_token, Printer->sharename ); } /**************************************************************************** @@ -583,7 +580,7 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename) DEBUGADD(10, ("printername: %s\n", printername)); - free_a_printer( &printer, 2); + free_a_printer( &printer, 2); } if ( !found ) { @@ -1445,7 +1442,7 @@ static DEVICEMODE* dup_devicemode(TALLOC_CTX *ctx, DEVICEMODE *devmode) return NULL; } - d->private = TALLOC_MEMDUP(ctx, devmode->private, devmode->driverextra); + d->dev_private = TALLOC_MEMDUP(ctx, devmode->dev_private, devmode->driverextra); return d; } @@ -1885,12 +1882,12 @@ BOOL convert_devicemode(const char *printername, const DEVICEMODE *devmode, * has a new one. JRA. */ - if ((devmode->driverextra != 0) && (devmode->private != NULL)) { - SAFE_FREE(nt_devmode->private); + if ((devmode->driverextra != 0) && (devmode->dev_private != NULL)) { + SAFE_FREE(nt_devmode->nt_dev_private); nt_devmode->driverextra=devmode->driverextra; - if((nt_devmode->private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL) + if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL) return False; - memcpy(nt_devmode->private, devmode->private, nt_devmode->driverextra); + memcpy(nt_devmode->nt_dev_private, devmode->dev_private, nt_devmode->driverextra); } *pp_nt_devmode = nt_devmode; @@ -2211,7 +2208,8 @@ static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printe uint32 *needed, uint32 in_size ) { REGISTRY_VALUE *val; - int size, data_len; + uint32 size; + int data_len; if ( !(val = get_printer_data( printer->info_2, key, value)) ) return WERR_BADFILE; @@ -2260,7 +2258,7 @@ static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char Internal routine for storing printerdata ***************************************************************************/ -static WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value, +WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value, uint32 type, uint8 *data, int real_len ) { delete_printer_data( printer->info_2, key, value ); @@ -4089,7 +4087,7 @@ static void free_dev_mode(DEVICEMODE *dev) if (dev == NULL) return; - SAFE_FREE(dev->private); + SAFE_FREE(dev->dev_private); SAFE_FREE(dev); } @@ -4132,8 +4130,8 @@ static BOOL convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode devmode->mediatype = ntdevmode->mediatype; devmode->dithertype = ntdevmode->dithertype; - if (ntdevmode->private != NULL) { - if ((devmode->private=(uint8 *)memdup(ntdevmode->private, ntdevmode->driverextra)) == NULL) + if (ntdevmode->nt_dev_private != NULL) { + if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL) return False; } @@ -6032,7 +6030,7 @@ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum) /**************************************************************************** ****************************************************************************/ -static BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer) +BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer) { char *cmd = lp_addprinter_cmd(); char **qlines; @@ -6042,7 +6040,7 @@ static BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printe int fd; fstring remote_machine = "%m"; SE_PRIV se_printop = SE_PRINT_OPERATOR; - BOOL is_print_op; + BOOL is_print_op = False; standard_sub_basic(current_user_info.smb_name, remote_machine,sizeof(remote_machine)); @@ -6051,7 +6049,8 @@ static BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printe printer->info_2->portname, printer->info_2->drivername, printer->info_2->location, printer->info_2->comment, remote_machine); - is_print_op = user_has_privileges( token, &se_printop ); + if ( token ) + is_print_op = user_has_privileges( token, &se_printop ); DEBUG(10,("Running [%s]\n", command)); @@ -8030,7 +8029,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S result = WERR_NOMEM; goto done; } - data_len = (size_t)regval_size(val); + data_len = regval_size(val); memcpy( *data_out, regval_data_p(val), data_len ); *out_data_len = data_len; } @@ -9250,7 +9249,7 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_ int i; REGISTRY_VALUE *val; char *value_name; - int data_len; + uint32 data_len; DEBUG(4,("_spoolss_enumprinterdataex\n")); diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c index 91f0cefa98b..c3fd53a3844 100644 --- a/source/rpc_server/srv_srvsvc_nt.c +++ b/source/rpc_server/srv_srvsvc_nt.c @@ -1634,8 +1634,10 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) { - if (!lp_change_share_cmd() || !*lp_change_share_cmd()) + if (!lp_change_share_cmd() || !*lp_change_share_cmd()) { + DEBUG(10,("_srv_net_share_set_info: No change share command\n")); return WERR_ACCESS_DENIED; + } slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"", lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment); @@ -1870,8 +1872,10 @@ WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S if (user.uid != sec_initial_uid() && !is_disk_op ) return WERR_ACCESS_DENIED; - if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) + if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) { + DEBUG(10,("_srv_net_share_del: No delete share command\n")); return WERR_ACCESS_DENIED; + } slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"", lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum)); @@ -1972,8 +1976,6 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC files_struct *fsp = NULL; SMB_STRUCT_STAT st; BOOL bad_path; - int access_mode; - int action; NTSTATUS nt_status; struct current_user user; connection_struct *conn = NULL; @@ -2021,15 +2023,16 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC goto error_exit; } - fsp = open_file_shared(conn, filename, &st, SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY), - (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, - &access_mode, &action); - + fsp = open_file_stat(conn, filename, &st); if (!fsp) { /* Perhaps it is a directory */ if (errno == EISDIR) - fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0, - (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action); + fsp = open_directory(conn, filename, &st, + READ_CONTROL_ACCESS, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, + 0, + NULL); if (!fsp) { DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename)); @@ -2088,8 +2091,6 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_ files_struct *fsp = NULL; SMB_STRUCT_STAT st; BOOL bad_path; - int access_mode; - int action; NTSTATUS nt_status; struct current_user user; connection_struct *conn = NULL; @@ -2138,15 +2139,17 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_ } - fsp = open_file_shared(conn, filename, &st, SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDWR), - (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, - &access_mode, &action); + fsp = open_file_stat(conn, filename, &st); if (!fsp) { /* Perhaps it is a directory */ if (errno == EISDIR) - fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0, - (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action); + fsp = open_directory(conn, filename, &st, + FILE_READ_ATTRIBUTES, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, + 0, + NULL); if (!fsp) { DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename)); @@ -2174,11 +2177,13 @@ error_exit: close_file(fsp, True); } - if (became_user) + if (became_user) { unbecome_user(); + } - if (conn) + if (conn) { close_cnum(conn, user.vuid); + } return r_u->status; } diff --git a/source/sam/idmap.c b/source/sam/idmap.c index 91fe97e23a4..ec3ccb29859 100644 --- a/source/sam/idmap.c +++ b/source/sam/idmap.c @@ -353,14 +353,14 @@ NTSTATUS idmap_close(void) if (proxyonly) return NT_STATUS_OK; - ret = cache_map->close(); + ret = cache_map->close_fn(); if (!NT_STATUS_IS_OK(ret)) { DEBUG(3, ("idmap_close: failed to close local tdb cache!\n")); } cache_map = NULL; if (remote_map) { - ret = remote_map->close(); + ret = remote_map->close_fn(); if (!NT_STATUS_IS_OK(ret)) { DEBUG(3, ("idmap_close: failed to close remote idmap repository!\n")); } diff --git a/source/sam/idmap_util.c b/source/sam/idmap_util.c index 3c9f420a9a7..cac8934f7b6 100644 --- a/source/sam/idmap_util.c +++ b/source/sam/idmap_util.c @@ -184,3 +184,17 @@ NTSTATUS idmap_sid_to_gid(const DOM_SID *sid, gid_t *gid, uint32 flags) return ret; } + +/* placeholder for checking lp_winbind_nss_info() */ +BOOL use_nss_info(const char *info) +{ + int i; + const char **list = lp_winbind_nss_info(); + + for (i=0; list[i]; i++) { + if (strequal(list[i], info)) + return True; + } + + return False; +} diff --git a/source/script/installman.sh b/source/script/installman.sh index d30429d50a0..5564ac02318 100755 --- a/source/script/installman.sh +++ b/source/script/installman.sh @@ -13,6 +13,10 @@ if [ $# -ge 4 ] ; then GROFF=$4 # sh cmd line, including options fi +if test ! -d docs/manpages; then + echo "No manpages present. SVN development version maybe?" + exit 0 +fi for lang in $langs; do if [ "X$lang" = XC ]; then diff --git a/source/script/mkproto.awk b/source/script/mkproto.awk index d9223a19739..3c482675872 100644 --- a/source/script/mkproto.awk +++ b/source/script/mkproto.awk @@ -136,6 +136,10 @@ END { gotstart = 1; } + if( $0 ~ /^NODE_STATUS_STRUCT/ ) { + gotstart = 1; + } + if(!gotstart) { next; } diff --git a/source/smbd/blocking.c b/source/smbd/blocking.c index 0e71174a2ee..72d021d4e64 100644 --- a/source/smbd/blocking.c +++ b/source/smbd/blocking.c @@ -20,8 +20,6 @@ #include "includes.h" -extern char *OutBuffer; - /**************************************************************************** This is the structure to queue to implement blocking locks. notify. It consists of the requesting SMB and the expiry time. @@ -175,7 +173,7 @@ static void send_blocking_reply(char *outbuf, int outsize) static void reply_lockingX_success(blocking_lock_record *blr) { - char *outbuf = OutBuffer; + char *outbuf = get_OutBuffer(); int bufsize = BUFFER_SIZE; char *inbuf = blr->inbuf; int outsize = 0; @@ -204,7 +202,7 @@ static void reply_lockingX_success(blocking_lock_record *blr) static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS status) { - char *outbuf = OutBuffer; + char *outbuf = get_OutBuffer(); char *inbuf = blr->inbuf; construct_reply_common(inbuf, outbuf); @@ -295,7 +293,7 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status static BOOL process_lockread(blocking_lock_record *blr) { - char *outbuf = OutBuffer; + char *outbuf = get_OutBuffer(); char *inbuf = blr->inbuf; ssize_t nread = -1; char *data, *p; @@ -367,7 +365,7 @@ static BOOL process_lockread(blocking_lock_record *blr) static BOOL process_lock(blocking_lock_record *blr) { - char *outbuf = OutBuffer; + char *outbuf = get_OutBuffer(); char *inbuf = blr->inbuf; int outsize; SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c index d0e0f6e143a..56e5727b7d9 100644 --- a/source/smbd/chgpasswd.c +++ b/source/smbd/chgpasswd.c @@ -970,8 +970,8 @@ static BOOL check_passwd_history(SAM_ACCOUNT *sampass, const char *plaintext) return True; } - dump_data(100, new_nt_p16, NT_HASH_LEN); - dump_data(100, pwhistory, PW_HISTORY_ENTRY_LEN*pwHisLen); + dump_data(100, (const char *)new_nt_p16, NT_HASH_LEN); + dump_data(100, (const char *)pwhistory, PW_HISTORY_ENTRY_LEN*pwHisLen); memset(zero_md5_nt_pw, '\0', SALTED_MD5_HASH_LEN); for (i=0; i<pwHisLen; i++) { diff --git a/source/smbd/close.c b/source/smbd/close.c index b3244432ff5..3fc7fdb0599 100644 --- a/source/smbd/close.c +++ b/source/smbd/close.c @@ -3,6 +3,7 @@ file closing Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Jeremy Allison 1992-2004. + Copyright (C) Volker Lendecke 2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -92,7 +93,7 @@ static int close_filestruct(files_struct *fsp) connection_struct *conn = fsp->conn; int ret = 0; - if (fsp->fd != -1) { + if (fsp->fh->fd != -1) { if(flush_write_cache(fsp, CLOSE_FLUSH) == -1) ret = -1; @@ -148,7 +149,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close) { share_mode_entry *share_entry = NULL; size_t share_entry_count = 0; - BOOL delete_on_close = False; + BOOL delete_file = False; connection_struct *conn = fsp->conn; int saved_errno = 0; int err = 0; @@ -156,6 +157,20 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close) remove_pending_lock_requests_by_fid(fsp); + if (fsp->aio_write_behind) { + /* + * If we're finishing write behind on a close we can get a write + * error here, we must remember this. + */ + int ret = wait_for_aio_completion(fsp); + if (ret) { + saved_errno = ret; + err1 = -1; + } + } else { + cancel_aio_by_fsp(fsp); + } + /* * If we're flushing on a close we can get a write * error here, we must remember this. @@ -180,34 +195,16 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close) lock_share_entry_fsp(fsp); - if (fsp->delete_on_close) { - - /* - * Modify the share mode entry for all files open - * on this device and inode to tell other smbds we have - * changed the delete on close flag. The last closer will delete the file - * if flag is set. - */ - - NTSTATUS status =set_delete_on_close_over_all(fsp, fsp->delete_on_close); - if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK)) - DEBUG(0,("close_normal_file: failed to change delete on close flag for file %s\n", - fsp->fsp_name )); - } - - share_entry_count = del_share_mode(fsp, &share_entry); + share_entry_count = del_share_mode(fsp, &share_entry, + &delete_file); DEBUG(10,("close_normal_file: share_entry_count = %lu for file %s\n", (unsigned long)share_entry_count, fsp->fsp_name )); - /* - * We delete on close if it's the last open, and the - * delete on close flag was set in the entry we just deleted. - */ - - if ((share_entry_count == 0) && share_entry && - GET_DELETE_ON_CLOSE_FLAG(share_entry->share_mode) ) - delete_on_close = True; + if (share_entry_count != 0) { + /* We're not the last ones -- don't delete */ + delete_file = False; + } SAFE_FREE(share_entry); @@ -219,7 +216,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close) * reference to a file. */ - if (normal_close && delete_on_close) { + if (normal_close && delete_file) { DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n", fsp->fsp_name)); if(SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) { @@ -297,7 +294,8 @@ static int close_directory(files_struct *fsp, BOOL normal_close) * reference to a directory also. */ - if (normal_close && fsp->directory_delete_on_close) { + if (normal_close && + get_delete_on_close_flag(fsp->dev, fsp->inode)) { BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name); DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n", fsp->fsp_name, ok ? "succeeded" : "failed" )); @@ -307,8 +305,9 @@ static int close_directory(files_struct *fsp, BOOL normal_close) * now fail as the directory has been deleted. */ - if(ok) + if(ok) { remove_pending_change_notify_requests_by_filename(fsp); + } process_pending_change_notify_queue((time_t)0); } @@ -317,8 +316,9 @@ static int close_directory(files_struct *fsp, BOOL normal_close) */ close_filestruct(fsp); - if (fsp->fsp_name) + if (fsp->fsp_name) { string_free(&fsp->fsp_name); + } file_free(fsp); return 0; diff --git a/source/smbd/conn.c b/source/smbd/conn.c index 26529c77a1f..534a3367d48 100644 --- a/source/smbd/conn.c +++ b/source/smbd/conn.c @@ -257,6 +257,7 @@ void conn_free(connection_struct *conn) free_namearray(conn->veto_list); free_namearray(conn->hide_list); free_namearray(conn->veto_oplock_list); + free_namearray(conn->aio_write_behind_list); string_free(&conn->user); string_free(&conn->dirpath); @@ -283,7 +284,7 @@ void msg_force_tdis(int msg_type, pid_t pid, void *buf, size_t len) connection_struct *conn, *next; fstring sharename; - fstrcpy(sharename, buf); + fstrcpy(sharename, (const char *)buf); if (strcmp(sharename, "*") == 0) { DEBUG(1,("Forcing close of all shares\n")); diff --git a/source/smbd/dir.c b/source/smbd/dir.c index 072f396b8cc..949e31210f6 100644 --- a/source/smbd/dir.c +++ b/source/smbd/dir.c @@ -53,7 +53,7 @@ struct dptr_struct { struct smb_Dir *dir_hnd; BOOL expect_close; char *wcard; - uint16 attr; + uint32 attr; char *path; BOOL has_wild; /* Set to true if the wcard entry has MS wildcard characters in it. */ }; @@ -68,7 +68,7 @@ static int dirhandles_open = 0; Make a dir struct. ****************************************************************************/ -void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T size,int mode,time_t date, BOOL uc) +void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T size,uint32 mode,time_t date, BOOL uc) { char *p; pstring mask2; @@ -175,7 +175,7 @@ static struct dptr_struct *dptr_get(int key, BOOL forclose) if (dirhandles_open >= MAX_OPEN_DIRECTORIES) dptr_idleoldest(); DEBUG(4,("dptr_get: Reopening dptr key %d\n",key)); - if (!(dptr->dir_hnd = OpenDir(dptr->conn, dptr->path))) { + if (!(dptr->dir_hnd = OpenDir(dptr->conn, dptr->path, dptr->wcard, dptr->attr))) { DEBUG(4,("dptr_get: Failed to open %s (%s)\n",dptr->path, strerror(errno))); return False; @@ -225,30 +225,6 @@ uint16 dptr_attr(int key) } /**************************************************************************** - Set the dir wcard for a dir index. - Returns 0 on ok, 1 on fail. -****************************************************************************/ - -BOOL dptr_set_wcard_and_attributes(int key, const char *wcard, uint16 attr) -{ - struct dptr_struct *dptr = dptr_get(key, False); - - if (dptr) { - dptr->attr = attr; - dptr->wcard = SMB_STRDUP(wcard); - if (!dptr->wcard) - return False; - if (wcard[0] == '.' && wcard[1] == 0) { - dptr->has_wild = True; - } else { - dptr->has_wild = ms_has_wild(wcard); - } - return True; - } - return False; -} - -/**************************************************************************** Close a dptr (internal func). ****************************************************************************/ @@ -399,7 +375,8 @@ static void dptr_close_oldest(BOOL old) a directory handle is never zero. ****************************************************************************/ -int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid) +int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid, + const char *wcard, uint32 attr) { struct dptr_struct *dptr = NULL; struct smb_Dir *dir_hnd; @@ -415,7 +392,7 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp if (!*dir2) dir2 = "."; - dir_hnd = OpenDir(conn, dir2); + dir_hnd = OpenDir(conn, dir2, wcard, attr); if (!dir_hnd) { return (-2); } @@ -503,9 +480,23 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp dptr->dir_hnd = dir_hnd; dptr->spid = spid; dptr->expect_close = expect_close; - dptr->wcard = NULL; /* Only used in lanman2 searches */ - dptr->attr = 0; /* Only used in lanman2 searches */ - dptr->has_wild = True; /* Only used in lanman2 searches */ + if (wcard) { + dptr->wcard = SMB_STRDUP(wcard); + if (!dptr->wcard) { + bitmap_clear(dptr_bmap, dptr->dnum - 1); + SAFE_FREE(dptr); + CloseDir(dir_hnd); + return -1; + } + } else { + dptr->wcard = NULL; + } + dptr->attr = attr; + if (lp_posix_pathnames() || (wcard && (wcard[0] == '.' && wcard[1] == 0))) { + dptr->has_wild = True; + } else { + dptr->has_wild = ms_has_wild(wcard); + } DLIST_ADD(dirptrs, dptr); @@ -715,9 +706,9 @@ struct dptr_struct *dptr_fetch_lanman2(int dptr_num) Check a filetype for being valid. ****************************************************************************/ -BOOL dir_check_ftype(connection_struct *conn,int mode,int dirtype) +BOOL dir_check_ftype(connection_struct *conn, uint32 mode, uint32 dirtype) { - int mask; + uint32 mask; /* Check the "may have" search bits. */ if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0) @@ -747,8 +738,8 @@ static BOOL mangle_mask_match(connection_struct *conn, fstring filename, char *m Get an 8.3 directory entry. ****************************************************************************/ -BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname, - SMB_OFF_T *size,int *mode,time_t *date,BOOL check_descend) +BOOL get_dir_entry(connection_struct *conn,char *mask,uint32 dirtype, pstring fname, + SMB_OFF_T *size,uint32 *mode,time_t *date,BOOL check_descend) { const char *dname; BOOL found = False; @@ -804,7 +795,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname *mode = dos_mode(conn,pathreal,&sbuf); if (!dir_check_ftype(conn,*mode,dirtype)) { - DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype)); + DEBUG(5,("[%s] attribs didn't match %x\n",filename,(unsigned int)dirtype)); continue; } @@ -831,7 +822,6 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S SEC_DESC *psd = NULL; size_t sd_size; files_struct *fsp; - int smb_action; NTSTATUS status; uint32 access_granted; @@ -840,32 +830,41 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S * we never hide files from them. */ - if (conn->admin_user) + if (conn->admin_user) { return True; + } /* If we can't stat it does not show it */ - if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) + if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) { return False; + } /* Pseudo-open the file (note - no fd's created). */ - if(S_ISDIR(pst->st_mode)) - fsp = open_directory(conn, name, pst, 0, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), - &smb_action); - else + if(S_ISDIR(pst->st_mode)) { + fsp = open_directory(conn, name, pst, + READ_CONTROL_ACCESS, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, + 0, /* no create options. */ + NULL); + } else { fsp = open_file_stat(conn, name, pst); + } - if (!fsp) + if (!fsp) { return False; + } /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ - sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, + sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); close_file(fsp, True); /* No access if SD get failed. */ - if (!sd_size) + if (!sd_size) { return False; + } return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA, &access_granted, &status); @@ -883,8 +882,7 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ SEC_DESC *psd = NULL; size_t sd_size; files_struct *fsp; - int smb_action; - int access_mode; + int info; NTSTATUS status; uint32 access_granted; @@ -893,27 +891,36 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ * we never hide files from them. */ - if (conn->admin_user) + if (conn->admin_user) { return True; + } /* If we can't stat it does not show it */ - if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) + if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) { return False; + } - /* Pseudo-open the file (note - no fd's created). */ + /* Pseudo-open the file */ - if(S_ISDIR(pst->st_mode)) + if(S_ISDIR(pst->st_mode)) { return True; - else - fsp = open_file_shared1(conn, name, pst, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE), - (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, - &access_mode, &smb_action); + } else { + fsp = open_file_ntcreate(conn, name, pst, + FILE_WRITE_ATTRIBUTES, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, + 0, + FILE_ATTRIBUTE_NORMAL, + INTERNAL_OPEN_ONLY, + &info); + } - if (!fsp) + if (!fsp) { return False; + } /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ - sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, + sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); close_file(fsp, False); @@ -1000,7 +1007,7 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char * Open a directory. ********************************************************************/ -struct smb_Dir *OpenDir(connection_struct *conn, const char *name) +struct smb_Dir *OpenDir(connection_struct *conn, const char *name, const char *mask, uint32 attr) { struct smb_Dir *dirp = SMB_MALLOC_P(struct smb_Dir); if (!dirp) { @@ -1014,7 +1021,7 @@ struct smb_Dir *OpenDir(connection_struct *conn, const char *name) if (!dirp->dir_path) { goto fail; } - dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path); + dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); if (!dirp->dir) { DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, strerror(errno) )); goto fail; diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c index 3602e3f9081..a2bc424b8e7 100644 --- a/source/smbd/dosmode.c +++ b/source/smbd/dosmode.c @@ -430,7 +430,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, if (!fsp) return -1; become_root(); - ret = SMB_VFS_FCHMOD(fsp, fsp->fd, unixmode); + ret = SMB_VFS_FCHMOD(fsp, fsp->fh->fd, unixmode); unbecome_root(); close_file_fchmod(fsp); } diff --git a/source/smbd/fake_file.c b/source/smbd/fake_file.c index 59ddb60db5e..799725a7820 100644 --- a/source/smbd/fake_file.c +++ b/source/smbd/fake_file.c @@ -22,77 +22,6 @@ extern struct current_user current_user; -/**************************************************************************** - Open a file with a share mode. -****************************************************************************/ -files_struct *open_fake_file_shared1(enum FAKE_FILE_TYPE fake_file_type, connection_struct *conn,char *fname, - SMB_STRUCT_STAT *psbuf, - uint32 desired_access, - int share_mode,int ofun, uint32 new_dos_attr, int oplock_request, - int *Access,int *action) -{ - int flags=0; - files_struct *fsp = NULL; - - if (fake_file_type == 0) { - return open_file_shared1(conn,fname,psbuf,desired_access, - share_mode,ofun,new_dos_attr, - oplock_request,Access,action); - } - - /* access check */ - if (current_user.uid != 0) { - DEBUG(1,("access_denied to service[%s] file[%s] user[%s]\n", - lp_servicename(SNUM(conn)),fname,conn->user)); - errno = EACCES; - return NULL; - } - - fsp = file_new(conn); - if(!fsp) - return NULL; - - DEBUG(5,("open_fake_file_shared1: fname = %s, FID = %d, share_mode = %x, ofun = %x, oplock request = %d\n", - fname, fsp->fnum, share_mode, ofun, oplock_request )); - - if (!check_name(fname,conn)) { - file_free(fsp); - return NULL; - } - - fsp->fd = -1; - fsp->mode = psbuf->st_mode; - fsp->inode = psbuf->st_ino; - fsp->dev = psbuf->st_dev; - fsp->vuid = current_user.vuid; - fsp->pos = -1; - fsp->can_lock = True; - fsp->can_read = ((flags & O_WRONLY)==0); - fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0); - fsp->share_mode = 0; - fsp->desired_access = desired_access; - fsp->print_file = False; - fsp->modified = False; - fsp->oplock_type = NO_OPLOCK; - fsp->sent_oplock_break = NO_BREAK_SENT; - fsp->is_directory = False; - fsp->is_stat = False; - fsp->directory_delete_on_close = False; - fsp->conn = conn; - string_set(&fsp->fsp_name,fname); - fsp->wcp = NULL; /* Write cache pointer. */ - - fsp->fake_file_handle = init_fake_file_handle(fake_file_type); - - if (fsp->fake_file_handle==NULL) { - file_free(fsp); - return NULL; - } - - conn->num_files_open++; - return fsp; -} - static FAKE_FILE fake_files[] = { #ifdef WITH_QUOTAS {FAKE_FILE_NAME_QUOTA_UNIX, FAKE_FILE_TYPE_QUOTA, init_quota_handle, destroy_quota_handle}, @@ -100,24 +29,11 @@ static FAKE_FILE fake_files[] = { {NULL, FAKE_FILE_TYPE_NONE, NULL, NULL } }; -int is_fake_file(char *fname) -{ - int i; - - if (!fname) - return 0; - - for (i=0;fake_files[i].name!=NULL;i++) { - if (strncmp(fname,fake_files[i].name,strlen(fake_files[i].name))==0) { - DEBUG(5,("is_fake_file: [%s] is a fake file\n",fname)); - return fake_files[i].type; - } - } - - return FAKE_FILE_TYPE_NONE; -} +/**************************************************************************** + Create a fake file handle +****************************************************************************/ -struct _FAKE_FILE_HANDLE *init_fake_file_handle(enum FAKE_FILE_TYPE type) +static struct _FAKE_FILE_HANDLE *init_fake_file_handle(enum FAKE_FILE_TYPE type) { TALLOC_CTX *mem_ctx = NULL; FAKE_FILE_HANDLE *fh = NULL; @@ -141,8 +57,9 @@ struct _FAKE_FILE_HANDLE *init_fake_file_handle(enum FAKE_FILE_TYPE type) fh->type = type; fh->mem_ctx = mem_ctx; - if (fake_files[i].init_pd) + if (fake_files[i].init_pd) { fh->pd = fake_files[i].init_pd(fh->mem_ctx); + } fh->free_pd = fake_files[i].free_pd; @@ -153,13 +70,88 @@ struct _FAKE_FILE_HANDLE *init_fake_file_handle(enum FAKE_FILE_TYPE type) return NULL; } +/**************************************************************************** + Does this name match a fake filename ? +****************************************************************************/ + +enum FAKE_FILE_TYPE is_fake_file(const char *fname) +{ +#ifdef HAVE_SYS_QUOTAS + int i; +#endif + + if (!fname) { + return FAKE_FILE_TYPE_NONE; + } + +#ifdef HAVE_SYS_QUOTAS + for (i=0;fake_files[i].name!=NULL;i++) { + if (strncmp(fname,fake_files[i].name,strlen(fake_files[i].name))==0) { + DEBUG(5,("is_fake_file: [%s] is a fake file\n",fname)); + return fake_files[i].type; + } + } +#endif + + return FAKE_FILE_TYPE_NONE; +} + + +/**************************************************************************** + Open a fake quota file with a share mode. +****************************************************************************/ + +files_struct *open_fake_file(connection_struct *conn, + enum FAKE_FILE_TYPE fake_file_type, + const char *fname, + uint32 access_mask) +{ + files_struct *fsp = NULL; + + /* access check */ + if (current_user.uid != 0) { + DEBUG(1,("open_fake_file_shared: access_denied to service[%s] file[%s] user[%s]\n", + lp_servicename(SNUM(conn)),fname,conn->user)); + errno = EACCES; + return NULL; + } + + fsp = file_new(conn); + if(!fsp) { + return NULL; + } + + DEBUG(5,("open_fake_file_shared: fname = %s, FID = %d, access_mask = 0x%x\n", + fname, fsp->fnum, (unsigned int)access_mask)); + + fsp->conn = conn; + fsp->fh->fd = -1; + fsp->vuid = current_user.vuid; + fsp->fh->pos = -1; + fsp->can_lock = True; /* Should this be true ? */ + fsp->access_mask = access_mask; + string_set(&fsp->fsp_name,fname); + + fsp->fake_file_handle = init_fake_file_handle(fake_file_type); + + if (fsp->fake_file_handle==NULL) { + file_free(fsp); + return NULL; + } + + conn->num_files_open++; + return fsp; +} + void destroy_fake_file_handle(FAKE_FILE_HANDLE **fh) { - if (!fh||!(*fh)) + if (!fh||!(*fh)) { return; + } - if ((*fh)->free_pd) + if ((*fh)->free_pd) { (*fh)->free_pd(&(*fh)->pd); + } talloc_destroy((*fh)->mem_ctx); (*fh) = NULL; diff --git a/source/smbd/fileio.c b/source/smbd/fileio.c index 69b8b576428..76189d114bb 100644 --- a/source/smbd/fileio.c +++ b/source/smbd/fileio.c @@ -65,20 +65,20 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) */ if(read_from_write_cache(fsp, data, pos, n)) { - fsp->pos = pos + n; - fsp->position_information = fsp->pos; + fsp->fh->pos = pos + n; + fsp->fh->position_information = fsp->fh->pos; return n; } flush_write_cache(fsp, READ_FLUSH); - fsp->pos = pos; + fsp->fh->pos = pos; if (n > 0) { #ifdef DMF_FIX int numretries = 3; tryagain: - readret = SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos); + readret = SMB_VFS_PREAD(fsp,fsp->fh->fd,data,n,pos); if (readret == -1) { if ((errno == EAGAIN) && numretries) { @@ -90,7 +90,7 @@ tryagain: return -1; } #else /* NO DMF fix. */ - readret = SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos); + readret = SMB_VFS_PREAD(fsp,fsp->fh->fd,data,n,pos); if (readret == -1) { return -1; @@ -104,8 +104,8 @@ tryagain: DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n", fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret )); - fsp->pos += ret; - fsp->position_information = fsp->pos; + fsp->fh->pos += ret; + fsp->fh->position_information = fsp->fh->pos; return(ret); } @@ -124,7 +124,7 @@ static ssize_t real_write_file(files_struct *fsp,const char *data, SMB_OFF_T pos if (pos == -1) { ret = vfs_write_data(fsp, data, n); } else { - fsp->pos = pos; + fsp->fh->pos = pos; if (pos && lp_strict_allocate(SNUM(fsp->conn))) { if (vfs_fill_sparse(fsp, pos) == -1) { return -1; @@ -137,7 +137,7 @@ static ssize_t real_write_file(files_struct *fsp,const char *data, SMB_OFF_T pos fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret )); if (ret != -1) { - fsp->pos += ret; + fsp->fh->pos += ret; /* * It turns out that setting the last write time from a Windows @@ -180,7 +180,7 @@ static int wcp_file_size_change(files_struct *fsp) write_cache *wcp = fsp->wcp; wcp->file_size = wcp->offset + wcp->data_size; - ret = SMB_VFS_FTRUNCATE(fsp, fsp->fd, wcp->file_size); + ret = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, wcp->file_size); if (ret == -1) { DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f error %s\n", fsp->fsp_name, (double)wcp->file_size, strerror(errno) )); @@ -221,7 +221,7 @@ ssize_t write_file(files_struct *fsp, const char *data, SMB_OFF_T pos, size_t n) SMB_STRUCT_STAT st; fsp->modified = True; - if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0) { + if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); if ((lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn)) && !IS_DOS_ARCHIVE(dosmode)) { file_set_dosmode(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st, False); @@ -288,9 +288,9 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", } DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f wcp->data_size=%u\n", - fsp->fsp_name, fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size)); + fsp->fsp_name, fsp->fh->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size)); - fsp->pos = pos + n; + fsp->fh->pos = pos + n; /* * If we have active cache and it isn't contiguous then we flush. @@ -589,7 +589,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", */ DEBUG(9,("write_file: non cacheable write : fd = %d, pos = %.0f, len = %u, current cache pos = %.0f \ -len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size )); +len = %u\n",fsp->fh->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size )); /* * If write would fit in the cache, and is larger than @@ -612,7 +612,7 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne if ((pos <= wcp->offset) && (pos + n >= wcp->offset + wcp->data_size) ) { DEBUG(9,("write_file: discarding overwritten write \ -cache: fd = %d, off=%.0f, size=%u\n", fsp->fd, (double)wcp->offset, (unsigned int)wcp->data_size )); +cache: fd = %d, off=%.0f, size=%u\n", fsp->fh->fd, (double)wcp->offset, (unsigned int)wcp->data_size )); wcp->data_size = 0; } @@ -635,7 +635,7 @@ cache: fd = %d, off=%.0f, size=%u\n", fsp->fd, (double)wcp->offset, (unsigned in if (cache_flush_needed) { DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", - write_path, fsp->fd, (double)wcp->file_size, (double)pos, (unsigned int)n, + write_path, fsp->fh->fd, (double)wcp->file_size, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size )); flush_write_cache(fsp, WRITE_FLUSH); @@ -752,7 +752,7 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) wcp->offset = 0; wcp->alloc_size = alloc_size; wcp->data_size = 0; - if((wcp->data = SMB_MALLOC(wcp->alloc_size)) == NULL) { + if((wcp->data = (char *)SMB_MALLOC(wcp->alloc_size)) == NULL) { DEBUG(0,("setup_write_cache: malloc fail for buffer size %u.\n", (unsigned int)wcp->alloc_size )); SAFE_FREE(wcp); @@ -809,7 +809,7 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) DO_PROFILE_DEC_INC(writecache_num_write_caches,writecache_flushed_writes[reason]); DEBUG(9,("flushing write cache: fd = %d, off=%.0f, size=%u\n", - fsp->fd, (double)wcp->offset, (unsigned int)data_size)); + fsp->fh->fd, (double)wcp->offset, (unsigned int)data_size)); #ifdef WITH_PROFILE if(data_size == wcp->alloc_size) { @@ -836,9 +836,9 @@ sync a file void sync_file(connection_struct *conn, files_struct *fsp) { - if(lp_strict_sync(SNUM(conn)) && fsp->fd != -1) { + if(lp_strict_sync(SNUM(conn)) && fsp->fh->fd != -1) { flush_write_cache(fsp, SYNC_FLUSH); - SMB_VFS_FSYNC(fsp,fsp->fd); + SMB_VFS_FSYNC(fsp,fsp->fh->fd); } } @@ -849,9 +849,9 @@ void sync_file(connection_struct *conn, files_struct *fsp) int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst) { - if (fsp->fd == -1) { + if (fsp->fh->fd == -1) { return SMB_VFS_STAT(fsp->conn, fsp->fsp_name, pst); } else { - return SMB_VFS_FSTAT(fsp,fsp->fd, pst); + return SMB_VFS_FSTAT(fsp,fsp->fh->fd, pst); } } diff --git a/source/smbd/filename.c b/source/smbd/filename.c index 3fb88974fef..f0a33e568eb 100644 --- a/source/smbd/filename.c +++ b/source/smbd/filename.c @@ -450,7 +450,7 @@ static BOOL scan_directory(connection_struct *conn, const char *path, char *name mangled = !mangle_check_cache( name, maxlength, SNUM(conn)); /* open the directory */ - if (!(cur_dir = OpenDir(conn, path))) { + if (!(cur_dir = OpenDir(conn, path, NULL, 0))) { DEBUG(3,("scan dir didn't open dir [%s]\n",path)); return(False); } diff --git a/source/smbd/files.c b/source/smbd/files.c index e893e9fefc1..c90c2b627ca 100644 --- a/source/smbd/files.c +++ b/source/smbd/files.c @@ -106,7 +106,19 @@ files_struct *file_new(connection_struct *conn) } ZERO_STRUCTP(fsp); - fsp->fd = -1; + + fsp->fh = SMB_MALLOC_P(struct fd_handle); + if (!fsp->fh) { + SAFE_FREE(fsp); + set_saved_error_triple(ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY); + return NULL; + } + + ZERO_STRUCTP(fsp->fh); + + fsp->fh->ref_count = 1; + fsp->fh->fd = -1; + fsp->conn = conn; fsp->file_id = get_gen_count(); GetTimeOfDay(&fsp->open_time); @@ -226,6 +238,10 @@ void file_close_user(int vuid) } } +/**************************************************************************** + Debug to enumerate all open files in the smbd. +****************************************************************************/ + void file_dump_open_table(void) { int count=0; @@ -233,7 +249,7 @@ void file_dump_open_table(void) for (fsp=Files;fsp;fsp=fsp->next,count++) { DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, fileid = %lu, dev = %x, inode = %.0f\n", - count, fsp->fnum, fsp->fsp_name, fsp->fd, (unsigned long)fsp->file_id, + count, fsp->fnum, fsp->fsp_name, fsp->fh->fd, (unsigned long)fsp->file_id, (unsigned int)fsp->dev, (double)fsp->inode )); } } @@ -248,7 +264,7 @@ files_struct *file_find_fd(int fd) files_struct *fsp; for (fsp=Files;fsp;fsp=fsp->next,count++) { - if (fsp->fd == fd) { + if (fsp->fh->fd == fd) { if (count > 10) { DLIST_PROMOTE(Files, fsp); } @@ -269,7 +285,7 @@ files_struct *file_find_dif(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_i files_struct *fsp; for (fsp=Files;fsp;fsp=fsp->next,count++) { - /* We can have a fsp->fd == -1 here as it could be a stat open. */ + /* We can have a fsp->fh->fd == -1 here as it could be a stat open. */ if (fsp->dev == dev && fsp->inode == inode && fsp->file_id == file_id ) { @@ -277,7 +293,7 @@ files_struct *file_find_dif(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_i DLIST_PROMOTE(Files, fsp); } /* Paranoia check. */ - if (fsp->fd == -1 && fsp->oplock_type != NO_OPLOCK) { + if (fsp->fh->fd == -1 && fsp->oplock_type != NO_OPLOCK) { DEBUG(0,("file_find_dif: file %s dev = %x, inode = %.0f, file_id = %u \ oplock_type = %u is a stat open with oplock type !\n", fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, (unsigned int)fsp->file_id, @@ -326,7 +342,7 @@ files_struct *file_find_di_first(SMB_DEV_T dev, SMB_INO_T inode) fsp_fi_cache.inode = inode; for (fsp=Files;fsp;fsp=fsp->next) { - if ( fsp->fd != -1 && + if ( fsp->fh->fd != -1 && fsp->dev == dev && fsp->inode == inode ) { /* Setup positive cache. */ @@ -349,7 +365,7 @@ files_struct *file_find_di_next(files_struct *start_fsp) files_struct *fsp; for (fsp = start_fsp->next;fsp;fsp=fsp->next) { - if ( fsp->fd != -1 && + if ( fsp->fh->fd != -1 && fsp->dev == start_fsp->dev && fsp->inode == start_fsp->inode ) return fsp; @@ -389,7 +405,7 @@ void fsp_set_pending_modtime(files_struct *tfsp, time_t pmod) } for (fsp = Files;fsp;fsp=fsp->next) { - if ( fsp->fd != -1 && + if ( fsp->fh->fd != -1 && fsp->dev == tfsp->dev && fsp->inode == tfsp->inode ) { fsp->pending_modtime = pmod; @@ -410,7 +426,7 @@ void file_sync_all(connection_struct *conn) for (fsp=Files;fsp;fsp=next) { next=fsp->next; - if ((conn == fsp->conn) && (fsp->fd != -1)) { + if ((conn == fsp->conn) && (fsp->fh->fd != -1)) { sync_file(conn,fsp); } } @@ -430,6 +446,12 @@ void file_free(files_struct *fsp) destroy_fake_file_handle(&fsp->fake_file_handle); } + if (fsp->fh->ref_count == 1) { + SAFE_FREE(fsp->fh); + } else { + fsp->fh->ref_count--; + } + bitmap_clear(file_bmap, fsp->fnum - FILE_HANDLE_OFFSET); files_used--; @@ -490,7 +512,7 @@ void file_chain_reset(void) } /**************************************************************************** -Save the chained fsp - done when about to do an oplock break. + Save the chained fsp - done when about to do an oplock break. ****************************************************************************/ void file_chain_save(void) @@ -499,10 +521,60 @@ void file_chain_save(void) } /**************************************************************************** -Restore the chained fsp - done after an oplock break. + Restore the chained fsp - done after an oplock break. ****************************************************************************/ void file_chain_restore(void) { chain_fsp = oplock_save_chain_fsp; } + +/**************************************************************************** + Duplicate the file handle part for a DOS or FCB open. +****************************************************************************/ + +files_struct *dup_file_fsp(files_struct *fsp, + uint32 access_mask, + uint32 share_access, + uint32 create_options) +{ + files_struct *dup_fsp = file_new(fsp->conn); + + if (!dup_fsp) { + return NULL; + } + + SAFE_FREE(dup_fsp->fh); + + dup_fsp->fh = fsp->fh; + dup_fsp->fh->ref_count++; + + dup_fsp->dev = fsp->dev; + dup_fsp->inode = fsp->inode; + dup_fsp->initial_allocation_size = fsp->initial_allocation_size; + dup_fsp->mode = fsp->mode; + dup_fsp->file_pid = fsp->file_pid; + dup_fsp->vuid = fsp->vuid; + dup_fsp->open_time = fsp->open_time; + dup_fsp->access_mask = access_mask; + dup_fsp->share_access = share_access; + dup_fsp->pending_modtime_owner = fsp->pending_modtime_owner; + dup_fsp->pending_modtime = fsp->pending_modtime; + dup_fsp->last_write_time = fsp->last_write_time; + dup_fsp->oplock_type = fsp->oplock_type; + dup_fsp->can_lock = fsp->can_lock; + dup_fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False; + if (!CAN_WRITE(fsp->conn)) { + dup_fsp->can_write = False; + } else { + dup_fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ? True : False; + } + dup_fsp->print_file = fsp->print_file; + dup_fsp->modified = fsp->modified; + dup_fsp->is_directory = fsp->is_directory; + dup_fsp->is_stat = fsp->is_stat; + dup_fsp->aio_write_behind = fsp->aio_write_behind; + string_set(&dup_fsp->fsp_name,fsp->fsp_name); + + return dup_fsp; +} diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index e3f6521fba8..86c6d056a07 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -163,7 +163,7 @@ void send_trans_reply(char *outbuf, static BOOL api_rpc_trans_reply(char *outbuf, smb_np_struct *p) { BOOL is_data_outstanding; - char *rdata = SMB_MALLOC(p->max_trans_reply); + char *rdata = (char *)SMB_MALLOC(p->max_trans_reply); int data_len; if(rdata == NULL) { diff --git a/source/smbd/mangle.c b/source/smbd/mangle.c index afc1ca12f05..ed69a6210e8 100644 --- a/source/smbd/mangle.c +++ b/source/smbd/mangle.c @@ -29,6 +29,7 @@ static const struct { } mangle_backends[] = { { "hash", mangle_hash_init }, { "hash2", mangle_hash2_init }, + { "posix", posix_mangle_init }, /*{ "tdb", mangle_tdb_init }, */ { NULL, NULL } }; @@ -39,7 +40,7 @@ static const struct { static void mangle_init(void) { int i; - char *method; + const char *method; if (mangle_fns) return; @@ -70,6 +71,13 @@ void mangle_reset_cache(void) mangle_fns->reset(); } +void mangle_change_to_posix(void) +{ + mangle_fns = NULL; + lp_set_mangling_method("posix"); + mangle_reset_cache(); +} + /* see if a filename has come out of our mangling code */ diff --git a/source/smbd/mangle_hash2.c b/source/smbd/mangle_hash2.c index 4325c07f580..e44aaf17e75 100644 --- a/source/smbd/mangle_hash2.c +++ b/source/smbd/mangle_hash2.c @@ -716,3 +716,42 @@ struct mangle_fns *mangle_hash2_init(void) return &mangle_fns; } + +static void posix_mangle_reset(void) +{;} + +static BOOL posix_is_mangled(const char *s, int snum) +{ + return False; +} + +static BOOL posix_is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards, int snum) +{ + return False; +} + +static BOOL posix_check_cache( char *s, size_t maxlen, int snum ) +{ + return False; +} + +static void posix_name_map(char *OutName, BOOL need83, BOOL cache83, int default_case, int snum) +{ + if (need83) { + memset(OutName, '\0', 13); + } +} + +/* POSIX paths backend - no mangle. */ +static struct mangle_fns posix_mangle_fns = { + posix_mangle_reset, + posix_is_mangled, + posix_is_8_3, + posix_check_cache, + posix_name_map +}; + +struct mangle_fns *posix_mangle_init(void) +{ + return &posix_mangle_fns; +} diff --git a/source/smbd/msdfs.c b/source/smbd/msdfs.c index b61a3280808..fffe44ab603 100644 --- a/source/smbd/msdfs.c +++ b/source/smbd/msdfs.c @@ -20,6 +20,7 @@ */ +#define DBGC_CLASS DBGC_MSDFS #include "includes.h" extern uint32 global_client_caps; @@ -576,7 +577,9 @@ static int setup_ver2_dfs_referral(char* pathname, char** ppdata, requestedpathlen = rpcstr_push(uni_requestedpath, pathname, -1, STR_TERMINATE); - dump_data(10, (const char *) uni_requestedpath,requestedpathlen); + if (DEBUGLVL(10)) { + dump_data(0, (const char *) uni_requestedpath,requestedpathlen); + } DEBUG(10,("ref count = %u\n",junction->referral_count)); @@ -671,7 +674,9 @@ static int setup_ver3_dfs_referral(char* pathname, char** ppdata, reqpathlen = rpcstr_push(uni_reqpath, pathname, -1, STR_TERMINATE); - dump_data(10, (char *) uni_reqpath,reqpathlen); + if (DEBUGLVL(10)) { + dump_data(0, (char *) uni_reqpath,reqpathlen); + } uni_reqpathoffset1 = REFERRAL_HEADER_SIZE + VERSION3_REFERRAL_SIZE * junction->referral_count; uni_reqpathoffset2 = uni_reqpathoffset1 + reqpathlen; @@ -797,8 +802,11 @@ int setup_dfs_referral(connection_struct *orig_conn, char *pathname, int max_ref return -1; } - DEBUG(10,("DFS Referral pdata:\n")); - dump_data(10,*ppdata,reply_size); + if (DEBUGLVL(10)) { + DEBUGADD(0,("DFS Referral pdata:\n")); + dump_data(0,*ppdata,reply_size); + } + return reply_size; } @@ -937,29 +945,30 @@ BOOL remove_msdfs_link(struct junction_map* jucn) return ret; } -static BOOL form_junctions(int snum, struct junction_map* jucn, int* jn_count) +static int form_junctions(int snum, struct junction_map* jucn, int jn_remain) { - int cnt = *jn_count; + int cnt = 0; DIR *dirp; char* dname; pstring connect_path; char* service_name = lp_servicename(snum); - connection_struct conns; - connection_struct *conn = &conns; + connection_struct conn; struct referral *ref = NULL; - BOOL ret = False; + if (jn_remain <= 0) + return(0); + pstrcpy(connect_path,lp_pathname(snum)); if(*connect_path == '\0') - return False; + return 0; /* * Fake up a connection struct for the VFS layer. */ - if (!create_conn_struct(conn, snum, connect_path)) - return False; + if (!create_conn_struct(&conn, snum, connect_path)) + return 0; /* form a junction for the msdfs root - convention DO NOT REMOVE THIS: NT clients will not work with us @@ -979,22 +988,25 @@ static BOOL form_junctions(int snum, struct junction_map* jucn, int* jn_count) ref->ttl = REFERRAL_TTL; if (*lp_msdfs_proxy(snum) != '\0') { pstrcpy(ref->alternate_path, lp_msdfs_proxy(snum)); - *jn_count = ++cnt; - ret = True; goto out; } slprintf(ref->alternate_path, sizeof(pstring)-1, "\\\\%s\\%s", get_local_machine_name(), service_name); cnt++; - + /* Now enumerate all dfs links */ - dirp = SMB_VFS_OPENDIR(conn, "."); + dirp = SMB_VFS_OPENDIR(&conn, ".", NULL, 0); if(!dirp) goto out; - while((dname = vfs_readdirname(conn, dirp)) != NULL) { - if (is_msdfs_link(conn, dname, &(jucn[cnt].referral_list), + while ((dname = vfs_readdirname(&conn, dirp)) != NULL) { + if (cnt >= jn_remain) { + SMB_VFS_CLOSEDIR(&conn,dirp); + DEBUG(2, ("ran out of MSDFS junction slots")); + goto out; + } + if (is_msdfs_link(&conn, dname, &(jucn[cnt].referral_list), &(jucn[cnt].referral_count), NULL)) { pstrcpy(jucn[cnt].service_name, service_name); pstrcpy(jucn[cnt].volume_name, dname); @@ -1002,14 +1014,13 @@ static BOOL form_junctions(int snum, struct junction_map* jucn, int* jn_count) } } - SMB_VFS_CLOSEDIR(conn,dirp); - *jn_count = cnt; + SMB_VFS_CLOSEDIR(&conn,dirp); out: - talloc_destroy(conn->mem_ctx); - return ret; + conn_free(&conn); + return cnt; } -int enum_msdfs_links(struct junction_map* jucn) +int enum_msdfs_links(struct junction_map* jucn, int jn_max) { int i=0; int jn_count = 0; @@ -1017,9 +1028,9 @@ int enum_msdfs_links(struct junction_map* jucn) if(!lp_host_msdfs()) return 0; - for(i=0;i < lp_numservices();i++) { + for(i=0;i < lp_numservices() && (jn_max - jn_count) > 0;i++) { if(lp_msdfs_root(i)) - form_junctions(i,jucn,&jn_count); + jn_count += form_junctions(i,jucn,jn_max - jn_count); } return jn_count; } diff --git a/source/smbd/notify.c b/source/smbd/notify.c index 92b86f350c7..ad49dc0a211 100644 --- a/source/smbd/notify.c +++ b/source/smbd/notify.c @@ -60,6 +60,7 @@ static void change_notify_reply_packet(char *inbuf, NTSTATUS error_code) */ set_message(outbuf,18,0,False); + show_msg(outbuf); if (!send_smb(smbd_server_fd(),outbuf)) exit_server("change_notify_reply_packet: send_smb failed."); } diff --git a/source/smbd/notify_hash.c b/source/smbd/notify_hash.c index 0464eaa2eb3..08eefab6520 100644 --- a/source/smbd/notify_hash.c +++ b/source/smbd/notify_hash.c @@ -76,7 +76,7 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags, * larger than the max time_t value). */ - dp = OpenDir(conn, path); + dp = OpenDir(conn, path, NULL, 0); if (dp == NULL) return False; diff --git a/source/smbd/ntquotas.c b/source/smbd/ntquotas.c index 8fbf858008b..9bc444d2536 100644 --- a/source/smbd/ntquotas.c +++ b/source/smbd/ntquotas.c @@ -259,4 +259,3 @@ void destroy_quota_handle(void **pqt_handle) return; } - diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c index a0f94d616df..f9b70de0ace 100644 --- a/source/smbd/nttrans.c +++ b/source/smbd/nttrans.c @@ -46,20 +46,12 @@ static const char *known_nt_pipes[] = { NULL }; -/* Map generic permissions to file object specific permissions */ - -struct generic_mapping file_generic_mapping = { - FILE_GENERIC_READ, - FILE_GENERIC_WRITE, - FILE_GENERIC_EXECUTE, - FILE_GENERIC_ALL -}; - static char *nttrans_realloc(char **ptr, size_t size) { char *tptr = NULL; - if (ptr==NULL) + if (ptr==NULL) { smb_panic("nttrans_realloc() called with NULL ptr\n"); + } tptr = SMB_REALLOC(*ptr, size); if(tptr == NULL) { @@ -99,8 +91,9 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, NTSTATUS nt_e set_message(outbuf,18,0,True); - if (NT_STATUS_V(nt_error)) + if (NT_STATUS_V(nt_error)) { ERROR_NT(nt_error); + } /* * If there genuinely are no parameters or data to send just send @@ -108,8 +101,10 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, NTSTATUS nt_e */ if(params_to_send == 0 && data_to_send == 0) { - if (!send_smb(smbd_server_fd(),outbuf)) + show_msg(outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) { exit_server("send_nt_replies: send_smb failed."); + } return 0; } @@ -119,8 +114,9 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, NTSTATUS nt_e * can cause NT redirector problems. */ - if (((params_to_send % 4) != 0) && (data_to_send != 0)) + if (((params_to_send % 4) != 0) && (data_to_send != 0)) { data_alignment_offset = 4 - (params_to_send % 4); + } /* * Space is bufsize minus Netbios over TCP header minus SMB header. @@ -221,16 +217,18 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, NTSTATUS nt_e * Copy the param bytes into the packet. */ - if(params_sent_thistime) + if(params_sent_thistime) { memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime); + } /* * Copy in the data bytes */ - if(data_sent_thistime) + if(data_sent_thistime) { memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+ data_alignment_offset,pd,data_sent_thistime); + } DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n", params_sent_thistime, data_sent_thistime, useable_space)); @@ -238,8 +236,10 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, NTSTATUS nt_e params_to_send, data_to_send, paramsize, datasize)); /* Send the packet */ - if (!send_smb(smbd_server_fd(),outbuf)) + show_msg(outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) { exit_server("send_nt_replies: send_smb failed."); + } pp += params_sent_thistime; pd += data_sent_thistime; @@ -267,6 +267,9 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, NTSTATUS nt_e BOOL is_ntfs_stream_name(const char *fname) { + if (lp_posix_pathnames()) { + return False; + } return (strchr_m(fname, ':') != NULL) ? True : False; } @@ -284,8 +287,9 @@ static BOOL saved_short_case_preserve; static void set_posix_case_semantics(connection_struct *conn, uint32 file_attributes) { - if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) + if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) { return; + } saved_case_sensitive = conn->case_sensitive; saved_case_preserve = conn->case_preserve; @@ -303,8 +307,9 @@ static void set_posix_case_semantics(connection_struct *conn, uint32 file_attrib static void restore_case_semantics(connection_struct *conn, uint32 file_attributes) { - if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) + if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) { return; + } conn->case_sensitive = saved_case_sensitive; conn->case_preserve = saved_case_preserve; @@ -312,192 +317,6 @@ static void restore_case_semantics(connection_struct *conn, uint32 file_attribut } /**************************************************************************** - Utility function to map create disposition. -****************************************************************************/ - -static int map_create_disposition( uint32 create_disposition) -{ - int ret; - - switch( create_disposition ) { - case FILE_CREATE: - /* create if not exist, fail if exist */ - ret = (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL); - break; - case FILE_SUPERSEDE: - case FILE_OVERWRITE_IF: - /* create if not exist, trunc if exist */ - ret = (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE); - break; - case FILE_OPEN: - /* fail if not exist, open if exists */ - ret = (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN); - break; - case FILE_OPEN_IF: - /* create if not exist, open if exists */ - ret = (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_OPEN); - break; - case FILE_OVERWRITE: - /* fail if not exist, truncate if exists */ - ret = (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE); - break; - default: - DEBUG(0,("map_create_disposition: Incorrect value for create_disposition = %d\n", - create_disposition )); - return -1; - } - - DEBUG(10,("map_create_disposition: Mapped create_disposition 0x%lx to 0x%x\n", - (unsigned long)create_disposition, ret )); - - return ret; -} - -/**************************************************************************** - Utility function to map share modes. -****************************************************************************/ - -static int map_share_mode( char *fname, uint32 create_options, - uint32 *desired_access, uint32 share_access, uint32 file_attributes) -{ - int smb_open_mode = -1; - uint32 original_desired_access = *desired_access; - - /* This is a nasty hack - must fix... JRA. */ - if (*desired_access == MAXIMUM_ALLOWED_ACCESS) { - *desired_access = FILE_GENERIC_ALL; - } - - /* - * Convert GENERIC bits to specific bits. - */ - - se_map_generic(desired_access, &file_generic_mapping); - - switch( *desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA) ) { - case FILE_READ_DATA: - smb_open_mode = DOS_OPEN_RDONLY; - break; - case FILE_WRITE_DATA: - case FILE_APPEND_DATA: - case FILE_WRITE_DATA|FILE_APPEND_DATA: - smb_open_mode = DOS_OPEN_WRONLY; - break; - case FILE_READ_DATA|FILE_WRITE_DATA: - case FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA: - case FILE_READ_DATA|FILE_APPEND_DATA: - smb_open_mode = DOS_OPEN_RDWR; - break; - } - - /* - * NB. For DELETE_ACCESS we should really check the - * directory permissions, as that is what controls - * delete, and for WRITE_DAC_ACCESS we should really - * check the ownership, as that is what controls the - * chmod. Note that this is *NOT* a security hole (this - * note is for you, Andrew) as we are not *allowing* - * the access at this point, the actual unlink or - * chown or chmod call would do this. We are just helping - * clients out by telling them if they have a hope - * of any of this succeeding. POSIX acls may still - * deny the real call. JRA. - */ - - if (smb_open_mode == -1) { - - if(*desired_access & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS| - FILE_EXECUTE|FILE_READ_ATTRIBUTES| - FILE_READ_EA|FILE_WRITE_EA|SYSTEM_SECURITY_ACCESS| - FILE_WRITE_ATTRIBUTES|READ_CONTROL_ACCESS)) { - smb_open_mode = DOS_OPEN_RDONLY; - } else if(*desired_access == 0) { - - /* - * JRA - NT seems to sometimes send desired_access as zero. play it safe - * and map to a stat open. - */ - - smb_open_mode = DOS_OPEN_RDONLY; - - } else { - DEBUG(0,("map_share_mode: Incorrect value 0x%lx for desired_access to file %s\n", - (unsigned long)*desired_access, fname)); - return -1; - } - } - - /* - * Set the special bit that means allow share delete. - * This is held outside the normal share mode bits at 1<<15. - * JRA. - */ - - if(share_access & FILE_SHARE_DELETE) { - smb_open_mode |= ALLOW_SHARE_DELETE; - DEBUG(10,("map_share_mode: FILE_SHARE_DELETE requested. open_mode = 0x%x\n", smb_open_mode)); - } - - if(*desired_access & DELETE_ACCESS) { - DEBUG(10,("map_share_mode: DELETE_ACCESS requested. open_mode = 0x%x\n", smb_open_mode)); - } - - /* - * We need to store the intent to open for Delete. This - * is what determines if a delete on close flag can be set. - * This is the wrong way (and place) to store this, but for 2.2 this - * is the only practical way. JRA. - */ - - if (create_options & FILE_DELETE_ON_CLOSE) { - /* - * W2K3 bug compatibility mode... To set delete on close - * the redirector must have *specifically* set DELETE_ACCESS - * in the desired_access field. Just asking for GENERIC_ALL won't do. JRA. - */ - - if (!(original_desired_access & DELETE_ACCESS)) { - DEBUG(5,("map_share_mode: FILE_DELETE_ON_CLOSE requested without \ -DELETE_ACCESS for file %s. (desired_access = 0x%lx)\n", - fname, (unsigned long)*desired_access)); - return -1; - } - /* Implicit delete access is *NOT* requested... */ - smb_open_mode |= DELETE_ON_CLOSE_FLAG; - DEBUG(10,("map_share_mode: FILE_DELETE_ON_CLOSE requested. open_mode = 0x%x\n", smb_open_mode)); - } - - /* Add in the requested share mode. */ - switch( share_access & (FILE_SHARE_READ|FILE_SHARE_WRITE)) { - case FILE_SHARE_READ: - smb_open_mode |= SET_DENY_MODE(DENY_WRITE); - break; - case FILE_SHARE_WRITE: - smb_open_mode |= SET_DENY_MODE(DENY_READ); - break; - case (FILE_SHARE_READ|FILE_SHARE_WRITE): - smb_open_mode |= SET_DENY_MODE(DENY_NONE); - break; - case FILE_SHARE_NONE: - smb_open_mode |= SET_DENY_MODE(DENY_ALL); - break; - } - - /* - * Handle an O_SYNC request. - */ - - if(file_attributes & FILE_FLAG_WRITE_THROUGH) - smb_open_mode |= FILE_SYNC_OPENMODE; - - DEBUG(10,("map_share_mode: Mapped desired access 0x%lx, share access 0x%lx, file attributes 0x%lx \ -to open_mode 0x%x\n", (unsigned long)*desired_access, (unsigned long)share_access, - (unsigned long)file_attributes, smb_open_mode )); - - return smb_open_mode; -} - -/**************************************************************************** Reply to an NT create and X call on a pipe. ****************************************************************************/ @@ -505,7 +324,6 @@ static int nt_open_pipe(char *fname, connection_struct *conn, char *inbuf, char *outbuf, int *ppnum) { smb_np_struct *p = NULL; - uint16 vuid = SVAL(inbuf, smb_uid); int i; @@ -513,15 +331,19 @@ static int nt_open_pipe(char *fname, connection_struct *conn, /* See if it is one we want to handle. */ - if (lp_disable_spoolss() && strequal(fname, "\\spoolss")) + if (lp_disable_spoolss() && strequal(fname, "\\spoolss")) { return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe)); + } - for( i = 0; known_nt_pipes[i]; i++ ) - if( strequal(fname,known_nt_pipes[i])) + for( i = 0; known_nt_pipes[i]; i++ ) { + if( strequal(fname,known_nt_pipes[i])) { break; + } + } - if ( known_nt_pipes[i] == NULL ) + if ( known_nt_pipes[i] == NULL ) { return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe)); + } /* Strip \\ off the name. */ fname++; @@ -529,11 +351,11 @@ static int nt_open_pipe(char *fname, connection_struct *conn, DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname)); p = open_rpc_pipe_p(fname, conn, vuid); - if (!p) + if (!p) { return(ERROR_DOS(ERRSRV,ERRnofids)); + } *ppnum = p->pnum; - return 0; } @@ -551,8 +373,9 @@ static int do_ntcreate_pipe_open(connection_struct *conn, srvstr_pull_buf(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE); - if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) + if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) { return ret; + } /* * Deal with pipe return. @@ -580,6 +403,66 @@ static int do_ntcreate_pipe_open(connection_struct *conn, } /**************************************************************************** + Reply to an NT create and X call for a quota file. +****************************************************************************/ + +int reply_ntcreate_and_X_quota(connection_struct *conn, + char *inbuf, + char *outbuf, + int length, + int bufsize, + enum FAKE_FILE_TYPE fake_file_type, + const char *fname) +{ + int result; + char *p; + uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess); + files_struct *fsp = open_fake_file(conn, fake_file_type, fname, desired_access); + + if (!fsp) { + return ERROR_NT(NT_STATUS_ACCESS_DENIED); + } + + set_message(outbuf,34,0,True); + + p = outbuf + smb_vwv2; + + /* SCVAL(p,0,NO_OPLOCK_RETURN); */ + p++; + SSVAL(p,0,fsp->fnum); +#if 0 + p += 2; + SIVAL(p,0,smb_action); + p += 4; + + /* Create time. */ + put_long_date(p,c_time); + p += 8; + put_long_date(p,sbuf.st_atime); /* access time */ + p += 8; + put_long_date(p,sbuf.st_mtime); /* write time */ + p += 8; + put_long_date(p,sbuf.st_mtime); /* change time */ + p += 8; + SIVAL(p,0,fattr); /* File Attributes. */ + p += 4; + SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf)); + p += 8; + SOFF_T(p,0,file_len); + p += 8; + if (flags & EXTENDED_RESPONSE_REQUIRED) + SSVAL(p,2,0x7); + p += 4; + SCVAL(p,0,fsp->is_directory ? 1 : 0); +#endif + + DEBUG(5,("reply_ntcreate_and_X_quota: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name)); + + result = chain_reply(inbuf,outbuf,length,bufsize); + return result; +} + +/**************************************************************************** Reply to an NT create and X call. ****************************************************************************/ @@ -588,23 +471,20 @@ int reply_ntcreate_and_X(connection_struct *conn, { int result; pstring fname; - enum FAKE_FILE_TYPE fake_file_type = FAKE_FILE_TYPE_NONE; uint32 flags = IVAL(inbuf,smb_ntcreate_Flags); - uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess); + uint32 access_mask = IVAL(inbuf,smb_ntcreate_DesiredAccess); uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes); uint32 share_access = IVAL(inbuf,smb_ntcreate_ShareAccess); uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition); uint32 create_options = IVAL(inbuf,smb_ntcreate_CreateOptions); uint16 root_dir_fid = (uint16)IVAL(inbuf,smb_ntcreate_RootDirectoryFid); - int smb_ofun; - int smb_open_mode; /* Breakout the oplock request bits so we can set the reply bits separately. */ int oplock_request = 0; - int fmode=0,rmode=0; + uint32 fattr=0; SMB_OFF_T file_len = 0; SMB_STRUCT_STAT sbuf; - int smb_action = 0; + int info = 0; BOOL bad_path = False; files_struct *fsp=NULL; char *p = NULL; @@ -614,11 +494,16 @@ int reply_ntcreate_and_X(connection_struct *conn, START_PROFILE(SMBntcreateX); - DEBUG(10,("reply_ntcreateX: flags = 0x%x, desired_access = 0x%x \ + DEBUG(10,("reply_ntcreateX: flags = 0x%x, access_mask = 0x%x \ file_attributes = 0x%x, share_access = 0x%x, create_disposition = 0x%x \ -create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attributes, - share_access, create_disposition, - create_options, root_dir_fid )); +create_options = 0x%x root_dir_fid = 0x%x\n", + (unsigned int)flags, + (unsigned int)access_mask, + (unsigned int)file_attributes, + (unsigned int)share_access, + (unsigned int)create_disposition, + (unsigned int)create_options, + (unsigned int)root_dir_fid )); /* If it's an IPC, use the pipe handler. */ @@ -637,16 +522,6 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib return ERROR_NT(NT_STATUS_NOT_SUPPORTED); } - /* - * We need to construct the open_and_X ofun value from the - * NT values, as that's what our code is structured to accept. - */ - - if((smb_ofun = map_create_disposition( create_disposition )) == -1) { - END_PROFILE(SMBntcreateX); - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); - } - /* * Get the file name. */ @@ -726,25 +601,25 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib */ if( is_ntfs_stream_name(fname)) { - -#ifdef HAVE_SYS_QUOTAS - if ((fake_file_type=is_fake_file(fname))!=FAKE_FILE_TYPE_NONE) { + enum FAKE_FILE_TYPE fake_file_type = is_fake_file(fname); + if (fake_file_type!=FAKE_FILE_TYPE_NONE) { /* - * here we go! support for changing the disk quotas --metze + * Here we go! support for changing the disk quotas --metze * - * we need to fake up to open this MAGIC QUOTA file - * and return a valid FID + * We need to fake up to open this MAGIC QUOTA file + * and return a valid FID. * * w2k close this file directly after openening * xp also tries a QUERY_FILE_INFO on the file and then close it */ + result = reply_ntcreate_and_X_quota(conn, inbuf, outbuf, length, bufsize, + fake_file_type, fname); + END_PROFILE(SMBntcreateX); + return result; } else { -#endif END_PROFILE(SMBntcreateX); return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); -#ifdef HAVE_SYS_QUOTAS } -#endif } } @@ -754,13 +629,6 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib */ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf); - if((smb_open_mode = map_share_mode(fname, create_options, &desired_access, - share_access, - file_attributes)) == -1) { - END_PROFILE(SMBntcreateX); - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); - } - oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; if (oplock_request) { oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0; @@ -778,20 +646,16 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib unix_convert(fname,conn,0,&bad_path,&sbuf); - /* FAKE_FILE is a special case */ - if (fake_file_type == FAKE_FILE_TYPE_NONE) { - /* Normal file. */ - if (bad_path) { - restore_case_semantics(conn, file_attributes); - END_PROFILE(SMBntcreateX); - return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); - } - /* All file access must go through check_name() */ - if (!check_name(fname,conn)) { - restore_case_semantics(conn, file_attributes); - END_PROFILE(SMBntcreateX); - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); - } + if (bad_path) { + restore_case_semantics(conn, file_attributes); + END_PROFILE(SMBntcreateX); + return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); + } + /* All file access must go through check_name() */ + if (!check_name(fname,conn)) { + restore_case_semantics(conn, file_attributes); + END_PROFILE(SMBntcreateX); + return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); } #if 0 @@ -802,7 +666,8 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib if (desired_access & DELETE_ACCESS) { #else /* Setting FILE_SHARE_DELETE is the hint. */ - if (lp_acl_check_permissions(SNUM(conn)) && (share_access & FILE_SHARE_DELETE) && (desired_access & DELETE_ACCESS)) { + if (lp_acl_check_permissions(SNUM(conn)) && (share_access & FILE_SHARE_DELETE) + && (access_mask & DELETE_ACCESS)) { #endif status = can_delete(conn, fname, file_attributes, bad_path, True); /* We're only going to fail here if it's access denied, as that's the @@ -811,7 +676,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib NT_STATUS_EQUAL(status,NT_STATUS_CANNOT_DELETE))) { restore_case_semantics(conn, file_attributes); END_PROFILE(SMBntcreateX); - return ERROR_NT(status); + return ERROR_NT(NT_STATUS_ACCESS_DENIED); } } @@ -828,8 +693,13 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action); - + fsp = open_directory(conn, fname, &sbuf, + access_mask, + share_access, + create_disposition, + create_options, + &info); + restore_case_semantics(conn, file_attributes); if(!fsp) { @@ -854,21 +724,14 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib * before issuing an oplock break request to * our client. JRA. */ - if (fake_file_type==FAKE_FILE_TYPE_NONE) { - fsp = open_file_shared1(conn,fname,&sbuf, - desired_access, - smb_open_mode, - smb_ofun,file_attributes,oplock_request, - &rmode,&smb_action); - } else { - /* to open a fake_file --metze */ - fsp = open_fake_file_shared1(fake_file_type,conn,fname,&sbuf, - desired_access, - smb_open_mode, - smb_ofun,file_attributes, oplock_request, - &rmode,&smb_action); - } - + fsp = open_file_ntcreate(conn,fname,&sbuf, + access_mask, + share_access, + create_disposition, + create_options, + file_attributes, + oplock_request, + &info); if (!fsp) { /* We cheat here. There are two cases we * care about. One is a directory rename, @@ -902,8 +765,13 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib } oplock_request = 0; - fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action); - + fsp = open_directory(conn, fname, &sbuf, + access_mask, + share_access, + create_disposition, + create_options, + &info); + if(!fsp) { restore_case_semantics(conn, file_attributes); END_PROFILE(SMBntcreateX); @@ -925,18 +793,18 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib restore_case_semantics(conn, file_attributes); file_len = sbuf.st_size; - fmode = dos_mode(conn,fname,&sbuf); - if(fmode == 0) { - fmode = FILE_ATTRIBUTE_NORMAL; + fattr = dos_mode(conn,fname,&sbuf); + if(fattr == 0) { + fattr = FILE_ATTRIBUTE_NORMAL; } - if (!fsp->is_directory && (fmode & aDIR)) { + if (!fsp->is_directory && (fattr & aDIR)) { close_file(fsp,False); END_PROFILE(SMBntcreateX); return ERROR_DOS(ERRDOS,ERRnoaccess); } /* Save the requested allocation size. */ - if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) { + if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) { SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize); #ifdef LARGE_SMB_OFF_T allocation_size |= (((SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32); @@ -1002,10 +870,11 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib p++; SSVAL(p,0,fsp->fnum); p += 2; - if ((create_disposition == FILE_SUPERSEDE) && (smb_action == FILE_WAS_OVERWRITTEN)) + if ((create_disposition == FILE_SUPERSEDE) && (info == FILE_WAS_OVERWRITTEN)) { SIVAL(p,0,FILE_WAS_SUPERSEDED); - else - SIVAL(p,0,smb_action); + } else { + SIVAL(p,0,info); + } p += 4; /* Create time. */ @@ -1026,14 +895,15 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib p += 8; put_long_date(p,sbuf.st_mtime); /* change time */ p += 8; - SIVAL(p,0,fmode); /* File Attributes. */ + SIVAL(p,0,fattr); /* File Attributes. */ p += 4; SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf)); p += 8; SOFF_T(p,0,file_len); p += 8; - if (flags & EXTENDED_RESPONSE_REQUIRED) + if (flags & EXTENDED_RESPONSE_REQUIRED) { SSVAL(p,2,0x7); + } p += 4; SCVAL(p,0,fsp->is_directory ? 1 : 0); @@ -1074,13 +944,15 @@ static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, cha return ERROR_NT(status); } - if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) + if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) { return ret; + } /* Realloc the size of parameters and data we will return */ params = nttrans_realloc(ppparams, 69); - if(params == NULL) + if(params == NULL) { return ERROR_DOS(ERRDOS,ERRnomem); + } p = params; SCVAL(p,0,NO_OPLOCK_RETURN); @@ -1153,16 +1025,20 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu return NT_STATUS_NO_MEMORY; } - if (psd->off_owner_sid==0) + if (psd->off_owner_sid==0) { security_info_sent &= ~OWNER_SECURITY_INFORMATION; - if (psd->off_grp_sid==0) + } + if (psd->off_grp_sid==0) { security_info_sent &= ~GROUP_SECURITY_INFORMATION; - if (psd->off_sacl==0) + } + if (psd->off_sacl==0) { security_info_sent &= ~SACL_SECURITY_INFORMATION; - if (psd->off_dacl==0) + } + if (psd->off_dacl==0) { security_info_sent &= ~DACL_SECURITY_INFORMATION; + } - ret = SMB_VFS_FSET_NT_ACL( fsp, fsp->fd, security_info_sent, psd); + ret = SMB_VFS_FSET_NT_ACL( fsp, fsp->fh->fd, security_info_sent, psd); if (!ret) { talloc_destroy(mem_ctx); @@ -1216,16 +1092,16 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o char *data = *ppdata; /* Breakout the oplock request bits so we can set the reply bits separately. */ int oplock_request = 0; - int fmode=0,rmode=0; + uint32 fattr=0; SMB_OFF_T file_len = 0; SMB_STRUCT_STAT sbuf; - int smb_action = 0; + int info = 0; BOOL bad_path = False; files_struct *fsp = NULL; char *p = NULL; BOOL extended_oplock_granted = False; uint32 flags; - uint32 desired_access; + uint32 access_mask; uint32 file_attributes; uint32 share_access; uint32 create_disposition; @@ -1233,8 +1109,6 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o uint32 sd_len; uint32 ea_len; uint16 root_dir_fid; - int smb_ofun; - int smb_open_mode; time_t c_time; struct ea_list *ea_list = NULL; TALLOC_CTX *ctx = NULL; @@ -1248,14 +1122,15 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o */ if (IS_IPC(conn)) { - if (lp_nt_pipe_support()) + if (lp_nt_pipe_support()) { return do_nt_transact_create_pipe(conn, inbuf, outbuf, length, bufsize, ppsetup, setup_count, ppparams, parameter_count, ppdata, data_count); - else + } else { return ERROR_DOS(ERRDOS,ERRnoaccess); + } } /* @@ -1268,7 +1143,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o } flags = IVAL(params,0); - desired_access = IVAL(params,8); + access_mask = IVAL(params,8); file_attributes = IVAL(params,20); share_access = IVAL(params,24); create_disposition = IVAL(params,28); @@ -1304,15 +1179,6 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o return ERROR_NT(NT_STATUS_NOT_SUPPORTED); } - /* - * We need to construct the open_and_X ofun value from the - * NT values, as that's what our code is structured to accept. - */ - - if((smb_ofun = map_create_disposition( create_disposition )) == -1) { - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); - } - /* * Get the file name. */ @@ -1324,8 +1190,9 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o files_struct *dir_fsp = file_fsp(params,4); size_t dir_name_len; - if(!dir_fsp) + if(!dir_fsp) { return ERROR_DOS(ERRDOS,ERRbadfid); + } if(!dir_fsp->is_directory) { srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status, False); @@ -1383,15 +1250,6 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o } } - /* - * Now contruct the smb_open_mode value from the desired access - * and the share access. - */ - - if((smb_open_mode = map_share_mode( fname, create_options, &desired_access, - share_access, file_attributes)) == -1) - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); - oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0; @@ -1422,7 +1280,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o if (desired_access & DELETE_ACCESS) { #else /* Setting FILE_SHARE_DELETE is the hint. */ - if (lp_acl_check_permissions(SNUM(conn)) && (share_access & FILE_SHARE_DELETE) && (desired_access & DELETE_ACCESS)) { + if (lp_acl_check_permissions(SNUM(conn)) && (share_access & FILE_SHARE_DELETE) && (access_mask & DELETE_ACCESS)) { #endif status = can_delete(conn, fname, file_attributes, bad_path, True); /* We're only going to fail here if it's access denied, as that's the @@ -1475,8 +1333,12 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o * CreateDirectory() call. */ - fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action); - + fsp = open_directory(conn, fname, &sbuf, + access_mask, + share_access, + create_disposition, + create_options, + &info); if(!fsp) { talloc_destroy(ctx); restore_case_semantics(conn, file_attributes); @@ -1489,9 +1351,14 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o * Ordinary file case. */ - fsp = open_file_shared1(conn,fname,&sbuf,desired_access, - smb_open_mode,smb_ofun,file_attributes, - oplock_request,&rmode,&smb_action); + fsp = open_file_ntcreate(conn,fname,&sbuf, + access_mask, + share_access, + create_disposition, + create_options, + file_attributes, + oplock_request, + &info); if (!fsp) { if(errno == EISDIR) { @@ -1506,8 +1373,12 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o } oplock_request = 0; - fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action); - + fsp = open_directory(conn, fname, &sbuf, + access_mask, + share_access, + create_disposition, + create_options, + &info); if(!fsp) { talloc_destroy(ctx); restore_case_semantics(conn, file_attributes); @@ -1536,12 +1407,12 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>. */ - if (lp_nt_acl_support(SNUM(conn)) && sd_len && smb_action == FILE_WAS_CREATED) { - uint32 saved_access = fsp->desired_access; + if (lp_nt_acl_support(SNUM(conn)) && sd_len && info == FILE_WAS_CREATED) { + uint32 saved_access_mask = fsp->access_mask; /* We have already checked that sd_len <= data_count here. */ - fsp->desired_access = FILE_GENERIC_ALL; + fsp->access_mask = FILE_GENERIC_ALL; status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION); if (!NT_STATUS_IS_OK(status)) { @@ -1550,10 +1421,10 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o restore_case_semantics(conn, file_attributes); return ERROR_NT(status); } - fsp->desired_access = saved_access; + fsp->access_mask = saved_access_mask; } - if (ea_len && (smb_action == FILE_WAS_CREATED)) { + if (ea_len && (info == FILE_WAS_CREATED)) { status = set_ea(conn, fsp, fname, ea_list); talloc_destroy(ctx); if (!NT_STATUS_IS_OK(status)) { @@ -1566,17 +1437,17 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o restore_case_semantics(conn, file_attributes); file_len = sbuf.st_size; - fmode = dos_mode(conn,fname,&sbuf); - if(fmode == 0) { - fmode = FILE_ATTRIBUTE_NORMAL; + fattr = dos_mode(conn,fname,&sbuf); + if(fattr == 0) { + fattr = FILE_ATTRIBUTE_NORMAL; } - if (!fsp->is_directory && (fmode & aDIR)) { + if (!fsp->is_directory && (fattr & aDIR)) { close_file(fsp,False); return ERROR_DOS(ERRDOS,ERRnoaccess); } /* Save the requested allocation size. */ - if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) { + if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) { SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(params,12); #ifdef LARGE_SMB_OFF_T allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32); @@ -1613,24 +1484,27 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o /* Realloc the size of parameters and data we will return */ params = nttrans_realloc(ppparams, 69); - if(params == NULL) + if(params == NULL) { return ERROR_DOS(ERRDOS,ERRnomem); + } p = params; - if (extended_oplock_granted) + if (extended_oplock_granted) { SCVAL(p,0, BATCH_OPLOCK_RETURN); - else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) + } else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) { SCVAL(p,0, LEVEL_II_OPLOCK_RETURN); - else + } else { SCVAL(p,0,NO_OPLOCK_RETURN); + } p += 2; SSVAL(p,0,fsp->fnum); p += 2; - if ((create_disposition == FILE_SUPERSEDE) && (smb_action == FILE_WAS_OVERWRITTEN)) + if ((create_disposition == FILE_SUPERSEDE) && (info == FILE_WAS_OVERWRITTEN)) { SIVAL(p,0,FILE_WAS_SUPERSEDED); - else - SIVAL(p,0,smb_action); + } else { + SIVAL(p,0,info); + } p += 8; /* Create time. */ @@ -1651,14 +1525,15 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o p += 8; put_long_date(p,sbuf.st_mtime); /* change time */ p += 8; - SIVAL(p,0,fmode); /* File Attributes. */ + SIVAL(p,0,fattr); /* File Attributes. */ p += 4; SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf)); p += 8; SOFF_T(p,0,file_len); p += 8; - if (flags & EXTENDED_RESPONSE_REQUIRED) + if (flags & EXTENDED_RESPONSE_REQUIRED) { SSVAL(p,2,0x7); + } p += 4; SCVAL(p,0,fsp->is_directory ? 1 : 0); @@ -1697,7 +1572,7 @@ int reply_ntcancel(connection_struct *conn, Copy a file. ****************************************************************************/ -static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *newname, uint16 attrs) +static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *newname, uint32 attrs) { BOOL bad_path_oldname = False; BOOL bad_path_newname = False; @@ -1705,9 +1580,8 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new pstring last_component_oldname; pstring last_component_newname; files_struct *fsp1,*fsp2; - uint16 fmode; - int access_mode; - int smb_action; + uint32 fattr; + int info; SMB_OFF_T ret=-1; int close_ret; NTSTATUS status = NT_STATUS_OK; @@ -1744,9 +1618,10 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new } /* Ensure attributes match. */ - fmode = dos_mode(conn,oldname,&sbuf1); - if ((fmode & ~attrs) & (aHIDDEN | aSYSTEM)) + fattr = dos_mode(conn,oldname,&sbuf1); + if ((fattr & ~attrs) & (aHIDDEN | aSYSTEM)) { return NT_STATUS_NO_SUCH_FILE; + } unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2); if (bad_path_newname) { @@ -1781,9 +1656,14 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new DEBUG(10,("copy_internals: doing file copy %s to %s\n", oldname, newname)); - fsp1 = open_file_shared1(conn,oldname,&sbuf1,FILE_READ_DATA,SET_DENY_MODE(DENY_ALL)|SET_OPEN_MODE(DOS_OPEN_RDONLY), - (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),FILE_ATTRIBUTE_NORMAL,0, - &access_mode,&smb_action); + fsp1 = open_file_ntcreate(conn,oldname,&sbuf1, + FILE_READ_DATA, /* Read-only. */ + 0, /* No sharing. */ + FILE_OPEN, + 0, /* No create options. */ + FILE_ATTRIBUTE_NORMAL, + INTERNAL_OPEN_ONLY, + &info); if (!fsp1) { get_saved_error_triple(NULL, NULL, &status); @@ -1794,9 +1674,14 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new return status; } - fsp2 = open_file_shared1(conn,newname,&sbuf2,FILE_WRITE_DATA,SET_DENY_MODE(DENY_ALL)|SET_OPEN_MODE(DOS_OPEN_WRONLY), - (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL),fmode,INTERNAL_OPEN_ONLY, - &access_mode,&smb_action); + fsp2 = open_file_ntcreate(conn,newname,&sbuf2, + FILE_WRITE_DATA, /* Read-only. */ + 0, /* No sharing. */ + FILE_CREATE, + 0, /* No create options. */ + fattr, + INTERNAL_OPEN_ONLY, + &info); if (!fsp2) { get_saved_error_triple(NULL, NULL, &status); @@ -1808,8 +1693,9 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new return status; } - if (sbuf1.st_size) + if (sbuf1.st_size) { ret = vfs_transfer_file(fsp1, fsp2, sbuf1.st_size); + } /* * As we are opening fsp1 read-only we only expect @@ -1826,7 +1712,7 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new /* Grrr. We have to do this as open_file_shared1 adds aARCH when it creates the file. This isn't the correct thing to do in the copy case. JRA */ - file_set_dosmode(conn, newname, fmode, &sbuf2, True); + file_set_dosmode(conn, newname, fattr, &sbuf2, True); if (ret < (SMB_OFF_T)sbuf1.st_size) { return NT_STATUS_DISK_FULL; @@ -1852,7 +1738,7 @@ int reply_ntrename(connection_struct *conn, pstring newname; char *p; NTSTATUS status; - uint16 attrs = SVAL(inbuf,smb_vwv0); + uint32 attrs = SVAL(inbuf,smb_vwv0); uint16 rename_type = SVAL(inbuf,smb_vwv1); START_PROFILE(SMBntrename); @@ -1952,22 +1838,26 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, files_struct *fsp; uint32 flags; - if(setup_count < 6) + if(setup_count < 6) { return ERROR_DOS(ERRDOS,ERRbadfunc); + } fsp = file_fsp(setup,4); flags = IVAL(setup, 0); DEBUG(3,("call_nt_transact_notify_change\n")); - if(!fsp) + if(!fsp) { return ERROR_DOS(ERRDOS,ERRbadfid); + } - if((!fsp->is_directory) || (conn != fsp->conn)) + if((!fsp->is_directory) || (conn != fsp->conn)) { return ERROR_DOS(ERRDOS,ERRbadfid); + } - if (!change_notify_set(inbuf, fsp, conn, flags)) + if (!change_notify_set(inbuf, fsp, conn, flags)) { return(UNIXERROR(ERRDOS,ERRbadfid)); + } DEBUG(3,("call_nt_transact_notify_change: notify change called on directory \ name = %s\n", fsp->fsp_name )); @@ -1990,8 +1880,9 @@ static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *o BOOL replace_if_exists = False; NTSTATUS status; - if(parameter_count < 4) + if(parameter_count < 4) { return ERROR_DOS(ERRDOS,ERRbadfunc); + } fsp = file_fsp(params, 0); replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False; @@ -2059,12 +1950,14 @@ static int call_nt_transact_query_security_desc(connection_struct *conn, char *i TALLOC_CTX *mem_ctx; files_struct *fsp = NULL; - if(parameter_count < 8) + if(parameter_count < 8) { return ERROR_DOS(ERRDOS,ERRbadfunc); + } fsp = file_fsp(params,0); - if(!fsp) + if(!fsp) { return ERROR_DOS(ERRDOS,ERRbadfid); + } security_info_wanted = IVAL(params,4); @@ -2072,8 +1965,9 @@ static int call_nt_transact_query_security_desc(connection_struct *conn, char *i (unsigned int)security_info_wanted )); params = nttrans_realloc(ppparams, 4); - if(params == NULL) + if(params == NULL) { return ERROR_DOS(ERRDOS,ERRnomem); + } if ((mem_ctx = talloc_init("call_nt_transact_query_security_desc")) == NULL) { DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n")); @@ -2084,10 +1978,11 @@ static int call_nt_transact_query_security_desc(connection_struct *conn, char *i * Get the permissions to return. */ - if (!lp_nt_acl_support(SNUM(conn))) + if (!lp_nt_acl_support(SNUM(conn))) { sd_size = get_null_nt_acl(mem_ctx, &psd); - else - sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, security_info_wanted, &psd); + } else { + sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, security_info_wanted, &psd); + } if (sd_size == 0) { talloc_destroy(mem_ctx); @@ -2168,25 +2063,30 @@ static int call_nt_transact_set_security_desc(connection_struct *conn, char *inb uint32 security_info_sent = 0; NTSTATUS nt_status; - if(parameter_count < 8) + if(parameter_count < 8) { return ERROR_DOS(ERRDOS,ERRbadfunc); + } - if((fsp = file_fsp(params,0)) == NULL) + if((fsp = file_fsp(params,0)) == NULL) { return ERROR_DOS(ERRDOS,ERRbadfid); + } - if(!lp_nt_acl_support(SNUM(conn))) + if(!lp_nt_acl_support(SNUM(conn))) { goto done; + } security_info_sent = IVAL(params,4); DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name, (unsigned int)security_info_sent )); - if (data_count == 0) + if (data_count == 0) { return ERROR_DOS(ERRDOS, ERRnoaccess); + } - if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, data_count, security_info_sent))) + if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, data_count, security_info_sent))) { return ERROR_NT(nt_status); + } done: @@ -2517,8 +2417,9 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, /* Realloc the size of parameters and data we will return */ param_len = 4; params = nttrans_realloc(ppparams, param_len); - if(params == NULL) + if(params == NULL) { return ERROR_DOS(ERRDOS,ERRnomem); + } data_len = 0; SIVAL(params,0,data_len); @@ -2541,19 +2442,20 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, /* Realloc the size of parameters and data we will return */ param_len = 4; params = nttrans_realloc(ppparams, param_len); - if(params == NULL) + if(params == NULL) { return ERROR_DOS(ERRDOS,ERRnomem); + } /* we should not trust the value in max_data_count*/ max_data_count = MIN(max_data_count,2048); pdata = nttrans_realloc(ppdata, max_data_count);/* should be max data count from client*/ - if(pdata == NULL) + if(pdata == NULL) { return ERROR_DOS(ERRDOS,ERRnomem); + } entry = pdata; - /* set params Size of returned Quota Data 4 bytes*/ /* but set it later when we know it */ @@ -2638,7 +2540,6 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, sid_parse(pdata+8,sid_len,&sid); - if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) { ZERO_STRUCT(qt); /* @@ -2651,12 +2552,14 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, /* Realloc the size of parameters and data we will return */ param_len = 4; params = nttrans_realloc(ppparams, param_len); - if(params == NULL) + if(params == NULL) { return ERROR_DOS(ERRDOS,ERRnomem); + } pdata = nttrans_realloc(ppdata, data_len); - if(pdata == NULL) + if(pdata == NULL) { return ERROR_DOS(ERRDOS,ERRnomem); + } entry = pdata; @@ -2881,12 +2784,15 @@ due to being in oplock break state.\n", (unsigned int)function_code )); /* Allocate the space for the setup, the maximum needed parameters and data */ - if(setup_count > 0) + if(setup_count > 0) { setup = (char *)SMB_MALLOC(setup_count); - if (total_parameter_count > 0) + } + if (total_parameter_count > 0) { params = (char *)SMB_MALLOC(total_parameter_count); - if (total_data_count > 0) + } + if (total_data_count > 0) { data = (char *)SMB_MALLOC(total_data_count); + } if ((total_parameter_count && !params) || (total_data_count && !data) || (setup_count && !setup)) { @@ -2908,10 +2814,12 @@ due to being in oplock break state.\n", (unsigned int)function_code )); if(setup) { DEBUG(10,("reply_nttrans: setup_count = %d\n", setup_count)); if ((smb_nt_SetupStart + setup_count < smb_nt_SetupStart) || - (smb_nt_SetupStart + setup_count < setup_count)) + (smb_nt_SetupStart + setup_count < setup_count)) { goto bad_param; - if (smb_nt_SetupStart + setup_count > length) + } + if (smb_nt_SetupStart + setup_count > length) { goto bad_param; + } memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count); dump_data(10, setup, setup_count); @@ -2919,22 +2827,26 @@ due to being in oplock break state.\n", (unsigned int)function_code )); if(params) { DEBUG(10,("reply_nttrans: parameter_count = %d\n", parameter_count)); if ((parameter_offset + parameter_count < parameter_offset) || - (parameter_offset + parameter_count < parameter_count)) + (parameter_offset + parameter_count < parameter_count)) { goto bad_param; + } if ((smb_base(inbuf) + parameter_offset + parameter_count > inbuf + length)|| - (smb_base(inbuf) + parameter_offset + parameter_count < smb_base(inbuf))) + (smb_base(inbuf) + parameter_offset + parameter_count < smb_base(inbuf))) { goto bad_param; + } memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count); dump_data(10, params, parameter_count); } if(data) { DEBUG(10,("reply_nttrans: data_count = %d\n",data_count)); - if ((data_offset + data_count < data_offset) || (data_offset + data_count < data_count)) + if ((data_offset + data_count < data_offset) || (data_offset + data_count < data_count)) { goto bad_param; + } if ((smb_base(inbuf) + data_offset + data_count > inbuf + length) || - (smb_base(inbuf) + data_offset + data_count < smb_base(inbuf))) + (smb_base(inbuf) + data_offset + data_count < smb_base(inbuf))) { goto bad_param; + } memcpy( data, smb_base(inbuf) + data_offset, data_count); dump_data(10, data, data_count); @@ -2947,8 +2859,10 @@ due to being in oplock break state.\n", (unsigned int)function_code )); of the parameter/data bytes */ outsize = set_message(outbuf,0,0,True); srv_signing_trans_stop(); - if (!send_smb(smbd_server_fd(),outbuf)) + show_msg(outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) { exit_server("reply_nttrans: send_smb failed."); + } while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) { BOOL ret; @@ -2979,10 +2893,12 @@ due to being in oplock break state.\n", (unsigned int)function_code )); } /* Revise total_params and total_data in case they have changed downwards */ - if (IVAL(inbuf, smb_nts_TotalParameterCount) < total_parameter_count) + if (IVAL(inbuf, smb_nts_TotalParameterCount) < total_parameter_count) { total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount); - if (IVAL(inbuf, smb_nts_TotalDataCount) < total_data_count) + } + if (IVAL(inbuf, smb_nts_TotalDataCount) < total_data_count) { total_data_count = IVAL(inbuf, smb_nts_TotalDataCount); + } parameter_count = IVAL(inbuf,smb_nts_ParameterCount); parameter_offset = IVAL(inbuf, smb_nts_ParameterOffset); @@ -3000,43 +2916,54 @@ due to being in oplock break state.\n", (unsigned int)function_code )); } if (parameter_count) { - if (parameter_displacement + parameter_count > total_parameter_count) + if (parameter_displacement + parameter_count > total_parameter_count) { goto bad_param; + } if ((parameter_displacement + parameter_count < parameter_displacement) || - (parameter_displacement + parameter_count < parameter_count)) + (parameter_displacement + parameter_count < parameter_count)) { goto bad_param; - if (parameter_displacement > total_parameter_count) + } + if (parameter_displacement > total_parameter_count) { goto bad_param; + } if ((smb_base(inbuf) + parameter_offset + parameter_count > inbuf + length) || - (smb_base(inbuf) + parameter_offset + parameter_count < smb_base(inbuf))) + (smb_base(inbuf) + parameter_offset + parameter_count < smb_base(inbuf))) { goto bad_param; - if (parameter_displacement + params < params) + } + if (parameter_displacement + params < params) { goto bad_param; + } memcpy( ¶ms[parameter_displacement], smb_base(inbuf) + parameter_offset, parameter_count); } if (data_count) { - if (data_displacement + data_count > total_data_count) + if (data_displacement + data_count > total_data_count) { goto bad_param; + } if ((data_displacement + data_count < data_displacement) || - (data_displacement + data_count < data_count)) + (data_displacement + data_count < data_count)) { goto bad_param; - if (data_displacement > total_data_count) + } + if (data_displacement > total_data_count) { goto bad_param; + } if ((smb_base(inbuf) + data_offset + data_count > inbuf + length) || - (smb_base(inbuf) + data_offset + data_count < smb_base(inbuf))) + (smb_base(inbuf) + data_offset + data_count < smb_base(inbuf))) { goto bad_param; - if (data_displacement + data < data) + } + if (data_displacement + data < data) { goto bad_param; + } memcpy( &data[data_displacement], smb_base(inbuf)+ data_offset, data_count); } } } - if (Protocol >= PROTOCOL_NT1) + if (Protocol >= PROTOCOL_NT1) { SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_IS_LONG_NAME); + } /* Now we must call the relevant NT_TRANS function */ switch(function_code) { diff --git a/source/smbd/open.c b/source/smbd/open.c index 8b30776fdd6..810913c025d 100644 --- a/source/smbd/open.c +++ b/source/smbd/open.c @@ -3,6 +3,7 @@ file opening and share modes Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Jeremy Allison 2001-2004 + Copyright (C) Volker Lendecke 2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -36,13 +37,16 @@ struct dev_inode_bundle { fd support routines - attempt to do a dos_open. ****************************************************************************/ -static int fd_open(struct connection_struct *conn, const char *fname, - int flags, mode_t mode) +static int fd_open(struct connection_struct *conn, + const char *fname, + int flags, + mode_t mode) { int fd; #ifdef O_NOFOLLOW - if (!lp_symlinks(SNUM(conn))) + if (!lp_symlinks(SNUM(conn))) { flags |= O_NOFOLLOW; + } #endif fd = SMB_VFS_OPEN(conn,fname,flags,mode); @@ -57,10 +61,15 @@ static int fd_open(struct connection_struct *conn, const char *fname, Close the file associated with a fsp. ****************************************************************************/ -int fd_close(struct connection_struct *conn, files_struct *fsp) +int fd_close(struct connection_struct *conn, + files_struct *fsp) { - if (fsp->fd == -1) - return 0; /* what we used to call a stat open. */ + if (fsp->fh->fd == -1) { + return 0; /* What we used to call a stat open. */ + } + if (fsp->fh->ref_count > 1) { + return 0; /* Shared handle. Only close last reference. */ + } return fd_close_posix(conn, fsp); } @@ -86,7 +95,10 @@ static void check_for_pipe(const char *fname) Do this by fd if possible. ****************************************************************************/ -void change_owner_to_parent(connection_struct *conn, files_struct *fsp, const char *fname, SMB_STRUCT_STAT *psbuf) +void change_owner_to_parent(connection_struct *conn, + files_struct *fsp, + const char *fname, + SMB_STRUCT_STAT *psbuf) { const char *parent_path = parent_dirname(fname); SMB_STRUCT_STAT parent_st; @@ -94,56 +106,67 @@ void change_owner_to_parent(connection_struct *conn, files_struct *fsp, const ch ret = SMB_VFS_STAT(conn, parent_path, &parent_st); if (ret == -1) { - DEBUG(0,("change_owner_to_parent: failed to stat parent directory %s. Error was %s\n", - parent_path, strerror(errno) )); + DEBUG(0,("change_owner_to_parent: failed to stat parent " + "directory %s. Error was %s\n", + parent_path, strerror(errno) )); return; } - if (fsp && fsp->fd != -1) { + if (fsp && fsp->fh->fd != -1) { become_root(); - ret = SMB_VFS_FCHOWN(fsp, fsp->fd, parent_st.st_uid, (gid_t)-1); + ret = SMB_VFS_FCHOWN(fsp, fsp->fh->fd, parent_st.st_uid, (gid_t)-1); unbecome_root(); if (ret == -1) { - DEBUG(0,("change_owner_to_parent: failed to fchown file %s to parent directory uid %u. \ -Error was %s\n", - fname, (unsigned int)parent_st.st_uid, strerror(errno) )); + DEBUG(0,("change_owner_to_parent: failed to fchown " + "file %s to parent directory uid %u. Error " + "was %s\n", fname, + (unsigned int)parent_st.st_uid, + strerror(errno) )); } - DEBUG(10,("change_owner_to_parent: changed new file %s to parent directory uid %u.\n", - fname, (unsigned int)parent_st.st_uid )); + DEBUG(10,("change_owner_to_parent: changed new file %s to " + "parent directory uid %u.\n", fname, + (unsigned int)parent_st.st_uid )); } else { - /* We've already done an lstat into psbuf, and we know it's a directory. If - we can cd into the directory and the dev/ino are the same then we can safely - chown without races as we're locking the directory in place by being in it. - This should work on any UNIX (thanks tridge :-). JRA. + /* We've already done an lstat into psbuf, and we know it's a + directory. If we can cd into the directory and the dev/ino + are the same then we can safely chown without races as + we're locking the directory in place by being in it. This + should work on any UNIX (thanks tridge :-). JRA. */ pstring saved_dir; SMB_STRUCT_STAT sbuf; if (!vfs_GetWd(conn,saved_dir)) { - DEBUG(0,("change_owner_to_parent: failed to get current working directory\n")); + DEBUG(0,("change_owner_to_parent: failed to get " + "current working directory\n")); return; } /* Chdir into the new path. */ if (vfs_ChDir(conn, fname) == -1) { - DEBUG(0,("change_owner_to_parent: failed to change current working directory to %s. \ -Error was %s\n", fname, strerror(errno) )); + DEBUG(0,("change_owner_to_parent: failed to change " + "current working directory to %s. Error " + "was %s\n", fname, strerror(errno) )); goto out; } if (SMB_VFS_STAT(conn,".",&sbuf) == -1) { - DEBUG(0,("change_owner_to_parent: failed to stat directory '.' (%s) \ -Error was %s\n", fname, strerror(errno))); + DEBUG(0,("change_owner_to_parent: failed to stat " + "directory '.' (%s) Error was %s\n", + fname, strerror(errno))); goto out; } /* Ensure we're pointing at the same place. */ - if (sbuf.st_dev != psbuf->st_dev || sbuf.st_ino != psbuf->st_ino || sbuf.st_mode != psbuf->st_mode ) { - DEBUG(0,("change_owner_to_parent: device/inode/mode on directory %s changed. Refusing to chown !\n", - fname )); + if (sbuf.st_dev != psbuf->st_dev || + sbuf.st_ino != psbuf->st_ino || + sbuf.st_mode != psbuf->st_mode ) { + DEBUG(0,("change_owner_to_parent: " + "device/inode/mode on directory %s changed. " + "Refusing to chown !\n", fname )); goto out; } @@ -151,14 +174,16 @@ Error was %s\n", fname, strerror(errno))); ret = SMB_VFS_CHOWN(conn, ".", parent_st.st_uid, (gid_t)-1); unbecome_root(); if (ret == -1) { - DEBUG(10,("change_owner_to_parent: failed to chown directory %s to parent directory uid %u. \ -Error was %s\n", - fname, (unsigned int)parent_st.st_uid, strerror(errno) )); + DEBUG(10,("change_owner_to_parent: failed to chown " + "directory %s to parent directory uid %u. " + "Error was %s\n", fname, + (unsigned int)parent_st.st_uid, strerror(errno) )); goto out; } - DEBUG(10,("change_owner_to_parent: changed ownership of new directory %s to parent directory uid %u.\n", - fname, (unsigned int)parent_st.st_uid )); + DEBUG(10,("change_owner_to_parent: changed ownership of new " + "directory %s to parent directory uid %u.\n", + fname, (unsigned int)parent_st.st_uid )); out: @@ -170,13 +195,19 @@ Error was %s\n", Open a file. ****************************************************************************/ -static BOOL open_file(files_struct *fsp,connection_struct *conn, - const char *fname,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access) +static BOOL open_file(files_struct *fsp, + connection_struct *conn, + const char *fname, + SMB_STRUCT_STAT *psbuf, + int flags, + mode_t unx_mode, + uint32 access_mask) { int accmode = (flags & O_ACCMODE); int local_flags = flags; + BOOL file_existed = VALID_STAT(*psbuf); - fsp->fd = -1; + fsp->fh->fd = -1; fsp->oplock_type = NO_OPLOCK; errno = EPERM; @@ -199,9 +230,9 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn, check_for_pipe(fname); return False; } else if(flags & O_CREAT) { - /* We don't want to write - but we must make sure that O_CREAT - doesn't create the file if we have write access into the - directory. + /* We don't want to write - but we must make sure that + O_CREAT doesn't create the file if we have write + access into the directory. */ flags &= ~O_CREAT; local_flags &= ~O_CREAT; @@ -221,12 +252,14 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn, */ if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) { - DEBUG(10,("open_file: truncate requested on read-only open for file %s\n",fname )); + DEBUG(10,("open_file: truncate requested on read-only open " + "for file %s\n",fname )); local_flags = (flags & ~O_ACCMODE)|O_RDWR; } - if ((desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) || - (local_flags & O_CREAT) || ((local_flags & O_TRUNC) == O_TRUNC) ) { + if ((access_mask & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) || + (local_flags & O_CREAT) || + ((local_flags & O_TRUNC) == O_TRUNC) ) { /* * We can't actually truncate here as the file may be locked. @@ -242,42 +275,50 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn, * open flags. JRA. */ - if (VALID_STAT(*psbuf) && S_ISFIFO(psbuf->st_mode)) + if (file_existed && S_ISFIFO(psbuf->st_mode)) { local_flags |= O_NONBLOCK; + } #endif /* Don't create files with Microsoft wildcard characters. */ - if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf) && ms_has_wild(fname)) { - set_saved_error_triple(ERRDOS, ERRinvalidname, NT_STATUS_OBJECT_NAME_INVALID); + if ((local_flags & O_CREAT) && !file_existed && + ms_has_wild(fname)) { + set_saved_error_triple(ERRDOS, ERRinvalidname, + NT_STATUS_OBJECT_NAME_INVALID); return False; } /* Actually do the open */ - fsp->fd = fd_open(conn, fname, local_flags, mode); - if (fsp->fd == -1) { - DEBUG(3,("Error opening file %s (%s) (local_flags=%d) (flags=%d)\n", + fsp->fh->fd = fd_open(conn, fname, local_flags, unx_mode); + if (fsp->fh->fd == -1) { + DEBUG(3,("Error opening file %s (%s) (local_flags=%d) " + "(flags=%d)\n", fname,strerror(errno),local_flags,flags)); check_for_pipe(fname); return False; } /* Inherit the ACL if the file was created. */ - if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf)) - inherit_access_acl(conn, fname, mode); + if ((local_flags & O_CREAT) && !file_existed) { + inherit_access_acl(conn, fname, unx_mode); + } - } else - fsp->fd = -1; /* What we used to call a stat open. */ + } else { + fsp->fh->fd = -1; /* What we used to call a stat open. */ + } - if (!VALID_STAT(*psbuf)) { + if (!file_existed) { int ret; - if (fsp->fd == -1) + if (fsp->fh->fd == -1) { ret = SMB_VFS_STAT(conn, fname, psbuf); - else { - ret = SMB_VFS_FSTAT(fsp,fsp->fd,psbuf); + } else { + ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,psbuf); /* If we have an fd, this stat should succeed. */ - if (ret == -1) - DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) )); + if (ret == -1) { + DEBUG(0,("Error doing fstat on open file %s " + "(%s)\n", fname,strerror(errno) )); + } } /* For a non-io open, this stat failing means file not found. JRA */ @@ -305,17 +346,23 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn, fsp->vuid = current_user.vuid; fsp->file_pid = global_smbpid; fsp->can_lock = True; - fsp->can_read = ((flags & O_WRONLY)==0); - fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0); - fsp->share_mode = 0; - fsp->desired_access = desired_access; + fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False; + if (!CAN_WRITE(conn)) { + fsp->can_write = False; + } else { + fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ? True : False; + } fsp->print_file = False; fsp->modified = False; fsp->oplock_type = NO_OPLOCK; fsp->sent_oplock_break = NO_BREAK_SENT; fsp->is_directory = False; fsp->is_stat = False; - fsp->directory_delete_on_close = False; + if (conn->aio_write_behind_list && + is_in_path(fname, conn->aio_write_behind_list, conn->case_sensitive)) { + fsp->aio_write_behind = True; + } + string_set(&fsp->fsp_name,fname); fsp->wcp = NULL; /* Write cache pointer. */ @@ -345,293 +392,119 @@ static BOOL is_executable(const char *fname) return False; } -enum {AFAIL,AREAD,AWRITE,AALL}; - -/******************************************************************* - Reproduce the share mode access table. - This is horrendoously complex, and really can't be justified on any - rational grounds except that this is _exactly_ what NT does. See - the DENY1 and DENY2 tests in smbtorture for a comprehensive set of - test routines. -********************************************************************/ - -static int access_table(int new_deny,int old_deny,int old_mode, - BOOL same_pid, BOOL isexe) -{ - if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL); - - if (same_pid) { - if (isexe && old_mode == DOS_OPEN_RDONLY && - old_deny == DENY_DOS && new_deny == DENY_READ) { - return AFAIL; - } - if (!isexe && old_mode == DOS_OPEN_RDONLY && - old_deny == DENY_DOS && new_deny == DENY_DOS) { - return AREAD; - } - if (new_deny == DENY_FCB && old_deny == DENY_DOS) { - if (isexe) return AFAIL; - if (old_mode == DOS_OPEN_RDONLY) return AFAIL; - return AALL; - } - if (old_mode == DOS_OPEN_RDONLY && old_deny == DENY_DOS) { - if (new_deny == DENY_FCB || new_deny == DENY_READ) { - if (isexe) return AREAD; - return AFAIL; - } - } - if (old_deny == DENY_FCB) { - if (new_deny == DENY_DOS || new_deny == DENY_FCB) return AALL; - return AFAIL; - } - } - - if (old_deny == DENY_DOS || new_deny == DENY_DOS || - old_deny == DENY_FCB || new_deny == DENY_FCB) { - if (isexe) { - if (old_deny == DENY_FCB || new_deny == DENY_FCB) { - return AFAIL; - } - if (old_deny == DENY_DOS) { - if (new_deny == DENY_READ && - (old_mode == DOS_OPEN_RDONLY || - old_mode == DOS_OPEN_RDWR)) { - return AFAIL; - } - if (new_deny == DENY_WRITE && - (old_mode == DOS_OPEN_WRONLY || - old_mode == DOS_OPEN_RDWR)) { - return AFAIL; - } - return AALL; - } - if (old_deny == DENY_NONE) return AALL; - if (old_deny == DENY_READ) return AWRITE; - if (old_deny == DENY_WRITE) return AREAD; - } - /* it isn't a exe, dll, sym or com file */ - if (old_deny == new_deny && same_pid) - return(AALL); - - if (old_deny == DENY_READ || new_deny == DENY_READ) return AFAIL; - if (old_mode == DOS_OPEN_RDONLY) return(AREAD); - - return(AFAIL); - } - - switch (new_deny) - { - case DENY_WRITE: - if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_RDONLY) return(AREAD); - if (old_deny==DENY_READ && old_mode==DOS_OPEN_RDONLY) return(AWRITE); - if (old_deny==DENY_NONE && old_mode==DOS_OPEN_RDONLY) return(AALL); - return(AFAIL); - case DENY_READ: - if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_WRONLY) return(AREAD); - if (old_deny==DENY_READ && old_mode==DOS_OPEN_WRONLY) return(AWRITE); - if (old_deny==DENY_NONE && old_mode==DOS_OPEN_WRONLY) return(AALL); - return(AFAIL); - case DENY_NONE: - if (old_deny==DENY_WRITE) return(AREAD); - if (old_deny==DENY_READ) return(AWRITE); - if (old_deny==DENY_NONE) return(AALL); - return(AFAIL); - } - return(AFAIL); -} - /**************************************************************************** Check if we can open a file with a share mode. + Returns True if conflict, False if not. ****************************************************************************/ -static BOOL check_share_mode(connection_struct *conn, share_mode_entry *share, int share_mode, uint32 desired_access, - const char *fname, BOOL fcbopen, int *flags) +static BOOL share_conflict(share_mode_entry *entry, + uint32 access_mask, + uint32 share_access) { - int deny_mode = GET_DENY_MODE(share_mode); - int old_open_mode = GET_OPEN_MODE(share->share_mode); - int old_deny_mode = GET_DENY_MODE(share->share_mode); - BOOL non_io_open_request; - BOOL non_io_open_existing; - - /* - * share modes = false means don't bother to check for - * DENY mode conflict. This is a *really* bad idea :-). JRA. - */ - - if(!lp_share_modes(SNUM(conn))) - return True; - - if (desired_access & ~(SYNCHRONIZE_ACCESS|READ_CONTROL_ACCESS|FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES)) { - non_io_open_request = False; - } else { - non_io_open_request = True; - } - - if (share->desired_access & ~(SYNCHRONIZE_ACCESS|READ_CONTROL_ACCESS|FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES)) { - non_io_open_existing = False; - } else { - non_io_open_existing = True; - } - - /* - * Don't allow any opens once the delete on close flag has been - * set. - */ - - if (GET_DELETE_ON_CLOSE_FLAG(share->share_mode)) { - DEBUG(5,("check_share_mode: Failing open on file %s as delete on close flag is set.\n", - fname )); - /* Use errno to map to correct error. */ - set_saved_error_triple(SMB_SUCCESS, 0, NT_STATUS_OK); + DEBUG(10,("share_conflict: entry->access_mask = 0x%x, " + "entry->share_access = 0x%x, " + "entry->private_options = 0x%x\n", + (unsigned int)entry->access_mask, + (unsigned int)entry->share_access, + (unsigned int)entry->private_options)); + + DEBUG(10,("share_conflict: access_mask = 0x%x, share_access = 0x%x\n", + (unsigned int)access_mask, (unsigned int)share_access)); + + if ((entry->access_mask & (FILE_WRITE_DATA| + FILE_APPEND_DATA| + FILE_READ_DATA| + FILE_EXECUTE| + DELETE_ACCESS)) == 0) { + DEBUG(10,("share_conflict: No conflict due to " + "entry->access_mask = 0x%x\n", + (unsigned int)entry->access_mask )); return False; } - /* this is a nasty hack, but necessary until we rewrite our open - handling to use a NTCreateX call as the basic call. - NT may open a file with neither read nor write access, and in - this case it expects the open not to conflict with any - existing deny modes. This happens (for example) during a - "xcopy /o" where the second file descriptor is used for - ACL sets - (tridge) - */ - - /* - * This is a bit wierd - the test for desired access not having the - * critical bits seems seems odd. Firstly, if both opens have no - * critical bits then always ignore. Then check the "allow delete" - * then check for either. This probably isn't quite right yet but - * gets us much closer. JRA. - */ - - /* - * If desired_access doesn't contain READ_DATA,WRITE_DATA,APPEND_DATA or EXECUTE - * and the existing desired_acces then share modes don't conflict. - */ - - if (non_io_open_request && non_io_open_existing) { - - /* - * Wrinkle discovered by smbtorture.... - * If both are non-io open and requester is asking for delete and current open has delete access - * but neither open has allowed file share delete then deny.... this is very strange and - * seems to be the only case in which non-io opens conflict. JRA. - */ - - if ((desired_access & DELETE_ACCESS) && (share->desired_access & DELETE_ACCESS) && - (!GET_ALLOW_SHARE_DELETE(share->share_mode) || !GET_ALLOW_SHARE_DELETE(share_mode))) { - DEBUG(5,("check_share_mode: Failing open on file %s as delete access requests conflict.\n", - fname )); - set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION); - return False; - } - - DEBUG(5,("check_share_mode: Allowing open on file %s as both desired access (0x%x) \ -and existing desired access (0x%x) are non-data opens\n", - fname, (unsigned int)desired_access, (unsigned int)share->desired_access )); - return True; - } else if (non_io_open_request || non_io_open_existing) { - /* - * If either are non-io opens then share modes don't conflict. - */ - DEBUG(5,("check_share_mode: One non-io open. Allowing open on file %s as desired access (0x%x) doesn't conflict with\ -existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsigned int)share->desired_access )); - return True; - } - - /* - * If delete access was requested and the existing share mode doesn't have - * ALLOW_SHARE_DELETE then deny. - */ - - if ((desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share->share_mode)) { - DEBUG(5,("check_share_mode: Failing open on file %s as delete access requested and allow share delete not set.\n", - fname )); - set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION); + if ((access_mask & (FILE_WRITE_DATA| + FILE_APPEND_DATA| + FILE_READ_DATA| + FILE_EXECUTE| + DELETE_ACCESS)) == 0) { + DEBUG(10,("share_conflict: No conflict due to " + "access_mask = 0x%x\n", + (unsigned int)access_mask )); return False; } - /* - * The inverse of the above. - * If delete access was granted and the new share mode doesn't have - * ALLOW_SHARE_DELETE then deny. - */ - - if ((share->desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share_mode)) { - DEBUG(5,("check_share_mode: Failing open on file %s as delete access granted and allow share delete not requested.\n", - fname )); - set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION); - return False; +#if 1 /* JRA TEST - Superdebug. */ +#define CHECK_MASK(num, am, right, sa, share) \ + DEBUG(10,("share_conflict: [%d] am (0x%x) & right (0x%x) = 0x%x\n", \ + (unsigned int)(num), (unsigned int)(am), \ + (unsigned int)(right), (unsigned int)(am)&(right) )); \ + DEBUG(10,("share_conflict: [%d] sa (0x%x) & share (0x%x) = 0x%x\n", \ + (unsigned int)(num), (unsigned int)(sa), \ + (unsigned int)(share), (unsigned int)(sa)&(share) )); \ + if (((am) & (right)) && !((sa) & (share))) { \ + DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \ +sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \ + (unsigned int)(share) )); \ + set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION); \ + return True; \ } - -#if 0 - /* Bluarc test may need this ... needs further investigation. */ - if (deny_mode == DENY_ALL || old_deny_mode == DENY_ALL) { - set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION); - return False; +#else +#define CHECK_MASK(num, am, right, sa, share) \ + if (((am) & (right)) && !((sa) & (share))) { \ + DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \ +sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \ + (unsigned int)(share) )); \ + set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION); \ + return True; \ } #endif - /* - * If desired_access doesn't contain READ_DATA,WRITE_DATA,APPEND_DATA or EXECUTE - * then share modes don't conflict. Likewise with existing desired access. - */ - - if ( !(desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) || - !(share->desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ) { - DEBUG(5,("check_share_mode: Allowing open on file %s as desired access (0x%x) doesn't conflict with \ -existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsigned int)share->desired_access )); - return True; - } - - { - int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode, - (share->pid == sys_getpid()),is_executable(fname)); - - if ((access_allowed == AFAIL) || - (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) || - (access_allowed == AREAD && *flags != O_RDONLY) || - (access_allowed == AWRITE && *flags != O_WRONLY)) { - - DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n", - deny_mode,old_deny_mode,old_open_mode, - (int)share->pid,fname, fcbopen, *flags, access_allowed)); - - set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION); - return False; - } - - if (access_allowed == AREAD) - *flags = O_RDONLY; - - if (access_allowed == AWRITE) - *flags = O_WRONLY; + CHECK_MASK(1, entry->access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA, + share_access, FILE_SHARE_WRITE); + CHECK_MASK(2, access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA, + entry->share_access, FILE_SHARE_WRITE); + + CHECK_MASK(3, entry->access_mask, FILE_READ_DATA | FILE_EXECUTE, + share_access, FILE_SHARE_READ); + CHECK_MASK(4, access_mask, FILE_READ_DATA | FILE_EXECUTE, + entry->share_access, FILE_SHARE_READ); - } + CHECK_MASK(5, entry->access_mask, DELETE_ACCESS, + share_access, FILE_SHARE_DELETE); + CHECK_MASK(6, access_mask, DELETE_ACCESS, + entry->share_access, FILE_SHARE_DELETE); - return True; + DEBUG(10,("share_conflict: No conflict.\n")); + return False; } - #if defined(DEVELOPER) -static void validate_my_share_entries(int num, share_mode_entry *share_entry) +static void validate_my_share_entries(int num, + share_mode_entry *share_entry) { files_struct *fsp; - if (share_entry->pid != sys_getpid()) + if (share_entry->pid != sys_getpid()) { return; + } - fsp = file_find_dif(share_entry->dev, share_entry->inode, share_entry->share_file_id); + fsp = file_find_dif(share_entry->dev, share_entry->inode, + share_entry->share_file_id); if (!fsp) { - DEBUG(0,("validate_my_share_entries: PANIC : %s\n", share_mode_str(num, share_entry) )); - smb_panic("validate_my_share_entries: Cannot match a share entry with an open file\n"); + DEBUG(0,("validate_my_share_entries: PANIC : %s\n", + share_mode_str(num, share_entry) )); + smb_panic("validate_my_share_entries: Cannot match a " + "share entry with an open file\n"); } if (((uint16)fsp->oplock_type) != share_entry->op_type) { pstring str; - DEBUG(0,("validate_my_share_entries: PANIC : %s\n", share_mode_str(num, share_entry) )); - slprintf(str, sizeof(str)-1, "validate_my_share_entries: file %s, oplock_type = 0x%x, op_type = 0x%x\n", - fsp->fsp_name, (unsigned int)fsp->oplock_type, (unsigned int)share_entry->op_type ); + DEBUG(0,("validate_my_share_entries: PANIC : %s\n", + share_mode_str(num, share_entry) )); + slprintf(str, sizeof(str)-1, "validate_my_share_entries: " + "file %s, oplock_type = 0x%x, op_type = 0x%x\n", + fsp->fsp_name, (unsigned int)fsp->oplock_type, + (unsigned int)share_entry->op_type ); smb_panic(str); } } @@ -651,42 +524,75 @@ static void free_broken_entry_list(struct share_mode_entry_list *broken_entry_li } } +static BOOL cause_oplock_break(int request, int existing, uint32 access_mask) +{ + if ((access_mask == DELETE_ACCESS) && + (request == NO_OPLOCK)) { + /* This is a delete request */ + return (BATCH_OPLOCK_TYPE(existing) != 0); + } + + if (EXCLUSIVE_OPLOCK_TYPE(existing) && (request != NO_OPLOCK)) { + return True; + } + + if ((existing != NO_OPLOCK) && (request == NO_OPLOCK)) { + return True; + } + + return False; +} + /**************************************************************************** Deal with open deny mode and oplock break processing. Invarient: Share mode must be locked on entry and exit. Returns -1 on error, or number of share modes on success (may be zero). ****************************************************************************/ -static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T dev, +static int open_mode_check(connection_struct *conn, + const char *fname, + SMB_DEV_T dev, SMB_INO_T inode, - uint32 desired_access, - int share_mode, int *p_flags, int *p_oplock_request, + uint32 access_mask, + uint32 share_access, + uint32 create_options, + int *p_flags, + int *p_oplock_request, BOOL *p_all_current_opens_are_level_II) { int i; int num_share_modes; int oplock_contention_count = 0; share_mode_entry *old_shares = NULL; - BOOL fcbopen = False; BOOL broke_oplock; + BOOL delete_on_close; - if(GET_OPEN_MODE(share_mode) == DOS_OPEN_FCB) - fcbopen = True; - - num_share_modes = get_share_modes(conn, dev, inode, &old_shares); + num_share_modes = get_share_modes(dev, inode, &old_shares, &delete_on_close); if(num_share_modes == 0) { SAFE_FREE(old_shares); return 0; } - if (desired_access && ((desired_access & ~(SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES))==0) && - ((desired_access & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES)) != 0)) { - /* Stat open that doesn't trigger oplock breaks or share mode checks... ! JRA. */ + if (access_mask && + ((access_mask & ~(SYNCHRONIZE_ACCESS| FILE_READ_ATTRIBUTES| + FILE_WRITE_ATTRIBUTES))==0) && + ((access_mask & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES| + FILE_WRITE_ATTRIBUTES)) != 0)) { + /* Stat open that doesn't trigger oplock breaks or share mode + * checks... ! JRA. */ SAFE_FREE(old_shares); return num_share_modes; } + /* A delete on close prohibits everything */ + + if (delete_on_close) { + SAFE_FREE(old_shares); + errno = EACCES; + return -1; + } + /* * Check if the share modes will give us access. */ @@ -699,132 +605,152 @@ static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T *p_all_current_opens_are_level_II = True; for(i = 0; i < num_share_modes; i++) { - BOOL cause_oplock_break = False; share_mode_entry *share_entry = &old_shares[i]; + BOOL opb_ret; #if defined(DEVELOPER) validate_my_share_entries(i, share_entry); #endif /* - * By observation of NetBench, oplocks are broken *before* share - * modes are checked. This allows a file to be closed by the client - * if the share mode would deny access and the client has an oplock. - * Check if someone has an oplock on this file. If so we must break - * it before continuing. + * By observation of NetBench, oplocks are broken + * *before* share modes are checked. This allows a + * file to be closed by the client if the share mode + * would deny access and the client has an oplock. + * Check if someone has an oplock on this file. If so + * we must break it before continuing. */ - - /* Was this a delete this file request ? */ - if (!*p_oplock_request && desired_access == DELETE_ACCESS && - !BATCH_OPLOCK_TYPE(share_entry->op_type)) { - /* Don't break the oplock in this case. */ - cause_oplock_break = False; - } else if((*p_oplock_request && EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) || - (!*p_oplock_request && (share_entry->op_type != NO_OPLOCK))) { - cause_oplock_break = True; + + if (!cause_oplock_break(*p_oplock_request, + share_entry->op_type, + access_mask)) { + if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) { + *p_all_current_opens_are_level_II = False; + } + continue; } - if(cause_oplock_break) { - BOOL opb_ret; + /* This is an oplock break */ - DEBUG(5,("open_mode_check: oplock_request = %d, breaking oplock (%x) on file %s, \ -dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsigned int)dev, (double)inode)); + DEBUG(5,("open_mode_check: oplock_request = %d, " + "breaking oplock (%x) on file %s, " + "dev = %x, inode = %.0f\n", + *p_oplock_request, share_entry->op_type, + fname, (unsigned int)dev, (double)inode)); - /* Ensure the reply for the open uses the correct sequence number. */ - /* This isn't a real deferred packet as it's response will also increment - * the sequence. - */ - srv_defer_sign_response(get_current_mid()); + /* Ensure the reply for the open uses the correct + * sequence number. */ + /* This isn't a real deferred packet as it's response + * will also increment the sequence. + */ + srv_defer_sign_response(get_current_mid()); - /* Oplock break - unlock to request it. */ - unlock_share_entry(conn, dev, inode); + /* Oplock break - unlock to request it. */ + unlock_share_entry(conn, dev, inode); - opb_ret = request_oplock_break(share_entry); + opb_ret = request_oplock_break(share_entry); - /* Now relock. */ - lock_share_entry(conn, dev, inode); + /* Now relock. */ + lock_share_entry(conn, dev, inode); - if(opb_ret == False) { - DEBUG(0,("open_mode_check: FAILED when breaking oplock (%x) on file %s, \ -dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode)); - SAFE_FREE(old_shares); - set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION); - return -1; - } - - broken_entry = SMB_MALLOC_P(struct share_mode_entry_list); - if (!broken_entry) { - smb_panic("open_mode_check: malloc fail.\n"); - } - broken_entry->entry = *share_entry; - DLIST_ADD(broken_entry_list, broken_entry); - broke_oplock = True; + if (!opb_ret) { + DEBUG(0,("open_mode_check: FAILED when breaking " + "oplock (%x) on file %s, dev = %x, " + "inode = %.0f\n", + old_shares[i].op_type, fname, + (unsigned int)dev, (double)inode)); + SAFE_FREE(old_shares); + set_saved_error_triple(ERRDOS, ERRbadshare, + NT_STATUS_SHARING_VIOLATION); + return -1; + } - } else if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) { - *p_all_current_opens_are_level_II = False; + broken_entry = SMB_MALLOC_P(struct share_mode_entry_list); + if (!broken_entry) { + smb_panic("open_mode_check: malloc fail.\n"); } + broken_entry->entry = *share_entry; + DLIST_ADD(broken_entry_list, broken_entry); + broke_oplock = True; + } /* end for */ if (broke_oplock) { /* Update the current open table. */ SAFE_FREE(old_shares); - num_share_modes = get_share_modes(conn, dev, inode, &old_shares); + num_share_modes = get_share_modes(dev, inode, + &old_shares, + &delete_on_close); } - /* Now we check the share modes, after any oplock breaks. */ - for(i = 0; i < num_share_modes; i++) { - share_mode_entry *share_entry = &old_shares[i]; + if (lp_share_modes(SNUM(conn))) { + /* Now we check the share modes, after any oplock breaks. */ + for(i = 0; i < num_share_modes; i++) { + share_mode_entry *share_entry = &old_shares[i]; - /* someone else has a share lock on it, check to see if we can too */ - if (!check_share_mode(conn, share_entry, share_mode, desired_access, - fname, fcbopen, p_flags)) { - SAFE_FREE(old_shares); - free_broken_entry_list(broken_entry_list); - errno = EACCES; - return -1; - } + /* someone else has a share lock on it, check to see + * if we can too */ + if (share_conflict(share_entry, access_mask, + share_access)) { + SAFE_FREE(old_shares); + free_broken_entry_list(broken_entry_list); + errno = EACCES; + return -1; + } + } } - for(broken_entry = broken_entry_list; broken_entry; broken_entry = broken_entry->next) { + for(broken_entry = broken_entry_list; broken_entry; + broken_entry = broken_entry->next) { oplock_contention_count++; /* Paranoia check that this is no longer an exlusive entry. */ for(i = 0; i < num_share_modes; i++) { share_mode_entry *share_entry = &old_shares[i]; - if (share_modes_identical(&broken_entry->entry, share_entry) && - EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type) ) { + if (!(share_modes_identical(&broken_entry->entry, + share_entry) && + EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type))) { + continue; + } - /* - * This should not happen. The target left this oplock - * as exlusive.... The process *must* be dead.... - */ + /* + * This should not happen. The target left this oplock + * as exlusive.... The process *must* be dead.... + */ - DEBUG(0,("open_mode_check: exlusive oplock left by process %d \ -after break ! For file %s, dev = %x, inode = %.0f. Deleting it to continue...\n", - (int)broken_entry->entry.pid, fname, (unsigned int)dev, (double)inode)); + DEBUG(0,("open_mode_check: exlusive oplock left by " + "process %d after break ! For file %s, " + "dev = %x, inode = %.0f. Deleting it to " + "continue...\n", + (int)broken_entry->entry.pid, fname, + (unsigned int)dev, (double)inode)); - if (process_exists(broken_entry->entry.pid)) { - DEBUG(0,("open_mode_check: Existent process %lu left active oplock.\n", - (unsigned long)broken_entry->entry.pid )); - } + if (process_exists(broken_entry->entry.pid)) { + DEBUG(0,("open_mode_check: Existent process " + "%lu left active oplock.\n", + (unsigned long)broken_entry->entry.pid )); + } - if (del_share_entry(dev, inode, &broken_entry->entry, NULL) == -1) { - free_broken_entry_list(broken_entry_list); - errno = EACCES; - set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION); - return -1; - } + if (del_share_entry(dev, inode, &broken_entry->entry, + NULL, &delete_on_close) == -1) { + free_broken_entry_list(broken_entry_list); + errno = EACCES; + set_saved_error_triple(ERRDOS, ERRbadshare, + NT_STATUS_SHARING_VIOLATION); + return -1; + } - /* - * We must reload the share modes after deleting the - * other process's entry. - */ + /* + * We must reload the share modes after deleting the + * other process's entry. + */ - SAFE_FREE(old_shares); - num_share_modes = get_share_modes(conn, dev, inode, &old_shares); - break; - } + SAFE_FREE(old_shares); + num_share_modes = get_share_modes(dev, inode, + &old_shares, + &delete_on_close); + break; } /* end for paranoia... */ } /* end for broken_entry */ free_broken_entry_list(broken_entry_list); @@ -849,7 +775,9 @@ after break ! For file %s, dev = %x, inode = %.0f. Deleting it to continue...\n" Delete the record for a handled deferred open entry. ****************************************************************************/ -static void delete_defered_open_entry_record(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode) +static void delete_defered_open_entry_record(connection_struct *conn, + SMB_DEV_T dev, + SMB_INO_T inode) { uint16 mid = get_current_mid(); pid_t mypid = sys_getpid(); @@ -864,7 +792,7 @@ static void delete_defered_open_entry_record(connection_struct *conn, SMB_DEV_T for (i = 0; i < num_de_entries; i++) { deferred_open_entry *entry = &de_array[i]; if (entry->pid == mypid && entry->mid == mid && entry->dev == dev && - entry->inode == inode) { + entry->inode == inode) { /* Remove the deferred open entry from the array. */ delete_deferred_open_entry(entry); @@ -879,8 +807,11 @@ static void delete_defered_open_entry_record(connection_struct *conn, SMB_DEV_T Handle the 1 second delay in returning a SHARING_VIOLATION error. ****************************************************************************/ -void defer_open_sharing_error(connection_struct *conn, struct timeval *ptv, - char *fname, SMB_DEV_T dev, SMB_INO_T inode) +static void defer_open_sharing_error(connection_struct *conn, + struct timeval *ptv, + const char *fname, + SMB_DEV_T dev, + SMB_INO_T inode) { uint16 mid = get_current_mid(); pid_t mypid = sys_getpid(); @@ -902,10 +833,12 @@ void defer_open_sharing_error(connection_struct *conn, struct timeval *ptv, /* * Check if a 1 second timeout has expired. */ - if (usec_time_diff(ptv, &entry->time) > SHARING_VIOLATION_USEC_WAIT) { - DEBUG(10,("defer_open_sharing_error: Deleting deferred open entry for mid %u, \ -file %s\n", - (unsigned int)mid, fname )); + if (usec_time_diff(ptv, &entry->time) > + SHARING_VIOLATION_USEC_WAIT) { + DEBUG(10,("defer_open_sharing_error: Deleting " + "deferred open entry for mid %u, " + "file %s\n", + (unsigned int)mid, fname )); /* Expired, return a real error. */ /* Remove the deferred open entry from the array. */ @@ -915,24 +848,30 @@ file %s\n", return; } /* - * If the timeout hasn't expired yet and we still have a sharing violation, - * just leave the entry in the deferred open array alone. We do need to - * reschedule this open call though (with the original created time). + * If the timeout hasn't expired yet and we still have + * a sharing violation, just leave the entry in the + * deferred open array alone. We do need to reschedule + * this open call though (with the original created + * time). */ - DEBUG(10,("defer_open_sharing_error: time [%u.%06u] updating \ -deferred open entry for mid %u, file %s\n", - (unsigned int)entry->time.tv_sec, - (unsigned int)entry->time.tv_usec, - (unsigned int)mid, fname )); - - push_sharing_violation_open_smb_message(&entry->time, (char *)&dib, sizeof(dib)); + DEBUG(10,("defer_open_sharing_error: time [%u.%06u] " + "updating deferred open entry for mid %u, file %s\n", + (unsigned int)entry->time.tv_sec, + (unsigned int)entry->time.tv_usec, + (unsigned int)mid, fname )); + + push_sharing_violation_open_smb_message(&entry->time, + (char *)&dib, + sizeof(dib)); SAFE_FREE(de_array); return; } } - DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred open entry for mid %u, file %s\n", - (unsigned int)ptv->tv_sec, (unsigned int)ptv->tv_usec, (unsigned int)mid, fname )); + DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred " + "open entry for mid %u, file %s\n", + (unsigned int)ptv->tv_sec, (unsigned int)ptv->tv_usec, + (unsigned int)mid, fname )); if (!push_sharing_violation_open_smb_message(ptv, (char *)&dib, sizeof(dib))) { SAFE_FREE(de_array); @@ -959,80 +898,302 @@ deferred open entry for mid %u, file %s\n", This requires a patch to Linux. ****************************************************************************/ -static void kernel_flock(files_struct *fsp, int deny_mode) +static void kernel_flock(files_struct *fsp, uint32 share_mode) { #if HAVE_KERNEL_SHARE_MODES int kernel_mode = 0; - if (deny_mode == DENY_READ) kernel_mode = LOCK_MAND|LOCK_WRITE; - else if (deny_mode == DENY_WRITE) kernel_mode = LOCK_MAND|LOCK_READ; - else if (deny_mode == DENY_ALL) kernel_mode = LOCK_MAND; - if (kernel_mode) flock(fsp->fd, kernel_mode); + if (share_mode == FILE_SHARE_WRITE) { + kernel_mode = LOCK_MAND|LOCK_WRITE; + } else if (share_mode == FILE_SHARE_READ) { + kernel_mode = LOCK_MAND|LOCK_READ; + } else if (share_mode == FILE_SHARE_NONE) { + kernel_mode = LOCK_MAND; + } + if (kernel_mode) { + flock(fsp->fh->fd, kernel_mode); + } #endif - ;; + ; } +/**************************************************************************** + On overwrite open ensure that the attributes match. +****************************************************************************/ -static BOOL open_match_attributes(connection_struct *conn, const char *path, uint32 old_dos_mode, uint32 new_dos_mode, - mode_t existing_mode, mode_t new_mode, mode_t *returned_mode) +static BOOL open_match_attributes(connection_struct *conn, + const char *path, + uint32 old_dos_attr, + uint32 new_dos_attr, + mode_t existing_unx_mode, + mode_t new_unx_mode, + mode_t *returned_unx_mode) { - uint32 noarch_old_dos_mode, noarch_new_dos_mode; + uint32 noarch_old_dos_attr, noarch_new_dos_attr; - noarch_old_dos_mode = (old_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE); - noarch_new_dos_mode = (new_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE); + noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE); + noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE); - if((noarch_old_dos_mode == 0 && noarch_new_dos_mode != 0) || - (noarch_old_dos_mode != 0 && ((noarch_old_dos_mode & noarch_new_dos_mode) == noarch_old_dos_mode))) - *returned_mode = new_mode; - else - *returned_mode = (mode_t)0; + if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) || + (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) { + *returned_unx_mode = new_unx_mode; + } else { + *returned_unx_mode = (mode_t)0; + } - DEBUG(10,("open_match_attributes: file %s old_dos_mode = 0x%x, existing_mode = 0%o, new_dos_mode = 0x%x returned_mode = 0%o\n", - path, - old_dos_mode, (unsigned int)existing_mode, new_dos_mode, (unsigned int)*returned_mode )); + DEBUG(10,("open_match_attributes: file %s old_dos_attr = 0x%x, " + "existing_unx_mode = 0%o, new_dos_attr = 0x%x " + "returned_unx_mode = 0%o\n", + path, + (unsigned int)old_dos_attr, + (unsigned int)existing_unx_mode, + (unsigned int)new_dos_attr, + (unsigned int)*returned_unx_mode )); /* If we're mapping SYSTEM and HIDDEN ensure they match. */ if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) { - if ((old_dos_mode & FILE_ATTRIBUTE_SYSTEM) && !(new_dos_mode & FILE_ATTRIBUTE_SYSTEM)) + if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) && + !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) { return False; + } } if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) { - if ((old_dos_mode & FILE_ATTRIBUTE_HIDDEN) && !(new_dos_mode & FILE_ATTRIBUTE_HIDDEN)) + if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) && + !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) { return False; + } } return True; } /**************************************************************************** - Open a file with a share mode. + Special FCB or DOS processing in the case of a sharing violation. + Try and find a duplicated file handle. ****************************************************************************/ -files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf, - int share_mode,int ofun, uint32 new_dos_mode, int oplock_request, - int *Access,int *action) +static files_struct *fcb_or_dos_open(connection_struct *conn, + const char *fname, SMB_DEV_T dev, + SMB_INO_T inode, + uint32 access_mask, + uint32 share_access, + uint32 create_options) { - return open_file_shared1(conn, fname, psbuf, 0, share_mode, ofun, new_dos_mode, - oplock_request, Access, action); + files_struct *fsp; + files_struct *dup_fsp; + + DEBUG(5,("fcb_or_dos_open: attempting old open semantics for " + "file %s.\n", fname )); + + for(fsp = file_find_di_first(dev, inode); fsp; + fsp = file_find_di_next(fsp)) { + + DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, " + "vuid = %u, file_pid = %u, private_options = 0x%x " + "access_mask = 0x%x\n", fsp->fsp_name, + fsp->fh->fd, (unsigned int)fsp->vuid, + (unsigned int)fsp->file_pid, + (unsigned int)fsp->fh->private_options, + (unsigned int)fsp->access_mask )); + + if (fsp->fh->fd != -1 && + fsp->vuid == current_user.vuid && + fsp->file_pid == global_smbpid && + (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | + NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) && + (fsp->access_mask & FILE_WRITE_DATA) && + strequal(fsp->fsp_name, fname)) { + DEBUG(10,("fcb_or_dos_open: file match\n")); + break; + } + } + + if (!fsp) { + return NULL; + } + + /* quite an insane set of semantics ... */ + if (is_executable(fname) && + (fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) { + DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n")); + return NULL; + } + + /* We need to duplicate this fsp. */ + dup_fsp = dup_file_fsp(fsp, access_mask, share_access, create_options); + if (!dup_fsp) { + return NULL; + } + + return dup_fsp; +} + +/**************************************************************************** + Open a file with a share mode - old openX method - map into NTCreate. +****************************************************************************/ + +BOOL map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func, + uint32 *paccess_mask, + uint32 *pshare_mode, + uint32 *pcreate_disposition, + uint32 *pcreate_options) +{ + uint32 access_mask; + uint32 share_mode; + uint32 create_disposition; + uint32 create_options = 0; + + DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, " + "open_func = 0x%x\n", + fname, (unsigned int)deny_mode, (unsigned int)open_func )); + + /* Create the NT compatible access_mask. */ + switch (GET_OPENX_MODE(deny_mode)) { + case DOS_OPEN_RDONLY: + access_mask = FILE_GENERIC_READ; + break; + case DOS_OPEN_WRONLY: + access_mask = FILE_GENERIC_WRITE; + break; + case DOS_OPEN_EXEC: /* This used to be FILE_READ_DATA... */ + case DOS_OPEN_RDWR: + case DOS_OPEN_FCB: + access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE; + break; + default: + DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n", + (unsigned int)GET_OPENX_MODE(deny_mode))); + return False; + } + + /* Create the NT compatible create_disposition. */ + switch (open_func) { + case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST: + create_disposition = FILE_CREATE; + break; + + case OPENX_FILE_EXISTS_OPEN: + create_disposition = FILE_OPEN; + break; + + case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST: + create_disposition = FILE_OPEN_IF; + break; + + case OPENX_FILE_EXISTS_TRUNCATE: + create_disposition = FILE_OVERWRITE; + break; + + case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST: + create_disposition = FILE_OVERWRITE_IF; + break; + + default: + /* From samba4 - to be confirmed. */ + if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) { + create_disposition = FILE_CREATE; + break; + } + DEBUG(10,("map_open_params_to_ntcreate: bad " + "open_func 0x%x\n", (unsigned int)open_func)); + return False; + } + + /* Create the NT compatible share modes. */ + switch (GET_DENY_MODE(deny_mode)) { + case DENY_ALL: + share_mode = FILE_SHARE_NONE; + break; + + case DENY_WRITE: + share_mode = FILE_SHARE_READ; + break; + + case DENY_READ: + share_mode = FILE_SHARE_WRITE; + break; + + case DENY_NONE: + share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE; + break; + + case DENY_DOS: + create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS; + if (is_executable(fname)) { + share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE; + } else { + if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) { + share_mode = FILE_SHARE_READ; + } else { + share_mode = FILE_SHARE_NONE; + } + } + break; + + case DENY_FCB: + create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB; + share_mode = FILE_SHARE_NONE; + break; + + default: + DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n", + (unsigned int)GET_DENY_MODE(deny_mode) )); + return False; + } + + DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, " + "share_mode = 0x%x, create_disposition = 0x%x, " + "create_options = 0x%x\n", + fname, + (unsigned int)access_mask, + (unsigned int)share_mode, + (unsigned int)create_disposition, + (unsigned int)create_options )); + + if (paccess_mask) { + *paccess_mask = access_mask; + } + if (pshare_mode) { + *pshare_mode = share_mode; + } + if (pcreate_disposition) { + *pcreate_disposition = create_disposition; + } + if (pcreate_options) { + *pcreate_options = create_options; + } + + return True; + } +/* Map generic permissions to file object specific permissions */ + +struct generic_mapping file_generic_mapping = { + FILE_GENERIC_READ, + FILE_GENERIC_WRITE, + FILE_GENERIC_EXECUTE, + FILE_GENERIC_ALL +}; + /**************************************************************************** Open a file with a share mode. ****************************************************************************/ -files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf, - uint32 desired_access, - int share_mode,int ofun, uint32 new_dos_mode, - int oplock_request, - int *Access,int *paction) +files_struct *open_file_ntcreate(connection_struct *conn, + const char *fname, + SMB_STRUCT_STAT *psbuf, + uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */ + uint32 share_access, /* share constants (FILE_SHARE_READ etc). */ + uint32 create_disposition, /* FILE_OPEN_IF etc. */ + uint32 create_options, /* options such as delete on close. */ + uint32 new_dos_attributes, /* attributes used for new file. */ + int oplock_request, /* internal Samba oplock codes. */ + /* Information (FILE_EXISTS etc.) */ + int *pinfo) { int flags=0; int flags2=0; - int deny_mode = GET_DENY_MODE(share_mode); - BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode); - BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode); BOOL file_existed = VALID_STAT(*psbuf); - BOOL fcbopen = False; BOOL def_acl = False; - BOOL add_share_mode = True; BOOL internal_only_open = False; SMB_DEV_T dev = 0; SMB_INO_T inode = 0; @@ -1040,15 +1201,40 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_ BOOL all_current_opens_are_level_II = False; BOOL fsp_open = False; files_struct *fsp = NULL; - int open_mode=0; - uint16 port = 0; - mode_t new_mode = (mode_t)0; - int action; - uint32 existing_dos_mode = 0; + mode_t new_unx_mode = (mode_t)0; + mode_t unx_mode = (mode_t)0; + int info; + uint32 existing_dos_attributes = 0; struct pending_message_list *pml = NULL; + uint16 port = 0; uint16 mid = get_current_mid(); - /* We add aARCH to this as this mode is only used if the file is created new. */ - mode_t mode = unix_mode(conn,new_dos_mode | aARCH,fname, True); + + if (conn->printer) { + /* + * Printers are handled completely differently. + * Most of the passed parameters are ignored. + */ + + if (pinfo) { + *pinfo = FILE_WAS_CREATED; + } + + DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n", fname)); + + return print_fsp_open(conn, fname); + } + + /* We add aARCH to this as this mode is only used if the file is + * created new. */ + unx_mode = unix_mode(conn, new_dos_attributes | aARCH,fname, True); + + DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x " + "access_mask=0x%x share_access=0x%x " + "create_disposition = 0x%x create_options=0x%x " + "unix mode=0%o oplock_request=%d\n", + fname, new_dos_attributes, access_mask, share_access, + create_disposition, create_options, unx_mode, + oplock_request)); if (oplock_request == INTERNAL_OPEN_ONLY) { internal_only_open = True; @@ -1061,52 +1247,42 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_ memcpy(&dib, pml->private_data.data, sizeof(dib)); /* There could be a race condition where the dev/inode pair - has changed since we deferred the message. If so, just - remove the deferred open entry and return sharing violation. */ - - /* If the timeout value is non-zero, we need to just - return sharing violation. Don't retry the open - as we were not notified of a close and we don't want to - trigger another spurious oplock break. */ - - if (!file_existed || dib.dev != psbuf->st_dev || dib.inode != psbuf->st_ino || - pml->msg_time.tv_sec || pml->msg_time.tv_usec) { + has changed since we deferred the message. If so, just + remove the deferred open entry and return sharing + violation. */ + + /* If the timeout value is non-zero, we need to just return + sharing violation. Don't retry the open as we were not + notified of a close and we don't want to trigger another + spurious oplock break. */ + + if (!file_existed || dib.dev != psbuf->st_dev || + dib.inode != psbuf->st_ino || pml->msg_time.tv_sec || + pml->msg_time.tv_usec) { /* Ensure we don't reprocess this message. */ remove_sharing_violation_open_smb_message(mid); /* Now remove the deferred open entry under lock. */ lock_share_entry(conn, dib.dev, dib.inode); - delete_defered_open_entry_record(conn, dib.dev, dib.inode); + delete_defered_open_entry_record(conn, dib.dev, + dib.inode); unlock_share_entry(conn, dib.dev, dib.inode); - set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION); + set_saved_error_triple(ERRDOS, ERRbadshare, + NT_STATUS_SHARING_VIOLATION); return NULL; } /* Ensure we don't reprocess this message. */ remove_sharing_violation_open_smb_message(mid); - - } - - if (conn->printer) { - /* printers are handled completely differently. Most of the passed parameters are - ignored */ - if (Access) - *Access = DOS_OPEN_WRONLY; - if (paction) - *paction = FILE_WAS_CREATED; - return print_fsp_open(conn, fname); } - DEBUG(10,("open_file_shared: fname = %s, dos_attrs = %x, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n", - fname, new_dos_mode, share_mode, ofun, (int)mode, oplock_request )); - if (!check_name(fname,conn)) { return NULL; } - new_dos_mode &= SAMBA_ATTRIBUTES_MASK; + new_dos_attributes &= SAMBA_ATTRIBUTES_MASK; if (file_existed) { - existing_dos_mode = dos_mode(conn, fname, psbuf); + existing_dos_attributes = dos_mode(conn, fname, psbuf); } /* ignore any oplock requests if oplocks are disabled */ @@ -1115,114 +1291,173 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_ } /* this is for OS/2 long file names - say we don't support them */ - if (strstr(fname,".+,;=[].")) { - /* OS/2 Workplace shell fix may be main code stream in a later release. */ - set_saved_error_triple(ERRDOS, ERRcannotopen, NT_STATUS_OBJECT_NAME_NOT_FOUND); - DEBUG(5,("open_file_shared: OS/2 long filenames are not supported.\n")); + if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) { + /* OS/2 Workplace shell fix may be main code stream in a later + * release. */ + set_saved_error_triple(ERRDOS, ERRcannotopen, + NT_STATUS_OBJECT_NAME_NOT_FOUND); + DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not " + "supported.\n")); return NULL; } - if ((GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL) && file_existed) { - DEBUG(5,("open_file_shared: create new requested for file %s and file already exists.\n", - fname )); - if (S_ISDIR(psbuf->st_mode)) { - errno = EISDIR; - } else { - errno = EEXIST; - } - return NULL; - } - - if (CAN_WRITE(conn) && (GET_FILE_CREATE_DISPOSITION(ofun) == FILE_CREATE_IF_NOT_EXIST)) - flags2 |= O_CREAT; + switch( create_disposition ) { + /* + * Currently we're using FILE_SUPERSEDE as the same as + * FILE_OVERWRITE_IF but they really are + * different. FILE_SUPERSEDE deletes an existing file + * (requiring delete access) then recreates it. + */ + case FILE_SUPERSEDE: + /* If file exists replace/overwrite. If file doesn't + * exist create. */ + flags2 |= (O_CREAT | O_TRUNC); + break; - if (CAN_WRITE(conn) && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) - flags2 |= O_TRUNC; + case FILE_OVERWRITE_IF: + /* If file exists replace/overwrite. If file doesn't + * exist create. */ + flags2 |= (O_CREAT | O_TRUNC); + break; - /* We only care about matching attributes on file exists and truncate. */ - if (file_existed && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) { - if (!open_match_attributes(conn, fname, existing_dos_mode, new_dos_mode, - psbuf->st_mode, mode, &new_mode)) { - DEBUG(5,("open_file_shared: attributes missmatch for file %s (%x %x) (0%o, 0%o)\n", - fname, existing_dos_mode, new_dos_mode, - (int)psbuf->st_mode, (int)mode )); + case FILE_OPEN: + /* If file exists open. If file doesn't exist error. */ + if (!file_existed) { + DEBUG(5,("open_file_ntcreate: FILE_OPEN " + "requested for file %s and file " + "doesn't exist.\n", fname )); + set_saved_error_triple(ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND); + errno = ENOENT; + return NULL; + } + break; + + case FILE_OVERWRITE: + /* If file exists overwrite. If file doesn't exist + * error. */ + if (!file_existed) { + DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE " + "requested for file %s and file " + "doesn't exist.\n", fname )); + set_saved_error_triple(ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND); + errno = ENOENT; + return NULL; + } + flags2 |= O_TRUNC; + break; + + case FILE_CREATE: + /* If file exists error. If file doesn't exist + * create. */ + if (file_existed) { + DEBUG(5,("open_file_ntcreate: FILE_CREATE " + "requested for file %s and file " + "already exists.\n", fname )); + if (S_ISDIR(psbuf->st_mode)) { + errno = EISDIR; + } else { + errno = EEXIST; + } + return NULL; + } + flags2 |= (O_CREAT|O_EXCL); + break; + + case FILE_OPEN_IF: + /* If file exists open. If file doesn't exist + * create. */ + flags2 |= O_CREAT; + break; + + default: + set_saved_error_triple(ERRDOS, ERRinvalidparam, + NT_STATUS_INVALID_PARAMETER); + return NULL; + } + + /* We only care about matching attributes on file exists and + * overwrite. */ + + if (file_existed && ((create_disposition == FILE_OVERWRITE) || + (create_disposition == FILE_OVERWRITE_IF))) { + if (!open_match_attributes(conn, fname, + existing_dos_attributes, + new_dos_attributes, psbuf->st_mode, + unx_mode, &new_unx_mode)) { + DEBUG(5,("open_file_ntcreate: attributes missmatch " + "for file %s (%x %x) (0%o, 0%o)\n", + fname, existing_dos_attributes, + new_dos_attributes, + (unsigned int)psbuf->st_mode, + (unsigned int)unx_mode )); errno = EACCES; return NULL; } } - if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL) - flags2 |= O_EXCL; + /* This is a nasty hack - must fix... JRA. */ + if (access_mask == MAXIMUM_ALLOWED_ACCESS) { + access_mask = FILE_GENERIC_ALL; + } - /* note that we ignore the append flag as - append does not mean the same thing under dos and unix */ + /* + * Convert GENERIC bits to specific bits. + */ - switch (GET_OPEN_MODE(share_mode)) { - case DOS_OPEN_EXEC: - case DOS_OPEN_RDONLY: - flags = O_RDONLY; - if (desired_access == 0) - desired_access = FILE_READ_DATA; - break; - case DOS_OPEN_WRONLY: - flags = O_WRONLY; - if (desired_access == 0) - desired_access = FILE_WRITE_DATA; - break; - case DOS_OPEN_FCB: - fcbopen = True; - flags = O_RDWR; - if (desired_access == 0) - desired_access = FILE_READ_DATA|FILE_WRITE_DATA; - break; - case DOS_OPEN_RDWR: - flags = O_RDWR; - if (desired_access == 0) - desired_access = FILE_READ_DATA|FILE_WRITE_DATA; - break; - default: - /* Force DOS error. */ - set_saved_error_triple(ERRDOS, ERRinvalidparam, NT_STATUS_INVALID); - return NULL; + se_map_generic(&access_mask, &file_generic_mapping); + + DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping " + "access_mask=0x%x\n", fname, access_mask )); + + /* + * Note that we ignore the append flag as append does not + * mean the same thing under DOS and Unix. + */ + + if (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) { + flags = O_RDWR; + } else { + flags = O_RDONLY; } + /* + * Currently we only look at FILE_WRITE_THROUGH for create options. + */ + #if defined(O_SYNC) - if (GET_FILE_SYNC_OPENMODE(share_mode)) { + if (create_options & FILE_WRITE_THROUGH) { flags2 |= O_SYNC; } #endif /* O_SYNC */ - if (flags != O_RDONLY && file_existed && - (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_mode))) { - if (!fcbopen) { - DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n", - fname, !CAN_WRITE(conn) ? "share" : "file" )); - errno = EACCES; - return NULL; - } - flags = O_RDONLY; + if (!CAN_WRITE(conn)) { + /* + * We should really return a permission denied error if either + * O_CREAT or O_TRUNC are set, but for compatibility with + * older versions of Samba we just AND them out. + */ + flags2 &= ~(O_CREAT|O_TRUNC); } - if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) { - DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname)); - errno = EINVAL; - return NULL; - } + /* + * Ensure we can't write on a read-only share or file. + */ - if (desired_access && ((desired_access & ~(SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES))==0) && - ((desired_access & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES)) != 0)) { - /* Stat open that doesn't trigger oplock breaks or share mode checks... ! JRA. */ - deny_mode = DENY_NONE; - if (file_existed) { - oplock_request = 0; - add_share_mode = False; - flags2 &= ~O_CREAT; - } + if (flags != O_RDONLY && file_existed && + (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) { + DEBUG(5,("open_file_ntcreate: write access requested for " + "file %s on read only %s\n", + fname, !CAN_WRITE(conn) ? "share" : "file" )); + set_saved_error_triple(ERRDOS, ERRnoaccess, + NT_STATUS_ACCESS_DENIED); + errno = EACCES; + return NULL; } fsp = file_new(conn); - if(!fsp) + if(!fsp) { return NULL; + } if (file_existed) { @@ -1231,47 +1466,86 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_ lock_share_entry(conn, dev, inode); - num_share_modes = open_mode_check(conn, fname, dev, inode, - desired_access, - share_mode, - &flags, &oplock_request, &all_current_opens_are_level_II); + num_share_modes = open_mode_check(conn, fname, dev, inode, + access_mask, share_access, + create_options, + &flags, &oplock_request, + &all_current_opens_are_level_II); if(num_share_modes == -1) { + if (!internal_only_open) { + NTSTATUS status; + get_saved_error_triple(NULL, NULL, &status); + if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION)) { + /* Check if this can be done with the + * deny_dos and fcb calls. */ + if (create_options & + (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS| + NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) { + files_struct *fsp_dup; + fsp_dup = fcb_or_dos_open(conn, fname, dev, + inode, access_mask, + share_access, + create_options); + + if (fsp_dup) { + unlock_share_entry(conn, dev, inode); + file_free(fsp); + if (pinfo) { + *pinfo = FILE_WAS_OPENED; + } + conn->num_files_open++; + return fsp_dup; + } + } + } + } + /* - * This next line is a subtlety we need for MS-Access. If a file open will - * fail due to share permissions and also for security (access) - * reasons, we need to return the access failed error, not the - * share error. This means we must attempt to open the file anyway - * in order to get the UNIX access error - even if we're going to - * fail the open for share reasons. This is bad, as we're burning - * another fd if there are existing locks but there's nothing else - * we can do. We also ensure we're not going to create or tuncate - * the file as we only want an access decision at this stage. JRA. + * This next line is a subtlety we need for + * MS-Access. If a file open will fail due to share + * permissions and also for security (access) reasons, + * we need to return the access failed error, not the + * share error. This means we must attempt to open the + * file anyway in order to get the UNIX access error - + * even if we're going to fail the open for share + * reasons. This is bad, as we're burning another fd + * if there are existing locks but there's nothing + * else we can do. We also ensure we're not going to + * create or tuncate the file as we only want an + * access decision at this stage. JRA. */ errno = 0; fsp_open = open_file(fsp,conn,fname,psbuf, - flags|(flags2&~(O_TRUNC|O_CREAT)),mode,desired_access); + flags|(flags2&~(O_TRUNC|O_CREAT)), + unx_mode,access_mask); - DEBUG(4,("open_file_shared : share_mode deny - calling open_file with \ -flags=0x%X flags2=0x%X mode=0%o returned %d\n", - flags,(flags2&~(O_TRUNC|O_CREAT)),(int)mode,(int)fsp_open )); + DEBUG(4,("open_file_ntcreate : share_mode deny - " + "calling open_file with flags=0x%X " + "flags2=0x%X mode=0%o returned %d\n", + flags, (flags2&~(O_TRUNC|O_CREAT)), + (unsigned int)unx_mode, (int)fsp_open )); if (!fsp_open && errno) { /* Default error. */ - set_saved_error_triple(ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED); + set_saved_error_triple(ERRDOS, ERRnoaccess, + NT_STATUS_ACCESS_DENIED); } /* - * If we're returning a share violation, ensure we cope with - * the braindead 1 second delay. + * If we're returning a share violation, ensure we + * cope with the braindead 1 second delay. */ if (!internal_only_open) { NTSTATUS status; get_saved_error_triple(NULL, NULL, &status); if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION)) { - /* The fsp->open_time here represents the current time of day. */ - defer_open_sharing_error(conn, &fsp->open_time, fname, dev, inode); + /* The fsp->open_time here represents + * the current time of day. */ + defer_open_sharing_error(conn, + &fsp->open_time, + fname, dev, inode); } } @@ -1282,7 +1556,8 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", * We have detected a sharing violation here * so return the correct error code */ - set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION); + set_saved_error_triple(ERRDOS, ERRbadshare, + NT_STATUS_SHARING_VIOLATION); } file_free(fsp); return NULL; @@ -1298,35 +1573,39 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", */ if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) && - (def_acl = directory_has_default_acl(conn, parent_dirname(fname)))) - mode = 0777; + (def_acl = directory_has_default_acl(conn, parent_dirname(fname)))) { + unx_mode = 0777; + } DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n", - flags,flags2,(int)mode)); + (unsigned int)flags,(unsigned int)flags2,(unsigned int)unx_mode)); /* * open_file strips any O_TRUNC flags itself. */ - fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,mode,desired_access); + fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,unx_mode,access_mask); - if (!fsp_open && (flags == O_RDWR) && (errno != ENOENT) && fcbopen) { - if((fsp_open = open_file(fsp,conn,fname,psbuf,O_RDONLY,mode,desired_access)) == True) + if (!fsp_open && (flags == O_RDWR) && (errno != ENOENT)) { + if((fsp_open = open_file(fsp,conn,fname,psbuf, + O_RDONLY,unx_mode,access_mask)) == True) { flags = O_RDONLY; + } } if (!fsp_open) { - if(file_existed) + if(file_existed) { unlock_share_entry(conn, dev, inode); + } file_free(fsp); return NULL; } /* - * Deal with the race condition where two smbd's detect the file doesn't - * exist and do the create at the same time. One of them will win and - * set a share mode, the other (ie. this one) should check if the - * requested share mode for this create is allowed. + * Deal with the race condition where two smbd's detect the file + * doesn't exist and do the create at the same time. One of them will + * win and set a share mode, the other (ie. this one) should check if + * the requested share mode for this create is allowed. */ if (!file_existed) { @@ -1343,22 +1622,47 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", lock_share_entry_fsp(fsp); - num_share_modes = open_mode_check(conn, fname, dev, inode, - desired_access, - share_mode, - &flags, &oplock_request, &all_current_opens_are_level_II); + num_share_modes = open_mode_check(conn, fname, dev, inode, + access_mask, share_access, + create_options, + &flags, &oplock_request, + &all_current_opens_are_level_II); if(num_share_modes == -1) { - /* - * If we're returning a share violation, ensure we cope with - * the braindead 1 second delay. - */ - NTSTATUS status; get_saved_error_triple(NULL, NULL, &status); if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION)) { - /* The fsp->open_time here represents the current time of day. */ - defer_open_sharing_error(conn, &fsp->open_time, fname, dev, inode); + /* Check if this can be done with the deny_dos + * and fcb calls. */ + if (create_options & + (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS| + NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) { + files_struct *fsp_dup; + fsp_dup = fcb_or_dos_open(conn, fname, dev, inode, + access_mask, share_access, + create_options); + if (fsp_dup) { + unlock_share_entry(conn, dev, inode); + fd_close(conn, fsp); + file_free(fsp); + if (pinfo) { + *pinfo = FILE_WAS_OPENED; + } + conn->num_files_open++; + return fsp_dup; + } + } + + /* + * If we're returning a share violation, + * ensure we cope with the braindead 1 second + * delay. + */ + + /* The fsp->open_time here represents the + * current time of day. */ + defer_open_sharing_error(conn, &fsp->open_time, + fname, dev, inode); } unlock_share_entry_fsp(fsp); @@ -1368,7 +1672,8 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", * We have detected a sharing violation here, so * return the correct code. */ - set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION); + set_saved_error_triple(ERRDOS, ERRbadshare, + NT_STATUS_SHARING_VIOLATION); return NULL; } @@ -1377,8 +1682,9 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", * exist. Ensure we return the correct value for action. */ - if (num_share_modes > 0) + if (num_share_modes > 0) { file_existed = True; + } /* * We exit this block with the share entry *locked*..... @@ -1391,7 +1697,8 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", mode and we have already checked our more authoritative locking database for permission to set this deny mode. If the kernel refuses the operations then the kernel is wrong */ - kernel_flock(fsp, deny_mode); + + kernel_flock(fsp, share_access); /* * At this point onwards, we can guarentee that the share entry @@ -1405,9 +1712,11 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", if (flags2&O_TRUNC) { /* - * We are modifing the file after open - update the stat struct.. + * We are modifing the file after open - update the stat + * struct.. */ - if ((SMB_VFS_FTRUNCATE(fsp,fsp->fd,0) == -1) || (SMB_VFS_FSTAT(fsp,fsp->fd,psbuf)==-1)) { + if ((SMB_VFS_FTRUNCATE(fsp,fsp->fh->fd,0) == -1) || + (SMB_VFS_FSTAT(fsp,fsp->fh->fd,psbuf)==-1)) { unlock_share_entry_fsp(fsp); fd_close(conn,fsp); file_free(fsp); @@ -1415,44 +1724,28 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", } } - switch (flags) { - case O_RDONLY: - open_mode = DOS_OPEN_RDONLY; - break; - case O_RDWR: - open_mode = DOS_OPEN_RDWR; - break; - case O_WRONLY: - open_mode = DOS_OPEN_WRONLY; - break; - } + /* Record the options we were opened with. */ + fsp->share_access = share_access; + fsp->fh->private_options = create_options; + fsp->access_mask = access_mask; - fsp->share_mode = SET_DENY_MODE(deny_mode) | - SET_OPEN_MODE(open_mode) | - SET_ALLOW_SHARE_DELETE(allow_share_delete); - - DEBUG(10,("open_file_shared : share_mode = %x\n", fsp->share_mode )); - - if (Access) { - (*Access) = (SET_DENY_MODE(deny_mode) | SET_OPEN_MODE(open_mode)); - } - - action = 0; - - if (file_existed && !(flags2 & O_TRUNC)) - action = FILE_WAS_OPENED; - if (file_existed && (flags2 & O_TRUNC)) - action = FILE_WAS_OVERWRITTEN; - if (!file_existed) { - action = FILE_WAS_CREATED; + if (file_existed) { + if (!(flags2 & O_TRUNC)) { + info = FILE_WAS_OPENED; + } else { + info = FILE_WAS_OVERWRITTEN; + } + } else { + info = FILE_WAS_CREATED; /* Change the owner if required. */ if (lp_inherit_owner(SNUM(conn))) { - change_owner_to_parent(conn, fsp, fsp->fsp_name, psbuf); + change_owner_to_parent(conn, fsp, fsp->fsp_name, + psbuf); } } - if (paction) { - *paction = action; + if (pinfo) { + *pinfo = info; } /* @@ -1461,7 +1754,8 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", */ if(oplock_request && (num_share_modes == 0) && - !IS_VETO_OPLOCK_PATH(conn,fname) && set_file_oplock(fsp, oplock_request) ) { + !IS_VETO_OPLOCK_PATH(conn,fname) && + set_file_oplock(fsp, oplock_request) ) { port = global_oplock_port; } else if (oplock_request && all_current_opens_are_level_II) { port = global_oplock_port; @@ -1472,26 +1766,25 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", oplock_request = 0; } - if (add_share_mode) { - set_share_mode(fsp, port, oplock_request); - } + set_share_mode(fsp, port, oplock_request); - if (delete_on_close) { - uint32 dosmode = existing_dos_mode; + if (create_options & FILE_DELETE_ON_CLOSE) { + uint32 dosattr= existing_dos_attributes; NTSTATUS result; - if (action == FILE_WAS_OVERWRITTEN || action == FILE_WAS_CREATED) { - dosmode = new_dos_mode; + if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED || + info == FILE_WAS_SUPERSEDED) { + dosattr = new_dos_attributes; } - result = set_delete_on_close_internal(fsp, delete_on_close, dosmode); - if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) { + result = can_set_delete_on_close(fsp, True, dosattr); + + if (!NT_STATUS_IS_OK(result)) { uint8 u_e_c; uint32 u_e_code; + BOOL dummy_del_on_close; /* Remember to delete the mode we just added. */ - if (add_share_mode) { - del_share_mode(fsp, NULL); - } + del_share_mode(fsp, NULL, &dummy_del_on_close); unlock_share_entry_fsp(fsp); fd_close(conn,fsp); file_free(fsp); @@ -1499,12 +1792,17 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", set_saved_error_triple(u_e_c, u_e_code, result); return NULL; } + set_delete_on_close(fsp, True); } - if (action == FILE_WAS_OVERWRITTEN || action == FILE_WAS_CREATED) { + if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED || + info == FILE_WAS_SUPERSEDED) { /* Files should be initially set as archive */ - if (lp_map_archive(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) { - file_set_dosmode(conn, fname, new_dos_mode | aARCH, NULL, True); + if (lp_map_archive(SNUM(conn)) || + lp_store_dos_attributes(SNUM(conn))) { + file_set_dosmode(conn, fname, + new_dos_attributes | aARCH, NULL, + True); } } @@ -1515,36 +1813,45 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", if (!file_existed && !def_acl) { - int saved_errno = errno; /* We might get ENOSYS in the next call.. */ + int saved_errno = errno; /* We might get ENOSYS in the next + * call.. */ - if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, mode) == -1 && errno == ENOSYS) + if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fh->fd, unx_mode) == -1 + && errno == ENOSYS) { errno = saved_errno; /* Ignore ENOSYS */ + } - } else if (new_mode) { + } else if (new_unx_mode) { int ret = -1; /* Attributes need changing. File already existed. */ { - int saved_errno = errno; /* We might get ENOSYS in the next call.. */ - ret = SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, new_mode); + int saved_errno = errno; /* We might get ENOSYS in the + * next call.. */ + ret = SMB_VFS_FCHMOD_ACL(fsp, fsp->fh->fd, + new_unx_mode); if (ret == -1 && errno == ENOSYS) { errno = saved_errno; /* Ignore ENOSYS */ } else { - DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n", - fname, (int)new_mode)); + DEBUG(5, ("open_file_shared: failed to reset " + "attributes of file %s to 0%o\n", + fname, (unsigned int)new_unx_mode)); ret = 0; /* Don't do the fchmod below. */ } } - if ((ret == -1) && (SMB_VFS_FCHMOD(fsp, fsp->fd, new_mode) == -1)) - DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n", - fname, (int)new_mode)); + if ((ret == -1) && + (SMB_VFS_FCHMOD(fsp, fsp->fh->fd, new_unx_mode) == -1)) + DEBUG(5, ("open_file_shared: failed to reset " + "attributes of file %s to 0%o\n", + fname, (unsigned int)new_unx_mode)); } - /* If this is a successful open, we must remove any deferred open records. */ + /* If this is a successful open, we must remove any deferred open + * records. */ delete_defered_open_entry_record(conn, fsp->dev, fsp->inode); unlock_share_entry_fsp(fsp); @@ -1557,17 +1864,20 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", Open a file for for write to ensure that we can fchmod it. ****************************************************************************/ -files_struct *open_file_fchmod(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf) +files_struct *open_file_fchmod(connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf) { files_struct *fsp = NULL; BOOL fsp_open; - if (!VALID_STAT(*psbuf)) + if (!VALID_STAT(*psbuf)) { return NULL; + } fsp = file_new(conn); - if(!fsp) + if(!fsp) { return NULL; + } /* note! we must use a non-zero desired access or we don't get a real file descriptor. Oh what a twisted web we weave. */ @@ -1602,96 +1912,135 @@ int close_file_fchmod(files_struct *fsp) Open a directory from an NT SMB call. ****************************************************************************/ -files_struct *open_directory(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf, - uint32 desired_access, int share_mode, int smb_ofun, int *action) +files_struct *open_directory(connection_struct *conn, + const char *fname, + SMB_STRUCT_STAT *psbuf, + uint32 access_mask, + uint32 share_access, + uint32 create_disposition, + uint32 create_options, + int *pinfo) { - BOOL got_stat = False; - files_struct *fsp = file_new(conn); - BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode); - - if(!fsp) + files_struct *fsp = NULL; + BOOL dir_existed = VALID_STAT(*psbuf) ? True : False; + BOOL create_dir = False; + int info = 0; + + DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, " + "share_access = 0x%x create_options = 0x%x, " + "create_disposition = 0x%x\n", + fname, + (unsigned int)access_mask, + (unsigned int)share_access, + (unsigned int)create_options, + (unsigned int)create_disposition)); + + if (is_ntfs_stream_name(fname)) { + DEBUG(0,("open_directory: %s is a stream name!\n", fname )); + /* NB. Is the DOS error ERRbadpath or ERRbaddirectory ? */ + set_saved_error_triple(ERRDOS, ERRbadpath, + NT_STATUS_NOT_A_DIRECTORY); return NULL; + } - if (VALID_STAT(*psbuf)) - got_stat = True; - - if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) { - file_free(fsp); - errno = EEXIST; /* Setup so correct error is returned to client. */ + if (dir_existed && !S_ISDIR(psbuf->st_mode)) { + DEBUG(0,("open_directory: %s is not a directory !\n", fname )); + /* NB. Is the DOS error ERRbadpath or ERRbaddirectory ? */ + set_saved_error_triple(ERRDOS, ERRbadpath, + NT_STATUS_NOT_A_DIRECTORY); return NULL; } - if (GET_FILE_CREATE_DISPOSITION(smb_ofun) == FILE_CREATE_IF_NOT_EXIST) { - - if (got_stat) { - - if(!S_ISDIR(psbuf->st_mode)) { - DEBUG(0,("open_directory: %s is not a directory !\n", fname )); - file_free(fsp); - errno = EACCES; + switch( create_disposition ) { + case FILE_OPEN: + /* If directory exists open. If directory doesn't + * exist error. */ + if (!dir_existed) { + DEBUG(5,("open_directory: FILE_OPEN requested " + "for directory %s and it doesn't " + "exist.\n", fname )); + set_saved_error_triple(ERRDOS, ERRbadfile, + NT_STATUS_OBJECT_NAME_NOT_FOUND); return NULL; } - *action = FILE_WAS_OPENED; - - } else { - - /* - * Try and create the directory. - */ - - /* We know bad_path is false as it's caught earlier. */ - - NTSTATUS status = mkdir_internal(conn, fname, False); + info = FILE_WAS_OPENED; + break; - if (!NT_STATUS_IS_OK(status)) { - DEBUG(2,("open_directory: unable to create %s. Error was %s\n", - fname, strerror(errno) )); - file_free(fsp); - /* Ensure we return the correct NT status to the client. */ - set_saved_error_triple(0, 0, status); + case FILE_CREATE: + /* If directory exists error. If directory doesn't + * exist create. */ + if (dir_existed) { + DEBUG(5,("open_directory: FILE_CREATE " + "requested for directory %s and it " + "already exists.\n", fname )); + set_saved_error_triple(ERRDOS, ERRfilexists, + NT_STATUS_OBJECT_NAME_COLLISION); return NULL; } + create_dir = True; + info = FILE_WAS_CREATED; + break; - /* Ensure we're checking for a symlink here.... */ - /* We don't want to get caught by a symlink racer. */ - - if(SMB_VFS_LSTAT(conn,fname, psbuf) != 0) { - file_free(fsp); - return NULL; + case FILE_OPEN_IF: + /* If directory exists open. If directory doesn't + * exist create. */ + if (!dir_existed) { + create_dir = True; + info = FILE_WAS_CREATED; + } else { + info = FILE_WAS_OPENED; } + break; - if(!S_ISDIR(psbuf->st_mode)) { - DEBUG(0,("open_directory: %s is not a directory !\n", fname )); - file_free(fsp); - return NULL; - } + case FILE_SUPERSEDE: + case FILE_OVERWRITE: + case FILE_OVERWRITE_IF: + default: + DEBUG(5,("open_directory: invalid create_disposition " + "0x%x for directory %s\n", + (unsigned int)create_disposition, fname)); + file_free(fsp); + set_saved_error_triple(ERRDOS, ERRinvalidparam, + NT_STATUS_INVALID_PARAMETER); + return NULL; + } + + if (create_dir) { + /* + * Try and create the directory. + */ - *action = FILE_WAS_CREATED; + /* We know bad_path is false as it's caught earlier. */ + NTSTATUS status = mkdir_internal(conn, fname, False); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(2,("open_directory: unable to create %s. " + "Error was %s\n", fname, strerror(errno) )); + /* Ensure we return the correct NT status to the + * client. */ + set_saved_error_triple(0, 0, status); + return NULL; } - } else { - /* - * Don't create - just check that it *was* a directory. - */ + /* Ensure we're checking for a symlink here.... */ + /* We don't want to get caught by a symlink racer. */ - if(!got_stat) { - DEBUG(3,("open_directory: unable to stat name = %s. Error was %s\n", - fname, strerror(errno) )); - file_free(fsp); + if(SMB_VFS_LSTAT(conn,fname, psbuf) != 0) { return NULL; } if(!S_ISDIR(psbuf->st_mode)) { - DEBUG(0,("open_directory: %s is not a directory !\n", fname )); - file_free(fsp); + DEBUG(0,("open_directory: %s is not a directory !\n", + fname )); return NULL; } + } - *action = FILE_WAS_OPENED; + fsp = file_new(conn); + if(!fsp) { + return NULL; } - - DEBUG(5,("open_directory: opening directory %s\n", fname)); /* * Setup the files_struct for it. @@ -1705,20 +2054,21 @@ files_struct *open_directory(connection_struct *conn, const char *fname, SMB_STR fsp->can_lock = True; fsp->can_read = False; fsp->can_write = False; - fsp->share_mode = share_mode; - fsp->desired_access = desired_access; + + fsp->share_access = share_access; + fsp->fh->private_options = create_options; + fsp->access_mask = access_mask; + fsp->print_file = False; fsp->modified = False; fsp->oplock_type = NO_OPLOCK; fsp->sent_oplock_break = NO_BREAK_SENT; fsp->is_directory = True; fsp->is_stat = False; - fsp->directory_delete_on_close = False; string_set(&fsp->fsp_name,fname); - if (delete_on_close) { - NTSTATUS status = set_delete_on_close_internal(fsp, delete_on_close, 0); - + if (create_options & FILE_DELETE_ON_CLOSE) { + NTSTATUS status = can_set_delete_on_close(fsp, True, 0); if (!NT_STATUS_IS_OK(status)) { file_free(fsp); return NULL; @@ -1726,10 +2076,14 @@ files_struct *open_directory(connection_struct *conn, const char *fname, SMB_STR } /* Change the owner if required. */ - if ((*action == FILE_WAS_CREATED) && lp_inherit_owner(SNUM(conn))) { + if ((info == FILE_WAS_CREATED) && lp_inherit_owner(SNUM(conn))) { change_owner_to_parent(conn, fsp, fsp->fsp_name, psbuf); } + if (pinfo) { + *pinfo = info; + } + conn->num_files_open++; return fsp; @@ -1739,7 +2093,8 @@ files_struct *open_directory(connection_struct *conn, const char *fname, SMB_STR Open a pseudo-file (no locking checks - a 'stat' open). ****************************************************************************/ -files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf) +files_struct *open_file_stat(connection_struct *conn, char *fname, + SMB_STRUCT_STAT *psbuf) { files_struct *fsp = NULL; @@ -1768,15 +2123,12 @@ files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_ST fsp->can_lock = False; fsp->can_read = False; fsp->can_write = False; - fsp->share_mode = 0; - fsp->desired_access = 0; fsp->print_file = False; fsp->modified = False; fsp->oplock_type = NO_OPLOCK; fsp->sent_oplock_break = NO_BREAK_SENT; fsp->is_directory = False; fsp->is_stat = True; - fsp->directory_delete_on_close = False; string_set(&fsp->fsp_name,fname); conn->num_files_open++; diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c index 9b8df98fd56..3cfce5c7a1f 100644 --- a/source/smbd/oplock.c +++ b/source/smbd/oplock.c @@ -343,6 +343,7 @@ BOOL process_local_message(char *buffer, int buf_size) SMB_INO_T inode; unsigned long file_id; uint16 break_cmd_type; + struct sockaddr_in toaddr; msg_len = IVAL(buffer,OPBRK_CMD_LEN_OFFSET); from_port = SVAL(buffer,OPBRK_CMD_PORT_OFFSET); @@ -366,6 +367,7 @@ BOOL process_local_message(char *buffer, int buf_size) } if (!koplocks->parse_message(msg_start, msg_len, &inode, &dev, &file_id)) { DEBUG(0,("kernel oplock break parse failure!\n")); + return False; } break; @@ -449,49 +451,54 @@ pid %d, port %d, dev = %x, inode = %.0f, file_id = %lu\n", * Now actually process the break request. */ - if((exclusive_oplocks_open + level_II_oplocks_open) != 0) { - if (oplock_break(dev, inode, file_id, False) == False) { - DEBUG(0,("process_local_message: oplock break failed.\n")); - return False; - } - } else { + if ((exclusive_oplocks_open == 0) && + (level_II_oplocks_open == 0)) { /* * If we have no record of any currently open oplocks, * it's not an error, as a close command may have * just been issued on the file that was oplocked. * Just log a message and return success in this case. */ - DEBUG(3,("process_local_message: oplock break requested with no outstanding \ -oplocks. Returning success.\n")); + DEBUG(3,("process_local_message: oplock break requested with " + "no outstanding oplocks. Returning success.\n")); + return True; + } + + if (!oplock_break(dev, inode, file_id, False)) { + DEBUG(0,("process_local_message: oplock break failed.\n")); + return False; } /* - * Do the appropriate reply - none in the kernel or async level II case. + * Do the appropriate reply - none in the kernel or async level II + * case. */ - if(break_cmd_type == OPLOCK_BREAK_CMD || break_cmd_type == LEVEL_II_OPLOCK_BREAK_CMD) { - struct sockaddr_in toaddr; - - /* Send the message back after OR'ing in the 'REPLY' bit. */ - SSVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET,break_cmd_type | CMD_REPLY); + if (!((break_cmd_type == OPLOCK_BREAK_CMD) || + (break_cmd_type == LEVEL_II_OPLOCK_BREAK_CMD))) { + return True; + } - memset((char *)&toaddr,'\0',sizeof(toaddr)); - toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - toaddr.sin_port = htons(from_port); - toaddr.sin_family = AF_INET; + /* Send the message back after OR'ing in the 'REPLY' bit. */ + SSVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET,break_cmd_type | CMD_REPLY); - if(sys_sendto( oplock_sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0, - (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) { - DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n", - (int)remotepid, strerror(errno))); - return False; - } + memset((char *)&toaddr,'\0',sizeof(toaddr)); + toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + toaddr.sin_port = htons(from_port); + toaddr.sin_family = AF_INET; - DEBUG(5,("process_local_message: oplock break reply sent to \ -pid %d, port %d, for file dev = %x, inode = %.0f, file_id = %lu\n", - (int)remotepid, from_port, (unsigned int)dev, (double)inode, file_id)); + if(sys_sendto( oplock_sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0, + (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) { + DEBUG(0,("process_local_message: sendto process %d failed. " + "Errno was %s\n", (int)remotepid, strerror(errno))); + return False; } + DEBUG(5,("process_local_message: oplock break reply sent to pid %d, " + "port %d, for file dev = %x, inode = %.0f, file_id = %lu\n", + (int)remotepid, from_port, (unsigned int)dev, + (double)inode, file_id)); + return True; } @@ -634,6 +641,7 @@ static BOOL oplock_break_level2(files_struct *fsp, BOOL local_request) /* Save the server smb signing state. */ sign_state = srv_oplock_set_signing(False); + show_msg(outbuf); if (!send_smb(smbd_server_fd(), outbuf)) exit_server("oplock_break_level2: send_smb failed."); @@ -677,7 +685,9 @@ static BOOL oplock_break_level2(files_struct *fsp, BOOL local_request) static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id, BOOL local_request) { char *inbuf = NULL; + char *saved_inbuf = NULL; char *outbuf = NULL; + char *saved_outbuf = NULL; files_struct *fsp = NULL; time_t start_time; BOOL shutdown_server = False; @@ -740,14 +750,15 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id, * messages crossing on the wire. */ - if((inbuf = (char *)SMB_MALLOC(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN))==NULL) { + if((inbuf = NewInBuffer(&saved_inbuf))==NULL) { DEBUG(0,("oplock_break: malloc fail for input buffer.\n")); return False; } - if((outbuf = (char *)SMB_MALLOC(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN))==NULL) { + if((outbuf = NewOutBuffer(&saved_outbuf))==NULL) { DEBUG(0,("oplock_break: malloc fail for output buffer.\n")); - SAFE_FREE(inbuf); + set_InBuffer(saved_inbuf); + free_InBuffer(inbuf); return False; } @@ -778,6 +789,7 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id, /* Save the server smb signing state. */ sign_state = srv_oplock_set_signing(False); + show_msg(outbuf); if (!send_smb(smbd_server_fd(), outbuf)) { srv_oplock_set_signing(sign_state); exit_server("oplock_break: send_smb failed."); @@ -823,11 +835,16 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id, * From Charles Hoch <hoch@exemplary.com>. If the break processing * code closes the file (as it often does), then the fsp pointer here * points to free()'d memory. We *must* revalidate fsp each time - * around the loop. + * around the loop. With async I/O, write calls may steal the global InBuffer, + * so ensure we're using the correct one each time around the loop. */ while((fsp = initial_break_processing(dev, inode, file_id)) && OPEN_FSP(fsp) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { + + inbuf = get_InBuffer(); + outbuf = get_OutBuffer(); + if(receive_smb(smbd_server_fd(),inbuf, timeout) == False) { /* * Die if we got an error. @@ -899,9 +916,13 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id, /* Restore the chain fnum. */ file_chain_restore(); + /* Restore the global In/Out buffers. */ + set_InBuffer(saved_inbuf); + set_OutBuffer(saved_outbuf); + /* Free the buffers we've been using to recurse. */ - SAFE_FREE(inbuf); - SAFE_FREE(outbuf); + free_InBuffer(inbuf); + free_OutBuffer(outbuf); /* We need this in case a readraw crossed on the wire. */ if(global_oplock_break) @@ -1136,7 +1157,7 @@ BOOL attempt_close_oplocked_file(files_struct *fsp) { DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name)); - if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !fsp->sent_oplock_break && (fsp->fd != -1)) { + if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !fsp->sent_oplock_break && (fsp->fh->fd != -1)) { /* Try and break the oplock. */ if (oplock_break(fsp->dev, fsp->inode, fsp->file_id, True)) { if(file_find_fsp(fsp) == NULL) /* Did the oplock break close the file ? */ @@ -1209,6 +1230,7 @@ void release_level_2_oplocks_on_change(files_struct *fsp) pid_t pid = sys_getpid(); int num_share_modes = 0; int i; + BOOL dummy; /* * If this file is level II oplocked then we need @@ -1225,7 +1247,8 @@ void release_level_2_oplocks_on_change(files_struct *fsp) DEBUG(0,("release_level_2_oplocks_on_change: failed to lock share mode entry for file %s.\n", fsp->fsp_name )); } - num_share_modes = get_share_modes(fsp->conn, fsp->dev, fsp->inode, &share_list); + num_share_modes = get_share_modes(fsp->dev, fsp->inode, &share_list, + &dummy); DEBUG(10,("release_level_2_oplocks_on_change: num_share_modes = %d\n", num_share_modes )); diff --git a/source/smbd/oplock_irix.c b/source/smbd/oplock_irix.c index ffcf3d0af4d..f4405a021e1 100644 --- a/source/smbd/oplock_irix.c +++ b/source/smbd/oplock_irix.c @@ -164,7 +164,7 @@ dev = %x, inode = %.0f\n, file_id = %ul", (unsigned int)fsp->dev, (double)fsp->i static BOOL irix_set_kernel_oplock(files_struct *fsp, int oplock_type) { - if (sys_fcntl_long(fsp->fd, F_OPLKREG, oplock_pipe_write) == -1) { + if (sys_fcntl_long(fsp->fh->fd, F_OPLKREG, oplock_pipe_write) == -1) { if(errno != EAGAIN) { DEBUG(0,("irix_set_kernel_oplock: Unable to get kernel oplock on file %s, dev = %x, \ inode = %.0f, file_id = %ul. Error was %s\n", @@ -173,7 +173,7 @@ inode = %.0f, file_id = %ul. Error was %s\n", } else { DEBUG(5,("irix_set_kernel_oplock: Refused oplock on file %s, fd = %d, dev = %x, \ inode = %.0f, file_id = %ul. Another process had the file open.\n", - fsp->fsp_name, fsp->fd, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id )); + fsp->fsp_name, fsp->fh->fd, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id )); } return False; } @@ -195,7 +195,7 @@ static void irix_release_kernel_oplock(files_struct *fsp) * Check and print out the current kernel * oplock state of this file. */ - int state = sys_fcntl_long(fsp->fd, F_OPLKACK, -1); + int state = sys_fcntl_long(fsp->fh->fd, F_OPLKACK, -1); dbgtext("irix_release_kernel_oplock: file %s, dev = %x, inode = %.0f file_id = %ul, has kernel \ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id, state ); @@ -204,7 +204,7 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev, /* * Remove the kernel oplock on this file. */ - if(sys_fcntl_long(fsp->fd, F_OPLKACK, OP_REVOKE) < 0) { + if(sys_fcntl_long(fsp->fh->fd, F_OPLKACK, OP_REVOKE) < 0) { if( DEBUGLVL( 0 )) { dbgtext("irix_release_kernel_oplock: Error when removing kernel oplock on file " ); dbgtext("%s, dev = %x, inode = %.0f, file_id = %ul. Error was %s\n", diff --git a/source/smbd/oplock_linux.c b/source/smbd/oplock_linux.c index 78dc260939e..477832c6e8e 100644 --- a/source/smbd/oplock_linux.c +++ b/source/smbd/oplock_linux.c @@ -179,10 +179,10 @@ dev = %x, inode = %.0f fd = %d, fileid = %lu \n", (unsigned int)fsp->dev, (doubl static BOOL linux_set_kernel_oplock(files_struct *fsp, int oplock_type) { - if (linux_setlease(fsp->fd, F_WRLCK) == -1) { + if (linux_setlease(fsp->fh->fd, F_WRLCK) == -1) { DEBUG(3,("linux_set_kernel_oplock: Refused oplock on file %s, fd = %d, dev = %x, \ inode = %.0f. (%s)\n", - fsp->fsp_name, fsp->fd, + fsp->fsp_name, fsp->fh->fd, (unsigned int)fsp->dev, (double)fsp->inode, strerror(errno))); return False; } @@ -204,7 +204,7 @@ static void linux_release_kernel_oplock(files_struct *fsp) * Check and print out the current kernel * oplock state of this file. */ - int state = fcntl(fsp->fd, F_GETLEASE, 0); + int state = fcntl(fsp->fh->fd, F_GETLEASE, 0); dbgtext("linux_release_kernel_oplock: file %s, dev = %x, inode = %.0f file_id = %lu has kernel \ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id, state ); @@ -213,7 +213,7 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev, /* * Remove the kernel oplock on this file. */ - if (linux_setlease(fsp->fd, F_UNLCK) == -1) { + if (linux_setlease(fsp->fh->fd, F_UNLCK) == -1) { if (DEBUGLVL(0)) { dbgtext("linux_release_kernel_oplock: Error when removing kernel oplock on file " ); dbgtext("%s, dev = %x, inode = %.0f, file_id = %lu. Error was %s\n", diff --git a/source/smbd/password.c b/source/smbd/password.c index 213ef98ea34..2ee8c1232e3 100644 --- a/source/smbd/password.c +++ b/source/smbd/password.c @@ -168,7 +168,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, vuser->n_groups = server_info->n_groups; if (vuser->n_groups) { - if (!(vuser->groups = memdup(server_info->groups, sizeof(gid_t) * vuser->n_groups))) { + if (!(vuser->groups = (gid_t *)memdup(server_info->groups, sizeof(gid_t) * vuser->n_groups))) { DEBUG(0,("register_vuid: failed to memdup vuser->groups\n")); data_blob_free(&session_key); free(vuser); @@ -316,7 +316,7 @@ void add_session_user(const char *user) DEBUG(3,("add_session_user: session userlist already too large.\n")); return; } - newlist = SMB_REALLOC( session_userlist, len_session_userlist + PSTRING_LEN ); + newlist = (char *)SMB_REALLOC( session_userlist, len_session_userlist + PSTRING_LEN ); if( newlist == NULL ) { DEBUG(1,("Unable to resize session_userlist\n")); return; diff --git a/source/smbd/pipes.c b/source/smbd/pipes.c index 6c7faa4c056..951c192e396 100644 --- a/source/smbd/pipes.c +++ b/source/smbd/pipes.c @@ -4,6 +4,7 @@ Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Luke Kenneth Casson Leighton 1996-1998 Copyright (C) Paul Ashton 1997-1998. + Copyright (C) Jeremy Allison 2005. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -33,11 +34,11 @@ extern struct pipe_id_info pipe_names[]; /**************************************************************************** - reply to an open and X on a named pipe - - This code is basically stolen from reply_open_and_X with some - wrinkles to handle pipes. + Reply to an open and X on a named pipe. + This code is basically stolen from reply_open_and_X with some + wrinkles to handle pipes. ****************************************************************************/ + int reply_open_pipe_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { @@ -45,7 +46,6 @@ int reply_open_pipe_and_X(connection_struct *conn, pstring pipe_name; uint16 vuid = SVAL(inbuf, smb_uid); smb_np_struct *p; - int smb_ofun = SVAL(inbuf,smb_vwv8); int size=0,fmode=0,mtime=0,rmode=0; int i; @@ -55,23 +55,26 @@ int reply_open_pipe_and_X(connection_struct *conn, /* If the name doesn't start \PIPE\ then this is directed */ /* 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 ) + if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 ) { return(ERROR_DOS(ERRSRV,ERRaccess)); + } DEBUG(4,("Opening pipe %s.\n", pipe_name)); /* See if it is one we want to handle. */ - for( i = 0; pipe_names[i].client_pipe ; i++ ) - if( strequal(pipe_name,pipe_names[i].client_pipe) ) + for( i = 0; pipe_names[i].client_pipe ; i++ ) { + if( strequal(pipe_name,pipe_names[i].client_pipe)) { break; + } + } - if (pipe_names[i].client_pipe == NULL) + if (pipe_names[i].client_pipe == NULL) { return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe)); + } /* Strip \PIPE\ off the name. */ pstrcpy(fname, pipe_name + PIPELEN); - #if 0 /* * Hack for NT printers... JRA. @@ -83,10 +86,11 @@ int reply_open_pipe_and_X(connection_struct *conn, /* Known pipes arrive with DIR attribs. Remove it so a regular file */ /* can be opened and add it in after the open. */ DEBUG(3,("Known pipe %s opening.\n",fname)); - smb_ofun |= FILE_CREATE_IF_NOT_EXIST; p = open_rpc_pipe_p(fname, conn, vuid); - if (!p) return(ERROR_DOS(ERRSRV,ERRnofids)); + if (!p) { + return(ERROR_DOS(ERRSRV,ERRnofids)); + } /* Prepare the reply */ set_message(outbuf,15,0,True); @@ -111,8 +115,9 @@ int reply_open_pipe_and_X(connection_struct *conn, } /**************************************************************************** - reply to a write on a pipe + Reply to a write on a pipe. ****************************************************************************/ + int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) { smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); @@ -121,25 +126,27 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) int outsize; char *data; - if (!p) + if (!p) { return(ERROR_DOS(ERRDOS,ERRbadfid)); + } data = smb_buf(inbuf) + 3; - if (numtowrite == 0) + if (numtowrite == 0) { nwritten = 0; - else + } else { nwritten = write_to_pipe(p, data, numtowrite); + } - if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) + if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) { return (UNIXERROR(ERRDOS,ERRnoaccess)); + } outsize = set_message(outbuf,1,0,True); SSVAL(outbuf,smb_vwv0,nwritten); - DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n", - p->pnum, nwritten)); + DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten)); return(outsize); } @@ -158,24 +165,25 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) int nwritten = -1; int smb_doff = SVAL(inbuf, smb_vwv11); BOOL pipe_start_message_raw = ((SVAL(inbuf, smb_vwv7) & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) == - (PIPE_START_MESSAGE|PIPE_RAW_MODE)); + (PIPE_START_MESSAGE|PIPE_RAW_MODE)); char *data; - if (!p) + if (!p) { return(ERROR_DOS(ERRDOS,ERRbadfid)); + } data = smb_base(inbuf) + smb_doff; - if (numtowrite == 0) + if (numtowrite == 0) { nwritten = 0; - else { + } else { if(pipe_start_message_raw) { /* * For the start of a message in named pipe byte mode, * the first two bytes are a length-of-pdu field. Ignore - * them (we don't trust the client. JRA. + * them (we don't trust the client). JRA. */ - if(numtowrite < 2) { + if(numtowrite < 2) { DEBUG(0,("reply_pipe_write_and_X: start of message set and not enough data sent.(%u)\n", (unsigned int)numtowrite )); return (UNIXERROR(ERRDOS,ERRnoaccess)); @@ -183,30 +191,30 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) data += 2; numtowrite -= 2; - } + } nwritten = write_to_pipe(p, data, numtowrite); } - if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) + if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) { return (UNIXERROR(ERRDOS,ERRnoaccess)); + } set_message(outbuf,6,0,True); nwritten = (pipe_start_message_raw ? nwritten + 2 : nwritten); SSVAL(outbuf,smb_vwv2,nwritten); - DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", - p->pnum, nwritten)); + DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten)); return chain_reply(inbuf,outbuf,length,bufsize); } /**************************************************************************** - reply to a read and X - - This code is basically stolen from reply_read_and_X with some - wrinkles to handle pipes. + Reply to a read and X. + This code is basically stolen from reply_read_and_X with some + wrinkles to handle pipes. ****************************************************************************/ + int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) { smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2); @@ -223,16 +231,18 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) uint32 smb_offs = IVAL(inbuf,smb_vwv3); #endif - if (!p) + if (!p) { return(ERROR_DOS(ERRDOS,ERRbadfid)); + } set_message(outbuf,12,0,True); data = smb_buf(outbuf); nread = read_from_pipe(p, data, smb_maxcnt, &unused); - if (nread < 0) + if (nread < 0) { return(UNIXERROR(ERRDOS,ERRnoaccess)); + } SSVAL(outbuf,smb_vwv5,nread); SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); @@ -247,20 +257,23 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) } /**************************************************************************** - reply to a close + Reply to a close. ****************************************************************************/ + int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) { smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); int outsize = set_message(outbuf,0,0,True); - if (!p) + if (!p) { return(ERROR_DOS(ERRDOS,ERRbadfid)); + } DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum)); - if (!close_rpc_pipe_hnd(p)) + if (!close_rpc_pipe_hnd(p)) { return ERROR_DOS(ERRDOS,ERRbadfid); + } return(outsize); } diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c index a3174440eff..ab14638a24c 100644 --- a/source/smbd/posix_acls.c +++ b/source/smbd/posix_acls.c @@ -84,7 +84,7 @@ struct pai_entry { }; struct pai_val { - BOOL protected; + BOOL pai_protected; unsigned int num_entries; struct pai_entry *entry_list; unsigned int num_def_entries; @@ -149,7 +149,7 @@ static unsigned int num_inherited_entries(canon_ace *ace_list) Create the on-disk format. Caller must free. ************************************************************************/ -static char *create_pai_buf(canon_ace *file_ace_list, canon_ace *dir_ace_list, BOOL protected, size_t *store_size) +static char *create_pai_buf(canon_ace *file_ace_list, canon_ace *dir_ace_list, BOOL pai_protected, size_t *store_size) { char *pai_buf = NULL; canon_ace *ace_list = NULL; @@ -177,7 +177,7 @@ static char *create_pai_buf(canon_ace *file_ace_list, canon_ace *dir_ace_list, B /* Set up the header. */ memset(pai_buf, '\0', PAI_ENTRIES_BASE); SCVAL(pai_buf,PAI_VERSION_OFFSET,PAI_VERSION); - SCVAL(pai_buf,PAI_FLAG_OFFSET,(protected ? PAI_ACL_FLAG_PROTECTED : 0)); + SCVAL(pai_buf,PAI_FLAG_OFFSET,(pai_protected ? PAI_ACL_FLAG_PROTECTED : 0)); SSVAL(pai_buf,PAI_NUM_ENTRIES_OFFSET,num_entries); SSVAL(pai_buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET,num_def_entries); @@ -213,7 +213,7 @@ static char *create_pai_buf(canon_ace *file_ace_list, canon_ace *dir_ace_list, B ************************************************************************/ static void store_inheritance_attributes(files_struct *fsp, canon_ace *file_ace_list, - canon_ace *dir_ace_list, BOOL protected) + canon_ace *dir_ace_list, BOOL pai_protected) { int ret; size_t store_size; @@ -227,19 +227,19 @@ static void store_inheritance_attributes(files_struct *fsp, canon_ace *file_ace_ * none of the entries in it are marked as inherited. */ - if (!protected && num_inherited_entries(file_ace_list) == 0 && num_inherited_entries(dir_ace_list) == 0) { + if (!pai_protected && num_inherited_entries(file_ace_list) == 0 && num_inherited_entries(dir_ace_list) == 0) { /* Instead just remove the attribute if it exists. */ - if (fsp->fd != -1) - SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, SAMBA_POSIX_INHERITANCE_EA_NAME); + if (fsp->fh->fd != -1) + SMB_VFS_FREMOVEXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME); else SMB_VFS_REMOVEXATTR(fsp->conn, fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME); return; } - pai_buf = create_pai_buf(file_ace_list, dir_ace_list, protected, &store_size); + pai_buf = create_pai_buf(file_ace_list, dir_ace_list, pai_protected, &store_size); - if (fsp->fd != -1) - ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, SAMBA_POSIX_INHERITANCE_EA_NAME, + if (fsp->fh->fd != -1) + ret = SMB_VFS_FSETXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME, pai_buf, store_size, 0); else ret = SMB_VFS_SETXATTR(fsp->conn,fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME, @@ -247,7 +247,7 @@ static void store_inheritance_attributes(files_struct *fsp, canon_ace *file_ace_ SAFE_FREE(pai_buf); - DEBUG(10,("store_inheritance_attribute:%s for file %s\n", protected ? " (protected)" : "", fsp->fsp_name)); + DEBUG(10,("store_inheritance_attribute:%s for file %s\n", pai_protected ? " (protected)" : "", fsp->fsp_name)); if (ret == -1 && !no_acl_syscall_error(errno)) DEBUG(1,("store_inheritance_attribute: Error %s\n", strerror(errno) )); } @@ -280,7 +280,7 @@ static BOOL get_protected_flag(struct pai_val *pal) { if (!pal) return False; - return pal->protected; + return pal->pai_protected; } /************************************************************************ @@ -352,7 +352,7 @@ static struct pai_val *create_pai_val(char *buf, size_t size) memset(paiv, '\0', sizeof(struct pai_val)); - paiv->protected = (CVAL(buf,PAI_FLAG_OFFSET) == PAI_ACL_FLAG_PROTECTED); + paiv->pai_protected = (CVAL(buf,PAI_FLAG_OFFSET) == PAI_ACL_FLAG_PROTECTED); paiv->num_entries = SVAL(buf,PAI_NUM_ENTRIES_OFFSET); paiv->num_def_entries = SVAL(buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET); @@ -360,7 +360,7 @@ static struct pai_val *create_pai_val(char *buf, size_t size) entry_offset = buf + PAI_ENTRIES_BASE; DEBUG(10,("create_pai_val:%s num_entries = %u, num_def_entries = %u\n", - paiv->protected ? " (protected)" : "", paiv->num_entries, paiv->num_def_entries )); + paiv->pai_protected ? " (pai_protected)" : "", paiv->num_entries, paiv->num_def_entries )); for (i = 0; i < paiv->num_entries; i++) { struct pai_entry *paie; @@ -445,8 +445,8 @@ static struct pai_val *load_inherited_info(files_struct *fsp) return NULL; do { - if (fsp->fd != -1) - ret = SMB_VFS_FGETXATTR(fsp, fsp->fd, SAMBA_POSIX_INHERITANCE_EA_NAME, + if (fsp->fh->fd != -1) + ret = SMB_VFS_FGETXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME, pai_buf, pai_buf_size); else ret = SMB_VFS_GETXATTR(fsp->conn,fsp->fsp_name,SAMBA_POSIX_INHERITANCE_EA_NAME, @@ -484,7 +484,7 @@ static struct pai_val *load_inherited_info(files_struct *fsp) paiv = create_pai_val(pai_buf, ret); - if (paiv && paiv->protected) + if (paiv && paiv->pai_protected) DEBUG(10,("load_inherited_info: ACL is protected for file %s\n", fsp->fsp_name)); SAFE_FREE(pai_buf); @@ -801,14 +801,14 @@ static BOOL nt4_compatible_acls(void) not get. Deny entries are implicit on get with ace->perms = 0. ****************************************************************************/ -static SEC_ACCESS map_canon_ace_perms(int *pacl_type, DOM_SID *powner_sid, canon_ace *ace, BOOL directory_ace) +static SEC_ACCESS map_canon_ace_perms(int snum, int *pacl_type, DOM_SID *powner_sid, canon_ace *ace, BOOL directory_ace) { SEC_ACCESS sa; uint32 nt_mask = 0; *pacl_type = SEC_ACE_TYPE_ACCESS_ALLOWED; - if ((ace->perms & ALL_ACE_PERMS) == ALL_ACE_PERMS) { + if (lp_acl_map_full_control(snum) && ((ace->perms & ALL_ACE_PERMS) == ALL_ACE_PERMS)) { if (directory_ace) { nt_mask = UNIX_DIRECTORY_ACCESS_RWX; } else { @@ -2422,7 +2422,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau * Finally apply it to the file or directory. */ - if(default_ace || fsp->is_directory || fsp->fd == -1) { + if(default_ace || fsp->is_directory || fsp->fh->fd == -1) { if (SMB_VFS_SYS_ACL_SET_FILE(conn, fsp->fsp_name, the_acl_type, the_acl) == -1) { /* * Some systems allow all the above calls and only fail with no ACL support @@ -2438,7 +2438,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau goto done; } } else { - if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fd, the_acl) == -1) { + if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fh->fd, the_acl) == -1) { /* * Some systems allow all the above calls and only fail with no ACL support * when attempting to apply the acl. HPUX with HFS is an example of this. JRA. @@ -2668,7 +2668,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) DEBUG(10,("get_nt_acl: called for file %s\n", fsp->fsp_name )); - if(fsp->is_directory || fsp->fd == -1) { + if(fsp->is_directory || fsp->fh->fd == -1) { /* Get the stat struct for the owner info. */ if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) { @@ -2692,13 +2692,13 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) } else { /* Get the stat struct for the owner info. */ - if(SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) { + if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) { return 0; } /* * Get the ACL from the fd. */ - posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd); + posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd); } DEBUG(5,("get_nt_acl : file ACL %s, directory ACL %s\n", @@ -2711,7 +2711,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) * Get the owner, group and world SIDs. */ - if (lp_profile_acls(SNUM(fsp->conn))) { + if (lp_profile_acls(SNUM(conn))) { /* For WXP SP1 the owner must be administrators. */ sid_copy(&owner_sid, &global_sid_Builtin_Administrators); sid_copy(&group_sid, &global_sid_Builtin_Users); @@ -2825,12 +2825,12 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) for (i = 0; i < num_acls; i++, ace = ace->next) { SEC_ACCESS acc; - acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace, fsp->is_directory); + acc = map_canon_ace_perms(SNUM(conn), &nt_acl_type, &owner_sid, ace, fsp->is_directory); init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, ace->inherited ? SEC_ACE_FLAG_INHERITED_ACE : 0); } /* The User must have access to a profile share - even if we can't map the SID. */ - if (lp_profile_acls(SNUM(fsp->conn))) { + if (lp_profile_acls(SNUM(conn))) { SEC_ACCESS acc; init_sec_access(&acc,FILE_GENERIC_ALL); @@ -2843,7 +2843,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) for (i = 0; i < num_def_acls; i++, ace = ace->next) { SEC_ACCESS acc; - acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace, fsp->is_directory); + acc = map_canon_ace_perms(SNUM(conn), &nt_acl_type, &owner_sid, ace, fsp->is_directory); init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT| SEC_ACE_FLAG_INHERIT_ONLY| @@ -2851,7 +2851,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) } /* The User must have access to a profile share - even if we can't map the SID. */ - if (lp_profile_acls(SNUM(fsp->conn))) { + if (lp_profile_acls(SNUM(conn))) { SEC_ACCESS acc; init_sec_access(&acc,FILE_GENERIC_ALL); @@ -2981,7 +2981,7 @@ static int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_ become_root(); /* Keep the current file gid the same. */ - ret = SMB_VFS_FCHOWN(fsp, fsp->fd, uid, (gid_t)-1); + ret = SMB_VFS_FCHOWN(fsp, fsp->fh->fd, uid, (gid_t)-1); unbecome_root(); close_file_fchmod(fsp); @@ -3022,11 +3022,11 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) * Get the current state of the file. */ - if(fsp->is_directory || fsp->fd == -1) { + if(fsp->is_directory || fsp->fh->fd == -1) { if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) return False; } else { - if(SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) + if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) return False; } @@ -3081,10 +3081,10 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) int ret; - if(fsp->fd == -1) + if(fsp->fh->fd == -1) ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf); else - ret = SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf); + ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf); if(ret != 0) return False; @@ -3683,8 +3683,8 @@ static BOOL remove_posix_acl(connection_struct *conn, files_struct *fsp, const c } /* Get the current file ACL. */ - if (fsp && fsp->fd != -1) { - file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd); + if (fsp && fsp->fh->fd != -1) { + file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd); } else { file_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_ACCESS); } @@ -3767,9 +3767,9 @@ BOOL set_unix_posix_acl(connection_struct *conn, files_struct *fsp, const char * return False; } - if (fsp && fsp->fd != -1) { + if (fsp && fsp->fh->fd != -1) { /* The preferred way - use an open fd. */ - if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fd, file_acl) == -1) { + if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fh->fd, file_acl) == -1) { DEBUG(5,("set_unix_posix_acl: acl_set_file failed on %s (%s)\n", fname, strerror(errno) )); SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); diff --git a/source/smbd/process.c b/source/smbd/process.c index 0373cd471c9..94d4b8d9032 100644 --- a/source/smbd/process.c +++ b/source/smbd/process.c @@ -28,8 +28,7 @@ extern int smb_echo_count; struct timeval smb_last_time; static char *InBuffer = NULL; -char *OutBuffer = NULL; -char *last_inbuf = NULL; +static char *OutBuffer = NULL; /* * Size of data we can send to client. Set @@ -87,7 +86,7 @@ static void free_queued_message(struct pending_message_list *msg) for processing. ****************************************************************************/ -static BOOL push_queued_message(enum q_type qt, char *buf, int msg_len, struct timeval *ptv, char *private, size_t private_len) +static BOOL push_queued_message(enum q_type qt, char *buf, int msg_len, struct timeval *ptv, char *private_data, size_t private_len) { struct pending_message_list *tmp_msg; struct pending_message_list *msg = SMB_MALLOC_P(struct pending_message_list); @@ -110,8 +109,8 @@ static BOOL push_queued_message(enum q_type qt, char *buf, int msg_len, struct t msg->msg_time = *ptv; } - if (private) { - msg->private_data = data_blob(private, private_len); + if (private_data) { + msg->private_data = data_blob(private_data, private_len); if (msg->private_data.data == NULL) { DEBUG(0,("push_message: malloc fail (3)\n")); data_blob_free(&msg->buf); @@ -249,7 +248,7 @@ struct pending_message_list *get_open_deferred_message(uint16 mid) for processing. ****************************************************************************/ -BOOL push_sharing_violation_open_smb_message(struct timeval *ptv, char *private, size_t priv_len) +BOOL push_sharing_violation_open_smb_message(struct timeval *ptv, char *private_data, size_t priv_len) { uint16 mid = SVAL(InBuffer,smb_mid); struct timeval tv; @@ -275,7 +274,7 @@ BOOL push_sharing_violation_open_smb_message(struct timeval *ptv, char *private, (unsigned int)tv.tv_sec, (unsigned int)tv.tv_usec)); return push_queued_message(SHARE_VIOLATION_QUEUE, InBuffer, - smb_len(InBuffer)+4, &tv, private, priv_len); + smb_len(InBuffer)+4, &tv, private_data, priv_len); } /**************************************************************************** @@ -287,11 +286,17 @@ static void async_processing(char *buffer, int buffer_len) { DEBUG(10,("async_processing: Doing async processing.\n")); + process_aio_queue(); + /* check for oplock messages (both UDP and kernel) */ if (receive_local_message(buffer, buffer_len, 1)) { process_local_message(buffer, buffer_len); } + /* Do the aio check again after receive_local_message as it does a select + and may have eaten our signal. */ + process_aio_queue(); + if (got_sig_term) { exit_server("Caught TERM signal"); } @@ -981,8 +986,6 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1)))) return(ERROR_DOS(ERRSRV,ERRaccess)); - last_inbuf = inbuf; - outsize = smb_messages[type].fn(conn, inbuf,outbuf,size,bufsize); } @@ -1299,6 +1302,7 @@ static int setup_select_timeout(void) void check_reload(int t) { + static pid_t mypid = 0; static time_t last_smb_conf_reload_time = 0; static time_t last_printer_reload_time = 0; time_t printcap_cache_time = (time_t)lp_printcap_cache_time(); @@ -1314,6 +1318,15 @@ void check_reload(int t) last_printer_reload_time = t; } + if (mypid != getpid()) { /* First time or fork happened meanwhile */ + /* randomize over 60 second the printcap reload to avoid all + * process hitting cupsd at the same time */ + int time_range = 60; + + last_printer_reload_time += random() % time_range; + mypid = getpid(); + } + if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) { reload_services(True); reload_after_sighup = False; @@ -1501,24 +1514,106 @@ machine %s in domain %s.\n", global_myname(), lp_workgroup())); } /**************************************************************************** - process commands from the client + Accessor functions for InBuffer, OutBuffer. ****************************************************************************/ -void smbd_process(void) +char *get_InBuffer(void) { - time_t last_timeout_processing_time = time(NULL); - unsigned int num_smbs = 0; - const size_t total_buffer_size = BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN; + return InBuffer; +} - InBuffer = (char *)SMB_MALLOC(total_buffer_size); - OutBuffer = (char *)SMB_MALLOC(total_buffer_size); - if ((InBuffer == NULL) || (OutBuffer == NULL)) - return; +void set_InBuffer(char *new_inbuf) +{ + InBuffer = new_inbuf; +} + +char *get_OutBuffer(void) +{ + return OutBuffer; +} + +void set_OutBuffer(char *new_outbuf) +{ + OutBuffer = new_outbuf; +} + +/**************************************************************************** + Free an InBuffer. Checks if not in use by aio system. + Must have been allocated by NewInBuffer. +****************************************************************************/ + +void free_InBuffer(char *inbuf) +{ + if (!aio_inbuffer_in_use(inbuf)) { + SAFE_FREE(inbuf); + } +} + +/**************************************************************************** + Free an OutBuffer. No outbuffers currently stolen by aio system. + Must have been allocated by NewInBuffer. +****************************************************************************/ + +void free_OutBuffer(char *outbuf) +{ + SAFE_FREE(outbuf); +} +const int total_buffer_size = (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN); + +/**************************************************************************** + Allocate a new InBuffer. Returns the new and old ones. +****************************************************************************/ + +char *NewInBuffer(char **old_inbuf) +{ + char *new_inbuf = (char *)SMB_MALLOC(total_buffer_size); + if (!new_inbuf) { + return NULL; + } + if (old_inbuf) { + *old_inbuf = InBuffer; + } + InBuffer = new_inbuf; #if defined(DEVELOPER) clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size); +#endif + return InBuffer; +} + +/**************************************************************************** + Allocate a new OutBuffer. Returns the new and old ones. +****************************************************************************/ + +char *NewOutBuffer(char **old_outbuf) +{ + char *new_outbuf = (char *)SMB_MALLOC(total_buffer_size); + if (!new_outbuf) { + return NULL; + } + if (old_outbuf) { + *old_outbuf = OutBuffer; + } + OutBuffer = new_outbuf; +#if defined(DEVELOPER) clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, OutBuffer, total_buffer_size); #endif + return OutBuffer; +} + +/**************************************************************************** + Process commands from the client +****************************************************************************/ + +void smbd_process(void) +{ + time_t last_timeout_processing_time = time(NULL); + unsigned int num_smbs = 0; + + /* Allocate the primary Inbut/Output buffers. */ + + if ((NewInBuffer(NULL) == NULL) || (NewOutBuffer(NULL) == NULL)) + return; max_recv = MIN(lp_maxxmit(),BUFFER_SIZE); diff --git a/source/smbd/reply.c b/source/smbd/reply.c index d49823bea5c..5e8c0ef296d 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -398,7 +398,9 @@ size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len } else { ret = srvstr_pull( inbuf, tmppath_ptr, src, dest_len, src_len, flags); } - if (allow_wcard_names) { + if (lp_posix_pathnames()) { + *err = check_path_syntax_posix(dest, tmppath); + } else if (allow_wcard_names) { *err = check_path_syntax_wcard(dest, tmppath); } else { *err = check_path_syntax(dest, tmppath); @@ -1012,9 +1014,9 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size pstring directory; pstring fname; SMB_OFF_T size; - int mode; + uint32 mode; time_t date; - int dirtype; + uint32 dirtype; int outsize = 0; unsigned int numentries = 0; unsigned int maxentries = 0; @@ -1032,6 +1034,10 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size NTSTATUS nt_status; BOOL allow_long_path_components = (SVAL(inbuf,smb_flg2) & FLAGS2_LONG_PATH_COMPONENTS) ? True : False; + if (lp_posix_pathnames()) { + return reply_unknown(inbuf, outbuf); + } + START_PROFILE(SMBsearch); *mask = *directory = *fname = 0; @@ -1109,7 +1115,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size ok = True; if (status_len == 0) { - dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid)); + dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid), mask, dirtype); if (dptr_num < 0) { if(dptr_num == -2) { END_PROFILE(SMBsearch); @@ -1118,10 +1124,6 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size END_PROFILE(SMBsearch); return ERROR_DOS(ERRDOS,ERRnofids); } - if (!dptr_set_wcard_and_attributes(dptr_num, mask, dirtype)) { - END_PROFILE(SMBsearch); - return ERROR_DOS(ERRDOS,ERRnomem); - } } else { dirtype = dptr_attr(dptr_num); } @@ -1228,6 +1230,10 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size char *p; NTSTATUS err; + if (lp_posix_pathnames()) { + return reply_unknown(inbuf, outbuf); + } + START_PROFILE(SMBfclose); outsize = set_message(outbuf,1,0,True); @@ -1269,20 +1275,24 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, { pstring fname; int outsize = 0; - int fmode=0; - int share_mode; + uint32 fattr=0; SMB_OFF_T size = 0; time_t mtime=0; - int rmode=0; + int info; SMB_STRUCT_STAT sbuf; BOOL bad_path = False; files_struct *fsp; int oplock_request = CORE_OPLOCK_REQUEST(inbuf); - uint16 dos_attr = SVAL(inbuf,smb_vwv1); + int deny_mode; + uint32 dos_attr = SVAL(inbuf,smb_vwv1); + uint32 access_mask; + uint32 share_mode; + uint32 create_disposition; + uint32 create_options = 0; NTSTATUS status; START_PROFILE(SMBopen); - share_mode = SVAL(inbuf,smb_vwv0); + deny_mode = SVAL(inbuf,smb_vwv0); srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status, False); if (!NT_STATUS_IS_OK(status)) { @@ -1298,8 +1308,20 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); } - fsp = open_file_shared(conn,fname,&sbuf,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), - (uint32)dos_attr, oplock_request,&rmode,NULL); + if (!map_open_params_to_ntcreate(fname, deny_mode, OPENX_FILE_EXISTS_OPEN, + &access_mask, &share_mode, &create_disposition, &create_options)) { + END_PROFILE(SMBopen); + return ERROR_DOS(ERRDOS, ERRbadaccess); + } + + fsp = open_file_ntcreate(conn,fname,&sbuf, + access_mask, + share_mode, + create_disposition, + create_options, + dos_attr, + oplock_request, + &info); if (!fsp) { END_PROFILE(SMBopen); @@ -1311,10 +1333,10 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, } size = sbuf.st_size; - fmode = dos_mode(conn,fname,&sbuf); + fattr = dos_mode(conn,fname,&sbuf); mtime = sbuf.st_mtime; - if (fmode & aDIR) { + if (fattr & aDIR) { DEBUG(3,("attempt to open a directory %s\n",fname)); close_file(fsp,False); END_PROFILE(SMBopen); @@ -1323,19 +1345,22 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, outsize = set_message(outbuf,7,0,True); SSVAL(outbuf,smb_vwv0,fsp->fnum); - SSVAL(outbuf,smb_vwv1,fmode); - if(lp_dos_filetime_resolution(SNUM(conn)) ) + SSVAL(outbuf,smb_vwv1,fattr); + if(lp_dos_filetime_resolution(SNUM(conn)) ) { put_dos_date3(outbuf,smb_vwv2,mtime & ~1); - else + } else { put_dos_date3(outbuf,smb_vwv2,mtime); + } SIVAL(outbuf,smb_vwv4,(uint32)size); - SSVAL(outbuf,smb_vwv6,rmode); + SSVAL(outbuf,smb_vwv6,FILE_WAS_OPENED); - if (oplock_request && lp_fake_oplocks(SNUM(conn))) + if (oplock_request && lp_fake_oplocks(SNUM(conn))) { SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED); + } - if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) + if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED); + } END_PROFILE(SMBopen); return(outsize); } @@ -1347,21 +1372,22 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { pstring fname; - int smb_mode = SVAL(inbuf,smb_vwv3); - int smb_attr = SVAL(inbuf,smb_vwv5); + uint16 open_flags = SVAL(inbuf,smb_vwv2); + int deny_mode = SVAL(inbuf,smb_vwv3); + uint32 smb_attr = SVAL(inbuf,smb_vwv5); /* Breakout the oplock request bits so we can set the reply bits separately. */ BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf); BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf); BOOL oplock_request = ex_oplock_request | core_oplock_request; #if 0 - int open_flags = SVAL(inbuf,smb_vwv2); int smb_sattr = SVAL(inbuf,smb_vwv4); uint32 smb_time = make_unix_date3(inbuf+smb_vwv6); #endif int smb_ofun = SVAL(inbuf,smb_vwv8); SMB_OFF_T size=0; - int fmode=0,mtime=0,rmode=0; + uint32 fattr=0; + int mtime=0; SMB_STRUCT_STAT sbuf; int smb_action = 0; BOOL bad_path = False; @@ -1369,6 +1395,10 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt NTSTATUS status; SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv9); ssize_t retval = -1; + uint32 access_mask; + uint32 share_mode; + uint32 create_disposition; + uint32 create_options = 0; START_PROFILE(SMBopenX); @@ -1398,18 +1428,23 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); } - /* Strange open mode mapping. */ - if (smb_ofun == 0) { - if (GET_OPEN_MODE(smb_mode) == DOS_OPEN_EXEC) { - smb_ofun = FILE_EXISTS_FAIL | FILE_CREATE_IF_NOT_EXIST; - } else { - END_PROFILE(SMBopenX); - return ERROR_FORCE_DOS(ERRDOS, ERRbadaccess); - } + if (!map_open_params_to_ntcreate(fname, deny_mode, smb_ofun, + &access_mask, + &share_mode, + &create_disposition, + &create_options)) { + END_PROFILE(SMBopenX); + return ERROR_DOS(ERRDOS, ERRbadaccess); } - fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,(uint32)smb_attr, - oplock_request, &rmode,&smb_action); + fsp = open_file_ntcreate(conn,fname,&sbuf, + access_mask, + share_mode, + create_disposition, + create_options, + smb_attr, + oplock_request, + &smb_action); if (!fsp) { END_PROFILE(SMBopenX); @@ -1440,9 +1475,9 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt size = get_allocation_size(conn,fsp,&sbuf); } - fmode = dos_mode(conn,fname,&sbuf); + fattr = dos_mode(conn,fname,&sbuf); mtime = sbuf.st_mtime; - if (fmode & aDIR) { + if (fattr & aDIR) { close_file(fsp,False); END_PROFILE(SMBopenX); return ERROR_DOS(ERRDOS,ERRnoaccess); @@ -1453,34 +1488,47 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt correct bit for extended oplock reply. */ - if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) + if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) { smb_action |= EXTENDED_OPLOCK_GRANTED; + } - if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) + if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { smb_action |= EXTENDED_OPLOCK_GRANTED; + } /* If the caller set the core oplock request bit and we granted one (by whatever means) - set the correct bit for core oplock reply. */ - if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) + if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) { SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED); + } - if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) + if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED); + } - set_message(outbuf,15,0,True); + if (open_flags & EXTENDED_RESPONSE_REQUIRED) { + set_message(outbuf,19,0,True); + } else { + set_message(outbuf,15,0,True); + } SSVAL(outbuf,smb_vwv2,fsp->fnum); - SSVAL(outbuf,smb_vwv3,fmode); - if(lp_dos_filetime_resolution(SNUM(conn)) ) + SSVAL(outbuf,smb_vwv3,fattr); + if(lp_dos_filetime_resolution(SNUM(conn)) ) { put_dos_date3(outbuf,smb_vwv4,mtime & ~1); - else + } else { put_dos_date3(outbuf,smb_vwv4,mtime); + } SIVAL(outbuf,smb_vwv6,(uint32)size); - SSVAL(outbuf,smb_vwv8,rmode); + SSVAL(outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode)); SSVAL(outbuf,smb_vwv11,smb_action); + if (open_flags & EXTENDED_RESPONSE_REQUIRED) { + SIVAL(outbuf, smb_vwv15, STD_RIGHT_ALL_ACCESS); + } + END_PROFILE(SMBopenX); return chain_reply(inbuf,outbuf,length,bufsize); } @@ -1522,18 +1570,21 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, pstring fname; int com; int outsize = 0; - int createmode; - int ofun = 0; + uint32 fattr = SVAL(inbuf,smb_vwv0); BOOL bad_path = False; files_struct *fsp; int oplock_request = CORE_OPLOCK_REQUEST(inbuf); SMB_STRUCT_STAT sbuf; NTSTATUS status; + uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE; + uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE; + uint32 create_disposition; + uint32 create_options = 0; + START_PROFILE(SMBcreate); com = SVAL(inbuf,smb_com); - createmode = SVAL(inbuf,smb_vwv0); srvstr_get_path(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), 0, STR_TERMINATE, &status, False); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBcreate); @@ -1548,20 +1599,27 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); } - if (createmode & aVOLID) + if (fattr & aVOLID) { DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname)); - + } + if(com == SMBmknew) { /* We should fail if file exists. */ - ofun = FILE_CREATE_IF_NOT_EXIST; + create_disposition = FILE_CREATE; } else { - /* SMBcreate - Create if file doesn't exist, truncate if it does. */ - ofun = FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE; - } - - /* Open file in dos compatibility share mode. */ - fsp = open_file_shared(conn,fname,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB), - ofun, (uint32)createmode, oplock_request, NULL, NULL); + /* Create if file doesn't exist, truncate if it does. */ + create_disposition = FILE_OPEN_IF; + } + + /* Open file using ntcreate. */ + fsp = open_file_ntcreate(conn,fname,&sbuf, + access_mask, + share_mode, + create_disposition, + create_options, + fattr, + oplock_request, + NULL); if (!fsp) { END_PROFILE(SMBcreate); @@ -1575,14 +1633,16 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, outsize = set_message(outbuf,1,0,True); SSVAL(outbuf,smb_vwv0,fsp->fnum); - if (oplock_request && lp_fake_oplocks(SNUM(conn))) + if (oplock_request && lp_fake_oplocks(SNUM(conn))) { SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED); + } - if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) + if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED); + } - DEBUG( 2, ( "new file %s\n", fname ) ); - DEBUG( 3, ( "mknew %s fd=%d dmode=%d\n", fname, fsp->fd, createmode ) ); + DEBUG( 2, ( "reply_mknew: file %s\n", fname ) ); + DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n", fname, fsp->fh->fd, (unsigned int)fattr ) ); END_PROFILE(SMBcreate); return(outsize); @@ -1596,7 +1656,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, { pstring fname; int outsize = 0; - int createattr; + uint32 fattr = SVAL(inbuf,smb_vwv0); BOOL bad_path = False; files_struct *fsp; int oplock_request = CORE_OPLOCK_REQUEST(inbuf); @@ -1608,7 +1668,6 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, START_PROFILE(SMBctemp); - createattr = SVAL(inbuf,smb_vwv0); srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status, False); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBctemp); @@ -1636,12 +1695,15 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, SMB_VFS_STAT(conn,fname,&sbuf); - /* Open file in dos compatibility share mode. */ /* We should fail if file does not exist. */ - fsp = open_file_shared(conn,fname,&sbuf, - SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB), - FILE_EXISTS_OPEN|FILE_FAIL_IF_NOT_EXIST, - (uint32)createattr, oplock_request, NULL, NULL); + fsp = open_file_ntcreate(conn,fname,&sbuf, + FILE_GENERIC_READ | FILE_GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, + 0, + fattr, + oplock_request, + NULL); /* close fd from smb_mkstemp() */ close(tmpfd); @@ -1660,10 +1722,11 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, /* the returned filename is relative to the directory */ s = strrchr_m(fname, '/'); - if (!s) + if (!s) { s = fname; - else + } else { s++; + } p = smb_buf(outbuf); #if 0 @@ -1675,15 +1738,17 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, p += namelen; outsize = set_message_end(outbuf, p); - if (oplock_request && lp_fake_oplocks(SNUM(conn))) + if (oplock_request && lp_fake_oplocks(SNUM(conn))) { SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED); + } - if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) + if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED); + } - DEBUG( 2, ( "created temp file %s\n", fname ) ); - DEBUG( 3, ( "ctemp %s fd=%d umode=%o\n", - fname, fsp->fd, sbuf.st_mode ) ); + DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fname ) ); + DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fname, fsp->fh->fd, + (unsigned int)sbuf.st_mode ) ); END_PROFILE(SMBctemp); return(outsize); @@ -1695,26 +1760,33 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype, SMB_STRUCT_STAT *pst) { - int smb_action; - int access_mode; files_struct *fsp; - uint16 fmode; + uint32 fmode; - if (!CAN_WRITE(conn)) + if (!CAN_WRITE(conn)) { return NT_STATUS_MEDIA_WRITE_PROTECTED; + } fmode = dos_mode(conn,fname,pst); - if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) + if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) { return NT_STATUS_NO_SUCH_FILE; + } - if (S_ISDIR(pst->st_mode)) + if (S_ISDIR(pst->st_mode)) { return NT_STATUS_OK; + } /* We need a better way to return NT status codes from open... */ set_saved_error_triple(0, 0, NT_STATUS_OK); - fsp = open_file_shared1(conn, fname, pst, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL), - (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action); + fsp = open_file_ntcreate(conn, fname, pst, + DELETE_ACCESS, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, + 0, + FILE_ATTRIBUTE_NORMAL, + 0, + NULL); if (!fsp) { NTSTATUS ret; @@ -1733,46 +1805,49 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype, Check if a user is allowed to delete a file. ********************************************************************/ -NTSTATUS can_delete(connection_struct *conn, char *fname, int dirtype, BOOL bad_path, BOOL check_is_at_open) +NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL bad_path, BOOL check_is_at_open) { SMB_STRUCT_STAT sbuf; - int fmode; - int smb_action; - int access_mode; + uint32 fattr; files_struct *fsp; - DEBUG(10,("can_delete: %s, dirtype = %d\n", - fname, dirtype )); + DEBUG(10,("can_delete: %s, dirtype = %d\n", fname, dirtype )); - if (!CAN_WRITE(conn)) + if (!CAN_WRITE(conn)) { return NT_STATUS_MEDIA_WRITE_PROTECTED; + } if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) { if(errno == ENOENT) { - if (bad_path) + if (bad_path) { return NT_STATUS_OBJECT_PATH_NOT_FOUND; - else + } else { return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } } return map_nt_error_from_unix(errno); } - fmode = dos_mode(conn,fname,&sbuf); + fattr = dos_mode(conn,fname,&sbuf); /* Can't delete a directory. */ - if (fmode & aDIR) + if (fattr & aDIR) { return NT_STATUS_FILE_IS_A_DIRECTORY; + } + #if 0 /* JRATEST */ else if (dirtype & aDIR) /* Asked for a directory and it isn't. */ return NT_STATUS_OBJECT_NAME_INVALID; #endif /* JRATEST */ if (!lp_delete_readonly(SNUM(conn))) { - if (fmode & aRONLY) + if (fattr & aRONLY) { return NT_STATUS_CANNOT_DELETE; + } } - if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) + if ((fattr & ~dirtype) & (aHIDDEN | aSYSTEM)) { return NT_STATUS_NO_SUCH_FILE; + } if (check_is_at_open) { if (!can_delete_file_in_directory(conn, fname)) { @@ -1785,8 +1860,14 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, int dirtype, BOOL bad_ /* We need a better way to return NT status codes from open... */ set_saved_error_triple(0, 0, NT_STATUS_OK); - fsp = open_file_shared1(conn, fname, &sbuf, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL), - (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action); + fsp = open_file_ntcreate(conn, fname, &sbuf, + DELETE_ACCESS, + FILE_SHARE_NONE, + FILE_OPEN, + 0, + FILE_ATTRIBUTE_NORMAL, + 0, + NULL); if (!fsp) { NTSTATUS ret; @@ -1807,7 +1888,7 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, int dirtype, BOOL bad_ code. ****************************************************************************/ -NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name) +NTSTATUS unlink_internals(connection_struct *conn, uint32 dirtype, char *name) { pstring directory; pstring mask; @@ -1869,8 +1950,11 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name) struct smb_Dir *dir_hnd = NULL; const char *dname; + if (strequal(mask,"????????.???")) + pstrcpy(mask,"*"); + if (check_name(directory,conn)) - dir_hnd = OpenDir(conn, directory); + dir_hnd = OpenDir(conn, directory, mask, dirtype); /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then the pattern matches against the long name, otherwise the short name @@ -1881,9 +1965,6 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name) long offset = 0; error = NT_STATUS_NO_SUCH_FILE; - if (strequal(mask,"????????.???")) - pstrcpy(mask,"*"); - while ((dname = ReadDirName(dir_hnd, &offset))) { SMB_STRUCT_STAT st; pstring fname; @@ -1944,7 +2025,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size { int outsize = 0; pstring name; - int dirtype; + uint32 dirtype; NTSTATUS status; START_PROFILE(SMBunlink); @@ -2052,7 +2133,7 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st header.length = 4; header.free = NULL; - if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) { + if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, nread) == -1) { /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */ if (errno == ENOSYS) { goto normal_readbraw; @@ -2199,7 +2280,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s SMB_STRUCT_STAT st; SMB_OFF_T size = 0; - if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0) { + if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st) == 0) { size = st.st_size; } @@ -2245,7 +2326,9 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length START_PROFILE(SMBlockread); CHECK_FSP(fsp,conn); - CHECK_READ(fsp); + if (!CHECK_READ(fsp,inbuf)) { + return(ERROR_DOS(ERRDOS,ERRbadaccess)); + } release_level_2_oplocks_on_change(fsp); @@ -2339,7 +2422,9 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int START_PROFILE(SMBread); CHECK_FSP(fsp,conn); - CHECK_READ(fsp); + if (!CHECK_READ(fsp,inbuf)) { + return(ERROR_DOS(ERRDOS,ERRbadaccess)); + } numtoread = SVAL(inbuf,smb_vwv1); startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); @@ -2407,7 +2492,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length SMB_STRUCT_STAT sbuf; DATA_BLOB header; - if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1) + if(SMB_VFS_FSTAT(fsp,fsp->fh->fd, &sbuf) == -1) return(UNIXERROR(ERRDOS,ERRnoaccess)); if (startpos > sbuf.st_size) @@ -2436,7 +2521,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length header.length = data - outbuf; header.free = NULL; - if ((nread = SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt)) == -1) { + if ((nread = SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, smb_maxcnt)) == -1) { /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */ if (errno == ENOSYS) { goto normal_read; @@ -2524,7 +2609,9 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt } CHECK_FSP(fsp,conn); - CHECK_READ(fsp); + if (!CHECK_READ(fsp,inbuf)) { + return(ERROR_DOS(ERRDOS,ERRbadaccess)); + } set_message(outbuf,12,0,True); @@ -2569,13 +2656,10 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt return ERROR_DOS(ERRDOS,ERRlock); } -#if 0 - /* Enable when the AIO code is moved over. JRA. */ if (schedule_aio_read_and_X(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt)) { END_PROFILE(SMBreadX); return -1; } -#endif nread = send_file_readX(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt); if (nread != -1) @@ -2607,7 +2691,9 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, } CHECK_FSP(fsp,conn); - CHECK_WRITE(fsp); + if (!CHECK_WRITE(fsp)) { + return(ERROR_DOS(ERRDOS,ERRbadaccess)); + } tcount = IVAL(inbuf,smb_vwv1); startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3); @@ -2665,7 +2751,6 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, /* Set up outbuf to return the correct return */ outsize = set_message(outbuf,1,0,True); SCVAL(outbuf,smb_com,SMBwritec); - SSVAL(outbuf,smb_vwv0,total_written); if (numtowrite != 0) { @@ -2697,6 +2782,8 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, total_written += nwritten; } + SSVAL(outbuf,smb_vwv0,total_written); + if ((lp_syncalways(SNUM(conn)) || write_through) && lp_strict_sync(SNUM(conn))) sync_file(conn,fsp); @@ -2741,7 +2828,9 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, START_PROFILE(SMBwriteunlock); CHECK_FSP(fsp,conn); - CHECK_WRITE(fsp); + if (!CHECK_WRITE(fsp)) { + return(ERROR_DOS(ERRDOS,ERRbadaccess)); + } numtowrite = SVAL(inbuf,smb_vwv1); startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); @@ -2755,10 +2844,11 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, /* The special X/Open SMB protocol handling of zero length writes is *NOT* done for this call */ - if(numtowrite == 0) + if(numtowrite == 0) { nwritten = 0; - else + } else { nwritten = write_file(fsp,data,startpos,numtowrite); + } if (lp_syncalways(SNUM(conn))) sync_file(conn,fsp); @@ -2812,7 +2902,9 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d } CHECK_FSP(fsp,conn); - CHECK_WRITE(fsp); + if (!CHECK_WRITE(fsp)) { + return(ERROR_DOS(ERRDOS,ERRbadaccess)); + } numtowrite = SVAL(inbuf,smb_vwv1); startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); @@ -2893,7 +2985,9 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng } CHECK_FSP(fsp,conn); - CHECK_WRITE(fsp); + if (!CHECK_WRITE(fsp)) { + return(ERROR_DOS(ERRDOS,ERRbadaccess)); + } set_message(outbuf,6,0,True); @@ -2946,15 +3040,11 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng nwritten = 0; } else { -#if 0 - /* Enable when AIO code is moved over. JRA. */ - if (schedule_aio_write_and_X(conn, inbuf, outbuf, length, bufsize, fsp,data,startpos,numtowrite)) { END_PROFILE(SMBwriteX); return -1; } -#endif nwritten = write_file(fsp,data,startpos,numtowrite); } @@ -3011,7 +3101,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int break; case 1: umode = SEEK_CUR; - res = fsp->pos + startpos; + res = fsp->fh->pos + startpos; break; case 2: umode = SEEK_END; @@ -3023,19 +3113,19 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int } if (umode == SEEK_END) { - if((res = SMB_VFS_LSEEK(fsp,fsp->fd,startpos,umode)) == -1) { + if((res = SMB_VFS_LSEEK(fsp,fsp->fh->fd,startpos,umode)) == -1) { if(errno == EINVAL) { SMB_OFF_T current_pos = startpos; SMB_STRUCT_STAT sbuf; - if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1) { + if(SMB_VFS_FSTAT(fsp,fsp->fh->fd, &sbuf) == -1) { END_PROFILE(SMBlseek); return(UNIXERROR(ERRDOS,ERRnoaccess)); } current_pos += sbuf.st_size; if(current_pos < 0) - res = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_SET); + res = SMB_VFS_LSEEK(fsp,fsp->fh->fd,0,SEEK_SET); } } @@ -3045,7 +3135,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int } } - fsp->pos = res; + fsp->fh->pos = res; outsize = set_message(outbuf,2,0,True); SIVAL(outbuf,smb_vwv0,res); @@ -3151,7 +3241,7 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size, pstrcpy( file_name, fsp->fsp_name); DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n", - fsp->fd, fsp->fnum, + fsp->fh->fd, fsp->fnum, conn->num_files_open)); /* @@ -3202,7 +3292,9 @@ int reply_writeclose(connection_struct *conn, START_PROFILE(SMBwriteclose); CHECK_FSP(fsp,conn); - CHECK_WRITE(fsp); + if (!CHECK_WRITE(fsp)) { + return(ERROR_DOS(ERRDOS,ERRbadaccess)); + } numtowrite = SVAL(inbuf,smb_vwv1); startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); @@ -3277,7 +3369,7 @@ int reply_lock(connection_struct *conn, offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3); DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n", - fsp->fd, fsp->fnum, (double)offset, (double)count)); + fsp->fh->fd, fsp->fnum, (double)offset, (double)count)); status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, &my_lock_ctx); if (NT_STATUS_V(status)) { @@ -3328,7 +3420,7 @@ int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, } DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n", - fsp->fd, fsp->fnum, (double)offset, (double)count ) ); + fsp->fh->fd, fsp->fnum, (double)offset, (double)count ) ); END_PROFILE(SMBunlock); return(outsize); @@ -3438,7 +3530,7 @@ int reply_printopen(connection_struct *conn, SSVAL(outbuf,smb_vwv0,fsp->fnum); DEBUG(3,("openprint fd=%d fnum=%d\n", - fsp->fd, fsp->fnum)); + fsp->fh->fd, fsp->fnum)); END_PROFILE(SMBsplopen); return(outsize); @@ -3464,7 +3556,7 @@ int reply_printclose(connection_struct *conn, } DEBUG(3,("printclose fd=%d fnum=%d\n", - fsp->fd,fsp->fnum)); + fsp->fh->fd,fsp->fnum)); close_err = close_file(fsp,True); @@ -3568,7 +3660,9 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_ } CHECK_FSP(fsp,conn); - CHECK_WRITE(fsp); + if (!CHECK_WRITE(fsp)) { + return(ERROR_DOS(ERRDOS,ERRbadaccess)); + } numtowrite = SVAL(smb_buf(inbuf),1); data = smb_buf(inbuf) + 3; @@ -3697,7 +3791,7 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory) const char *dname = NULL; BOOL ret = False; long offset = 0; - struct smb_Dir *dir_hnd = OpenDir(conn, directory); + struct smb_Dir *dir_hnd = OpenDir(conn, directory, NULL, 0); if(dir_hnd == NULL) return True; @@ -3765,7 +3859,7 @@ BOOL rmdir_internals(connection_struct *conn, char *directory) */ BOOL all_veto_files = True; const char *dname; - struct smb_Dir *dir_hnd = OpenDir(conn, directory); + struct smb_Dir *dir_hnd = OpenDir(conn, directory, NULL, 0); if(dir_hnd != NULL) { long dirpos = 0; @@ -3987,7 +4081,7 @@ static void rename_open_files(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T Rename an open file - given an fsp. ****************************************************************************/ -NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char *newname, uint16 attrs, BOOL replace_if_exists) +NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char *newname, uint32 attrs, BOOL replace_if_exists) { SMB_STRUCT_STAT sbuf; BOOL bad_path = False; @@ -4101,7 +4195,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char * code. ****************************************************************************/ -NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, uint16 attrs, BOOL replace_if_exists) +NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, uint32 attrs, BOOL replace_if_exists) { pstring directory; pstring mask; @@ -4323,17 +4417,17 @@ directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n", const char *dname; pstring destname; + if (strequal(mask,"????????.???")) + pstrcpy(mask,"*"); + if (check_name(directory,conn)) - dir_hnd = OpenDir(conn, directory); + dir_hnd = OpenDir(conn, directory, mask, attrs); if (dir_hnd) { long offset = 0; error = NT_STATUS_NO_SUCH_FILE; /* Was error = NT_STATUS_OBJECT_NAME_NOT_FOUND; - gentest fix. JRA */ - if (strequal(mask,"????????.???")) - pstrcpy(mask,"*"); - while ((dname = ReadDirName(dir_hnd, &offset))) { pstring fname; BOOL sysdir_entry = False; @@ -4434,7 +4528,7 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, pstring name; pstring newname; char *p; - uint16 attrs = SVAL(inbuf,smb_vwv0); + uint32 attrs = SVAL(inbuf,smb_vwv0); NTSTATUS status; START_PROFILE(SMBmv); @@ -4485,45 +4579,66 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, int count,BOOL target_is_directory, int *err_ret) { - int Access,action; SMB_STRUCT_STAT src_sbuf, sbuf2; SMB_OFF_T ret=-1; files_struct *fsp1,*fsp2; pstring dest; uint32 dosattrs; + uint32 new_create_disposition; *err_ret = 0; pstrcpy(dest,dest1); if (target_is_directory) { char *p = strrchr_m(src,'/'); - if (p) + if (p) { p++; - else + } else { p = src; + } pstrcat(dest,"/"); pstrcat(dest,p); } - if (!vfs_file_exist(conn,src,&src_sbuf)) + if (!vfs_file_exist(conn,src,&src_sbuf)) { return(False); + } + + if (!target_is_directory && count) { + new_create_disposition = FILE_OPEN; + } else { + if (!map_open_params_to_ntcreate(dest1,0,ofun, + NULL, NULL, &new_create_disposition, NULL)) { + return(False); + } + } - fsp1 = open_file_shared(conn,src,&src_sbuf,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY), - (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),FILE_ATTRIBUTE_NORMAL,INTERNAL_OPEN_ONLY, - &Access,&action); + fsp1 = open_file_ntcreate(conn,src,&src_sbuf, + FILE_GENERIC_READ, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, + 0, + FILE_ATTRIBUTE_NORMAL, + INTERNAL_OPEN_ONLY, + NULL); - if (!fsp1) + if (!fsp1) { return(False); - - if (!target_is_directory && count) - ofun = FILE_EXISTS_OPEN; + } dosattrs = dos_mode(conn, src, &src_sbuf); - if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1) + if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1) { ZERO_STRUCTP(&sbuf2); + } - fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY), - ofun,dosattrs,INTERNAL_OPEN_ONLY,&Access,&action); + fsp2 = open_file_ntcreate(conn,dest,&sbuf2, + FILE_GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, + new_create_disposition, + 0, + dosattrs, + INTERNAL_OPEN_ONLY, + NULL); if (!fsp2) { close_file(fsp1,False); @@ -4531,7 +4646,7 @@ BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, } if ((ofun&3) == 1) { - if(SMB_VFS_LSEEK(fsp2,fsp2->fd,0,SEEK_END) == -1) { + if(SMB_VFS_LSEEK(fsp2,fsp2->fh->fd,0,SEEK_END) == -1) { DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) )); /* * Stop the copy from occurring. @@ -4541,8 +4656,9 @@ BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, } } - if (src_sbuf.st_size) + if (src_sbuf.st_size) { ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size); + } close_file(fsp1,False); @@ -4679,16 +4795,16 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, const char *dname; pstring destname; + if (strequal(mask,"????????.???")) + pstrcpy(mask,"*"); + if (check_name(directory,conn)) - dir_hnd = OpenDir(conn, directory); + dir_hnd = OpenDir(conn, directory, mask, 0); if (dir_hnd) { long offset = 0; error = ERRbadfile; - if (strequal(mask,"????????.???")) - pstrcpy(mask,"*"); - while ((dname = ReadDirName(dir_hnd, &offset))) { pstring fname; pstrcpy(fname,dname); @@ -4956,7 +5072,7 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length, /* we don't support these - and CANCEL_LOCK makes w2k and XP reboot so I don't really want to be compatible! (tridge) */ - return ERROR_NT(NT_STATUS_UNSUCCESSFUL); + return ERROR_DOS(ERRDOS, ERRnoatomiclocks); } if (locktype & LOCKING_ANDX_CANCEL_LOCK) { @@ -5159,7 +5275,9 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length, outsize = set_message(outbuf,8,0,True); CHECK_FSP(fsp,conn); - CHECK_READ(fsp); + if (!CHECK_READ(fsp,inbuf)) { + return(ERROR_DOS(ERRDOS,ERRbadaccess)); + } startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1); maxcount = SVAL(inbuf,smb_vwv3); @@ -5287,7 +5405,9 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, START_PROFILE(SMBwriteBmpx); CHECK_FSP(fsp,conn); - CHECK_WRITE(fsp); + if (!CHECK_WRITE(fsp)) { + return(ERROR_DOS(ERRDOS,ERRbadaccess)); + } if (HAS_CACHED_ERROR(fsp)) { return(CACHED_ERROR(fsp)); } @@ -5391,7 +5511,9 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz START_PROFILE(SMBwriteBs); CHECK_FSP(fsp,conn); - CHECK_WRITE(fsp); + if (!CHECK_WRITE(fsp)) { + return(ERROR_DOS(ERRDOS,ERRbadaccess)); + } tcount = SVAL(inbuf,smb_vwv1); startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); diff --git a/source/smbd/server.c b/source/smbd/server.c index b40a8267cc9..4217d821f4c 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -30,7 +30,6 @@ int last_message = -1; /* a useful macro to debug the last message processed */ #define LAST_MESSAGE() smb_fn_name(last_message) -extern char *last_inbuf; extern struct auth_context *negprot_global_auth_context; extern pstring user_socket_options; extern SIG_ATOMIC_T got_sig_term; @@ -635,6 +634,7 @@ void exit_server(const char *reason) if (!reason) { int oldlevel = DEBUGLEVEL; + char *last_inbuf = get_InBuffer(); DEBUGLEVEL = 10; DEBUG(0,("Last message was %s\n",smb_fn_name(last_message))); if (last_inbuf) @@ -951,6 +951,9 @@ void build_options(BOOL screen); if (!init_change_notify()) exit(1); + /* Setup aio signal handler. */ + initialize_async_io_handler(); + /* re-initialise the timezone */ TimeInit(); diff --git a/source/smbd/service.c b/source/smbd/service.c index 24f4df76942..d330e847e2e 100644 --- a/source/smbd/service.c +++ b/source/smbd/service.c @@ -379,6 +379,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, conn->veto_list = NULL; conn->hide_list = NULL; conn->veto_oplock_list = NULL; + conn->aio_write_behind_list = NULL; string_set(&conn->dirpath,""); string_set(&conn->user,user); conn->nt_user_token = NULL; @@ -604,6 +605,25 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, } #endif + /* Add veto/hide lists */ + if (!IS_IPC(conn) && !IS_PRINT(conn)) { + set_namearray( &conn->veto_list, lp_veto_files(snum)); + set_namearray( &conn->hide_list, lp_hide_files(snum)); + set_namearray( &conn->veto_oplock_list, lp_veto_oplocks(snum)); + } + + /* Invoke VFS make connection hook - do this before the VFS_STAT call to allow + any filesystems needing user credentials to initialize themselves. */ + + if (SMB_VFS_CONNECT(conn, lp_servicename(snum), user) < 0) { + DEBUG(0,("make_connection: VFS make connection failed!\n")); + change_to_root_user(); + yield_connection(conn, lp_servicename(snum)); + conn_free(conn); + *status = NT_STATUS_UNSUCCESSFUL; + return NULL; + } + /* win2000 does not check the permissions on the directory during the tree connect, instead relying on permission check during individual operations. To match this behaviour @@ -612,6 +632,8 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, if (SMB_VFS_STAT(conn, conn->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) { DEBUG(0,("'%s' does not exist or is not a directory, when connecting to [%s]\n", conn->connectpath, lp_servicename(snum))); change_to_root_user(); + /* Call VFS disconnect hook */ + SMB_VFS_DISCONNECT(conn); yield_connection(conn, lp_servicename(snum)); conn_free(conn); *status = NT_STATUS_BAD_NETWORK_NAME; @@ -646,27 +668,8 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, dbgtext( "(pid %d)\n", (int)sys_getpid() ); } - /* Add veto/hide lists */ - if (!IS_IPC(conn) && !IS_PRINT(conn)) { - set_namearray( &conn->veto_list, lp_veto_files(snum)); - set_namearray( &conn->hide_list, lp_hide_files(snum)); - set_namearray( &conn->veto_oplock_list, lp_veto_oplocks(snum)); - } - - /* Invoke VFS make connection hook */ - - if (SMB_VFS_CONNECT(conn, lp_servicename(snum), user) < 0) { - DEBUG(0,("make_connection: VFS make connection failed!\n")); - change_to_root_user(); - yield_connection(conn, lp_servicename(snum)); - conn_free(conn); - *status = NT_STATUS_UNSUCCESSFUL; - return NULL; - } - /* we've finished with the user stuff - go back to root */ change_to_root_user(); - return(conn); } diff --git a/source/smbd/sesssetup.c b/source/smbd/sesssetup.c index 3b33db24e80..1ddd6256b31 100644 --- a/source/smbd/sesssetup.c +++ b/source/smbd/sesssetup.c @@ -96,6 +96,7 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, set_message_end(outbuf,p); + show_msg(outbuf); return send_smb(smbd_server_fd(),outbuf); } @@ -223,7 +224,7 @@ static int reply_spnego_kerberos(connection_struct *conn, fstrcpy(wb_request.domain_name, domain); - wb_result = winbindd_request(WINBINDD_DOMAIN_INFO, + wb_result = winbindd_request_response(WINBINDD_DOMAIN_INFO, &wb_request, &wb_response); if (wb_result == NSS_STATUS_SUCCESS) { diff --git a/source/smbd/statcache.c b/source/smbd/statcache.c index 8e22d9687b8..97ecd4152c8 100644 --- a/source/smbd/statcache.c +++ b/source/smbd/statcache.c @@ -64,7 +64,7 @@ void stat_cache_add( const char *full_orig_name, const char *orig_translated_pat if((*full_orig_name == '\0') || (full_orig_name[0] == '.' && ((full_orig_name[1] == '\0') || - (full_orig_name[1] == '.' && full_orig_name[1] == '\0')))) + (full_orig_name[1] == '.' && full_orig_name[2] == '\0')))) return; /* diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index ebb46a23b26..602656080ed 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -3,6 +3,7 @@ SMB transaction2 handling Copyright (C) Jeremy Allison 1994-2003 Copyright (C) Stefan (metze) Metzmacher 2003 + Copyright (C) Volker Lendecke 2005 Extensively modified by Andrew Tridgell, 1995 @@ -119,8 +120,8 @@ static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_str return False; } - if (fsp && fsp->fd != -1) { - sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fd, ea_name, val, attr_size); + if (fsp && fsp->fh->fd != -1) { + sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fh->fd, ea_name, val, attr_size); } else { sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size); } @@ -171,8 +172,8 @@ static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_str for (i = 0, ea_namelist = TALLOC(mem_ctx, ea_namelist_size); i < 6; ea_namelist = TALLOC_REALLOC_ARRAY(mem_ctx, ea_namelist, char, ea_namelist_size), i++) { - if (fsp && fsp->fd != -1) { - sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fd, ea_namelist, ea_namelist_size); + if (fsp && fsp->fh->fd != -1) { + sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fh->fd, ea_namelist, ea_namelist_size); } else { sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist, ea_namelist_size); } @@ -337,10 +338,10 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname, s if (ea_list->ea.value.length == 0) { /* Remove the attribute. */ - if (fsp && (fsp->fd != -1)) { + if (fsp && (fsp->fh->fd != -1)) { DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n", unix_ea_name, fsp->fsp_name)); - ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, unix_ea_name); + ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fh->fd, unix_ea_name); } else { DEBUG(10,("set_ea: deleting ea name %s on file %s.\n", unix_ea_name, fname)); @@ -355,10 +356,10 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname, s } #endif } else { - if (fsp && (fsp->fd != -1)) { + if (fsp && (fsp->fh->fd != -1)) { DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n", unix_ea_name, fsp->fsp_name)); - ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, unix_ea_name, + ret = SMB_VFS_FSETXATTR(fsp, fsp->fh->fd, unix_ea_name, ea_list->ea.value.data, ea_list->ea.value.length, 0); } else { DEBUG(10,("set_ea: setting ea name %s on file %s.\n", @@ -591,6 +592,7 @@ static int send_trans2_replies(char *outbuf, /* If there genuinely are no parameters or data to send just send the empty packet */ if(params_to_send == 0 && data_to_send == 0) { + show_msg(outbuf); if (!send_smb(smbd_server_fd(),outbuf)) exit_server("send_trans2_replies: send_smb failed."); return 0; @@ -685,6 +687,7 @@ static int send_trans2_replies(char *outbuf, params_to_send, data_to_send, paramsize, datasize)); /* Send the packet */ + show_msg(outbuf); if (!send_smb(smbd_server_fd(),outbuf)) exit_server("send_trans2_replies: send_smb failed."); @@ -715,20 +718,20 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i { char *params = *pparams; char *pdata = *ppdata; - int16 open_mode; - int16 open_attr; + int deny_mode; + int32 open_attr; BOOL oplock_request; #if 0 BOOL return_additional_info; int16 open_sattr; time_t open_time; #endif - int16 open_ofun; + int open_ofun; int32 open_size; char *pname; pstring fname; SMB_OFF_T size=0; - int fmode=0,mtime=0,rmode; + int fattr=0,mtime=0; SMB_INO_T inode = 0; SMB_STRUCT_STAT sbuf; int smb_action = 0; @@ -738,6 +741,10 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i struct ea_list *ea_list = NULL; uint16 flags = 0; NTSTATUS status; + uint32 access_mask; + uint32 share_mode; + uint32 create_disposition; + uint32 create_options = 0; /* * Ensure we have enough parameters to perform the operation. @@ -748,7 +755,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i } flags = SVAL(params, 0); - open_mode = SVAL(params, 2); + deny_mode = SVAL(params, 2); open_attr = SVAL(params,6); oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; if (oplock_request) { @@ -764,16 +771,18 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i open_size = IVAL(params,14); pname = ¶ms[28]; - if (IS_IPC(conn)) + if (IS_IPC(conn)) { return(ERROR_DOS(ERRSRV,ERRaccess)); + } srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status, False); if (!NT_STATUS_IS_OK(status)) { return ERROR_NT(status); } - DEBUG(3,("call_trans2open %s mode=%d attr=%d ofun=%d size=%d\n", - fname,open_mode, open_attr, open_ofun, open_size)); + DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n", + fname, (unsigned int)deny_mode, (unsigned int)open_attr, + (unsigned int)open_ofun, open_size)); /* XXXX we need to handle passed times, sattr and flags */ @@ -786,11 +795,12 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess); } - /* Strange open mode mapping. */ - if (open_ofun == 0) { - if (GET_OPEN_MODE(open_mode) == DOS_OPEN_EXEC) { - open_ofun = FILE_EXISTS_FAIL | FILE_CREATE_IF_NOT_EXIST; - } + if (!map_open_params_to_ntcreate(fname, deny_mode, open_ofun, + &access_mask, + &share_mode, + &create_disposition, + &create_options)) { + return ERROR_DOS(ERRDOS, ERRbadaccess); } /* Any data in this call is an EA list. */ @@ -820,8 +830,14 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i } } - fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,(uint32)open_attr, - oplock_request, &rmode,&smb_action); + fsp = open_file_ntcreate(conn,fname,&sbuf, + access_mask, + share_mode, + create_disposition, + create_options, + open_attr, + oplock_request, + &smb_action); if (!fsp) { talloc_destroy(ctx); @@ -833,10 +849,10 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i } size = get_file_size(sbuf); - fmode = dos_mode(conn,fname,&sbuf); + fattr = dos_mode(conn,fname,&sbuf); mtime = sbuf.st_mtime; inode = sbuf.st_ino; - if (fmode & aDIR) { + if (fattr & aDIR) { talloc_destroy(ctx); close_file(fsp,False); return(ERROR_DOS(ERRDOS,ERRnoaccess)); @@ -859,10 +875,10 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i *pparams = params; SSVAL(params,0,fsp->fnum); - SSVAL(params,2,fmode); + SSVAL(params,2,open_attr); put_dos_date2(params,4, mtime); SIVAL(params,8, (uint32)size); - SSVAL(params,12,rmode); + SSVAL(params,12,open_ofun); SSVAL(params,16,0); /* Padding. */ if (oplock_request && lp_fake_oplocks(SNUM(conn))) { @@ -996,7 +1012,7 @@ static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *ps static BOOL get_lanman2_dir_entry(connection_struct *conn, void *inbuf, void *outbuf, - char *path_mask,int dirtype,int info_level, + char *path_mask,uint32 dirtype,int info_level, int requires_resume_key, BOOL dont_descend,char **ppdata, char *base_data, int space_remaining, @@ -1012,7 +1028,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, char *p, *q, *pdata = *ppdata; uint32 reskey=0; long prev_dirpos=0; - int mode=0; + uint32 mode=0; SMB_OFF_T file_size = 0; SMB_BIG_UINT allocation_size = 0; uint32 len; @@ -1020,7 +1036,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, char *nameptr; char *last_entry_ptr; BOOL was_8_3; - int nt_extmode; /* Used for NT connections instead of mode */ + uint32 nt_extmode; /* Used for NT connections instead of mode */ BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/'); BOOL check_mangled_names = lp_manglednames(SNUM(conn)); @@ -1576,7 +1592,7 @@ static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outb requested. */ char *params = *pparams; char *pdata = *ppdata; - int dirtype = SVAL(params,0); + uint32 dirtype = SVAL(params,0); int maxentries = SVAL(params,2); uint16 findfirst_flags = SVAL(params,4); BOOL close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE); @@ -1606,9 +1622,9 @@ static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outb *directory = *mask = 0; - DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \ + DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", - dirtype, maxentries, close_after_first, close_if_end, requires_resume_key, + (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key, info_level, max_data_bytes)); if (!maxentries) { @@ -1711,19 +1727,13 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } *pparams = params; - dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid)); - if (dptr_num < 0) { - talloc_destroy(ea_ctx); - return(UNIXERROR(ERRDOS,ERRbadfile)); - } - /* Save the wildcard match and attribs we are using on this directory - needed as lanman2 assumes these are being saved between calls */ - if (!dptr_set_wcard_and_attributes(dptr_num, mask, dirtype)) { - dptr_close(&dptr_num); + dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid), mask, dirtype); + if (dptr_num < 0) { talloc_destroy(ea_ctx); - return ERROR_NT(NT_STATUS_NO_MEMORY); + return(UNIXERROR(ERRDOS,ERRbadfile)); } DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, mask, dirtype)); @@ -2336,7 +2346,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned fsp.conn = conn; fsp.fnum = -1; - fsp.fd = -1; + fsp.fh->fd = -1; /* access check */ if (current_user.uid != 0) { @@ -2390,7 +2400,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned data_len = 12; SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION); SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION); - SBIG_UINT(pdata,4,((SMB_BIG_UINT)CIFS_UNIX_POSIX_ACLS_CAP)); /* We have POSIX ACLs. */ + SBIG_UINT(pdata,4,((SMB_BIG_UINT)(CIFS_UNIX_POSIX_ACLS_CAP| + CIFS_UNIX_POSIX_PATHNAMES_CAP))); /* We have POSIX ACLs and pathname capability. */ break; case SMB_MAC_QUERY_FS_INFO: @@ -2426,21 +2437,10 @@ static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outb { char *pdata = *ppdata; char *params = *pparams; - files_struct *fsp = NULL; uint16 info_level; int outsize; - SMB_NTQUOTA_STRUCT quotas; - - ZERO_STRUCT(quotas); - - DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn)))); - /* access check */ - if ((current_user.uid != 0)||!CAN_WRITE(conn)) { - DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n", - lp_servicename(SNUM(conn)),conn->user)); - return ERROR_DOS(ERRSRV,ERRaccess); - } + DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn)))); /* */ if (total_params < 4) { @@ -2449,67 +2449,112 @@ static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outb return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - fsp = file_fsp(params,0); - - if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) { - DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n")); - return ERROR_NT(NT_STATUS_INVALID_HANDLE); - } - info_level = SVAL(params,2); switch(info_level) { - case SMB_FS_QUOTA_INFORMATION: - /* note: normaly there're 48 bytes, - * but we didn't use the last 6 bytes for now - * --metze - */ - if (total_data < 42) { - DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n", - total_data)); - return ERROR_DOS(ERRDOS,ERRunknownlevel); + case SMB_SET_CIFS_UNIX_INFO: + { + uint16 client_unix_major; + uint16 client_unix_minor; + uint32 client_unix_cap_low; + uint32 client_unix_cap_high; + + if (!lp_unix_extensions()) { + return ERROR_DOS(ERRDOS,ERRunknownlevel); + } + + /* There should be 12 bytes of capabilities set. */ + if (total_data < 8) { + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + client_unix_major = SVAL(pdata,0); + client_unix_minor = SVAL(pdata,2); + client_unix_cap_low = IVAL(pdata,4); + client_unix_cap_high = IVAL(pdata,8); + /* Just print these values for now. */ + DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \ +cap_low = 0x%x, cap_high = 0x%x\n", + (unsigned int)client_unix_major, + (unsigned int)client_unix_minor, + (unsigned int)client_unix_cap_low, + (unsigned int)client_unix_cap_high )); + + /* Here is where we must switch to posix pathname processing... */ + lp_set_posix_pathnames(); + mangle_change_to_posix(); + break; } + case SMB_FS_QUOTA_INFORMATION: + { + files_struct *fsp = NULL; + SMB_NTQUOTA_STRUCT quotas; + + ZERO_STRUCT(quotas); + + /* access check */ + if ((current_user.uid != 0)||!CAN_WRITE(conn)) { + DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n", + lp_servicename(SNUM(conn)),conn->user)); + return ERROR_DOS(ERRSRV,ERRaccess); + } + + /* note: normaly there're 48 bytes, + * but we didn't use the last 6 bytes for now + * --metze + */ + fsp = file_fsp(params,0); + if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) { + DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n")); + return ERROR_NT(NT_STATUS_INVALID_HANDLE); + } + + if (total_data < 42) { + DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n", + total_data)); + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } - /* unknown_1 24 NULL bytes in pdata*/ + /* unknown_1 24 NULL bytes in pdata*/ - /* the soft quotas 8 bytes (SMB_BIG_UINT)*/ - quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24); + /* the soft quotas 8 bytes (SMB_BIG_UINT)*/ + quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24); #ifdef LARGE_SMB_OFF_T - quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32); + quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32); #else /* LARGE_SMB_OFF_T */ - if ((IVAL(pdata,28) != 0)&& - ((quotas.softlim != 0xFFFFFFFF)|| - (IVAL(pdata,28)!=0xFFFFFFFF))) { - /* more than 32 bits? */ - return ERROR_DOS(ERRDOS,ERRunknownlevel); - } + if ((IVAL(pdata,28) != 0)&& + ((quotas.softlim != 0xFFFFFFFF)|| + (IVAL(pdata,28)!=0xFFFFFFFF))) { + /* more than 32 bits? */ + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } #endif /* LARGE_SMB_OFF_T */ - /* the hard quotas 8 bytes (SMB_BIG_UINT)*/ - quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32); + /* the hard quotas 8 bytes (SMB_BIG_UINT)*/ + quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32); #ifdef LARGE_SMB_OFF_T - quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32); + quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32); #else /* LARGE_SMB_OFF_T */ - if ((IVAL(pdata,36) != 0)&& - ((quotas.hardlim != 0xFFFFFFFF)|| - (IVAL(pdata,36)!=0xFFFFFFFF))) { - /* more than 32 bits? */ - return ERROR_DOS(ERRDOS,ERRunknownlevel); - } + if ((IVAL(pdata,36) != 0)&& + ((quotas.hardlim != 0xFFFFFFFF)|| + (IVAL(pdata,36)!=0xFFFFFFFF))) { + /* more than 32 bits? */ + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } #endif /* LARGE_SMB_OFF_T */ - /* quota_flags 2 bytes **/ - quotas.qflags = SVAL(pdata,40); + /* quota_flags 2 bytes **/ + quotas.qflags = SVAL(pdata,40); - /* unknown_2 6 NULL bytes follow*/ + /* unknown_2 6 NULL bytes follow*/ - /* now set the quotas */ - if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) { - DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn)))); - return ERROR_DOS(ERRSRV,ERRerror); - } + /* now set the quotas */ + if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) { + DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn)))); + return ERROR_DOS(ERRSRV,ERRerror); + } - break; + break; + } default: DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n", info_level)); @@ -2678,6 +2723,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char * char *pdata = *ppdata; uint16 info_level; int mode=0; + int nlink; SMB_OFF_T file_size=0; SMB_BIG_UINT allocation_size=0; unsigned int data_size = 0; @@ -2695,7 +2741,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char * files_struct *fsp = NULL; TALLOC_CTX *ea_ctx = NULL; struct ea_list *ea_list = NULL; - uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */ + uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */ if (!params) return ERROR_NT(NT_STATUS_INVALID_PARAMETER); @@ -2720,7 +2766,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char * pstrcpy(fname, fsp->fsp_name); /* We know this name is ok, it's already passed the checks. */ - } else if(fsp && (fsp->is_directory || fsp->fd == -1)) { + } else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) { /* * This is actually a QFILEINFO on a directory * handle (returned from an NT SMB). NT5.0 seems @@ -2740,7 +2786,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char * return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); } - delete_pending = fsp->is_directory ? fsp->directory_delete_on_close : 0; + delete_pending = + get_delete_on_close_flag(sbuf.st_dev, + sbuf.st_ino); } else { /* * Original code - this is an open file. @@ -2748,13 +2796,15 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char * CHECK_FSP(fsp,conn); pstrcpy(fname, fsp->fsp_name); - if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) { + if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) { DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno))); return(UNIXERROR(ERRDOS,ERRbadfid)); } - pos = fsp->position_information; - delete_pending = fsp->delete_on_close; - desired_access = fsp->desired_access; + pos = fsp->fh->position_information; + delete_pending = + get_delete_on_close_flag(sbuf.st_dev, + sbuf.st_ino); + access_mask = fsp->access_mask; } } else { NTSTATUS status = NT_STATUS_OK; @@ -2794,6 +2844,23 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char * DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno))); return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); } + + delete_pending = get_delete_on_close_flag(sbuf.st_dev, + sbuf.st_ino); + if (delete_pending) { + return ERROR_NT(NT_STATUS_DELETE_PENDING); + } + } + + nlink = sbuf.st_nlink; + + if ((nlink > 0) && S_ISDIR(sbuf.st_mode)) { + /* NTFS does not seem to count ".." */ + nlink -= 1; + } + + if ((nlink > 0) && delete_pending) { + nlink -= 1; } if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) @@ -3023,11 +3090,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd data_size = 24; SOFF_T(pdata,0,allocation_size); SOFF_T(pdata,8,file_size); - if (delete_pending & sbuf.st_nlink) - SIVAL(pdata,16,sbuf.st_nlink - 1); - else - SIVAL(pdata,16,sbuf.st_nlink); - SCVAL(pdata,20,0); + SIVAL(pdata,16,nlink); + SCVAL(pdata,20,delete_pending?1:0); SCVAL(pdata,21,(mode&aDIR)?1:0); SSVAL(pdata,22,0); /* Padding. */ break; @@ -3098,10 +3162,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd pdata += 40; SOFF_T(pdata,0,allocation_size); SOFF_T(pdata,8,file_size); - if (delete_pending && sbuf.st_nlink) - SIVAL(pdata,16,sbuf.st_nlink - 1); - else - SIVAL(pdata,16,sbuf.st_nlink); + SIVAL(pdata,16,nlink); SCVAL(pdata,20,delete_pending); SCVAL(pdata,21,(mode&aDIR)?1:0); SSVAL(pdata,22,0); @@ -3129,7 +3190,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd case SMB_FILE_ACCESS_INFORMATION: DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n")); - SIVAL(pdata,0,desired_access); + SIVAL(pdata,0,access_mask); data_size = 4; break; @@ -3312,8 +3373,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd uint16 num_file_acls = 0; uint16 num_def_acls = 0; - if (fsp && !fsp->is_directory && (fsp->fd != -1)) { - file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd); + if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) { + file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd); } else { file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS); } @@ -3398,50 +3459,46 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd open_file_shared. JRA. ****************************************************************************/ -NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close, uint32 dosmode) +NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close, + uint32 dosmode) { - if (delete_on_close) { - /* - * Only allow delete on close for writable files. - */ - - if (!lp_delete_readonly(SNUM(fsp->conn))) { - if (dosmode & aRONLY) { - DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but file attribute is readonly.\n", - fsp->fsp_name )); - return NT_STATUS_CANNOT_DELETE; - } - } + if (!delete_on_close) { + return NT_STATUS_OK; + } - /* - * Only allow delete on close for writable shares. - */ + /* + * Only allow delete on close for writable files. + */ - if (!CAN_WRITE(fsp->conn)) { - DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n", - fsp->fsp_name )); - return NT_STATUS_ACCESS_DENIED; - } + if ((dosmode & aRONLY) && + !lp_delete_readonly(SNUM(fsp->conn))) { + DEBUG(10,("can_set_delete_on_close: file %s delete on close " + "flag set but file attribute is readonly.\n", + fsp->fsp_name )); + return NT_STATUS_CANNOT_DELETE; + } - /* - * Only allow delete on close for files/directories opened with delete intent. - */ + /* + * Only allow delete on close for writable shares. + */ - if (!(fsp->desired_access & DELETE_ACCESS)) { - DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n", - fsp->fsp_name )); - return NT_STATUS_ACCESS_DENIED; - } + if (!CAN_WRITE(fsp->conn)) { + DEBUG(10,("can_set_delete_on_close: file %s delete on " + "close flag set but write access denied on share.\n", + fsp->fsp_name )); + return NT_STATUS_ACCESS_DENIED; } - if(fsp->is_directory) { - fsp->directory_delete_on_close = delete_on_close; - DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n", - delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name )); - } else { - fsp->delete_on_close = delete_on_close; - DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n", - delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name )); + /* + * Only allow delete on close for files/directories opened with delete + * intent. + */ + + if (!(fsp->access_mask & DELETE_ACCESS)) { + DEBUG(10,("can_set_delete_on_close: file %s delete on " + "close flag set but delete access denied.\n", + fsp->fsp_name )); + return NT_STATUS_ACCESS_DENIED; } return NT_STATUS_OK; @@ -3456,10 +3513,12 @@ NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close, u if flag is set. ****************************************************************************/ -NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close) +NTSTATUS set_delete_on_close(files_struct *fsp, BOOL delete_on_close) { - DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n", - delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name )); + DEBUG(10,("set_delete_on_close: %s delete on close flag for " + "fnum = %d, file %s\n", + delete_on_close ? "Adding" : "Removing", fsp->fnum, + fsp->fsp_name )); if (fsp->is_directory || fsp->is_stat) return NT_STATUS_OK; @@ -3468,8 +3527,9 @@ NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close) return NT_STATUS_ACCESS_DENIED; if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) { - DEBUG(0,("set_delete_on_close_over_all: failed to change delete on close flag for file %s\n", - fsp->fsp_name )); + DEBUG(0,("set_delete_on_close: failed to change delete " + "on close flag for file %s\n", + fsp->fsp_name )); unlock_share_entry_fsp(fsp); return NT_STATUS_ACCESS_DENIED; } @@ -3601,7 +3661,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char fsp = file_fsp(params,0); info_level = SVAL(params,2); - if(fsp && (fsp->is_directory || fsp->fd == -1)) { + if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) { /* * This is actually a SETFILEINFO on a directory * handle (returned from an NT SMB). NT5.0 seems @@ -3617,7 +3677,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char * Doing a DELETE_ON_CLOSE should cancel a print job. */ if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) { - fsp->share_mode = FILE_DELETE_ON_CLOSE; + fsp->fh->private_options |= FILE_DELETE_ON_CLOSE; DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name )); @@ -3633,7 +3693,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char CHECK_FSP(fsp,conn); pstrcpy(fname, fsp->fsp_name); - fd = fsp->fd; + fd = fsp->fh->fd; if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) { DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno))); @@ -3850,8 +3910,6 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char if (fd == -1) { files_struct *new_fsp = NULL; - int access_mode = 0; - int action = 0; if(global_oplock_break) { /* Queue this file modify as we are the process of an oplock break. */ @@ -3863,16 +3921,20 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char return -1; } - new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA, - SET_OPEN_MODE(DOS_OPEN_RDWR), - (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), + new_fsp = open_file_ntcreate(conn, fname, &sbuf, + FILE_WRITE_DATA, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, + 0, FILE_ATTRIBUTE_NORMAL, - INTERNAL_OPEN_ONLY, &access_mode, &action); + INTERNAL_OPEN_ONLY, + NULL); - if (new_fsp == NULL) + if (new_fsp == NULL) { return(UNIXERROR(ERRDOS,ERRbadpath)); + } ret = vfs_allocate_file_space(new_fsp, allocation_size); - if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) { + if (SMB_VFS_FSTAT(new_fsp,new_fsp->fh->fd,&new_sbuf) != 0) { DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n", new_fsp->fnum, strerror(errno))); ret = -1; @@ -3932,14 +3994,15 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char if (fsp == NULL) return(UNIXERROR(ERRDOS,ERRbadfid)); - status = set_delete_on_close_internal(fsp, delete_on_close, dosmode); + status = can_set_delete_on_close(fsp, delete_on_close, + dosmode); if (!NT_STATUS_IS_OK(status)) { return ERROR_NT(status); } /* The set is across all open files on this dev/inode pair. */ - status =set_delete_on_close_over_all(fsp, delete_on_close); + status =set_delete_on_close(fsp, delete_on_close); if (!NT_STATUS_IS_OK(status)) { return ERROR_NT(status); } @@ -3967,7 +4030,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n", fname, (double)position_information )); if (fsp) { - fsp->position_information = position_information; + fsp->fh->position_information = position_information; } /* We're done. We only get position info in this call. */ @@ -4391,8 +4454,6 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", if (fd == -1) { files_struct *new_fsp = NULL; - int access_mode = 0; - int action = 0; if(global_oplock_break) { /* Queue this file modify as we are the process of an oplock break. */ @@ -4404,22 +4465,27 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", return -1; } - new_fsp = open_file_shared(conn, fname, &sbuf, - SET_OPEN_MODE(DOS_OPEN_RDWR), - (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), + new_fsp = open_file_ntcreate(conn, fname, &sbuf, + FILE_WRITE_DATA, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, + 0, FILE_ATTRIBUTE_NORMAL, - INTERNAL_OPEN_ONLY, &access_mode, &action); + INTERNAL_OPEN_ONLY, + NULL); - if (new_fsp == NULL) + if (new_fsp == NULL) { return(UNIXERROR(ERRDOS,ERRbadpath)); + } ret = vfs_set_filelen(new_fsp, size); close_file(new_fsp,True); } else { ret = vfs_set_filelen(fsp, size); } - if (ret == -1) + if (ret == -1) { return (UNIXERROR(ERRHRD,ERRdiskfull)); + } } /* @@ -4883,6 +4949,7 @@ int reply_trans2(connection_struct *conn, of the parameter/data bytes */ outsize = set_message(outbuf,0,0,True); srv_signing_trans_stop(); + show_msg(outbuf); if (!send_smb(smbd_server_fd(),outbuf)) exit_server("reply_trans2: send_smb failed."); diff --git a/source/smbd/vfs-wrap.c b/source/smbd/vfs-wrap.c index abc17a37a23..39ac402f346 100644 --- a/source/smbd/vfs-wrap.c +++ b/source/smbd/vfs-wrap.c @@ -88,7 +88,7 @@ int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_ /* Directory operations */ -DIR *vfswrap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) +DIR *vfswrap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr) { DIR *result; @@ -226,7 +226,7 @@ ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void if (result == -1 && errno == ESPIPE) { /* Maintain the fiction that pipes can be seeked (sought?) on. */ result = SMB_VFS_READ(fsp, fd, data, n); - fsp->pos = 0; + fsp->fh->pos = 0; } #else /* HAVE_PREAD */ @@ -237,7 +237,7 @@ ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void if (curr == -1 && errno == ESPIPE) { /* Maintain the fiction that pipes can be seeked (sought?) on. */ result = SMB_VFS_READ(fsp, fd, data, n); - fsp->pos = 0; + fsp->fh->pos = 0; return result; } @@ -432,15 +432,15 @@ static int copy_reg(const char *source, const char *dest) return -1; } -int vfswrap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new) +int vfswrap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname) { int result; START_PROFILE(syscall_rename); - result = rename(old, new); + result = rename(oldname, newname); if (errno == EXDEV) { /* Rename across filesystems needed. */ - result = copy_reg(old, new); + result = copy_reg(oldname, newname); } END_PROFILE(syscall_rename); @@ -660,7 +660,7 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs SMB_OFF_T retlen; SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write); - retlen = SMB_VFS_WRITE(fsp,fsp->fd,(char *)zero_space,current_len_to_write); + retlen = SMB_VFS_WRITE(fsp,fsp->fh->fd,(char *)zero_space,current_len_to_write); if (retlen <= 0) return -1; @@ -1052,3 +1052,38 @@ int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp { return sys_fsetxattr(fd, name, value, size, flags); } + +int vfswrap_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return sys_aio_read(aiocb); +} + +int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return sys_aio_write(aiocb); +} + +int vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return sys_aio_return(aiocb); +} + +int vfswrap_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_AIOCB *aiocb) +{ + return sys_aio_cancel(fd, aiocb); +} + +int vfswrap_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return sys_aio_error(aiocb); +} + +int vfswrap_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb) +{ + return sys_aio_fsync(op, aiocb); +} + +int vfswrap_aio_suspend(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *timeout) +{ + return sys_aio_suspend(aiocb, n, timeout); +} diff --git a/source/smbd/vfs.c b/source/smbd/vfs.c index b09935eaa99..67970f203ac 100644 --- a/source/smbd/vfs.c +++ b/source/smbd/vfs.c @@ -145,7 +145,16 @@ static struct vfs_ops default_vfs = { vfswrap_fremovexattr, vfswrap_setxattr, vfswrap_lsetxattr, - vfswrap_fsetxattr + vfswrap_fsetxattr, + + /* AIO operations. */ + vfswrap_aio_read, + vfswrap_aio_write, + vfswrap_aio_return, + vfswrap_aio_cancel, + vfswrap_aio_error, + vfswrap_aio_fsync, + vfswrap_aio_suspend } }; @@ -277,20 +286,20 @@ BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object) DLIST_ADD(conn->vfs_handles, handle); for(i=0; ops[i].op != NULL; i++) { - DEBUG(5, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer)); - if(ops[i].layer == SMB_VFS_LAYER_OPAQUE) { - /* Check whether this operation was already made opaque by different module */ - if(((void**)&conn->vfs_opaque.ops)[ops[i].type] == ((void**)&default_vfs.ops)[ops[i].type]) { - /* No, it isn't overloaded yet. Overload. */ - DEBUGADD(5, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object)); - ((void**)&conn->vfs_opaque.ops)[ops[i].type] = ops[i].op; - ((vfs_handle_struct **)&conn->vfs_opaque.handles)[ops[i].type] = handle; - } - } - /* Change current VFS disposition*/ - DEBUGADD(5, ("Accepting operation type %d from module %s\n", ops[i].type, vfs_object)); - ((void**)&conn->vfs.ops)[ops[i].type] = ops[i].op; - ((vfs_handle_struct **)&conn->vfs.handles)[ops[i].type] = handle; + DEBUG(5, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer)); + if(ops[i].layer == SMB_VFS_LAYER_OPAQUE) { + /* Check whether this operation was already made opaque by different module */ + if(((void**)&conn->vfs_opaque.ops)[ops[i].type] == ((void**)&default_vfs.ops)[ops[i].type]) { + /* No, it isn't overloaded yet. Overload. */ + DEBUGADD(5, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object)); + ((void**)&conn->vfs_opaque.ops)[ops[i].type] = ops[i].op; + ((vfs_handle_struct **)&conn->vfs_opaque.handles)[ops[i].type] = handle; + } + } + /* Change current VFS disposition*/ + DEBUGADD(5, ("Accepting operation type %d from module %s\n", ops[i].type, vfs_object)); + ((void**)&conn->vfs.ops)[ops[i].type] = ops[i].op; + ((vfs_handle_struct **)&conn->vfs.handles)[ops[i].type] = handle; } SAFE_FREE(module_name); @@ -421,7 +430,7 @@ ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count) while (total < byte_count) { - ssize_t ret = SMB_VFS_READ(fsp, fsp->fd, buf + total, + ssize_t ret = SMB_VFS_READ(fsp, fsp->fh->fd, buf + total, byte_count - total); if (ret == 0) return total; @@ -443,7 +452,7 @@ ssize_t vfs_pread_data(files_struct *fsp, char *buf, while (total < byte_count) { - ssize_t ret = SMB_VFS_PREAD(fsp, fsp->fd, buf + total, + ssize_t ret = SMB_VFS_PREAD(fsp, fsp->fh->fd, buf + total, byte_count - total, offset + total); if (ret == 0) return total; @@ -468,7 +477,7 @@ ssize_t vfs_write_data(files_struct *fsp,const char *buffer,size_t N) ssize_t ret; while (total < N) { - ret = SMB_VFS_WRITE(fsp,fsp->fd,buffer + total,N - total); + ret = SMB_VFS_WRITE(fsp,fsp->fh->fd,buffer + total,N - total); if (ret == -1) return -1; @@ -487,7 +496,7 @@ ssize_t vfs_pwrite_data(files_struct *fsp,const char *buffer, ssize_t ret; while (total < N) { - ret = SMB_VFS_PWRITE(fsp, fsp->fd, buffer + total, + ret = SMB_VFS_PWRITE(fsp, fsp->fh->fd, buffer + total, N - total, offset + total); if (ret == -1) @@ -526,7 +535,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len) return -1; } - ret = SMB_VFS_FSTAT(fsp,fsp->fd,&st); + ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st); if (ret == -1) return ret; @@ -540,7 +549,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len) fsp->fsp_name, (double)st.st_size )); flush_write_cache(fsp, SIZECHANGE_FLUSH); - if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fd, (SMB_OFF_T)len)) != -1) { + if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, (SMB_OFF_T)len)) != -1) { set_filelen_write_cache(fsp, len); } return ret; @@ -582,7 +591,7 @@ int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len) release_level_2_oplocks_on_change(fsp); DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len)); flush_write_cache(fsp, SIZECHANGE_FLUSH); - if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fd, len)) != -1) + if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, len)) != -1) set_filelen_write_cache(fsp, len); return ret; @@ -608,7 +617,7 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len) ssize_t pwrite_ret; release_level_2_oplocks_on_change(fsp); - ret = SMB_VFS_FSTAT(fsp,fsp->fd,&st); + ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st); if (ret == -1) { return ret; } @@ -637,7 +646,7 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len) while (total < num_to_write) { size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (num_to_write - total)); - pwrite_ret = SMB_VFS_PWRITE(fsp, fsp->fd, sparse_buf, curr_write_size, offset + total); + pwrite_ret = SMB_VFS_PWRITE(fsp, fsp->fh->fd, sparse_buf, curr_write_size, offset + total); if (pwrite_ret == -1) { DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file %s failed with error %s\n", fsp->fsp_name, strerror(errno) )); @@ -676,7 +685,7 @@ SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n) in_fsp = in; out_fsp = out; - return transfer_file_internal(in_fsp->fd, out_fsp->fd, n, read_fn, write_fn); + return transfer_file_internal(in_fsp->fh->fd, out_fsp->fh->fd, n, read_fn, write_fn); } /******************************************************************* diff --git a/source/tdb/tdb.c b/source/tdb/tdb.c index 47a2f070b68..2c94f945875 100644 --- a/source/tdb/tdb.c +++ b/source/tdb/tdb.c @@ -1309,7 +1309,7 @@ static int tdb_next_lock(TDB_CONTEXT *tdb, struct tdb_traverse_lock *tlock, if fn is NULL then it is not called a non-zero return value from fn() indicates that the traversal should stop */ -int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *private) +int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *private_val) { TDB_DATA key, dbuf; struct list_struct rec; @@ -1347,7 +1347,7 @@ int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *private) ret = -1; goto out; } - if (fn && fn(tdb, key, dbuf, private)) { + if (fn && fn(tdb, key, dbuf, private_val)) { /* They want us to terminate traversal */ ret = count; if (unlock_record(tdb, tl.off) != 0) { diff --git a/source/torture/cmd_vfs.c b/source/torture/cmd_vfs.c index 132e0776aba..974d3b8feed 100644 --- a/source/torture/cmd_vfs.c +++ b/source/torture/cmd_vfs.c @@ -129,7 +129,7 @@ static NTSTATUS cmd_opendir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc return NT_STATUS_OK; } - vfs->currentdir = SMB_VFS_OPENDIR(vfs->conn, argv[1]); + vfs->currentdir = SMB_VFS_OPENDIR(vfs->conn, argv[1], NULL, 0); if (vfs->currentdir == NULL) { printf("opendir error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; @@ -142,7 +142,7 @@ static NTSTATUS cmd_opendir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - struct dirent *dent; + SMB_STRUCT_DIRENT *dent; if (vfs->currentdir == NULL) { printf("readdir: error=-1 (no open directory)\n"); @@ -286,7 +286,7 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c vfs->files[fd] = SMB_MALLOC_P(struct files_struct); vfs->files[fd]->fsp_name = SMB_STRDUP(argv[1]); - vfs->files[fd]->fd = fd; + vfs->files[fd]->fh->fd = fd; vfs->files[fd]->conn = vfs->conn; printf("open: fd=%d\n", fd); return NT_STATUS_OK; diff --git a/source/torture/nbio.c b/source/torture/nbio.c index 4d61fa05312..e00fce02dbc 100644 --- a/source/torture/nbio.c +++ b/source/torture/nbio.c @@ -228,11 +228,11 @@ void nb_rmdir(const char *fname) } } -void nb_rename(const char *old, const char *new) +void nb_rename(const char *oldname, const char *newname) { - if (!cli_rename(c, old, new)) { + if (!cli_rename(c, oldname, newname)) { printf("ERROR: rename %s %s failed (%s)\n", - old, new, cli_errstr(c)); + oldname, newname, cli_errstr(c)); exit(1); } } diff --git a/source/torture/torture.c b/source/torture/torture.c index ef9497d9ad9..f59da14b795 100644 --- a/source/torture/torture.c +++ b/source/torture/torture.c @@ -210,16 +210,16 @@ static BOOL check_error(int line, struct cli_state *c, uint8 eclass, uint32 ecode, NTSTATUS nterr) { if (cli_is_dos_error(c)) { - uint8 class; + uint8 cclass; uint32 num; /* Check DOS error */ - cli_dos_error(c, &class, &num); + cli_dos_error(c, &cclass, &num); - if (eclass != class || ecode != num) { + if (eclass != cclass || ecode != num) { printf("unexpected error code class=%d code=%d\n", - (int)class, (int)num); + (int)cclass, (int)num); printf(" expected %d/%d %s (line=%d)\n", (int)eclass, (int)ecode, nt_errstr(nterr), line); return False; @@ -2114,7 +2114,7 @@ test how many open files this server supports on the one socket static BOOL run_maxfidtest(int dummy) { struct cli_state *cli; - const char *template = "\\maxfid.%d.%d"; + const char *ftemplate = "\\maxfid.%d.%d"; fstring fname; int fnums[0x11000], i; int retries=4; @@ -2130,7 +2130,7 @@ static BOOL run_maxfidtest(int dummy) cli_sockopt(cli, sockops); for (i=0; i<0x11000; i++) { - slprintf(fname,sizeof(fname)-1,template, i,(int)getpid()); + slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid()); if ((fnums[i] = cli_open(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) == -1) { @@ -2146,7 +2146,7 @@ static BOOL run_maxfidtest(int dummy) printf("cleaning up\n"); for (;i>=0;i--) { - slprintf(fname,sizeof(fname)-1,template, i,(int)getpid()); + slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid()); cli_close(cli, fnums[i]); if (!cli_unlink(cli, fname)) { printf("unlink of %s failed (%s)\n", diff --git a/source/ubiqx/debugparse.c b/source/ubiqx/debugparse.c index 195fc245bc0..c5fe3e2ee85 100644 --- a/source/ubiqx/debugparse.c +++ b/source/ubiqx/debugparse.c @@ -262,16 +262,16 @@ void dbg_test( void ) int i; int linecount = 1; dbg_Token old = dbg_null, - new = dbg_null, + newtok= dbg_null, state = dbg_null; while( fgets( bufr, DBG_BSIZE, stdin ) ) { for( i = 0; bufr[i]; i++ ) { - old = new; - new = dbg_char2token( &state, bufr[i] ); - switch( new ) + old = newtok; + newtok = dbg_char2token( &state, bufr[i] ); + switch( newtok ) { case dbg_header: if( linecount > 1 ) @@ -283,8 +283,8 @@ void dbg_test( void ) case dbg_ignore: break; default: - if( old != new ) - (void)printf( "\n[%05d]%12s: ", linecount, dbg_token2string(new) ); + if( old != newtok ) + (void)printf( "\n[%05d]%12s: ", linecount, dbg_token2string(newtok) ); (void)putchar( bufr[i] ); } } diff --git a/source/utils/debug2html.c b/source/utils/debug2html.c index f9a1f43f461..bec4d81ae2b 100644 --- a/source/utils/debug2html.c +++ b/source/utils/debug2html.c @@ -69,7 +69,7 @@ * Functions... */ -static dbg_Token modechange( dbg_Token new, dbg_Token mode ) +static dbg_Token modechange( dbg_Token newmode, dbg_Token mode ) /* ------------------------------------------------------------------------ ** * Handle a switch between header and message printing. * @@ -89,7 +89,7 @@ static dbg_Token modechange( dbg_Token new, dbg_Token mode ) * ------------------------------------------------------------------------ ** */ { - switch( new ) + switch( newmode ) { case dbg_null: case dbg_ignore: @@ -114,7 +114,7 @@ static dbg_Token modechange( dbg_Token new, dbg_Token mode ) return( mode ); } /* modechange */ -static void newblock( dbg_Token old, dbg_Token new ) +static void newblock( dbg_Token old, dbg_Token newtok ) /* ------------------------------------------------------------------------ ** * Handle the transition between tokens. * @@ -147,7 +147,7 @@ static void newblock( dbg_Token old, dbg_Token new ) break; } - switch( new ) + switch( newtok ) { case dbg_timestamp: (void)printf( "<B>[" ); @@ -223,7 +223,7 @@ int main( int argc, char *argv[] ) int len; char bufr[DBG_BSIZE]; dbg_Token old = dbg_null, - new = dbg_null, + newtok = dbg_null, state = dbg_null, mode = dbg_null; @@ -236,14 +236,14 @@ int main( int argc, char *argv[] ) { for( i = 0; i < len; i++ ) { - old = new; - new = dbg_char2token( &state, bufr[i] ); - if( new != old ) + old = newtok; + newtok = dbg_char2token( &state, bufr[i] ); + if( newtok != old ) { - mode = modechange( new, mode ); - newblock( old, new ); + mode = modechange( newtok, mode ); + newblock( old, newtok ); } - charprint( new, bufr[i] ); + charprint( newtok, bufr[i] ); } } (void)modechange( dbg_eof, mode ); diff --git a/source/utils/net.c b/source/utils/net.c index 61c366710c6..d4c96e9db8f 100644 --- a/source/utils/net.c +++ b/source/utils/net.c @@ -567,7 +567,7 @@ static int net_afs_key(int argc, const char **argv) struct afs_keyfile keyfile; if (argc != 2) { - d_printf("usage: 'net afskey <keyfile> cell'\n"); + d_printf("usage: 'net afs key <keyfile> cell'\n"); return -1; } diff --git a/source/utils/net.h b/source/utils/net.h index c67786cf9e3..a2df6596b47 100644 --- a/source/utils/net.h +++ b/source/utils/net.h @@ -32,7 +32,6 @@ typedef struct copy_clistate { struct cli_state *cli_share_dst; char *cwd; uint16 attribute; - int mode; }copy_clistate; /* INCLUDE FILES */ @@ -98,3 +97,16 @@ extern struct in_addr opt_dest_ip; extern const char *share_type[]; +/* Structure for mapping accounts to groups */ +/* Array element is the group rid */ +typedef struct _groupmap { + uint32 rid; + uint32 gidNumber; + fstring sambaSID; + fstring group_dn; +} GROUPMAP; + +typedef struct _accountmap { + uint32 rid; + fstring cn; +} ACCOUNTMAP; diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c index fb34b1e9e38..3f92404dda2 100644 --- a/source/utils/net_rpc.c +++ b/source/utils/net_rpc.c @@ -22,6 +22,8 @@ #include "includes.h" #include "utils/net.h" +static int net_mode_share; + /** * @file net_rpc.c * @@ -2848,18 +2850,15 @@ rpc_share_migrate_shares_internals(const DOM_SID *domain_sid, const char *domain /* finally add the share on the dst server */ - printf("migrating: [%s], path: %s, comment: %s, %s share-ACLs\n", - netname, path, remark, opt_acls ? "including" : "without" ); - - if (opt_verbose && opt_acls) - display_sec_desc(ctr_src.share.info502[i].info_502_str.sd); + printf("migrating: [%s], path: %s, comment: %s, without share-ACLs\n", + netname, path, remark); result = cli_srvsvc_net_share_add(cli_dst, mem_ctx, netname, type, remark, ctr_src.share.info502[i].info_502.perms, ctr_src.share.info502[i].info_502.max_uses, ctr_src.share.info502[i].info_502.num_uses, path, password, level, - opt_acls? ctr_src.share.info502[i].info_502_str.sd : NULL); + NULL); if (W_ERROR_V(result) == W_ERROR_V(WERR_ALREADY_EXISTS)) { printf(" [%s] does already exist\n", netname); @@ -2940,7 +2939,7 @@ static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state fstrcat(dir, "\\"); fstrcat(dir, f->name); - switch (local_state->mode) + switch (net_mode_share) { case NET_MODE_SHARE_MIGRATE: /* create that directory */ @@ -2954,7 +2953,7 @@ static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state False); break; default: - d_printf("Unsupported mode %d\n", local_state->mode); + d_printf("Unsupported mode %d\n", net_mode_share); return; } @@ -2983,7 +2982,7 @@ static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state DEBUG(3,("got file: %s\n", filename)); - switch (local_state->mode) + switch (net_mode_share) { case NET_MODE_SHARE_MIGRATE: nt_status = net_copy_file(local_state->mem_ctx, @@ -2996,7 +2995,7 @@ static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state True); break; default: - d_printf("Unsupported file mode %d\n", local_state->mode); + d_printf("Unsupported file mode %d\n", net_mode_share); return; } @@ -3040,7 +3039,7 @@ BOOL copy_top_level_perms(struct copy_clistate *cp_clistate, { NTSTATUS nt_status; - switch (cp_clistate->mode) { + switch (net_mode_share) { case NET_MODE_SHARE_MIGRATE: DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename)); nt_status = net_copy_fileattr(cp_clistate->mem_ctx, @@ -3053,7 +3052,7 @@ BOOL copy_top_level_perms(struct copy_clistate *cp_clistate, False); break; default: - d_printf("Unsupported mode %d\n", cp_clistate->mode); + d_printf("Unsupported mode %d\n", net_mode_share); break; } @@ -3098,9 +3097,6 @@ rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_ pstring mask = "\\*"; char *dst = NULL; - /* decrese argc and safe mode */ - cp_clistate.mode = argv[--argc][0]; - dst = SMB_STRDUP(opt_destination?opt_destination:"127.0.0.1"); result = get_share_info(cli, mem_ctx, level, argc, argv, &ctr_src); @@ -3124,13 +3120,13 @@ rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_ continue; } - switch (cp_clistate.mode) + switch (net_mode_share) { case NET_MODE_SHARE_MIGRATE: printf("syncing"); break; default: - d_printf("Unsupported mode %d\n", cp_clistate.mode); + d_printf("Unsupported mode %d\n", net_mode_share); break; } printf(" [%s] files and directories %s ACLs, %s DOS Attributes %s\n", @@ -3154,7 +3150,7 @@ rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_ got_src_share = True; - if (cp_clistate.mode == NET_MODE_SHARE_MIGRATE) { + if (net_mode_share == NET_MODE_SHARE_MIGRATE) { /* open share destination */ nt_status = connect_to_service(&cp_clistate.cli_share_dst, NULL, dst, netname, "A:"); @@ -3372,8 +3368,7 @@ static int rpc_share_migrate(int argc, const char **argv) {NULL, NULL} }; - char mode = NET_MODE_SHARE_MIGRATE; - argv[argc++] = &mode; + net_mode_share = NET_MODE_SHARE_MIGRATE; return net_run_function(argc, argv, func, rpc_share_usage); } @@ -3689,7 +3684,7 @@ static BOOL get_user_sids(const char *domain, const char *user, fstrcpy(request.data.name.dom_name, domain); fstrcpy(request.data.name.name, user); - result = winbindd_request(WINBINDD_LOOKUPNAME, &request, &response); + result = winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response); if (result != NSS_STATUS_SUCCESS) { DEBUG(1, ("winbind could not find %s\n", full_name)); @@ -3711,7 +3706,7 @@ static BOOL get_user_sids(const char *domain, const char *user, fstrcpy(request.data.username, full_name); - result = winbindd_request(WINBINDD_GETGROUPS, &request, &response); + result = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response); if (result != NSS_STATUS_SUCCESS) { DEBUG(1, ("winbind could not get groups of %s\n", full_name)); @@ -3730,7 +3725,7 @@ static BOOL get_user_sids(const char *domain, const char *user, sidrequest.data.gid = gid; - result = winbindd_request(WINBINDD_GID_TO_SID, + result = winbindd_request_response(WINBINDD_GID_TO_SID, &sidrequest, &sidresponse); if (result != NSS_STATUS_SUCCESS) { @@ -3774,7 +3769,7 @@ static BOOL get_user_tokens(int *num_tokens, struct user_token **user_tokens) ZERO_STRUCT(request); ZERO_STRUCT(response); - if (winbindd_request(WINBINDD_LIST_USERS, &request, &response) != + if (winbindd_request_response(WINBINDD_LIST_USERS, &request, &response) != NSS_STATUS_SUCCESS) return False; @@ -5994,6 +5989,7 @@ int net_rpc_help(int argc, const char **argv) {"trustdom", rpc_trustdom_usage}, /*{"abortshutdown", rpc_shutdown_abort_usage},*/ /*{"shutdown", rpc_shutdown_usage}, */ + {"vampire", rpc_vampire_usage}, {NULL, NULL} }; diff --git a/source/utils/net_rpc_samsync.c b/source/utils/net_rpc_samsync.c index 84872897fc5..dd3364dfcb0 100644 --- a/source/utils/net_rpc_samsync.c +++ b/source/utils/net_rpc_samsync.c @@ -4,6 +4,7 @@ Copyright (C) Andrew Tridgell 2002 Copyright (C) Tim Potter 2001,2002 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005 Modified by Volker Lendecke 2002 This program is free software; you can redistribute it and/or modify @@ -24,6 +25,12 @@ #include "includes.h" #include "utils/net.h" +/* uid's and gid's for writing deltas to ldif */ +static uint32 ldif_gid = 999; +static uint32 ldif_uid = 999; +/* Kkeep track of ldap initialization */ +static int init_ldap = 1; + static void display_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *g) { int i; @@ -425,10 +432,10 @@ sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta) /* Logon Hours */ if (delta->buf_logon_hrs.buffer) { - pstring old, new; - pdb_sethexhours(old, pdb_get_hours(account)); - pdb_sethexhours(new, delta->buf_logon_hrs.buffer); - if (!strequal(old, new)) + pstring oldstr, newstr; + pdb_sethexhours(oldstr, pdb_get_hours(account)); + pdb_sethexhours(newstr, delta->buf_logon_hrs.buffer); + if (!strequal(oldstr, newstr)) pdb_set_hours(account, (const char *)delta->buf_logon_hrs.buffer, PDB_CHANGED); } @@ -1148,6 +1155,985 @@ fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds, return result; } +static NTSTATUS +populate_ldap_for_ldif(fstring sid, const char *suffix, const char + *builtin_sid, FILE *add_fd) +{ + char *user_suffix, *group_suffix, *machine_suffix, *idmap_suffix; + char *user_attr=NULL, *group_attr=NULL; + char *suffix_attr; + int len; + + /* Get the suffix attribute */ + suffix_attr = sstring_sub(suffix, '=', ','); + if (suffix_attr == NULL) { + len = strlen(suffix); + suffix_attr = (char*)SMB_MALLOC(len+1); + memcpy(suffix_attr, suffix, len); + suffix_attr[len] = '\0'; + } + + /* Write the base */ + fprintf(add_fd, "# %s\n", suffix); + fprintf(add_fd, "dn: %s\n", suffix); + fprintf(add_fd, "objectClass: dcObject\n"); + fprintf(add_fd, "objectClass: organization\n"); + fprintf(add_fd, "o: %s\n", suffix_attr); + fprintf(add_fd, "dc: %s\n", suffix_attr); + fprintf(add_fd, "\n"); + fflush(add_fd); + + user_suffix = lp_ldap_user_suffix(); + /* If it exists and is distinct from other containers, + Write the Users entity */ + if (user_suffix && *user_suffix && + strcmp(user_suffix, suffix)) { + user_attr = sstring_sub(lp_ldap_user_suffix(), '=', ','); + fprintf(add_fd, "# %s\n", user_suffix); + fprintf(add_fd, "dn: %s\n", user_suffix); + fprintf(add_fd, "objectClass: organizationalUnit\n"); + fprintf(add_fd, "ou: %s\n", user_attr); + fprintf(add_fd, "\n"); + fflush(add_fd); + } + + + group_suffix = lp_ldap_group_suffix(); + /* If it exists and is distinct from other containers, + Write the Groups entity */ + if (group_suffix && *group_suffix && + strcmp(group_suffix, suffix)) { + group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ','); + fprintf(add_fd, "# %s\n", group_suffix); + fprintf(add_fd, "dn: %s\n", group_suffix); + fprintf(add_fd, "objectClass: organizationalUnit\n"); + fprintf(add_fd, "ou: %s\n", group_attr); + fprintf(add_fd, "\n"); + fflush(add_fd); + } + + /* If it exists and is distinct from other containers, + Write the Computers entity */ + machine_suffix = lp_ldap_machine_suffix(); + if (machine_suffix && *machine_suffix && + strcmp(machine_suffix, user_suffix) && + strcmp(machine_suffix, suffix)) { + fprintf(add_fd, "# %s\n", lp_ldap_machine_suffix()); + fprintf(add_fd, "dn: %s\n", lp_ldap_machine_suffix()); + fprintf(add_fd, "objectClass: organizationalUnit\n"); + fprintf(add_fd, "ou: %s\n", + sstring_sub(lp_ldap_machine_suffix(), '=', ',')); + fprintf(add_fd, "\n"); + fflush(add_fd); + } + + /* If it exists and is distinct from other containers, + Write the IdMap entity */ + idmap_suffix = lp_ldap_idmap_suffix(); + if (idmap_suffix && *idmap_suffix && + strcmp(idmap_suffix, user_suffix) && + strcmp(idmap_suffix, suffix)) { + fprintf(add_fd, "# %s\n", idmap_suffix); + fprintf(add_fd, "dn: %s\n", idmap_suffix); + fprintf(add_fd, "ObjectClass: organizationalUnit\n"); + fprintf(add_fd, "ou: %s\n", + sstring_sub(lp_ldap_idmap_suffix(), '=', ',')); + fprintf(add_fd, "\n"); + fflush(add_fd); + } + + /* Write the root entity */ + fprintf(add_fd, "# root, %s, %s\n", user_attr, suffix); + fprintf(add_fd, "dn: uid=root,ou=%s,%s\n", user_attr, suffix); + fprintf(add_fd, "cn: root\n"); + fprintf(add_fd, "sn: root\n"); + fprintf(add_fd, "objectClass: inetOrgPerson\n"); + fprintf(add_fd, "objectClass: sambaSAMAccount\n"); + fprintf(add_fd, "objectClass: posixAccount\n"); + fprintf(add_fd, "objectClass: shadowAccount\n"); + fprintf(add_fd, "gidNumber: 0\n"); + fprintf(add_fd, "uid: root\n"); + fprintf(add_fd, "uidNumber: 0\n"); + fprintf(add_fd, "homeDirectory: /home/root\n"); + fprintf(add_fd, "sambaPwdLastSet: 0\n"); + fprintf(add_fd, "sambaLogonTime: 0\n"); + fprintf(add_fd, "sambaLogoffTime: 2147483647\n"); + fprintf(add_fd, "sambaKickoffTime: 2147483647\n"); + fprintf(add_fd, "sambaPwdCanChange: 0\n"); + fprintf(add_fd, "sambaPwdMustChange: 2147483647\n"); + fprintf(add_fd, "sambaHomePath: \\\\PDC-SRV\root\n"); + fprintf(add_fd, "sambaHomeDrive: H:\n"); + fprintf(add_fd, "sambaProfilePath: \\\\PDC-SRV\\profiles\\root\n"); + fprintf(add_fd, "sambaprimaryGroupSID: %s-512\n", sid); + fprintf(add_fd, "sambaLMPassword: XXX\n"); + fprintf(add_fd, "sambaNTPassword: XXX\n"); + fprintf(add_fd, "sambaAcctFlags: [U\n"); + fprintf(add_fd, "sambaSID: %s-500\n", sid); + fprintf(add_fd, "loginShell: /bin/false\n"); + fprintf(add_fd, "\n"); + fflush(add_fd); + + /* Write the domain entity */ + fprintf(add_fd, "# %s, %s\n", lp_workgroup(), suffix); + fprintf(add_fd, "dn: sambaDomainName=%s,%s\n", lp_workgroup(), + suffix); + fprintf(add_fd, "objectClass: sambaDomain\n"); + fprintf(add_fd, "objectClass: sambaUnixIdPool\n"); + fprintf(add_fd, "sambaDomainName: %s\n", lp_workgroup()); + fprintf(add_fd, "sambaSID: %s\n", sid); + fprintf(add_fd, "uidNumber: %d\n", ++ldif_uid); + fprintf(add_fd, "gidNumber: %d\n", ++ldif_gid); + fprintf(add_fd, "\n"); + fflush(add_fd); + + /* Write user nobody entity */ + fprintf(add_fd, "# nobody, %s, %s\n", user_attr, suffix); + fprintf(add_fd, "dn: uid=nobody,ou=%s,%s\n", user_attr, suffix); + fprintf(add_fd, "cn: nobody\n"); + fprintf(add_fd, "sn: nobody\n"); + fprintf(add_fd, "objectClass: inetOrgPerson\n"); + fprintf(add_fd, "objectClass: sambaSAMAccount\n"); + fprintf(add_fd, "objectClass: posixAccount\n"); + fprintf(add_fd, "objectClass: shadowAccount\n"); + fprintf(add_fd, "gidNumber: 514\n"); + fprintf(add_fd, "uid: nobody\n"); + fprintf(add_fd, "uidNumber: 999\n"); + fprintf(add_fd, "homeDirectory: /dev/null\n"); + fprintf(add_fd, "sambaPwdLastSet: 0\n"); + fprintf(add_fd, "sambaLogonTime: 0\n"); + fprintf(add_fd, "sambaLogoffTime: 2147483647\n"); + fprintf(add_fd, "sambaKickoffTime: 2147483647\n"); + fprintf(add_fd, "sambaPwdCanChange: 0\n"); + fprintf(add_fd, "sambaPwdMustChange: 2147483647\n"); + fprintf(add_fd, "sambaHomePath: \\\\PDC-SMD3\\homes\\nobody\n"); + fprintf(add_fd, "sambaHomeDrive: H:\n"); + fprintf(add_fd, "sambaProfilePath: \\\\PDC-SMB3\\profiles\\nobody\n"); + fprintf(add_fd, "sambaprimaryGroupSID: %s-514\n", sid); + fprintf(add_fd, "sambaLMPassword: NOPASSWORDXXXXXXXXXXXXXXXXXXXXX\n"); + fprintf(add_fd, "sambaNTPassword: NOPASSWORDXXXXXXXXXXXXXXXXXXXXX\n"); + fprintf(add_fd, "sambaAcctFlags: [NU\n"); + fprintf(add_fd, "sambaSID: %s-2998\n", sid); + fprintf(add_fd, "loginShell: /bin/false\n"); + fprintf(add_fd, "\n"); + fflush(add_fd); + + /* Write the Domain Admins entity */ + fprintf(add_fd, "# Domain Admins, %s, %s\n", group_attr, + suffix); + fprintf(add_fd, "dn: cn=Domain Admins,ou=%s,%s\n", group_attr, + suffix); + fprintf(add_fd, "objectClass: posixGroup\n"); + fprintf(add_fd, "objectClass: sambaGroupMapping\n"); + fprintf(add_fd, "cn: Domain Admins\n"); + fprintf(add_fd, "memberUid: Administrator\n"); + fprintf(add_fd, "description: Netbios Domain Administrators\n"); + fprintf(add_fd, "gidNumber: 512\n"); + fprintf(add_fd, "sambaSID: %s-512\n", sid); + fprintf(add_fd, "sambaGroupType: 2\n"); + fprintf(add_fd, "displayName: Domain Admins\n"); + fprintf(add_fd, "\n"); + fflush(add_fd); + + /* Write the Domain Users entity */ + fprintf(add_fd, "# Domain Users, %s, %s\n", group_attr, + suffix); + fprintf(add_fd, "dn: cn=Domain Users,ou=%s,%s\n", group_attr, + suffix); + fprintf(add_fd, "objectClass: posixGroup\n"); + fprintf(add_fd, "objectClass: sambaGroupMapping\n"); + fprintf(add_fd, "cn: Domain Users\n"); + fprintf(add_fd, "description: Netbios Domain Users\n"); + fprintf(add_fd, "gidNumber: 513\n"); + fprintf(add_fd, "sambaSID: %s-513\n", sid); + fprintf(add_fd, "sambaGroupType: 2\n"); + fprintf(add_fd, "displayName: Domain Users\n"); + fprintf(add_fd, "\n"); + fflush(add_fd); + + /* Write the Domain Guests entity */ + fprintf(add_fd, "# Domain Guests, %s, %s\n", group_attr, + suffix); + fprintf(add_fd, "dn: cn=Domain Guests,ou=%s,%s\n", group_attr, + suffix); + fprintf(add_fd, "objectClass: posixGroup\n"); + fprintf(add_fd, "objectClass: sambaGroupMapping\n"); + fprintf(add_fd, "cn: Domain Guests\n"); + fprintf(add_fd, "description: Netbios Domain Guests\n"); + fprintf(add_fd, "gidNumber: 514\n"); + fprintf(add_fd, "sambaSID: %s-514\n", sid); + fprintf(add_fd, "sambaGroupType: 2\n"); + fprintf(add_fd, "displayName: Domain Guests\n"); + fprintf(add_fd, "\n"); + fflush(add_fd); + + /* Write the Domain Computers entity */ + fprintf(add_fd, "# Domain Computers, %s, %s\n", group_attr, + suffix); + fprintf(add_fd, "dn: cn=Domain Computers,ou=%s,%s\n", + group_attr, suffix); + fprintf(add_fd, "objectClass: posixGroup\n"); + fprintf(add_fd, "objectClass: sambaGroupMapping\n"); + fprintf(add_fd, "gidNumber: 515\n"); + fprintf(add_fd, "cn: Domain Computers\n"); + fprintf(add_fd, "description: Netbios Domain Computers accounts\n"); + fprintf(add_fd, "sambaSID: %s-515\n", sid); + fprintf(add_fd, "sambaGroupType: 2\n"); + fprintf(add_fd, "displayName: Domain Computers\n"); + fprintf(add_fd, "\n"); + fflush(add_fd); + + /* Write the Admininistrators Groups entity */ + fprintf(add_fd, "# Administrators, %s, %s\n", group_attr, + suffix); + fprintf(add_fd, "dn: cn=Administrators,ou=%s,%s\n", group_attr, + suffix); + fprintf(add_fd, "objectClass: posixGroup\n"); + fprintf(add_fd, "objectClass: sambaGroupMapping\n"); + fprintf(add_fd, "gidNumber: 544\n"); + fprintf(add_fd, "cn: Administrators\n"); + fprintf(add_fd, "description: Netbios Domain Members can fully administer the computer/sambaDomainName\n"); + fprintf(add_fd, "sambaSID: %s-544\n", builtin_sid); + fprintf(add_fd, "sambaGroupType: 5\n"); + fprintf(add_fd, "displayName: Administrators\n"); + fprintf(add_fd, "\n"); + + /* Write the Print Operator entity */ + fprintf(add_fd, "# Print Operators, %s, %s\n", group_attr, + suffix); + fprintf(add_fd, "dn: cn=Print Operators,ou=%s,%s\n", + group_attr, suffix); + fprintf(add_fd, "objectClass: posixGroup\n"); + fprintf(add_fd, "objectClass: sambaGroupMapping\n"); + fprintf(add_fd, "gidNumber: 550\n"); + fprintf(add_fd, "cn: Print Operators\n"); + fprintf(add_fd, "description: Netbios Domain Print Operators\n"); + fprintf(add_fd, "sambaSID: %s-550\n", builtin_sid); + fprintf(add_fd, "sambaGroupType: 5\n"); + fprintf(add_fd, "displayName: Print Operators\n"); + fprintf(add_fd, "\n"); + fflush(add_fd); + + /* Write the Backup Operators entity */ + fprintf(add_fd, "# Backup Operators, %s, %s\n", group_attr, + suffix); + fprintf(add_fd, "dn: cn=Backup Operators,ou=%s,%s\n", + group_attr, suffix); + fprintf(add_fd, "objectClass: posixGroup\n"); + fprintf(add_fd, "objectClass: sambaGroupMapping\n"); + fprintf(add_fd, "gidNumber: 551\n"); + fprintf(add_fd, "cn: Backup Operators\n"); + fprintf(add_fd, "description: Netbios Domain Members can bypass file security to back up files\n"); + fprintf(add_fd, "sambaSID: %s-551\n", builtin_sid); + fprintf(add_fd, "sambaGroupType: 5\n"); + fprintf(add_fd, "displayName: Backup Operators\n"); + fprintf(add_fd, "\n"); + fflush(add_fd); + + /* Write the Replicators entity */ + fprintf(add_fd, "# Replicators, %s, %s\n", group_attr, suffix); + fprintf(add_fd, "dn: cn=Replicators,ou=%s,%s\n", group_attr, + suffix); + fprintf(add_fd, "objectClass: posixGroup\n"); + fprintf(add_fd, "objectClass: sambaGroupMapping\n"); + fprintf(add_fd, "gidNumber: 552\n"); + fprintf(add_fd, "cn: Replicators\n"); + fprintf(add_fd, "description: Netbios Domain Supports file replication in a sambaDomainName\n"); + fprintf(add_fd, "sambaSID: %s-552\n", builtin_sid); + fprintf(add_fd, "sambaGroupType: 5\n"); + fprintf(add_fd, "displayName: Replicators\n"); + fprintf(add_fd, "\n"); + fflush(add_fd); + + /* Deallocate memory, and return */ + if (suffix_attr != NULL) SAFE_FREE(suffix_attr); + return NT_STATUS_OK; +} + +static NTSTATUS +map_populate_groups(GROUPMAP *groupmap, ACCOUNTMAP *accountmap, fstring sid, + const char *suffix, const char *builtin_sid) +{ + char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ','); + + /* Map the groups created by populate_ldap_for_ldif */ + groupmap[0].rid = 512; + groupmap[0].gidNumber = 512; + pstr_sprintf(groupmap[0].sambaSID, "%s-512", sid); + pstr_sprintf(groupmap[0].group_dn, "cn=Domain Admins,ou=%s,%s", + group_attr, suffix); + accountmap[0].rid = 512; + pstr_sprintf(accountmap[0].cn, "%s", "Domain Admins"); + + groupmap[1].rid = 513; + groupmap[1].gidNumber = 513; + pstr_sprintf(groupmap[1].sambaSID, "%s-513", sid); + pstr_sprintf(groupmap[1].group_dn, "cn=Domain Users,ou=%s,%s", + group_attr, suffix); + accountmap[1].rid = 513; + pstr_sprintf(accountmap[1].cn, "%s", "Domain Users"); + + groupmap[2].rid = 514; + groupmap[2].gidNumber = 514; + pstr_sprintf(groupmap[2].sambaSID, "%s-514", sid); + pstr_sprintf(groupmap[2].group_dn, "cn=Domain Guests,ou=%s,%s", + group_attr, suffix); + accountmap[2].rid = 514; + pstr_sprintf(accountmap[2].cn, "%s", "Domain Guests"); + + groupmap[3].rid = 515; + groupmap[3].gidNumber = 515; + pstr_sprintf(groupmap[3].sambaSID, "%s-515", sid); + pstr_sprintf(groupmap[3].group_dn, "cn=Domain Computers,ou=%s,%s", + group_attr, suffix); + accountmap[3].rid = 515; + pstr_sprintf(accountmap[3].cn, "%s", "Domain Computers"); + + groupmap[4].rid = 544; + groupmap[4].gidNumber = 544; + pstr_sprintf(groupmap[4].sambaSID, "%s-544", builtin_sid); + pstr_sprintf(groupmap[4].group_dn, "cn=Administrators,ou=%s,%s", + group_attr, suffix); + accountmap[4].rid = 515; + pstr_sprintf(accountmap[4].cn, "%s", "Administrators"); + + groupmap[5].rid = 550; + groupmap[5].gidNumber = 550; + pstr_sprintf(groupmap[5].sambaSID, "%s-550", builtin_sid); + pstr_sprintf(groupmap[5].group_dn, "cn=Print Operators,ou=%s,%s", + group_attr, suffix); + accountmap[5].rid = 550; + pstr_sprintf(accountmap[5].cn, "%s", "Print Operators"); + + groupmap[6].rid = 551; + groupmap[6].gidNumber = 551; + pstr_sprintf(groupmap[6].sambaSID, "%s-551", builtin_sid); + pstr_sprintf(groupmap[6].group_dn, "cn=Backup Operators,ou=%s,%s", + group_attr, suffix); + accountmap[6].rid = 551; + pstr_sprintf(accountmap[6].cn, "%s", "Backup Operators"); + + groupmap[7].rid = 552; + groupmap[7].gidNumber = 552; + pstr_sprintf(groupmap[7].sambaSID, "%s-552", builtin_sid); + pstr_sprintf(groupmap[7].group_dn, "cn=Replicators,ou=%s,%s", + group_attr, suffix); + accountmap[7].rid = 551; + pstr_sprintf(accountmap[7].cn, "%s", "Replicators"); + return NT_STATUS_OK; +} + +static NTSTATUS +fetch_group_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupmap, + FILE *add_fd, fstring sid, char *suffix) +{ + fstring groupname; + uint32 grouptype = 0, g_rid = 0; + char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ','); + + /* Get the group name */ + unistr2_to_ascii(groupname, + &(delta->group_info.uni_grp_name), + sizeof(groupname)-1); + + /* Set up the group type (always 2 for group info) */ + grouptype = 2; + + /* These groups are entered by populate_ldap_for_ldif */ + if (strcmp(groupname, "Domain Admins") == 0 || + strcmp(groupname, "Domain Users") == 0 || + strcmp(groupname, "Domain Guests") == 0 || + strcmp(groupname, "Domain Computers") == 0 || + strcmp(groupname, "Administrators") == 0 || + strcmp(groupname, "Print Operators") == 0 || + strcmp(groupname, "Backup Operators") == 0 || + strcmp(groupname, "Replicators") == 0) { + return NT_STATUS_OK; + } else { + /* Increment the gid for the new group */ + ldif_gid++; + } + + /* Map the group rid, gid, and dn */ + g_rid = delta->group_info.gid.g_rid; + groupmap->rid = g_rid; + groupmap->gidNumber = ldif_gid; + pstr_sprintf(groupmap->sambaSID, "%s-%d", sid, g_rid); + pstr_sprintf(groupmap->group_dn, + "cn=%s,ou=%s,%s", groupname, group_attr, suffix); + + /* Write the data to the temporary add ldif file */ + fprintf(add_fd, "# %s, %s, %s\n", groupname, group_attr, + suffix); + fprintf(add_fd, "dn: cn=%s,ou=%s,%s\n", groupname, group_attr, + suffix); + fprintf(add_fd, "objectClass: posixGroup\n"); + fprintf(add_fd, "objectClass: sambaGroupMapping\n"); + fprintf(add_fd, "cn: %s\n", groupname); + fprintf(add_fd, "gidNumber: %d\n", ldif_gid); + fprintf(add_fd, "sambaSID: %s\n", groupmap->sambaSID); + fprintf(add_fd, "sambaGroupType: %d\n", grouptype); + fprintf(add_fd, "displayName: %s\n", groupname); + fprintf(add_fd, "\n"); + fflush(add_fd); + + /* Return */ + return NT_STATUS_OK; +} + +static NTSTATUS +fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupmap, + ACCOUNTMAP *accountmap, FILE *add_fd, + fstring sid, char *suffix, int alloced) +{ + fstring username, homedir, logonscript, homedrive, homepath; + fstring hex_nt_passwd, hex_lm_passwd; + fstring description, fullname, sambaSID; + uchar lm_passwd[16], nt_passwd[16]; + char *flags; + const char *blank = "", *shell = "/bin/bash"; + const char* nopasswd = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; + static uchar zero_buf[16]; + uint32 rid = 0, group_rid = 0, gidNumber = 0; + time_t unix_time; + int i; + + /* Get the username */ + unistr2_to_ascii(username, + &(delta->account_info.uni_acct_name), + sizeof(username)-1); + + /* Get the rid */ + rid = delta->account_info.user_rid; + + /* Map the rid and username for group member info later */ + accountmap->rid = rid; + pstr_sprintf(accountmap->cn, "%s", username); + + /* Get the home directory */ + unistr2_to_ascii(homedir, &(delta->account_info.uni_home_dir), + sizeof(homedir)-1); + if (strcmp(homedir, blank) == 0) { + pstr_sprintf(homedir, "/home/%s", username); + } else { + strncpy(homepath, homedir, sizeof(homepath)); + } + + /* Get the logon script */ + unistr2_to_ascii(logonscript, &(delta->account_info.uni_logon_script), + sizeof(logonscript)-1); + + /* Get the home drive */ + unistr2_to_ascii(homedrive, &(delta->account_info.uni_dir_drive), + sizeof(homedrive)-1); + + /* Get the description */ + unistr2_to_ascii(description, &(delta->account_info.uni_acct_desc), + sizeof(description)-1); + if (strcmp(description, blank) == 0) { + pstr_sprintf(description, "System User"); + } + + /* Get the display name */ + unistr2_to_ascii(fullname, &(delta->account_info.uni_full_name), + sizeof(fullname)-1); + + /* Get lm and nt password data */ + if (memcmp(delta->account_info.pass.buf_lm_pwd, zero_buf, 16) != 0) { + sam_pwd_hash(delta->account_info.user_rid, + delta->account_info.pass.buf_lm_pwd, + lm_passwd, 0); + pdb_sethexpwd(hex_lm_passwd, lm_passwd, + delta->account_info.acb_info); + } else { + pdb_sethexpwd(hex_lm_passwd, NULL, 0); + } + if (memcmp(delta->account_info.pass.buf_nt_pwd, zero_buf, 16) != 0) { + sam_pwd_hash(delta->account_info.user_rid, + delta->account_info.pass.buf_nt_pwd, + nt_passwd, 0); + pdb_sethexpwd(hex_nt_passwd, nt_passwd, + delta->account_info.acb_info); + } else { + pdb_sethexpwd(hex_nt_passwd, NULL, 0); + } + unix_time = nt_time_to_unix(&(delta->account_info.pwd_last_set_time)); + + /* The nobody user is entered by populate_ldap_for_ldif */ + if (strcmp(username, "nobody") == 0) { + return NT_STATUS_OK; + } else { + /* Increment the uid for the new user */ + ldif_uid++; + } + + /* Set up group id and sambaSID for the user */ + group_rid = delta->account_info.group_rid; + for (i=0; i<alloced; i++) { + if (groupmap[i].rid == group_rid) break; + } + if (i == alloced){ + DEBUG(1, ("Could not find rid %d in groupmap array\n", + group_rid)); + return NT_STATUS_UNSUCCESSFUL; + } + gidNumber = groupmap[i].gidNumber; + pstr_sprintf(sambaSID, groupmap[i].sambaSID); + + /* Set up sambaAcctFlags */ + flags = pdb_encode_acct_ctrl(delta->account_info.acb_info, + NEW_PW_FORMAT_SPACE_PADDED_LEN); + + /* Add the user to the temporary add ldif file */ + fprintf(add_fd, "# %s, %s, %s\n", username, + sstring_sub(lp_ldap_user_suffix(), '=', ','), suffix); + fprintf(add_fd, "dn: uid=%s,ou=%s,%s\n", username, + sstring_sub(lp_ldap_user_suffix(), '=', ','), suffix); + fprintf(add_fd, "ObjectClass: top\n"); + fprintf(add_fd, "objectClass: inetOrgPerson\n"); + fprintf(add_fd, "objectClass: posixAccount\n"); + fprintf(add_fd, "objectClass: shadowAccount\n"); + fprintf(add_fd, "objectClass: sambaSamAccount\n"); + fprintf(add_fd, "cn: %s\n", username); + fprintf(add_fd, "sn: %s\n", username); + fprintf(add_fd, "uid: %s\n", username); + fprintf(add_fd, "uidNumber: %d\n", ldif_uid); + fprintf(add_fd, "gidNumber: %d\n", gidNumber); + fprintf(add_fd, "homeDirectory: %s\n", homedir); + if (strcmp(homepath, blank) != 0) + fprintf(add_fd, "SambaHomePath: %s\n", homepath); + if (strcmp(homedrive, blank) != 0) + fprintf(add_fd, "SambaHomeDrive: %s\n", homedrive); + if (strcmp(logonscript, blank) != 0) + fprintf(add_fd, "SambaLogonScript: %s\n", logonscript); + fprintf(add_fd, "loginShell: %s\n", shell); + fprintf(add_fd, "gecos: System User\n"); + fprintf(add_fd, "description: %s\n", description); + fprintf(add_fd, "sambaSID: %s-%d\n", sid, rid); + fprintf(add_fd, "sambaPrimaryGroupSID: %s\n", sambaSID); + if(strcmp(fullname, blank) != 0) + fprintf(add_fd, "displayName: %s\n", fullname); + if (strcmp(nopasswd, hex_lm_passwd) != 0) + fprintf(add_fd, "sambaLMPassword: %s\n", hex_lm_passwd); + if (strcmp(nopasswd, hex_nt_passwd) != 0) + fprintf(add_fd, "sambaNTPassword: %s\n", hex_nt_passwd); + fprintf(add_fd, "sambaPwdLastSet: %d\n", unix_time); + fprintf(add_fd, "sambaAcctFlags: %s\n", flags); + fprintf(add_fd, "\n"); + fflush(add_fd); + + /* Return */ + return NT_STATUS_OK; +} + +static NTSTATUS +fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupmap, + FILE *add_fd, fstring sid, char *suffix, + unsigned db_type) +{ + fstring aliasname, description; + uint32 grouptype = 0, g_rid = 0; + char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ','); + + /* Get the alias name */ + unistr2_to_ascii(aliasname, &(delta->alias_info.uni_als_name), + sizeof(aliasname)-1); + + /* Get the alias description */ + unistr2_to_ascii(description, &(delta->alias_info.uni_als_desc), + sizeof(description)-1); + + /* Set up the group type */ + switch (db_type) { + case SAM_DATABASE_DOMAIN: + grouptype = 4; + break; + case SAM_DATABASE_BUILTIN: + grouptype = 5; + break; + default: + grouptype = 4; + break; + } + + /* + These groups are entered by populate_ldap_for_ldif + Note that populate creates a group called Relicators, + but NT returns a group called Replicator + */ + if (strcmp(aliasname, "Domain Admins") == 0 || + strcmp(aliasname, "Domain Users") == 0 || + strcmp(aliasname, "Domain Guests") == 0 || + strcmp(aliasname, "Domain Computers") == 0 || + strcmp(aliasname, "Administrators") == 0 || + strcmp(aliasname, "Print Operators") == 0 || + strcmp(aliasname, "Backup Operators") == 0 || + strcmp(aliasname, "Replicator") == 0) { + return NT_STATUS_OK; + } else { + /* Increment the gid for the new group */ + ldif_gid++; + } + + /* Map the group rid and gid */ + g_rid = delta->group_info.gid.g_rid; + groupmap->gidNumber = ldif_gid; + pstr_sprintf(groupmap->sambaSID, "%s-%d", sid, g_rid); + + /* Write the data to the temporary add ldif file */ + fprintf(add_fd, "# %s, %s, %s\n", aliasname, group_attr, + suffix); + fprintf(add_fd, "dn: cn=%s,ou=%s,%s\n", aliasname, group_attr, + suffix); + fprintf(add_fd, "objectClass: posixGroup\n"); + fprintf(add_fd, "objectClass: sambaGroupMapping\n"); + fprintf(add_fd, "cn: %s\n", aliasname); + fprintf(add_fd, "gidNumber: %d\n", ldif_gid); + fprintf(add_fd, "sambaSID: %s\n", groupmap->sambaSID); + fprintf(add_fd, "sambaGroupType: %d\n", grouptype); + fprintf(add_fd, "displayName: %s\n", aliasname); + fprintf(add_fd, "description: %s\n", description); + fprintf(add_fd, "\n"); + fflush(add_fd); + + /* Return */ + return NT_STATUS_OK; +} + +static NTSTATUS +fetch_groupmem_info_to_ldif(SAM_DELTA_CTR *delta, SAM_DELTA_HDR *hdr_delta, + GROUPMAP *groupmap, ACCOUNTMAP *accountmap, + FILE *mod_fd, int alloced) +{ + fstring group_dn; + uint32 group_rid = 0, rid = 0; + int i, j, k; + + /* Get the dn for the group */ + if (delta->grp_mem_info.num_members > 0) { + group_rid = hdr_delta->target_rid; + for (j=0; j<alloced; j++) { + if (groupmap[j].rid == group_rid) break; + } + if (j == alloced){ + DEBUG(1, ("Could not find rid %d in groupmap array\n", + group_rid)); + return NT_STATUS_UNSUCCESSFUL; + } + pstr_sprintf(group_dn, "%s", groupmap[j].group_dn); + fprintf(mod_fd, "dn: %s\n", group_dn); + + /* Get the cn for each member */ + for (i=0; i<delta->grp_mem_info.num_members; i++) { + rid = delta->grp_mem_info.rids[i]; + for (k=0; k<alloced; k++) { + if (accountmap[k].rid == rid) break; + } + if (k == alloced){ + DEBUG(1, ("Could not find rid %d in accountmap array\n", rid)); + return NT_STATUS_UNSUCCESSFUL; + } + fprintf(mod_fd, "memberUid: %s\n", accountmap[k].cn); + } + fprintf(mod_fd, "\n"); + } + fflush(mod_fd); + + /* Return */ + return NT_STATUS_OK; +} + +static NTSTATUS +fetch_database_to_ldif(struct cli_state *cli, unsigned db_type, + DOM_CRED *ret_creds, DOM_SID dom_sid, + const char *user_file) +{ + char *suffix; + const char *builtin_sid = "S-1-5-32"; + char *ldif_file; + fstring sid, domainname; + unsigned sync_context = 0; + NTSTATUS result; + int k; + TALLOC_CTX *mem_ctx; + SAM_DELTA_HDR *hdr_deltas; + SAM_DELTA_CTR *deltas; + uint32 num_deltas; + const char *add_ldif = "/tmp/add.ldif", *mod_ldif = "/tmp/mod.ldif"; + FILE *add_fd, *mod_fd, *ldif_fd; + char sys_cmd[1024]; + int num_alloced = 0, g_index = 0, a_index = 0; + + /* Set up array for mapping accounts to groups */ + /* Array element is the group rid */ + GROUPMAP *groupmap = NULL; + + /* Set up array for mapping account rid's to cn's */ + /* Array element is the account rid */ + ACCOUNTMAP *accountmap = NULL; + + /* Ensure we have an output file */ + if (user_file) + ldif_file = user_file; + else + ldif_file = "/tmp/tmp.ldif"; + + /* Open the add and mod ldif files */ + add_fd = fopen(add_ldif, "a"); + mod_fd = fopen(mod_ldif, "a"); + if (add_fd == NULL || mod_fd == NULL) { + DEBUG(1, ("Could not open %s\n", add_ldif)); + return NT_STATUS_UNSUCCESSFUL; + } + + /* Open the user's ldif file */ + ldif_fd = fopen(ldif_file, "a"); + if (ldif_fd == NULL) { + DEBUG(1, ("Could not open %s\n", ldif_file)); + return NT_STATUS_UNSUCCESSFUL; + } + + if (!(mem_ctx = talloc_init("fetch_database"))) { + return NT_STATUS_NO_MEMORY; + } + + /* Get the sid */ + sid_to_string(sid, &dom_sid); + + /* Get the ldap suffix */ + suffix = lp_ldap_suffix(); + if (suffix == NULL || strcmp(suffix, "") == 0) { + DEBUG(0,("ldap suffix missing from smb.conf--exiting\n")); + exit(1); + } + + /* Get other smb.conf data */ + if (!(lp_workgroup()) || !*(lp_workgroup())) { + DEBUG(0,("workgroup missing from smb.conf--exiting\n")); + exit(1); + } + + /* Allocate initial memory for groupmap and accountmap arrays */ + if (init_ldap == 1) { + groupmap = SMB_MALLOC_ARRAY(GROUPMAP, 8); + accountmap = SMB_MALLOC_ARRAY(ACCOUNTMAP, 8); + if (groupmap == NULL || accountmap == NULL) { + DEBUG(1,("GROUPMAP malloc failed\n")); + return NT_STATUS_NO_MEMORY; + } + + /* Initialize the arrays */ + memset(groupmap, 0, sizeof(GROUPMAP)*8); + memset(accountmap, 0, sizeof(ACCOUNTMAP)*8); + + /* Remember how many we malloced */ + num_alloced = 8; + + /* Initial database population */ + populate_ldap_for_ldif(sid, suffix, builtin_sid, add_fd); + map_populate_groups(groupmap, accountmap, sid, suffix, + builtin_sid); + + /* Don't do this again */ + init_ldap = 0; + } + + /* Announce what we are doing */ + switch( db_type ) { + case SAM_DATABASE_DOMAIN: + d_printf("Fetching DOMAIN database\n"); + break; + case SAM_DATABASE_BUILTIN: + d_printf("Fetching BUILTIN database\n"); + break; + case SAM_DATABASE_PRIVS: + d_printf("Fetching PRIVS databases\n"); + break; + default: + d_printf("Fetching unknown database type %u\n", db_type ); + break; + } + + do { + result = cli_netlogon_sam_sync(cli, mem_ctx, ret_creds, + db_type, sync_context, + &num_deltas, &hdr_deltas, + &deltas); + if (!NT_STATUS_IS_OK(result) && + !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { + return NT_STATUS_OK; + } + + clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), + ret_creds); + + /* Re-allocate memory for groupmap and accountmap arrays */ + groupmap = SMB_REALLOC_ARRAY(groupmap, GROUPMAP, + num_deltas+num_alloced); + accountmap = SMB_REALLOC_ARRAY(accountmap, ACCOUNTMAP, + num_deltas+num_alloced); + if (groupmap == NULL || accountmap == NULL) { + DEBUG(1,("GROUPMAP malloc failed\n")); + return NT_STATUS_NO_MEMORY; + } + + /* Initialize the new records */ + memset(&groupmap[num_alloced], 0, + sizeof(GROUPMAP)*num_deltas); + memset(&accountmap[num_alloced], 0, + sizeof(ACCOUNTMAP)*num_deltas); + + /* Remember how many we alloced this time */ + num_alloced += num_deltas; + + /* Loop through the deltas */ + for (k=0; k<num_deltas; k++) { + switch(hdr_deltas[k].type) { + case SAM_DELTA_DOMAIN_INFO: + /* Is this case needed? */ + unistr2_to_ascii(domainname, + &deltas[k].domain_info.uni_dom_name, + sizeof(domainname)-1); + break; + + case SAM_DELTA_GROUP_INFO: + fetch_group_info_to_ldif( + &deltas[k], &groupmap[g_index], + add_fd, sid, suffix); + g_index++; + break; + + case SAM_DELTA_ACCOUNT_INFO: + fetch_account_info_to_ldif( + &deltas[k], groupmap, + &accountmap[a_index], add_fd, + sid, suffix, num_alloced); + a_index++; + break; + + case SAM_DELTA_ALIAS_INFO: + fetch_alias_info_to_ldif( + &deltas[k], &groupmap[g_index], + add_fd, sid, suffix, db_type); + g_index++; + break; + + case SAM_DELTA_GROUP_MEM: + fetch_groupmem_info_to_ldif( + &deltas[k], &hdr_deltas[k], + groupmap, accountmap, + mod_fd, num_alloced); + break; + + case SAM_DELTA_ALIAS_MEM: + break; + case SAM_DELTA_POLICY_INFO: + break; + case SAM_DELTA_PRIVS_INFO: + break; + case SAM_DELTA_TRUST_DOMS: + /* Implemented but broken */ + break; + case SAM_DELTA_SECRET_INFO: + /* Implemented but broken */ + break; + case SAM_DELTA_RENAME_GROUP: + /* Not yet implemented */ + break; + case SAM_DELTA_RENAME_USER: + /* Not yet implemented */ + break; + case SAM_DELTA_RENAME_ALIAS: + /* Not yet implemented */ + break; + case SAM_DELTA_DELETE_GROUP: + /* Not yet implemented */ + break; + case SAM_DELTA_DELETE_USER: + /* Not yet implemented */ + break; + case SAM_DELTA_MODIFIED_COUNT: + break; + default: + break; + } /* end of switch */ + } /* end of for loop */ + + /* Increment sync_context */ + sync_context += 1; + + } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); + + /* Close the ldif files */ + fclose(add_fd); + fclose(mod_fd); + + /* Write ldif data to the user's file */ + if (db_type == SAM_DATABASE_DOMAIN) { + fprintf(ldif_fd, + "# SAM_DATABASE_DOMAIN: ADD ENTITIES\n"); + fprintf(ldif_fd, + "# =================================\n\n"); + fflush(ldif_fd); + } else if (db_type == SAM_DATABASE_BUILTIN) { + fprintf(ldif_fd, + "# SAM_DATABASE_BUILTIN: ADD ENTITIES\n"); + fprintf(ldif_fd, + "# ==================================\n\n"); + fflush(ldif_fd); + } + pstr_sprintf(sys_cmd, "cat %s >> %s", add_ldif, ldif_file); + system(sys_cmd); + if (db_type == SAM_DATABASE_DOMAIN) { + fprintf(ldif_fd, + "# SAM_DATABASE_DOMAIN: MODIFY ENTITIES\n"); + fprintf(ldif_fd, + "# ====================================\n\n"); + fflush(ldif_fd); + } else if (db_type == SAM_DATABASE_BUILTIN) { + fprintf(ldif_fd, + "# SAM_DATABASE_BUILTIN: MODIFY ENTITIES\n"); + fprintf(ldif_fd, + "# =====================================\n\n"); + fflush(ldif_fd); + } + pstr_sprintf(sys_cmd, "cat %s >> %s", mod_ldif, ldif_file); + system(sys_cmd); + + /* Delete the temporary ldif files */ + pstr_sprintf(sys_cmd, "rm -f %s %s", add_ldif, mod_ldif); + system(sys_cmd); + + /* Close the ldif file */ + fclose(ldif_fd); + + /* Deallocate memory for the mapping arrays */ + SAFE_FREE(groupmap); + SAFE_FREE(accountmap); + + /* Return */ + talloc_destroy(mem_ctx); + return NT_STATUS_OK; +} + +/** + * Basic usage function for 'net rpc vampire' + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + **/ + +int rpc_vampire_usage(int argc, const char **argv) +{ + d_printf("net rpc vampire [ldif [<ldif-filename>] [options]\n"\ + "\t to pull accounts from a remote PDC where we are a BDC\n"\ + "\t\t no args puts accounts in local passdb from smb.conf\n"\ + "\t\t ldif - put accounts in ldif format (file defaults to /tmp/tmp.ldif\n"); + + net_common_flags_usage(argc, argv); + return -1; +} + + /* dump sam database via samsync rpc calls */ NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid, const char *domain_name, @@ -1193,7 +2179,13 @@ NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid, goto fail; } - result = fetch_database(cli, SAM_DATABASE_DOMAIN, &ret_creds, *domain_sid); + if (argc >= 1 && (strcmp(argv[0], "ldif") == 0)) { + result = fetch_database_to_ldif(cli, SAM_DATABASE_DOMAIN, + &ret_creds, *domain_sid, argv[1]); + } else { + result = fetch_database(cli, SAM_DATABASE_DOMAIN, &ret_creds, + *domain_sid); + } if (!NT_STATUS_IS_OK(result)) { d_printf("Failed to fetch domain database: %s\n", @@ -1204,8 +2196,14 @@ NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid, goto fail; } - result = fetch_database(cli, SAM_DATABASE_BUILTIN, &ret_creds, - global_sid_Builtin); + if (argc >= 1 && (strcmp(argv[0], "ldif") == 0)) { + result = fetch_database_to_ldif(cli, SAM_DATABASE_BUILTIN, + &ret_creds, global_sid_Builtin, + argv[1]); + } else { + result = fetch_database(cli, SAM_DATABASE_BUILTIN, &ret_creds, + global_sid_Builtin); + } if (!NT_STATUS_IS_OK(result)) { d_printf("Failed to fetch builtin database: %s\n", @@ -1219,3 +2217,4 @@ NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid, fail: return result; } + diff --git a/source/utils/nmblookup.c b/source/utils/nmblookup.c index 4ed42847867..d1d735f7f9e 100644 --- a/source/utils/nmblookup.c +++ b/source/utils/nmblookup.c @@ -101,7 +101,7 @@ static void do_node_status(int fd, const char *name, int type, struct in_addr ip { struct nmb_name nname; int count, i, j; - struct node_status *status; + NODE_STATUS_STRUCT *status; struct node_status_extra extra; fstring cleanname; diff --git a/source/utils/ntlm_auth.c b/source/utils/ntlm_auth.c index fcaad18ef60..6d5737aad4a 100644 --- a/source/utils/ntlm_auth.c +++ b/source/utils/ntlm_auth.c @@ -105,7 +105,7 @@ static char winbind_separator(void) /* Send off request */ - if (winbindd_request(WINBINDD_INFO, NULL, &response) != + if (winbindd_request_response(WINBINDD_INFO, NULL, &response) != NSS_STATUS_SUCCESS) { d_printf("could not obtain winbind separator!\n"); return *lp_winbind_separator(); @@ -135,7 +135,7 @@ const char *get_winbind_domain(void) /* Send off request */ - if (winbindd_request(WINBINDD_DOMAIN_NAME, NULL, &response) != + if (winbindd_request_response(WINBINDD_DOMAIN_NAME, NULL, &response) != NSS_STATUS_SUCCESS) { DEBUG(0, ("could not obtain winbind domain name!\n")); return lp_workgroup(); @@ -161,7 +161,7 @@ const char *get_winbind_netbios_name(void) /* Send off request */ - if (winbindd_request(WINBINDD_NETBIOS_NAME, NULL, &response) != + if (winbindd_request_response(WINBINDD_NETBIOS_NAME, NULL, &response) != NSS_STATUS_SUCCESS) { DEBUG(0, ("could not obtain winbind netbios name!\n")); return global_myname(); @@ -231,7 +231,7 @@ static BOOL get_require_membership_sid(void) { return False; } - if (winbindd_request(WINBINDD_LOOKUPNAME, &request, &response) != + if (winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response) != NSS_STATUS_SUCCESS) { DEBUG(0, ("Winbindd lookupname failed to resolve %s into a SID!\n", require_membership_of)); @@ -268,7 +268,7 @@ static BOOL check_plaintext_auth(const char *user, const char *pass, if (require_membership_of_sid) fstrcpy(request.data.auth.require_membership_of_sid, require_membership_of_sid); - result = winbindd_request(WINBINDD_PAM_AUTH, &request, &response); + result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response); /* Display response */ @@ -348,7 +348,7 @@ NTSTATUS contact_winbind_auth_crap(const char *username, request.data.auth_crap.nt_resp_len = nt_response->length; } - result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response); + result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response); /* Display response */ diff --git a/source/utils/pdbedit.c b/source/utils/pdbedit.c index 88ec6b1f4fa..7c934cdb6c5 100644 --- a/source/utils/pdbedit.c +++ b/source/utils/pdbedit.c @@ -76,9 +76,9 @@ static int export_database (struct pdb_context *in, struct pdb_context while (NT_STATUS_IS_OK(in->pdb_getsampwent(in, user))) { DEBUG(4, ("Processing account %s\n", - user->private.username)); + user->private_u.username)); if (!username || - (strcmp(username, user->private.username) + (strcmp(username, user->private_u.username) == 0)) { out->pdb_add_sam_account(out, user); if (!NT_STATUS_IS_OK(pdb_reset_sam(user))) { diff --git a/source/utils/profiles.c b/source/utils/profiles.c index 0830d6b74b0..b718770ba34 100644 --- a/source/utils/profiles.c +++ b/source/utils/profiles.c @@ -395,7 +395,7 @@ static void print_sid(DOM_SID *sid); int verbose = 1; DOM_SID old_sid, new_sid; -int change = 0, new = 0; +int change = 0, new_val = 0; /* Compare two SIDs for equality */ static int my_sid_equal(DOM_SID *s1, DOM_SID *s2) @@ -562,7 +562,7 @@ int main(int argc, char *argv[]) break; case 'n': - new = 1; + new_val = 1; if (!get_sid(&new_sid, poptGetOptArg(pc))) { fprintf(stderr, "Argument to -n should be a SID in form of S-1-5-...\n"); poptPrintUsage(pc, stderr, 0); @@ -584,7 +584,7 @@ int main(int argc, char *argv[]) exit(1); } - if ((!change & new) || (change & !new)) { + if ((!change & new_val) || (change & !new_val)) { fprintf(stderr, "You must specify both -c and -n if one or the other is set!\n"); poptPrintUsage(pc, stderr, 0); exit(252); diff --git a/source/utils/smbcacls.c b/source/utils/smbcacls.c index 048ec8dc3ef..00000b5cfbe 100644 --- a/source/utils/smbcacls.c +++ b/source/utils/smbcacls.c @@ -318,7 +318,7 @@ static BOOL parse_ace(SEC_ACE *ace, char *str) /* add an ACE to a list of ACEs in a SEC_ACL */ static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace) { - SEC_ACL *new; + SEC_ACL *new_ace; SEC_ACE *aces; if (! *the_acl) { (*the_acl) = make_sec_acl(ctx, 3, 1, ace); @@ -328,9 +328,9 @@ static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace) aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces); memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE)); memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE)); - new = make_sec_acl(ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces); + new_ace = make_sec_acl(ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces); SAFE_FREE(aces); - (*the_acl) = new; + (*the_acl) = new_ace; return True; } diff --git a/source/utils/status.c b/source/utils/status.c index 75e7cb3de71..f3c88616662 100644 --- a/source/utils/status.c +++ b/source/utils/status.c @@ -111,37 +111,47 @@ static void print_share_mode(share_mode_entry *e, char *fname) count++; if (Ucrit_checkPid(e->pid)) { - d_printf("%-5d ",(int)e->pid); - switch (GET_DENY_MODE(e->share_mode)) { - case DENY_NONE: d_printf("DENY_NONE "); break; - case DENY_ALL: d_printf("DENY_ALL "); break; - case DENY_DOS: d_printf("DENY_DOS "); break; - case DENY_READ: d_printf("DENY_READ "); break; - case DENY_WRITE:printf("DENY_WRITE "); break; - case DENY_FCB: d_printf("DENY_FCB "); break; - } - d_printf("0x%-8x ",(unsigned int)e->desired_access); - switch (e->share_mode&0xF) { - case 0: d_printf("RDONLY "); break; - case 1: d_printf("WRONLY "); break; - case 2: d_printf("RDWR "); break; - } - - if((e->op_type & - (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) == - (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) - d_printf("EXCLUSIVE+BATCH "); - else if (e->op_type & EXCLUSIVE_OPLOCK) - d_printf("EXCLUSIVE "); - else if (e->op_type & BATCH_OPLOCK) - d_printf("BATCH "); - else if (e->op_type & LEVEL_II_OPLOCK) - d_printf("LEVEL_II "); - else - d_printf("NONE "); - - d_printf(" %s %s",fname, - asctime(LocalTime((time_t *)&e->time.tv_sec))); + d_printf("%-5d ",(int)e->pid); + switch (map_share_mode_to_deny_mode(e->share_access, + e->private_options)) { + case DENY_NONE: d_printf("DENY_NONE "); break; + case DENY_ALL: d_printf("DENY_ALL "); break; + case DENY_DOS: d_printf("DENY_DOS "); break; + case DENY_READ: d_printf("DENY_READ "); break; + case DENY_WRITE:printf("DENY_WRITE "); break; + case DENY_FCB: d_printf("DENY_FCB "); break; + default: { + d_printf("unknown-please report ! " + "e->share_access = 0x%x, " + "e->private_options = 0x%x\n", + (unsigned int)e->share_access, + (unsigned int)e->private_options ); + break; + } + } + d_printf("0x%-8x ",(unsigned int)e->access_mask); + if (e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA)) { + d_printf("RDWR "); + } else if (e->access_mask & FILE_WRITE_DATA) { + d_printf("WRONLY "); + } else { + d_printf("RDONLY "); + } + + if((e->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) == + (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) { + d_printf("EXCLUSIVE+BATCH "); + } else if (e->op_type & EXCLUSIVE_OPLOCK) { + d_printf("EXCLUSIVE "); + } else if (e->op_type & BATCH_OPLOCK) { + d_printf("BATCH "); + } else if (e->op_type & LEVEL_II_OPLOCK) { + d_printf("LEVEL_II "); + } else { + d_printf("NONE "); + } + + d_printf(" %s %s",fname, asctime(LocalTime((time_t *)&e->time.tv_sec))); } } diff --git a/source/web/cgi.c b/source/web/cgi.c index 5d52ad62793..6c9cfce13cd 100644 --- a/source/web/cgi.c +++ b/source/web/cgi.c @@ -457,6 +457,10 @@ static void cgi_download(char *file) printf("Content-Type: image/gif\r\n"); } else if (strcmp(p,".jpg")==0) { printf("Content-Type: image/jpeg\r\n"); + } else if (strcmp(p,".png")==0) { + printf("Content-Type: image/png\r\n"); + } else if (strcmp(p,".css")==0) { + printf("Content-Type: text/css\r\n"); } else if (strcmp(p,".txt")==0) { printf("Content-Type: text/plain\r\n"); } else { diff --git a/source/web/diagnose.c b/source/web/diagnose.c index f4b022cf587..c7a7a3598ee 100644 --- a/source/web/diagnose.c +++ b/source/web/diagnose.c @@ -21,14 +21,8 @@ #include "includes.h" #include "web/swat_proto.h" -extern struct in_addr loopback_ip; - #ifdef WITH_WINBIND -NSS_STATUS winbindd_request(int req_type, - struct winbindd_request *request, - struct winbindd_response *response); - /* check to see if winbind is running by pinging it */ BOOL winbindd_running(void) @@ -41,6 +35,7 @@ BOOL winbindd_running(void) response */ BOOL nmbd_running(void) { + extern struct in_addr loopback_ip; int fd, count, flags; struct in_addr *ip_list; @@ -65,6 +60,7 @@ BOOL nmbd_running(void) BOOL smbd_running(void) { static struct cli_state cli; + extern struct in_addr loopback_ip; if (!cli_initialise(&cli)) return False; diff --git a/source/web/statuspage.c b/source/web/statuspage.c index 57b5d0f7b73..871e07b5d06 100644 --- a/source/web/statuspage.c +++ b/source/web/statuspage.c @@ -108,23 +108,28 @@ static char *tstring(time_t t) static void print_share_mode(share_mode_entry *e, char *fname) { char *utf8_fname; + int deny_mode = map_share_mode_to_deny_mode(e->share_access, + e->private_options); printf("<tr><td>%s</td>",_(mapPid2Machine(e->pid))); printf("<td>"); - switch ((e->share_mode>>4)&0xF) { + switch ((deny_mode>>4)&0xF) { case DENY_NONE: printf("DENY_NONE"); break; case DENY_ALL: printf("DENY_ALL "); break; case DENY_DOS: printf("DENY_DOS "); break; + case DENY_FCB: printf("DENY_FCB "); break; case DENY_READ: printf("DENY_READ "); break; case DENY_WRITE:printf("DENY_WRITE "); break; } printf("</td>"); printf("<td>"); - switch (e->share_mode&0xF) { - case 0: printf("%s", _("RDONLY ")); break; - case 1: printf("%s", _("WRONLY ")); break; - case 2: printf("%s", _("RDWR ")); break; + if (e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA)) { + printf("%s", _("RDWR ")); + } else if (e->access_mask & FILE_WRITE_DATA) { + printf("%s", _("WRONLY ")); + } else { + printf("%s", _("RDONLY ")); } printf("</td>"); diff --git a/source/web/swat.c b/source/web/swat.c index 8505f1a6859..14889e35aab 100644 --- a/source/web/swat.c +++ b/source/web/swat.c @@ -216,7 +216,7 @@ static void show_parameter(int snum, struct parm_struct *parm) void *ptr = parm->ptr; char *utf8_s1, *utf8_s2; - if (parm->class == P_LOCAL && snum >= 0) { + if (parm->p_class == P_LOCAL && snum >= 0) { ptr = lp_local_ptr(snum, ptr); } @@ -344,9 +344,9 @@ static void show_parameters(int snum, int allparameters, unsigned int parm_filte const char *last_heading = NULL; while ((parm = lp_next_parameter(snum, &i, allparameters))) { - if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL)) + if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL)) continue; - if (parm->class == P_SEPARATOR) { + if (parm->p_class == P_SEPARATOR) { heading = parm->label; continue; } @@ -360,7 +360,7 @@ static void show_parameters(int snum, int allparameters, unsigned int parm_filte if (!(parm->flags & FLAG_BASIC)) { void *ptr = parm->ptr; - if (parm->class == P_LOCAL && snum >= 0) { + if (parm->p_class == P_LOCAL && snum >= 0) { ptr = lp_local_ptr(snum, ptr); } @@ -488,7 +488,7 @@ static void commit_parameter(int snum, struct parm_struct *parm, const char *v) int i; char *s; - if (snum < 0 && parm->class == P_LOCAL) { + if (snum < 0 && parm->p_class == P_LOCAL) { /* this handles the case where we are changing a local variable globally. We need to change the parameter in all shares where it is currently set to the default */ |