summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-07-11 19:58:09 +0000
committerGerald Carter <jerry@samba.org>2005-07-11 19:58:09 +0000
commit43e83b009de0dc1e4c2e69eef95407cce69e783d (patch)
treef24e4772486276e66c81c8e660535df6fdfe4451
parent0afb83f20c6f72211f8a0b11d607b07a50d5a8eb (diff)
parent369c89d3c33bb59f63c029fa0e7a994c89ec92fb (diff)
downloadsamba-43e83b009de0dc1e4c2e69eef95407cce69e783d.tar.gz
r8329: merging changes from SAMBA_3_0 and setting version to 3.0.20pre2
-rw-r--r--Roadmap11
-rw-r--r--examples/VFS/skel_opaque.c56
-rw-r--r--examples/VFS/skel_transparent.c56
-rw-r--r--examples/debugging/README28
-rw-r--r--examples/debugging/solaris-oops.sh55
-rw-r--r--examples/mklogon/mklogon.conf77
-rw-r--r--examples/mklogon/mklogon.pl383
-rw-r--r--examples/scripts/python/SambaParm.py84
-rwxr-xr-xexamples/scripts/python/generate_parm_table.py8
-rw-r--r--source/Makefile.in121
-rw-r--r--source/VERSION2
-rw-r--r--source/auth/auth_ntlmssp.c2
-rw-r--r--source/auth/auth_winbind.c2
-rw-r--r--source/client/smbmnt.c14
-rw-r--r--source/client/smbspool.c4
-rw-r--r--source/configure.in96
-rw-r--r--source/include/ads.h24
-rw-r--r--source/include/debug.h1
-rw-r--r--source/include/doserr.h3
-rw-r--r--source/include/idmap.h2
-rw-r--r--source/include/includes.h41
-rw-r--r--source/include/libsmbclient.h2
-rw-r--r--source/include/msdfs.h1
-rw-r--r--source/include/nt_printing.h17
-rw-r--r--source/include/ntlmssp.h2
-rw-r--r--source/include/passdb.h6
-rw-r--r--source/include/privileges.h24
-rw-r--r--source/include/reg_objects.h14
-rw-r--r--source/include/rpc_reg.h36
-rwxr-xr-xsource/include/rpc_spoolss.h2
-rw-r--r--source/include/smb.h154
-rw-r--r--source/include/smb_acls.h4
-rw-r--r--source/include/smb_macros.h11
-rw-r--r--source/include/socket_wrapper.h22
-rw-r--r--source/include/spnego.h4
-rw-r--r--source/include/trans2.h10
-rw-r--r--source/include/vfs.h47
-rw-r--r--source/include/vfs_macros.h45
-rw-r--r--source/lib/data_blob.c1
-rw-r--r--source/lib/debug.c1
-rw-r--r--source/lib/privileges.c127
-rw-r--r--source/lib/secace.c26
-rw-r--r--source/lib/smbldap_util.c51
-rw-r--r--source/lib/socket_wrapper.c146
-rw-r--r--source/lib/system.c158
-rw-r--r--source/lib/util.c34
-rw-r--r--source/lib/util_str.c27
-rw-r--r--source/libads/ads_ldap.c129
-rw-r--r--source/libads/ads_struct.c5
-rw-r--r--source/libads/ldap.c96
-rw-r--r--source/libsmb/asn1.c11
-rw-r--r--source/libsmb/clierror.c4
-rw-r--r--source/libsmb/clifile.c7
-rw-r--r--source/libsmb/doserr.c3
-rw-r--r--source/libsmb/errormap.c4
-rw-r--r--source/libsmb/libsmb_cache.c4
-rw-r--r--source/libsmb/libsmb_compat.c6
-rw-r--r--source/libsmb/libsmbclient.c20
-rw-r--r--source/libsmb/namequery.c12
-rw-r--r--source/libsmb/smberr.c34
-rw-r--r--source/libsmb/spnego.c2
-rw-r--r--source/locking/locking.c120
-rw-r--r--source/locking/posix.c82
-rw-r--r--source/modules/vfs_afsacl.c16
-rw-r--r--source/modules/vfs_audit.c14
-rw-r--r--source/modules/vfs_cap.c10
-rw-r--r--source/modules/vfs_catia.c10
-rw-r--r--source/modules/vfs_extd_audit.c18
-rw-r--r--source/modules/vfs_full_audit.c122
-rw-r--r--source/modules/vfs_netatalk.c14
-rw-r--r--source/modules/vfs_shadow_copy.c6
-rw-r--r--source/nsswitch/wb_client.c24
-rw-r--r--source/nsswitch/wb_common.c6
-rw-r--r--source/nsswitch/wbinfo.c48
-rw-r--r--source/nsswitch/winbind_client.h2
-rw-r--r--source/nsswitch/winbind_nss_aix.c20
-rw-r--r--source/nsswitch/winbind_nss_linux.c38
-rw-r--r--source/nsswitch/winbind_nss_solaris.h26
-rw-r--r--source/nsswitch/winbindd.c48
-rw-r--r--source/nsswitch/winbindd.h10
-rw-r--r--source/nsswitch/winbindd_ads.c39
-rw-r--r--source/nsswitch/winbindd_async.c374
-rw-r--r--source/nsswitch/winbindd_cache.c8
-rw-r--r--source/nsswitch/winbindd_dual.c58
-rw-r--r--source/nsswitch/winbindd_group.c45
-rw-r--r--source/nsswitch/winbindd_misc.c12
-rw-r--r--source/nsswitch/winbindd_nss.h2
-rw-r--r--source/nsswitch/winbindd_rpc.c9
-rw-r--r--source/nsswitch/winbindd_sid.c60
-rw-r--r--source/nsswitch/winbindd_user.c165
-rw-r--r--source/nsswitch/winbindd_util.c34
-rw-r--r--source/nsswitch/winbindd_wins.c6
-rw-r--r--source/nsswitch/wins.c6
-rw-r--r--source/pam_smbpass/support.c28
-rw-r--r--source/param/loadparm.c93
-rw-r--r--source/param/params.c6
-rw-r--r--source/passdb/passdb.c76
-rw-r--r--source/passdb/pdb_get_set.c284
-rw-r--r--source/passdb/pdb_interface.c10
-rw-r--r--source/passdb/pdb_ldap.c12
-rw-r--r--source/printing/nt_printing.c272
-rw-r--r--source/printing/printfsp.c23
-rw-r--r--source/printing/printing.c2
-rw-r--r--source/python/py_spoolss_printers.c2
-rw-r--r--source/python/py_srvsvc.c2
-rw-r--r--source/python/py_winbind.c32
-rw-r--r--source/registry/reg_db.c294
-rw-r--r--source/registry/reg_eventlog.c12
-rw-r--r--source/registry/reg_frontend.c29
-rw-r--r--source/registry/reg_objects.c45
-rw-r--r--source/registry/reg_printing.c1538
-rw-r--r--source/registry/reg_shares.c12
-rw-r--r--source/registry/reg_util.c11
-rw-r--r--source/rpc_client/cli_reg.c34
-rw-r--r--source/rpc_parse/parse_eventlog.c6
-rw-r--r--source/rpc_parse/parse_reg.c53
-rw-r--r--source/rpc_parse/parse_spoolss.c16
-rw-r--r--source/rpc_parse/parse_svcctl.c1
-rw-r--r--source/rpc_server/srv_dfs.c4
-rw-r--r--source/rpc_server/srv_dfs_nt.c6
-rw-r--r--source/rpc_server/srv_eventlog.c2
-rw-r--r--source/rpc_server/srv_eventlog_nt.c44
-rw-r--r--source/rpc_server/srv_lsa_nt.c2
-rw-r--r--source/rpc_server/srv_reg.c85
-rw-r--r--source/rpc_server/srv_reg_nt.c181
-rw-r--r--source/rpc_server/srv_samr_nt.c31
-rw-r--r--source/rpc_server/srv_samr_util.c8
-rw-r--r--source/rpc_server/srv_spoolss_nt.c143
-rw-r--r--source/rpc_server/srv_srvsvc_nt.c43
-rw-r--r--source/sam/idmap.c4
-rw-r--r--source/sam/idmap_util.c14
-rwxr-xr-xsource/script/installman.sh4
-rw-r--r--source/script/mkproto.awk4
-rw-r--r--source/smbd/blocking.c10
-rw-r--r--source/smbd/chgpasswd.c4
-rw-r--r--source/smbd/close.c60
-rw-r--r--source/smbd/conn.c3
-rw-r--r--source/smbd/dir.c129
-rw-r--r--source/smbd/dosmode.c2
-rw-r--r--source/smbd/fake_file.c174
-rw-r--r--source/smbd/fileio.c44
-rw-r--r--source/smbd/filename.c2
-rw-r--r--source/smbd/files.c94
-rw-r--r--source/smbd/ipc.c2
-rw-r--r--source/smbd/mangle.c10
-rw-r--r--source/smbd/mangle_hash2.c39
-rw-r--r--source/smbd/msdfs.c61
-rw-r--r--source/smbd/notify.c1
-rw-r--r--source/smbd/notify_hash.c2
-rw-r--r--source/smbd/ntquotas.c1
-rw-r--r--source/smbd/nttrans.c757
-rw-r--r--source/smbd/open.c1906
-rw-r--r--source/smbd/oplock.c93
-rw-r--r--source/smbd/oplock_irix.c8
-rw-r--r--source/smbd/oplock_linux.c8
-rw-r--r--source/smbd/password.c4
-rw-r--r--source/smbd/pipes.c89
-rw-r--r--source/smbd/posix_acls.c76
-rw-r--r--source/smbd/process.c131
-rw-r--r--source/smbd/reply.c470
-rw-r--r--source/smbd/server.c5
-rw-r--r--source/smbd/service.c41
-rw-r--r--source/smbd/sesssetup.c3
-rw-r--r--source/smbd/statcache.c2
-rw-r--r--source/smbd/trans2.c433
-rw-r--r--source/smbd/vfs-wrap.c49
-rw-r--r--source/smbd/vfs.c59
-rw-r--r--source/tdb/tdb.c4
-rw-r--r--source/torture/cmd_vfs.c6
-rw-r--r--source/torture/nbio.c6
-rw-r--r--source/torture/torture.c14
-rw-r--r--source/ubiqx/debugparse.c12
-rw-r--r--source/utils/debug2html.c22
-rw-r--r--source/utils/net.c2
-rw-r--r--source/utils/net.h14
-rw-r--r--source/utils/net_rpc.c44
-rw-r--r--source/utils/net_rpc_samsync.c1013
-rw-r--r--source/utils/nmblookup.c2
-rw-r--r--source/utils/ntlm_auth.c12
-rw-r--r--source/utils/pdbedit.c4
-rw-r--r--source/utils/profiles.c6
-rw-r--r--source/utils/smbcacls.c6
-rw-r--r--source/utils/status.c72
-rw-r--r--source/web/cgi.c4
-rw-r--r--source/web/diagnose.c8
-rw-r--r--source/web/statuspage.c15
-rw-r--r--source/web/swat.c10
187 files changed, 8657 insertions, 4690 deletions
diff --git a/Roadmap b/Roadmap
index 6d678783f57..c4359b1387f 100644
--- a/Roadmap
+++ b/Roadmap
@@ -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,
+ &regdb_fetch_keys,
+ &regdb_store_keys,
+ &regdb_fetch_values,
+ &regdb_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,
+ &regdb_fetch_keys,
+ &regdb_store_keys,
+ &regdb_fetch_values,
+ &regdb_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, &reg_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( &regvals );
-
- /* 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(&regvals, "RefusePasswordChange",
- REG_DWORD,
- (const char*)&dwValue, sizeof(dwValue));
- val = dup_registry_value(
- regval_ctr_specific_value( &regvals, 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(&regvals, REGSTR_PRODUCTTYPE, REG_SZ,
- value, value_length);
-
- val = dup_registry_value( regval_ctr_specific_value( &regvals, 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( &regvals );
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( &params[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 = &params[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, &quotas)!=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, &quotas)!=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 */