diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2009-03-20 01:30:36 +0100 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2009-03-20 01:30:36 +0100 |
commit | 5fe2b28f45289dc5578cdd536600f0d30a14d820 (patch) | |
tree | 4bdf36d0d4d8bdddcb3d618b4b01839370ed57c3 /source3 | |
parent | ec9aeeab00584f4d3dfe9afb83dc1a77b8463b81 (diff) | |
parent | 3a4638db0351368d3b148bf547546f28fa0b1479 (diff) | |
download | samba-5fe2b28f45289dc5578cdd536600f0d30a14d820.tar.gz samba-5fe2b28f45289dc5578cdd536600f0d30a14d820.tar.bz2 samba-5fe2b28f45289dc5578cdd536600f0d30a14d820.zip |
Merge branch 'master' of git://git.samba.org/samba into minschema
Diffstat (limited to 'source3')
175 files changed, 7613 insertions, 14076 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 28b5437838..cf74182f27 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -88,12 +88,11 @@ UNINSTALLLIBCMD_A=@UNINSTALLLIBCMD_A@ VPATH=@srcdir@ srcdir=@abs_srcdir@ builddir=@abs_builddir@ -SHELL=/bin/sh -DESTDIR=/ - # XXX: Perhaps this should be @SHELL@ instead -- apparently autoconf # will search for a POSIX-compliant shell, and that might not be # /bin/sh on some platforms. I guess it's not a big problem -- mbp +SHELL=/bin/sh +DESTDIR=/ # See the autoconf manual "Installation Directory Variables" for a # discussion of the subtle use of these variables. @@ -366,7 +365,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \ lib/substitute.o lib/dbwrap_util.o \ lib/ms_fnmatch.o lib/select.o lib/errmap_unix.o \ lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \ - ../lib/util/charset/iconv.o lib/pam_errors.o intl/lang_tdb.o \ + lib/iconv.o lib/pam_errors.o intl/lang_tdb.o \ lib/conn_tdb.o lib/adt_tree.o lib/gencache.o \ lib/module.o lib/events.o @LIBTEVENT_OBJ0@ \ lib/ldap_escape.o @CHARSET_STATIC@ \ @@ -449,7 +448,19 @@ LIBSAMBA_OBJ = $(LIBSMB_OBJ0) \ LIBCLI_LDAP_MESSAGE_OBJ = ../libcli/ldap/ldap_message.o LIBCLI_LDAP_NDR_OBJ = ../libcli/ldap/ldap_ndr.o -CLDAP_OBJ = libads/cldap.o $(LIBCLI_LDAP_MESSAGE_OBJ) $(LIBCLI_LDAP_NDR_OBJ) +LIBTSOCKET_OBJ = ../lib/tsocket/tsocket.o \ + ../lib/tsocket/tsocket_helpers.o \ + ../lib/tsocket/tsocket_bsd.o \ + ../lib/tsocket/tsocket_recvfrom.o \ + ../lib/tsocket/tsocket_sendto.o \ + ../lib/tsocket/tsocket_connect.o \ + ../lib/tsocket/tsocket_writev.o \ + ../lib/tsocket/tsocket_readv.o + +CLDAP_OBJ = libads/cldap.o \ + ../libcli/cldap/cldap.o \ + ../lib/util/idtree.o \ + $(LIBCLI_LDAP_MESSAGE_OBJ) $(LIBCLI_LDAP_NDR_OBJ) $(LIBTSOCKET_OBJ) LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/clikrb5.o libsmb/clispnego.o ../lib/util/asn1.o \ @@ -457,7 +468,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \ libsmb/clitrans.o libsmb/clisecdesc.o libsmb/clidgram.o \ libsmb/clistr.o libsmb/cliquota.o libsmb/clifsinfo.o libsmb/clidfs.o \ - libsmb/credentials.o libsmb/pwd_cache.o \ + libsmb/credentials.o \ libsmb/clioplock.o libsmb/clirap2.o \ libsmb/smb_seal.o libsmb/async_smb.o \ $(LIBSAMBA_OBJ) \ @@ -578,7 +589,7 @@ RPC_NTSVCS_OBJ = rpc_server/srv_ntsvcs_nt.o \ RPC_DFS_OBJ = ../librpc/gen_ndr/srv_dfs.o rpc_server/srv_dfs_nt.o -RPC_SPOOLSS_OBJ = rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o \ +RPC_SPOOLSS_OBJ = rpc_server/srv_spoolss_nt.o \ ../librpc/gen_ndr/srv_spoolss.o RPC_EVENTLOG_OBJ = rpc_server/srv_eventlog_nt.o \ @@ -591,9 +602,7 @@ RPC_ECHO_OBJ = rpc_server/srv_echo_nt.o ../librpc/gen_ndr/srv_echo.o RPC_SERVER_OBJ = @RPC_STATIC@ $(RPC_PIPE_OBJ) -RPC_PARSE_OBJ = $(RPC_PARSE_OBJ2) \ - rpc_parse/parse_spoolss.o \ - rpc_parse/parse_buffer.o +RPC_PARSE_OBJ = $(RPC_PARSE_OBJ2) RPC_CLIENT_OBJ = rpc_client/cli_pipe.o rpc_client/rpc_transport_np.o \ rpc_client/rpc_transport_sock.o rpc_client/rpc_transport_smbd.o @@ -611,7 +620,7 @@ PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \ passdb/util_unixsids.o passdb/lookup_sid.o \ passdb/login_cache.o @PDB_STATIC@ \ lib/account_pol.o $(PRIVILEGES_OBJ) \ - lib/util_nscd.o lib/winbind_util.o + lib/util_nscd.o lib/winbind_util.o $(SERVER_MUTEX_OBJ) DEVEL_HELP_WEIRD_OBJ = modules/weird.o CP850_OBJ = modules/CP850.o @@ -667,6 +676,7 @@ VFS_READAHEAD_OBJ = modules/vfs_readahead.o VFS_TSMSM_OBJ = modules/vfs_tsmsm.o VFS_FILEID_OBJ = modules/vfs_fileid.o VFS_AIO_FORK_OBJ = modules/vfs_aio_fork.o +VFS_PREOPEN_OBJ = modules/vfs_preopen.o VFS_SYNCOPS_OBJ = modules/vfs_syncops.o VFS_ACL_XATTR_OBJ = modules/vfs_acl_xattr.o VFS_ACL_TDB_OBJ = modules/vfs_acl_tdb.o @@ -714,7 +724,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \ smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o \ smbd/blocking.o smbd/sec_ctx.o smbd/srvstr.o \ smbd/vfs.o smbd/perfcount.o smbd/statcache.o smbd/seal.o \ - smbd/posix_acls.o lib/sysacls.o $(SERVER_MUTEX_OBJ) \ + smbd/posix_acls.o lib/sysacls.o \ smbd/process.o smbd/service.o smbd/error.o \ printing/printfsp.o lib/sysquotas.o lib/sysquotas_linux.o \ lib/sysquotas_xfs.o lib/sysquotas_4A.o \ @@ -931,7 +941,7 @@ NET_OBJ = $(NET_OBJ1) \ $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(LIBADDNS_OBJ0) \ $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) \ $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \ - $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(SERVER_MUTEX_OBJ) \ + $(SMBLDAP_OBJ) $(DCUTIL_OBJ) \ $(AFS_OBJ) $(AFS_SETTOKEN_OBJ) $(READLINE_OBJ) \ $(LDB_OBJ) $(LIBGPO_OBJ) @BUILD_INIPARSER@ $(DISPLAY_SEC_OBJ) \ $(REG_SMBCONF_OBJ) @LIBNETAPI_STATIC@ $(LIBNET_OBJ) \ @@ -1094,7 +1104,7 @@ WINBINDD_OBJ = \ $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \ $(DCUTIL_OBJ) $(IDMAP_OBJ) $(NSS_INFO_OBJ) \ $(AFS_OBJ) $(AFS_SETTOKEN_OBJ) \ - $(LIBADS_SERVER_OBJ) $(SERVER_MUTEX_OBJ) $(LDB_OBJ) \ + $(LIBADS_SERVER_OBJ) $(LDB_OBJ) \ $(TDB_VALIDATE_OBJ) WBINFO_OBJ = ../nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \ @@ -1161,7 +1171,7 @@ NTLM_AUTH_OBJ1 = utils/ntlm_auth.o utils/ntlm_auth_diagnostics.o NTLM_AUTH_OBJ = ${NTLM_AUTH_OBJ1} $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \ ../lib/util/asn1.o libsmb/spnego.o libsmb/clikrb5.o libads/kerberos.o \ - $(SERVER_MUTEX_OBJ) $(LIBADS_SERVER_OBJ) \ + $(LIBADS_SERVER_OBJ) \ $(PASSDB_OBJ) $(GROUPDB_OBJ) \ $(SMBLDAP_OBJ) $(LIBNMB_OBJ) \ $(LDB_OBJ) $(WBCOMMON_OBJ) @LIBWBCLIENT_STATIC@ \ @@ -1631,6 +1641,10 @@ bin/ldbrename: $(BINARY_PREREQS) $(LDBRENAME_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) +bin/versiontest: $(BINARY_PREREQS) lib/version_test.o $(VERSION_OBJ) + @echo Linking $@ + @$(CC) $(FLAGS) -o $@ $(VERSION_OBJ) lib/version_test.o + ##################################################################### # @@ -2208,7 +2222,7 @@ installliblua:: installdirs liblua @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(LIBDIR) -$(INSTALLLIBCMD_SH) $(LIBLUA_SHARED_TARGET_SONAME) $(DESTDIR)$(LIBDIR) @rm -f $(DESTDIR)$(LIBDIR)/`basename $(LIBLUA_SHARED_TARGET)` - -if test -e $(LIBLUA_SHARED_TARGET_SONAME) ; then \ + -if test -f $(LIBLUA_SHARED_TARGET_SONAME) ; then \ ln -f -s `basename $(LIBLUA_SHARED_TARGET_SONAME)` \ $(DESTDIR)$(LIBDIR)/`basename $(LIBLUA_SHARED_TARGET)` ; \ fi @@ -2279,7 +2293,7 @@ bin/librpc_dssetup.@SHLIBEXT@: $(BINARY_PREREQS) $(RPC_DSSETUP_OBJ) @echo "Linking $@" @$(SHLD_MODULE) $(RPC_DSSETUP_OBJ) -bin/librpc_spoolss2.@SHLIBEXT@: $(BINARY_PREREQS) $(RPC_SPOOLSS_OBJ) +bin/librpc_spoolss.@SHLIBEXT@: $(BINARY_PREREQS) $(RPC_SPOOLSS_OBJ) @echo "Linking $@" @$(SHLD_MODULE) $(RPC_SPOOLSS_OBJ) @@ -2567,6 +2581,10 @@ bin/aio_fork.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_AIO_FORK_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(VFS_AIO_FORK_OBJ) +bin/preopen.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_PREOPEN_OBJ) + @echo "Building plugin $@" + @$(SHLD_MODULE) $(VFS_PREOPEN_OBJ) + bin/acl_xattr.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_ACL_XATTR_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(VFS_ACL_XATTR_OBJ) diff --git a/source3/autogen.sh b/source3/autogen.sh index 1a33eb22cc..9ade370cd4 100755 --- a/source3/autogen.sh +++ b/source3/autogen.sh @@ -65,7 +65,7 @@ echo "$0: running script/mkversion.sh" rm -rf autom4te*.cache rm -f configure include/config.h* -IPATHS="-Im4 -I../lib/replace -I../source4" +IPATHS="-Im4 -I../m4 -I../lib/replace -I../source4" echo "$0: running $AUTOHEADER $IPATHS" $AUTOHEADER $IPATHS || exit 1 diff --git a/source3/client/client.c b/source3/client/client.c index aaa9e35d96..a6f31bcf17 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -103,6 +103,9 @@ struct cli_state *cli; static char CLI_DIRSEP_CHAR = '\\'; static char CLI_DIRSEP_STR[] = { '\\', '\0' }; +/* Authentication for client connections. */ +struct user_auth_info *auth_info; + /* Accessor functions for directory paths. */ static char *fileselection; static const char *client_get_fileselection(void) @@ -299,7 +302,7 @@ static int do_dskattr(void) char *targetpath = NULL; TALLOC_CTX *ctx = talloc_tos(); - if ( !cli_resolve_path(ctx, "", cli, client_get_cur_dir(), &targetcli, &targetpath)) { + if ( !cli_resolve_path(ctx, "", auth_info, cli, client_get_cur_dir(), &targetcli, &targetpath)) { d_printf("Error in dskattr: %s\n", cli_errstr(cli)); return 1; } @@ -393,7 +396,7 @@ static int do_cd(const char *new_dir) new_cd = clean_name(ctx, new_cd); client_set_cur_dir(new_cd); - if ( !cli_resolve_path(ctx, "", cli, new_cd, &targetcli, &targetpath)) { + if ( !cli_resolve_path(ctx, "", auth_info, cli, new_cd, &targetcli, &targetpath)) { d_printf("cd %s: %s\n", new_cd, cli_errstr(cli)); client_set_cur_dir(saved_dir); goto out; @@ -819,7 +822,7 @@ void do_list(const char *mask, /* check for dfs */ - if ( !cli_resolve_path(ctx, "", cli, head, &targetcli, &targetpath ) ) { + if ( !cli_resolve_path(ctx, "", auth_info, cli, head, &targetcli, &targetpath ) ) { d_printf("do_list: [%s] %s\n", head, cli_errstr(cli)); remove_do_list_queue_head(); continue; @@ -852,7 +855,7 @@ void do_list(const char *mask, } } else { /* check for dfs */ - if (cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetpath)) { + if (cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetpath)) { if (cli_list(targetcli, targetpath, attribute, do_list_helper, NULL) == -1) { d_printf("%s listing %s\n", cli_errstr(targetcli), targetpath); @@ -1018,7 +1021,7 @@ static int do_get(const char *rname, const char *lname_in, bool reget) strlower_m(lname); } - if (!cli_resolve_path(ctx, "", cli, rname, &targetcli, &targetname ) ) { + if (!cli_resolve_path(ctx, "", auth_info, cli, rname, &targetcli, &targetname ) ) { d_printf("Failed to open %s: %s\n", rname, cli_errstr(cli)); return 1; } @@ -1381,7 +1384,7 @@ static bool do_mkdir(const char *name) struct cli_state *targetcli; char *targetname = NULL; - if (!cli_resolve_path(ctx, "", cli, name, &targetcli, &targetname)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, name, &targetcli, &targetname)) { d_printf("mkdir %s: %s\n", name, cli_errstr(cli)); return false; } @@ -1419,7 +1422,7 @@ static bool do_altname(const char *name) static int cmd_quit(void) { - cli_cm_shutdown(); + cli_shutdown(cli); exit(0); /* NOTREACHED */ return 0; @@ -1464,7 +1467,7 @@ static int cmd_mkdir(void) return 1; } - if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) { return 1; } @@ -1625,7 +1628,7 @@ static int do_put(const char *rname, const char *lname, bool reput) struct push_state state; NTSTATUS status; - if (!cli_resolve_path(ctx, "", cli, rname, &targetcli, &targetname)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, rname, &targetcli, &targetname)) { d_printf("Failed to open %s: %s\n", rname, cli_errstr(cli)); return 1; } @@ -1714,7 +1717,7 @@ static int do_put(const char *rname, const char *lname, bool reput) } if (f == x_stdin) { - cli_cm_shutdown(); + cli_shutdown(cli); exit(0); } @@ -2183,7 +2186,7 @@ static int cmd_wdel(void) return 1; } - if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) { d_printf("cmd_wdel %s: %s\n", mask, cli_errstr(cli)); return 1; } @@ -2218,7 +2221,7 @@ static int cmd_open(void) return 1; } - if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) { d_printf("open %s: %s\n", mask, cli_errstr(cli)); return 1; } @@ -2311,7 +2314,7 @@ static int cmd_posix_open(void) } mode = (mode_t)strtol(buf, (char **)NULL, 8); - if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) { d_printf("posix_open %s: %s\n", mask, cli_errstr(cli)); return 1; } @@ -2359,7 +2362,7 @@ static int cmd_posix_mkdir(void) } mode = (mode_t)strtol(buf, (char **)NULL, 8); - if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) { d_printf("posix_mkdir %s: %s\n", mask, cli_errstr(cli)); return 1; } @@ -2393,7 +2396,7 @@ static int cmd_posix_unlink(void) return 1; } - if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) { d_printf("posix_unlink %s: %s\n", mask, cli_errstr(cli)); return 1; } @@ -2427,7 +2430,7 @@ static int cmd_posix_rmdir(void) return 1; } - if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) { d_printf("posix_rmdir %s: %s\n", mask, cli_errstr(cli)); return 1; } @@ -2667,7 +2670,7 @@ static int cmd_rmdir(void) return 1; } - if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) { d_printf("rmdir %s: %s\n", mask, cli_errstr(cli)); return 1; } @@ -2714,7 +2717,7 @@ static int cmd_link(void) return 1; } - if (!cli_resolve_path(ctx, "", cli, oldname, &targetcli, &targetname)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, oldname, &targetcli, &targetname)) { d_printf("link %s: %s\n", oldname, cli_errstr(cli)); return 1; } @@ -2765,7 +2768,7 @@ static int cmd_symlink(void) return 1; } - if (!cli_resolve_path(ctx, "", cli, oldname, &targetcli, &targetname)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, oldname, &targetcli, &targetname)) { d_printf("link %s: %s\n", oldname, cli_errstr(cli)); return 1; } @@ -2813,7 +2816,7 @@ static int cmd_chmod(void) mode = (mode_t)strtol(buf, NULL, 8); - if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetname)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname)) { d_printf("chmod %s: %s\n", src, cli_errstr(cli)); return 1; } @@ -2966,7 +2969,7 @@ static int cmd_getfacl(void) return 1; } - if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetname)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname)) { d_printf("stat %s: %s\n", src, cli_errstr(cli)); return 1; } @@ -3132,7 +3135,7 @@ static int cmd_stat(void) return 1; } - if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetname)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname)) { d_printf("stat %s: %s\n", src, cli_errstr(cli)); return 1; } @@ -3233,7 +3236,7 @@ static int cmd_chown(void) if (!src) { return 1; } - if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetname) ) { + if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname) ) { d_printf("chown %s: %s\n", src, cli_errstr(cli)); return 1; } @@ -3287,12 +3290,12 @@ static int cmd_rename(void) return 1; } - if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetsrc)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetsrc)) { d_printf("rename %s: %s\n", src, cli_errstr(cli)); return 1; } - if (!cli_resolve_path(ctx, "", cli, dest, &targetcli, &targetdest)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, dest, &targetcli, &targetdest)) { d_printf("rename %s: %s\n", dest, cli_errstr(cli)); return 1; } @@ -3362,7 +3365,7 @@ static int cmd_hardlink(void) return 1; } - if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetname)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname)) { d_printf("hardlink %s: %s\n", src, cli_errstr(cli)); return 1; } @@ -3815,7 +3818,7 @@ static int cmd_logon(void) static int cmd_list_connect(void) { - cli_cm_display(); + cli_cm_display(cli); return 0; } @@ -3829,7 +3832,7 @@ static int cmd_show_connect( void ) struct cli_state *targetcli; char *targetpath; - if (!cli_resolve_path(ctx, "", cli, client_get_cur_dir(), + if (!cli_resolve_path(ctx, "", auth_info, cli, client_get_cur_dir(), &targetcli, &targetpath ) ) { d_printf("showconnect %s: %s\n", cur_dir, cli_errstr(cli)); return 1; @@ -4051,7 +4054,8 @@ static int process_command_string(const char *cmd_in) if (!cli) { cli = cli_cm_open(talloc_tos(), NULL, have_ip ? dest_ss_str : desthost, - service, true, smb_encrypt, + service, auth_info, + true, smb_encrypt, max_protocol, port, name_type); if (!cli) { return 1; @@ -4220,7 +4224,7 @@ static char **remote_completion(const char *text, int len) goto cleanup; } - if (!cli_resolve_path(ctx, "", cli, dirmask, &targetcli, &targetpath)) { + if (!cli_resolve_path(ctx, "", auth_info, cli, dirmask, &targetcli, &targetpath)) { goto cleanup; } if (cli_list(targetcli, targetpath, aDIR | aSYSTEM | aHIDDEN, @@ -4517,7 +4521,7 @@ static int process(const char *base_directory) cli = cli_cm_open(talloc_tos(), NULL, have_ip ? dest_ss_str : desthost, - service, true, smb_encrypt, + service, auth_info, true, smb_encrypt, max_protocol, port, name_type); if (!cli) { return 1; @@ -4526,7 +4530,7 @@ static int process(const char *base_directory) if (base_directory && *base_directory) { rc = do_cd(base_directory); if (rc) { - cli_cm_shutdown(); + cli_shutdown(cli); return rc; } } @@ -4537,7 +4541,7 @@ static int process(const char *base_directory) process_stdin(); } - cli_cm_shutdown(); + cli_shutdown(cli); return rc; } @@ -4550,7 +4554,7 @@ static int do_host_query(const char *query_host) struct sockaddr_storage ss; cli = cli_cm_open(talloc_tos(), NULL, - query_host, "IPC$", true, smb_encrypt, + query_host, "IPC$", auth_info, true, smb_encrypt, max_protocol, port, name_type); if (!cli) return 1; @@ -4568,9 +4572,9 @@ static int do_host_query(const char *query_host) /* Workgroups simply don't make sense over anything else but port 139... */ - cli_cm_shutdown(); + cli_shutdown(cli); cli = cli_cm_open(talloc_tos(), NULL, - query_host, "IPC$", true, smb_encrypt, + query_host, "IPC$", auth_info, true, smb_encrypt, max_protocol, 139, name_type); } @@ -4581,7 +4585,7 @@ static int do_host_query(const char *query_host) list_servers(lp_workgroup()); - cli_cm_shutdown(); + cli_shutdown(cli); return(0); } @@ -4598,7 +4602,7 @@ static int do_tar_op(const char *base_directory) if (!cli) { cli = cli_cm_open(talloc_tos(), NULL, have_ip ? dest_ss_str : desthost, - service, true, smb_encrypt, + service, auth_info, true, smb_encrypt, max_protocol, port, name_type); if (!cli) return 1; @@ -4609,14 +4613,14 @@ static int do_tar_op(const char *base_directory) if (base_directory && *base_directory) { ret = do_cd(base_directory); if (ret) { - cli_cm_shutdown(); + cli_shutdown(cli); return ret; } } ret=process_tar(); - cli_cm_shutdown(); + cli_shutdown(cli); return(ret); } @@ -4625,7 +4629,7 @@ static int do_tar_op(const char *base_directory) Handle a message operation. ****************************************************************************/ -static int do_message_op(struct user_auth_info *auth_info) +static int do_message_op(struct user_auth_info *a_info) { struct sockaddr_storage ss; struct nmb_name called, calling; @@ -4663,12 +4667,12 @@ static int do_message_op(struct user_auth_info *auth_info) if (!cli_session_request(cli, &calling, &called)) { d_printf("session request failed\n"); - cli_cm_shutdown(); + cli_shutdown(cli); return 1; } - send_message(get_cmdline_auth_info_username(auth_info)); - cli_cm_shutdown(); + send_message(get_cmdline_auth_info_username(a_info)); + cli_shutdown(cli); return 0; } @@ -4714,7 +4718,6 @@ static int do_message_op(struct user_auth_info *auth_info) POPT_TABLEEND }; TALLOC_CTX *frame = talloc_stackframe(); - struct user_auth_info *auth_info; if (!client_set_cur_dir("\\")) { exit(ENOMEM); @@ -4970,12 +4973,11 @@ static int do_message_op(struct user_auth_info *auth_info) poptFreeContext(pc); - /* Store the username and password for dfs support */ - - cli_cm_set_credentials(auth_info); - DEBUG(3,("Client started (version %s).\n", samba_version_string())); + /* Ensure we have a password (or equivalent). */ + set_cmdline_auth_info_getpass(auth_info); + if (tar_type) { if (cmdstr) process_command_string(cmdstr); diff --git a/source3/client/clitar.c b/source3/client/clitar.c index 18edf037e2..c9f3e87c4d 100644 --- a/source3/client/clitar.c +++ b/source3/client/clitar.c @@ -1513,6 +1513,7 @@ int process_tar(void) if (strrchr_m(cliplist[i], '\\')) { char *p; + char saved_char; char *saved_dir = talloc_strdup(ctx, client_get_cur_dir()); if (!saved_dir) { @@ -1531,13 +1532,28 @@ int process_tar(void) if (!tarmac) { return 1; } + /* + * Strip off the last \\xxx + * xxx element of tarmac to set + * it as current directory. + */ p = strrchr_m(tarmac, '\\'); if (!p) { return 1; } + saved_char = p[1]; p[1] = '\0'; + client_set_cur_dir(tarmac); + /* + * Restore the character we + * just replaced to + * put the pathname + * back as it was. + */ + p[1] = saved_char; + DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac)); do_list(tarmac,attribute,do_tar, False, True); diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c index 8623d3c04b..0c551cce75 100644 --- a/source3/client/mount.cifs.c +++ b/source3/client/mount.cifs.c @@ -1463,7 +1463,8 @@ mount_retry: } } printf("mount error(%d): %s\n", errno, strerror(errno)); - printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n"); + printf("Refer to the mount.cifs(8) manual page (e.g. man " + "mount.cifs)\n"); rc = EX_FAIL; goto mount_exit; } diff --git a/source3/configure.in b/source3/configure.in index d67feccb9b..dc5850aba1 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -20,10 +20,29 @@ AC_SUBST(builddir) m4_include(m4/samba_version.m4) m4_include(m4/check_path.m4) +m4_include(pkg.m4) AC_LIBREPLACE_CC_CHECKS -m4_include(../lib/talloc/libtalloc.m4) +AC_ARG_ENABLE(external_libtalloc, [AS_HELP_STRING([--enable-external-libtalloc], [Enable external talloc [default=auto]])], +[ enable_external_libtalloc=$enableval ], [ enable_external_libtalloc=auto ]) + +if test "x$enable_external_libtalloc" != xno +then + PKG_CHECK_MODULES(TALLOC, talloc >= 1.3.0, + [ enable_external_libtalloc=yes ], + [ if test x$enable_external_libtalloc = xyes; then + AC_MSG_ERROR([Unable to find libtalloc]) + else + enable_external_libtalloc=no + fi + ]) +fi + +if test "x$enable_external_libtalloc" = xno +then + m4_include(../lib/talloc/libtalloc.m4) +fi LIBTALLOC_OBJ0="" for obj in ${TALLOC_OBJ}; do @@ -266,7 +285,7 @@ if test "$ac_cv_prog_gnu_ld" = "yes"; then else AC_MSG_CHECKING(GNU ld release version) changequote(,)dnl - ac_cv_gnu_ld_vernr=`echo $ac_cv_gnu_ld_version | sed -n 's,^.*\([1-9][0-9]*\.[0-9][0-9]*\).*$,\1,p'` + ac_cv_gnu_ld_vernr=`echo $ac_cv_gnu_ld_version | sed -n 's,^.*[^0-9\.]\+\([1-9][0-9]*\.[0-9][0-9]*\).*$,\1,p'` ac_cv_gnu_ld_vernr_major=`echo $ac_cv_gnu_ld_vernr | cut -d '.' -f 1` ac_cv_gnu_ld_vernr_minor=`echo $ac_cv_gnu_ld_vernr | cut -d '.' -f 2` changequote([,])dnl @@ -278,7 +297,7 @@ if test "$ac_cv_prog_gnu_ld" = "yes"; then if test "$ac_cv_gnu_ld_vernr_major" -lt 2 || test "$ac_cv_gnu_ld_vernr_minor" -lt 14; then ac_cv_gnu_ld_no_default_allow_shlib_undefined=yes fi - if test "$ac_cv_gnu_ld_vernr_major" -gt 2 || test "$ac_cv_gnu_ld_vernr_major"=2 && test "$ac_cv_gnu_ld_vernr_minor" -ge 12; then + if test "$ac_cv_gnu_ld_vernr_major" -gt 2 || test "$ac_cv_gnu_ld_vernr_major" = 2 && test "$ac_cv_gnu_ld_vernr_minor" -ge 12; then ac_cv_gnu_ld_version_script=yes fi fi @@ -414,10 +433,10 @@ AC_SUBST(DYNEXP) dnl Add modules that have to be built by default here dnl These have to be built static: -default_static_modules="pdb_smbpasswd pdb_tdbsam pdb_wbc_sam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss2 rpc_eventlog auth_sam auth_unix auth_winbind auth_wbc auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template" +default_static_modules="pdb_smbpasswd pdb_tdbsam pdb_wbc_sam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss rpc_eventlog auth_sam auth_unix auth_winbind auth_wbc auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template" dnl These are preferably build shared, and static if dlopen() is not available -default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer" +default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer vfs_preopen" if test "x$developer" = xyes; then default_static_modules="$default_static_modules rpc_rpcecho" @@ -1177,13 +1196,10 @@ if test x"$LIBUNWIND_PTRACE" != x"" ; then #endif ], [ - int main(int argc, const char ** argv) - { - pid_t me = (pid_t)-1; - ptrace(PTRACE_ATTACH, me, 0, 0); - ptrace(PTRACE_DETACH, me, 0, 0); - return 0; - } + pid_t me = (pid_t)-1; + ptrace(PTRACE_ATTACH, me, 0, 0); + ptrace(PTRACE_DETACH, me, 0, 0); + return 0; ], [ AC_MSG_RESULT(yes) @@ -3261,6 +3277,9 @@ if test x"$with_ads_support" != x"no"; then ac_save_CPPFLAGS=$CPPFLAGS ac_save_LDFLAGS=$LDFLAGS + # remove needless evil rpath stuff as early as possible: + LIB_REMOVE_USR_LIB(KRB5_LIBS) + LIB_REMOVE_USR_LIB(KRB5_LDFLAGS) CFLAGS="$KRB5_CFLAGS $CFLAGS" CPPFLAGS="$KRB5_CPPFLAGS $CPPFLAGS" LDFLAGS="$KRB5_LDFLAGS $LDFLAGS" @@ -4723,35 +4742,6 @@ SMB_LIBRARY(addns, 0, no, [undefined API]) ################################################# -# check to see if we should set the protected madvise flag, -# which will keep smbd alive in low memory conditions -AC_MSG_CHECKING(whether to protect smbd from being killed in low memory) -AC_ARG_WITH(madvise-protect, -[AS_HELP_STRING([--with-madvise-protect], [Include low memory madvise protection (default=no)])], -[ case "$withval" in - yes) - AC_TRY_COMPILE([ - #include <sys/mman.h> - ],[ - int a = MADV_PROTECT; - ], - [samba_cv_madvise_protect=yes], - [samba_cv_madvise_protect=no]) - if test x"$samba_cv_madvise_protect" = x"yes"; then - AC_MSG_RESULT(yes) - AC_DEFINE(WITH_MADVISE_PROTECTED,1,[Whether to include low memory protection support]) - else - AC_MSG_ERROR(Low memory protection supporte requires availability of MADVISE_PROTECT flag.) - fi - ;; - *) - AC_MSG_RESULT(no) - ;; - esac ], - AC_MSG_RESULT(no) -) - -################################################# # these tests are taken from the GNU fileutils package AC_CHECKING(how to get filesystem space usage) space=no @@ -6100,7 +6090,7 @@ do done dnl Always build these modules static -MODULE_rpc_spoolss2=STATIC +MODULE_rpc_spoolss=STATIC MODULE_rpc_srvsvc=STATIC MODULE_idmap_tdb=STATIC MODULE_idmap_passdb=STATIC @@ -6144,7 +6134,7 @@ SMB_MODULE(rpc_ntsvcs, \$(RPC_NTSVCS_OBJ), "bin/librpc_ntsvcs.$SHLIBEXT", RPC) SMB_MODULE(rpc_netlogon, \$(RPC_NETLOG_OBJ), "bin/librpc_NETLOGON.$SHLIBEXT", RPC) SMB_MODULE(rpc_netdfs, \$(RPC_DFS_OBJ), "bin/librpc_netdfs.$SHLIBEXT", RPC) SMB_MODULE(rpc_srvsvc, \$(RPC_SVC_OBJ), "bin/librpc_svcsvc.$SHLIBEXT", RPC) -SMB_MODULE(rpc_spoolss2, \$(RPC_SPOOLSS_OBJ), "bin/librpc_spoolss2.$SHLIBEXT", RPC) +SMB_MODULE(rpc_spoolss, \$(RPC_SPOOLSS_OBJ), "bin/librpc_spoolss.$SHLIBEXT", RPC) SMB_MODULE(rpc_eventlog, \$(RPC_EVENTLOG_OBJ), "bin/librpc_eventlog.$SHLIBEXT", RPC) SMB_MODULE(rpc_samr, \$(RPC_SAMR_OBJ), "bin/librpc_samr.$SHLIBEXT", RPC) SMB_MODULE(rpc_rpcecho, \$(RPC_ECHO_OBJ), "bin/librpc_rpcecho.$SHLIBEXT", RPC) @@ -6214,6 +6204,7 @@ SMB_MODULE(vfs_readahead, \$(VFS_READAHEAD_OBJ), "bin/readahead.$SHLIBEXT", VFS) SMB_MODULE(vfs_tsmsm, \$(VFS_TSMSM_OBJ), "bin/tsmsm.$SHLIBEXT", VFS) SMB_MODULE(vfs_fileid, \$(VFS_FILEID_OBJ), "bin/fileid.$SHLIBEXT", VFS) SMB_MODULE(vfs_aio_fork, \$(VFS_AIO_FORK_OBJ), "bin/aio_fork.$SHLIBEXT", VFS) +SMB_MODULE(vfs_preopen, \$(VFS_PREOPEN_OBJ), "bin/preopen.$SHLIBEXT", VFS) SMB_MODULE(vfs_syncops, \$(VFS_SYNCOPS_OBJ), "bin/syncops.$SHLIBEXT", VFS) SMB_MODULE(vfs_zfsacl, \$(VFS_ZFSACL_OBJ), "bin/zfsacl.$SHLIBEXT", VFS) SMB_MODULE(vfs_notify_fam, \$(VFS_NOTIFY_FAM_OBJ), "bin/notify_fam.$SHLIBEXT", VFS) @@ -6370,7 +6361,6 @@ AC_ZLIB([ZLIB_OBJS=""], [ dnl Remove -L/usr/lib/? from LDFLAGS and LIBS LIB_REMOVE_USR_LIB(LDFLAGS) LIB_REMOVE_USR_LIB(LIBS) -LIB_REMOVE_USR_LIB(KRB5_LIBS) dnl Remove -I/usr/include/? from CFLAGS and CPPFLAGS CFLAGS_REMOVE_USR_INCLUDE(CFLAGS) diff --git a/source3/include/client.h b/source3/include/client.h index d62d1c05d2..320a90e66b 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -104,7 +104,7 @@ struct rpc_cli_transport { uint32_t max_rdata_len, void *priv); /** - * Get the result from the read_send operation. + * Get the result from the trans_send operation. */ NTSTATUS (*trans_recv)(struct async_req *req, TALLOC_CTX *mem_ctx, uint8_t **prdata, uint32_t *prdata_len); @@ -167,6 +167,10 @@ struct smb_trans_enc_state { }; struct cli_state { + /** + * A list of subsidiary connections for DFS. + */ + struct cli_state *prev, *next; int port; int fd; /* Last read or write error. */ @@ -183,9 +187,9 @@ struct cli_state { fstring desthost; /* The credentials used to open the cli_state connection. */ - fstring domain; - fstring user_name; - struct pwd_info pwd; + char *domain; + char *user_name; + char *password; /* Can be null to force use of zero NTLMSSP session key. */ /* * The following strings are the @@ -276,6 +280,9 @@ struct cli_state { * chained async_req. */ struct cli_request *chain_accumulator; + + /* Where (if anywhere) this is mounted under DFS. */ + char *dfs_mountpoint; }; typedef struct file_info { diff --git a/source3/include/includes.h b/source3/include/includes.h index ca918b37df..4bf4b5c735 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -584,10 +584,6 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx); #include "../lib/util/time.h" #include "../lib/util/asn1.h" -/* And a little extension. Abort on type mismatch */ -#define talloc_get_type_abort(ptr, type) \ - (type *)talloc_check_name_abort(ptr, #type) - #include "ads.h" #include "ads_dns.h" #include "interfaces.h" @@ -626,7 +622,6 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx); #include "ntdomain.h" #include "reg_objects.h" #include "reg_db.h" -#include "rpc_spoolss.h" #include "rpc_perfcount.h" #include "rpc_perfcount_defs.h" #include "librpc/gen_ndr/notify.h" diff --git a/source3/include/libsmb_internal.h b/source3/include/libsmb_internal.h index 166685c380..0bfcd8fab7 100644 --- a/source3/include/libsmb_internal.h +++ b/source3/include/libsmb_internal.h @@ -74,7 +74,7 @@ struct _SMBCSRV { bool no_pathinfo; bool no_pathinfo2; bool no_nt_session; - POLICY_HND pol; + struct policy_handle pol; SMBCSRV *next, *prev; @@ -181,6 +181,12 @@ struct SMBC_internal_data { */ bool case_sensitive; + /* + * Auth info needed for DFS traversal. + */ + + struct user_auth_info *auth_info; + struct smbc_server_cache * server_cache; /* POSIX emulation functions */ diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h index 43fd363b55..7dc60a8f03 100644 --- a/source3/include/nt_printing.h +++ b/source3/include/nt_printing.h @@ -440,7 +440,7 @@ typedef struct _Printer{ fstring localmachine; uint32 printerlocal; struct spoolss_NotifyOption *option; - POLICY_HND client_hnd; + struct policy_handle client_hnd; bool client_connected; uint32 change; /* are we in a FindNextPrinterChangeNotify() call? */ @@ -459,4 +459,20 @@ typedef struct _Printer{ } Printer_entry; +/* + * The printer attributes. + * I #defined all of them (grabbed form MSDN) + * I'm only using: + * ( SHARED | NETWORK | RAW_ONLY ) + * RAW_ONLY _MUST_ be present otherwise NT will send an EMF file + */ + +#define PRINTER_ATTRIBUTE_SAMBA (PRINTER_ATTRIBUTE_RAW_ONLY|\ + PRINTER_ATTRIBUTE_SHARED|\ + PRINTER_ATTRIBUTE_LOCAL) +#define PRINTER_ATTRIBUTE_NOT_SAMBA (PRINTER_ATTRIBUTE_NETWORK) + +#define DRIVER_ANY_VERSION 0xffffffff +#define DRIVER_MAX_VERSION 4 + #endif /* NT_PRINTING_H_ */ diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index 0eff9bdbac..c95931b5d0 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -117,7 +117,7 @@ typedef struct _input_data { struct policy { struct policy *next, *prev; - POLICY_HND pol_hnd; + struct policy_handle pol_hnd; void *data_ptr; }; @@ -293,11 +293,4 @@ struct api_struct { /* end higher order functions */ -typedef struct { - uint32 size; - prs_struct prs; - uint32 struct_start; - uint32 string_at_end; -} RPC_BUFFER; - #endif /* _NT_DOMAIN_H */ diff --git a/source3/include/passdb.h b/source3/include/passdb.h index 93c1e3f0ab..9cbc6bd340 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -186,7 +186,6 @@ enum pdb_search_type { }; struct pdb_search { - TALLOC_CTX *mem_ctx; enum pdb_search_type type; struct samr_displayentry *cache; uint32 num_entries; diff --git a/source3/include/popt_common.h b/source3/include/popt_common.h index bbd013a18f..ae8378f28b 100644 --- a/source3/include/popt_common.h +++ b/source3/include/popt_common.h @@ -53,6 +53,7 @@ struct user_auth_info { int signing_state; bool smb_encrypt; bool use_machine_account; + bool fallback_after_kerberos; }; #endif /* _POPT_COMMON_H */ diff --git a/source3/include/proto.h b/source3/include/proto.h index e1eab8dc16..3d87f75c7b 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -347,9 +347,6 @@ size_t convert_string(charset_t from, charset_t to, bool convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to, void const *src, size_t srclen, void *dst, size_t *converted_size, bool allow_bad_conv); -bool convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to, - void const *src, size_t srclen, void **dst, - size_t *converted_size, bool allow_bad_conv); size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen); char *strdup_upper(const char *s); char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *s); @@ -1075,27 +1072,31 @@ const char *my_netbios_names(int i); bool set_netbios_aliases(const char **str_array); bool init_names(void); struct user_auth_info *user_auth_info_init(TALLOC_CTX *mem_ctx); -const char *get_cmdline_auth_info_username(struct user_auth_info *auth_info); +const char *get_cmdline_auth_info_username(const struct user_auth_info *auth_info); void set_cmdline_auth_info_username(struct user_auth_info *auth_info, const char *username); void set_cmdline_auth_info_password(struct user_auth_info *auth_info, const char *password); -const char *get_cmdline_auth_info_password(struct user_auth_info *auth_info); +const char *get_cmdline_auth_info_password(const struct user_auth_info *auth_info); bool set_cmdline_auth_info_signing_state(struct user_auth_info *auth_info, const char *arg); -int get_cmdline_auth_info_signing_state(struct user_auth_info *auth_info); +int get_cmdline_auth_info_signing_state(const struct user_auth_info *auth_info); void set_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info, bool b); -bool get_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info); +bool get_cmdline_auth_info_use_kerberos(const struct user_auth_info *auth_info); +void set_cmdline_auth_info_fallback_after_kerberos(struct user_auth_info *auth_info, + bool b); +bool get_cmdline_auth_info_fallback_after_kerberos(const struct user_auth_info *auth_info); void set_cmdline_auth_info_use_krb5_ticket(struct user_auth_info *auth_info); void set_cmdline_auth_info_smb_encrypt(struct user_auth_info *auth_info); void set_cmdline_auth_info_use_machine_account(struct user_auth_info *auth_info); -bool get_cmdline_auth_info_got_pass(struct user_auth_info *auth_info); -bool get_cmdline_auth_info_smb_encrypt(struct user_auth_info *auth_info); -bool get_cmdline_auth_info_use_machine_account(struct user_auth_info *auth_info); +bool get_cmdline_auth_info_got_pass(const struct user_auth_info *auth_info); +bool get_cmdline_auth_info_smb_encrypt(const struct user_auth_info *auth_info); +bool get_cmdline_auth_info_use_machine_account(const struct user_auth_info *auth_info); struct user_auth_info *get_cmdline_auth_info_copy(TALLOC_CTX *mem_ctx, - struct user_auth_info *info); + const struct user_auth_info *info); bool set_cmdline_auth_info_machine_account_creds(struct user_auth_info *auth_info); +void set_cmdline_auth_info_getpass(struct user_auth_info *auth_info); bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid, gid_t **gids, size_t *num_gids); bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf); @@ -1173,7 +1174,6 @@ bool mask_match_search(const char *string, const char *pattern, bool is_case_sen bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive); bool unix_wild_match(const char *pattern, const char *string); bool name_to_fqdn(fstring fqdn, const char *name); -void *talloc_check_name_abort(const void *ptr, const char *name); void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob); uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options); pid_t procid_to_pid(const struct server_id *proc); @@ -1209,7 +1209,7 @@ void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned coun void *talloc_zeronull(const void *context, size_t size, const char *name); NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname, char **pbase, char **pstream); -bool is_valid_policy_hnd(const POLICY_HND *hnd); +bool is_valid_policy_hnd(const struct policy_handle *hnd); bool policy_hnd_equal(const struct policy_handle *hnd1, const struct policy_handle *hnd2); const char *strip_hostname(const char *s); @@ -1400,13 +1400,13 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx, uint16_t port, int timeout); NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd); -struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct timeval wait_time, - const struct sockaddr_storage *pss, - uint16_t port, - int timeout); -NTSTATUS open_socket_out_defer_recv(struct async_req *req, int *pfd); +struct tevent_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct timeval wait_time, + const struct sockaddr_storage *pss, + uint16_t port, + int timeout); +NTSTATUS open_socket_out_defer_recv(struct tevent_req *req, int *pfd); bool open_any_socket_out(struct sockaddr_storage *addrs, int num_addrs, int timeout, int *fd_index, int *fd); int open_udp_socket(const char *host, int port); @@ -1557,7 +1557,6 @@ char *rpcstr_pull_unistr2_talloc(TALLOC_CTX *ctx, const UNISTR2 *src); int rpcstr_push(void *dest, const char *src, size_t dest_len, int flags); int rpcstr_push_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src); void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen); -void unistr3_to_ascii(char *dest, const UNISTR3 *str, size_t maxlen); char *unistr2_to_ascii_talloc(TALLOC_CTX *ctx, const UNISTR2 *str); const char *unistr2_static(const UNISTR2 *str); smb_ucs2_t toupper_w(smb_ucs2_t val); @@ -2359,27 +2358,17 @@ NTSTATUS cli_cm_force_encryption(struct cli_state *c, const char *password, const char *domain, const char *sharename); -const char *cli_cm_get_mntpoint(struct cli_state *c); struct cli_state *cli_cm_open(TALLOC_CTX *ctx, struct cli_state *referring_cli, const char *server, const char *share, + const struct user_auth_info *auth_info, bool show_hdr, bool force_encrypt, int max_protocol, int port, int name_type); -void cli_cm_shutdown(void); -void cli_cm_display(void); -void cli_cm_set_credentials(struct user_auth_info *auth_info); -void cli_cm_set_port(int port_number); -void cli_cm_set_dest_name_type(int type); -void cli_cm_set_signing_state(int state); -void cli_cm_set_username(const char *username); -void cli_cm_set_password(const char *newpass); -void cli_cm_set_use_kerberos(void); -void cli_cm_set_fallback_after_kerberos(void); -void cli_cm_set_dest_ss(struct sockaddr_storage *pss); +void cli_cm_display(const struct cli_state *c); bool cli_dfs_get_referral(TALLOC_CTX *ctx, struct cli_state *cli, const char *path, @@ -2388,6 +2377,7 @@ bool cli_dfs_get_referral(TALLOC_CTX *ctx, uint16 *consumed); bool cli_resolve_path(TALLOC_CTX *ctx, const char *mountpt, + const struct user_auth_info *dfs_auth_info, struct cli_state *rootcli, const char *path, struct cli_state **targetcli, @@ -2430,9 +2420,12 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli, void cli_setup_packet_buf(struct cli_state *cli, char *buf); void cli_setup_packet(struct cli_state *cli); void cli_setup_bcc(struct cli_state *cli, void *p); -void cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password); -void cli_setup_signing_state(struct cli_state *cli, int signing_state); +NTSTATUS cli_set_domain(struct cli_state *cli, const char *domain); +NTSTATUS cli_set_username(struct cli_state *cli, const char *username); +NTSTATUS cli_set_password(struct cli_state *cli, const char *password); +NTSTATUS cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password); struct cli_state *cli_initialise(void); +struct cli_state *cli_initialise_ex(int signing_state); void cli_nt_pipes_close(struct cli_state *cli); void cli_shutdown(struct cli_state *cli); void cli_sockopt(struct cli_state *cli, const char *options); @@ -3160,11 +3153,6 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam const char *old_passwd, const char *new_passwd, char **err_str); -/* The following definitions come from libsmb/pwd_cache.c */ - -void pwd_set_cleartext(struct pwd_info *pwd, const char *clr); -void pwd_get_cleartext(struct pwd_info *pwd, fstring clr); - /* The following definitions come from libsmb/samlogon_cache.c */ bool netsamlogon_cache_init(void); @@ -3210,7 +3198,7 @@ bool srv_oplock_set_signing(bool onoff); bool srv_check_sign_mac(const char *inbuf, bool must_be_ok); void srv_calculate_sign_mac(char *outbuf); void srv_defer_sign_response(uint16 mid); -void srv_cancel_sign_response(uint16 mid); +void srv_cancel_sign_response(uint16 mid, bool cancel); void srv_set_signing_negotiated(void); bool srv_is_signing_active(void); bool srv_is_signing_negotiated(void); @@ -3415,11 +3403,16 @@ void brl_register_msgs(struct messaging_context *msg_ctx); const char *lock_type_name(enum brl_type lock_type); const char *lock_flav_name(enum brl_flavour lock_flav); -bool is_locked(files_struct *fsp, - uint32 smbpid, - uint64_t count, - uint64_t offset, - enum brl_type lock_type); +void init_strict_lock_struct(files_struct *fsp, + uint32 smbpid, + br_off start, + br_off size, + enum brl_type lock_type, + struct lock_struct *plock); +bool strict_lock_default(files_struct *fsp, + struct lock_struct *plock); +void strict_unlock_default(files_struct *fsp, + struct lock_struct *plock); NTSTATUS query_lock(files_struct *fsp, uint32 *psmbpid, uint64_t *pcount, @@ -3485,9 +3478,9 @@ bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp); bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp); NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close, uint32 dosmode); -void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok); -void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, UNIX_USER_TOKEN *tok); -bool set_delete_on_close(files_struct *fsp, bool delete_on_close, UNIX_USER_TOKEN *tok); +void set_delete_on_close_token(struct share_mode_lock *lck, const UNIX_USER_TOKEN *tok); +void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, const UNIX_USER_TOKEN *tok); +bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USER_TOKEN *tok); bool set_sticky_write_time(struct file_id fileid, struct timespec write_time); bool set_write_time(struct file_id fileid, struct timespec write_time); int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, @@ -4618,14 +4611,14 @@ bool pdb_sid_to_id(const DOM_SID *sid, union unid_t *id, bool pdb_rid_algorithm(void); bool pdb_new_rid(uint32 *rid); bool initialize_password_db(bool reload, struct event_context *event_ctx); -struct pdb_search *pdb_search_init(enum pdb_search_type type); -struct pdb_search *pdb_search_users(uint32 acct_flags); -struct pdb_search *pdb_search_groups(void); -struct pdb_search *pdb_search_aliases(const DOM_SID *sid); +struct pdb_search *pdb_search_init(TALLOC_CTX *mem_ctx, + enum pdb_search_type type); +struct pdb_search *pdb_search_users(TALLOC_CTX *mem_ctx, uint32 acct_flags); +struct pdb_search *pdb_search_groups(TALLOC_CTX *mem_ctx); +struct pdb_search *pdb_search_aliases(TALLOC_CTX *mem_ctx, const DOM_SID *sid); uint32 pdb_search_entries(struct pdb_search *search, uint32 start_idx, uint32 max_entries, struct samr_displayentry **result); -void pdb_search_destroy(struct pdb_search *search); bool pdb_get_trusteddom_pw(const char *domain, char** pwd, DOM_SID *sid, time_t *pass_last_set_time); bool pdb_set_trusteddom_pw(const char* domain, const char* pwd, @@ -4796,7 +4789,6 @@ bool nt_printing_init(struct messaging_context *msg_ctx); uint32 update_c_setprinter(bool initialize); uint32 get_c_setprinter(void); int get_builtin_ntforms(nt_forms_struct **list); -bool get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form); bool get_a_builtin_ntform_by_string(const char *form_name, nt_forms_struct *form); int get_ntforms(nt_forms_struct **list); int write_ntforms(nt_forms_struct **list, int number); @@ -4932,7 +4924,7 @@ bool print_job_resume(struct auth_serversupplied_info *server_info, int snum, ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size); int print_queue_length(int snum, print_status_struct *pstatus); uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum, - char *jobname, NT_DEVICEMODE *nt_devmode ); + const char *jobname, NT_DEVICEMODE *nt_devmode ); void print_job_endpage(int snum, uint32 jobid); bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type); int print_queue_status(int snum, @@ -5178,13 +5170,13 @@ WERROR regkey_open_internal( TALLOC_CTX *ctx, REGISTRY_KEY **regkey, NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, bool sec_qos, uint32 des_access, - POLICY_HND *pol); + struct policy_handle *pol); NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, bool sec_qos, - uint32 des_access, POLICY_HND *pol); + uint32 des_access, struct policy_handle *pol); NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, + struct policy_handle *pol, int num_sids, const DOM_SID *sids, char ***pdomains, @@ -5192,7 +5184,7 @@ NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli, enum lsa_SidType **ptypes); NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_names, + struct policy_handle *pol, int num_names, const char **names, const char ***dom_names, int level, @@ -5406,7 +5398,7 @@ NTSTATUS rpc_transport_sock_init(TALLOC_CTX *mem_ctx, int fd, NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 reg_type, uint32 access_mask, - POLICY_HND *reg_hnd); + struct policy_handle *reg_hnd); /* The following definitions come from rpc_client/cli_samr.c */ @@ -5439,7 +5431,7 @@ void get_query_dispinfo_params(int loop_count, uint32 *max_entries, NTSTATUS rpccli_try_samr_connects(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32_t access_mask, - POLICY_HND *connect_pol); + struct policy_handle *connect_pol); /* The following definitions come from rpc_client/cli_spoolss.c */ @@ -5475,43 +5467,100 @@ WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, uint32_t level, uint32_t offered, union spoolss_JobInfo *info); -WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - char *name, uint32 flags, uint32 level, - uint32 *num_printers, PRINTER_INFO_CTR *ctr); -WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - uint32 level, uint32 *num_ports, PORT_INFO_CTR *ctr); -WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - uint32 level, const char *env, - uint32 *num_drivers, - PRINTER_DRIVER_CTR *ctr); -WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *handle, int level, uint32 *num_forms, - FORM_1 **forms); -WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 level, uint32 firstjob, - uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr); -WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, const char *valuename, - REGISTRY_VALUE *value); -WERROR rpccli_spoolss_setprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, REGISTRY_VALUE *value); -WERROR rpccli_spoolss_enumprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 ndx, - uint32 value_offered, uint32 data_offered, - uint32 *value_needed, uint32 *data_needed, - REGISTRY_VALUE *value); -WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, const char *keyname, - REGVAL_CTR *ctr); -WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, const char *keyname, - uint16 **keylist, uint32 *len); +WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_FormInfo **info); +WERROR rpccli_spoolss_enumprintprocessors(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *servername, + const char *environment, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_PrintProcessorInfo **info); +WERROR rpccli_spoolss_enumprintprocessordatatypes(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *servername, + const char *print_processor_name, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_PrintProcDataTypesInfo **info); +WERROR rpccli_spoolss_enumports(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *servername, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_PortInfo **info); +WERROR rpccli_spoolss_enummonitors(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *servername, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_MonitorInfo **info); +WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t firstjob, + uint32_t numjobs, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_JobInfo **info); +WERROR rpccli_spoolss_enumprinterdrivers(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *server, + const char *environment, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_DriverInfo **info); +WERROR rpccli_spoolss_enumprinters(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + uint32_t flags, + const char *server, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_PrinterInfo **info); +WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + const char *value_name, + uint32_t offered, + enum winreg_Type *type, + union spoolss_PrinterData *data); +WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + const char *key_name, + const char ***key_buffer, + uint32_t offered); +WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + const char *key_name, + uint32_t offered, + uint32_t *count, + struct spoolss_PrinterEnumValues **info); /* The following definitions come from rpc_client/init_spoolss.c */ bool init_systemtime(struct spoolss_Time *r, struct tm *unixtime); +WERROR pull_spoolss_PrinterData(TALLOC_CTX *mem_ctx, + const DATA_BLOB *blob, + union spoolss_PrinterData *data, + enum winreg_Type type); +WERROR push_spoolss_PrinterData(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, + enum winreg_Type type, + union spoolss_PrinterData *data); /* The following definitions come from rpc_client/init_lsa.c */ @@ -5624,44 +5673,16 @@ NTSTATUS cli_do_rpc_ndr(struct rpc_pipe_client *cli, const struct ndr_interface_table *table, uint32 opnum, void *r); -/* The following definitions come from rpc_parse/parse_buffer.c */ - -bool rpcbuf_init(RPC_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx); -bool prs_rpcbuffer(const char *desc, prs_struct *ps, int depth, RPC_BUFFER *buffer); -bool prs_rpcbuffer_p(const char *desc, prs_struct *ps, int depth, RPC_BUFFER **buffer); -bool rpcbuf_alloc_size(RPC_BUFFER *buffer, uint32 buffer_size); -void rpcbuf_move(RPC_BUFFER *src, RPC_BUFFER **dest); -uint32 rpcbuf_get_size(RPC_BUFFER *buffer); -bool smb_io_relstr(const char *desc, RPC_BUFFER *buffer, int depth, UNISTR *string); -bool smb_io_relarraystr(const char *desc, RPC_BUFFER *buffer, int depth, uint16 **string); -bool smb_io_relsecdesc(const char *desc, RPC_BUFFER *buffer, int depth, SEC_DESC **secdesc); -uint32 size_of_relative_string(UNISTR *string); - /* The following definitions come from rpc_parse/parse_misc.c */ bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth); -bool smb_io_nttime(const char *desc, prs_struct *ps, int depth, NTTIME *nttime); +bool smb_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime); +bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime); bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth); bool smb_io_uuid(const char *desc, struct GUID *uuid, prs_struct *ps, int depth); void init_unistr(UNISTR *str, const char *buf); -bool smb_io_unistr(const char *desc, UNISTR *uni, prs_struct *ps, int depth); -bool smb_io_buffer5(const char *desc, BUFFER5 *buf5, prs_struct *ps, int depth); -void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf); -void copy_unistr2(UNISTR2 *str, const UNISTR2 *from); void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags); -void init_unistr2_w(TALLOC_CTX *ctx, UNISTR2 *str, const smb_ucs2_t *buf); -void init_unistr2_from_unistr(TALLOC_CTX *ctx, UNISTR2 *to, const UNISTR *from); -void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob) ; -bool prs_io_unistr2_p(const char *desc, prs_struct *ps, int depth, UNISTR2 **uni2); -bool prs_io_unistr2(const char *desc, prs_struct *ps, int depth, UNISTR2 *uni2 ); -bool smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth); -bool smb_io_pol_hnd(const char *desc, POLICY_HND *pol, prs_struct *ps, int depth); -void init_unistr3(UNISTR3 *str, const char *buf); -bool smb_io_unistr3(const char *desc, UNISTR3 *name, prs_struct *ps, int depth); -bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64); -uint32 str_len_uni(UNISTR *source); -bool policy_handle_is_valid(const POLICY_HND *hnd); /* The following definitions come from rpc_parse/parse_prs.c */ @@ -5709,6 +5730,7 @@ bool prs_pointer( const char *name, prs_struct *ps, int depth, bool prs_uint16(const char *name, prs_struct *ps, int depth, uint16 *data16); bool prs_uint32(const char *name, prs_struct *ps, int depth, uint32 *data32); bool prs_int32(const char *name, prs_struct *ps, int depth, int32 *data32); +bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64); bool prs_ntstatus(const char *name, prs_struct *ps, int depth, NTSTATUS *status); bool prs_dcerpc_status(const char *name, prs_struct *ps, int depth, NTSTATUS *status); bool prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status); @@ -5716,9 +5738,7 @@ bool prs_uint8s(bool charmode, const char *name, prs_struct *ps, int depth, uint bool prs_uint16s(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len); bool prs_uint16uni(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len); bool prs_uint32s(bool charmode, const char *name, prs_struct *ps, int depth, uint32 *data32s, int len); -bool prs_buffer5(bool charmode, const char *name, prs_struct *ps, int depth, BUFFER5 *str); bool prs_unistr2(bool charmode, const char *name, prs_struct *ps, int depth, UNISTR2 *str); -bool prs_unistr3(bool charmode, const char *name, UNISTR3 *str, prs_struct *ps, int depth); bool prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str); bool prs_string(const char *name, prs_struct *ps, int depth, char *str, int max_buf_size); bool prs_string_alloc(const char *name, prs_struct *ps, int depth, const char **str); @@ -5788,140 +5808,6 @@ bool smb_io_rpc_auth_schannel_chk(const char *desc, int auth_len, bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth); bool sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth); -/* The following definitions come from rpc_parse/parse_spoolss.c */ - -bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime); -bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime); -bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode); -bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, - const POLICY_HND *handle, - const char *valuename, uint32 size); -bool spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth); -bool smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth); -bool smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth); -bool smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth); -bool smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth); -bool smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth); -bool smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth); -bool smb_io_printer_info_6(const char *desc, RPC_BUFFER *buffer, - PRINTER_INFO_6 *info, int depth); -bool smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth); -bool smb_io_port_info_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth); -bool smb_io_port_info_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth); -bool smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) ; -bool smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) ; -bool smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth); -bool smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth); -bool smb_io_job_info_1(const char *desc, RPC_BUFFER *buffer, JOB_INFO_1 *info, int depth); -bool smb_io_job_info_2(const char *desc, RPC_BUFFER *buffer, JOB_INFO_2 *info, int depth); -bool smb_io_form_1(const char *desc, RPC_BUFFER *buffer, FORM_1 *info, int depth); -bool smb_io_port_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth); -bool smb_io_port_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth); -bool smb_io_printprocessor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth); -bool smb_io_printprocdatatype_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth); -bool smb_io_printmonitor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_1 *info, int depth); -bool smb_io_printmonitor_info_2(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_2 *info, int depth); -uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info); -uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info); -uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info); -uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info); -uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info); -uint32 spoolss_size_printer_info_6(PRINTER_INFO_6 *info); -uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info); -uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info); -uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info); -uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info); -uint32 spoolss_size_string_array(uint16 *string); -uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info); -uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info); -uint32 spoolss_size_job_info_1(JOB_INFO_1 *info); -uint32 spoolss_size_job_info_2(JOB_INFO_2 *info); -uint32 spoolss_size_form_1(FORM_1 *info); -uint32 spoolss_size_port_info_1(PORT_INFO_1 *info); -uint32 spoolss_size_port_info_2(PORT_INFO_2 *info); -uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info); -uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info); -uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p); -uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info); -uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info); -bool spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth); -bool make_spoolss_q_enumprinters( - SPOOL_Q_ENUMPRINTERS *q_u, - uint32 flags, - char *servername, - uint32 level, - RPC_BUFFER *buffer, - uint32 offered -); -bool make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, - fstring servername, uint32 level, - RPC_BUFFER *buffer, uint32 offered); -bool spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth); -bool spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth); -bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth); -bool make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd, - uint32 firstjob, - uint32 numofjobs, - uint32 level, - RPC_BUFFER *buffer, - uint32 offered); -bool spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth); -bool make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u, - const char *name, - const char *environment, - uint32 level, - RPC_BUFFER *buffer, uint32 offered); -bool spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth); -bool spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth); -bool spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth); -bool spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth); -bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src); -bool spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth); -bool spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth); -bool spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth); -bool spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth); -bool spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth); -bool spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth); -bool make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u, - const POLICY_HND *hnd, - uint32 idx, uint32 valuelen, uint32 datalen); -bool make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u, - const POLICY_HND *hnd, const char *key, - uint32 size); -bool make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd, - char* value, uint32 data_type, char* data, uint32 data_size); -bool spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth); -bool spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth); -bool spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth); -void free_devmode(DEVICEMODE *devmode); -void free_printer_info_1(PRINTER_INFO_1 *printer); -void free_printer_info_2(PRINTER_INFO_2 *printer); -void free_printer_info_3(PRINTER_INFO_3 *printer); -void free_printer_info_4(PRINTER_INFO_4 *printer); -void free_printer_info_5(PRINTER_INFO_5 *printer); -void free_printer_info_6(PRINTER_INFO_6 *printer); -void free_printer_info_7(PRINTER_INFO_7 *printer); -void free_job_info_2(JOB_INFO_2 *job); -bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u, - POLICY_HND *hnd, const char *key, - uint32 size); -bool spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth); -bool spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth); -bool make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, - uint32 level, RPC_BUFFER *buffer, - uint32 offered); - /* The following definitions come from rpc_server/srv_eventlog_lib.c */ TDB_CONTEXT *elog_init_tdb( char *tdbfilename ); @@ -5959,9 +5845,9 @@ NTSTATUS evlog_tdb_entry_to_evt_entry(TALLOC_CTX *mem_ctx, bool init_pipe_handle_list(pipes_struct *p, const struct ndr_syntax_id *syntax); -bool create_policy_hnd(pipes_struct *p, POLICY_HND *hnd, void *data_ptr); -bool find_policy_by_hnd(pipes_struct *p, POLICY_HND *hnd, void **data_p); -bool close_policy_hnd(pipes_struct *p, POLICY_HND *hnd); +bool create_policy_hnd(pipes_struct *p, struct policy_handle *hnd, void *data_ptr); +bool find_policy_by_hnd(pipes_struct *p, struct policy_handle *hnd, void **data_p); +bool close_policy_hnd(pipes_struct *p, struct policy_handle *hnd); void close_policy_by_pipe(pipes_struct *p); bool pipe_access_check(pipes_struct *p); @@ -6000,14 +5886,14 @@ NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name, const char *client_address, struct auth_serversupplied_info *server_info, struct fake_file_handle **phandle); -struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev, +struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev, + struct fake_file_handle *handle, + const uint8_t *data, size_t len); +NTSTATUS np_write_recv(struct tevent_req *req, ssize_t *pnwritten); +struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct fake_file_handle *handle, - const uint8_t *data, size_t len); -NTSTATUS np_write_recv(struct async_req *req, ssize_t *nwritten); -struct async_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct fake_file_handle *handle, - uint8_t *data, size_t len); -NTSTATUS np_read_recv(struct async_req *req, ssize_t *nread, + uint8_t *data, size_t len); +NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread, bool *is_data_outstanding); /* The following definitions come from rpc_server/srv_samr_util.c */ @@ -6022,11 +5908,6 @@ void copy_id23_to_sam_passwd(struct samu *to, void copy_id25_to_sam_passwd(struct samu *to, struct samr_UserInfo25 *from); -/* The following definitions come from rpc_server/srv_spoolss.c */ - -void spoolss2_get_pipe_fns( struct api_struct **fns, int *n_fns ); -NTSTATUS rpc_spoolss2_init(void); - /* The following definitions come from rpc_server/srv_spoolss_nt.c */ WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename ); @@ -6041,11 +5922,11 @@ void reset_all_printerdata(struct messaging_context *msg, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data); -bool convert_devicemode(const char *printername, const DEVICEMODE *devmode, - NT_DEVICEMODE **pp_nt_devmode); +bool convert_devicemode(const char *printername, + const struct spoolss_DeviceMode *devmode, + NT_DEVICEMODE **pp_nt_devmode); WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value, uint32 type, uint8 *data, int real_len ); -WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u); void spoolss_notify_server_name(int snum, struct spoolss_Notify *data, print_queue_struct *queue, @@ -6113,27 +5994,13 @@ void spoolss_notify_cjobs(int snum, TALLOC_CTX *mem_ctx); void construct_info_data(struct spoolss_Notify *info_data, enum spoolss_NotifyType type, - enum spoolss_Field field, + uint16_t field, int id); -DEVICEMODE *construct_dev_mode(const char *servicename); -WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u); -WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u); -WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u); +struct spoolss_DeviceMode *construct_dev_mode(TALLOC_CTX *mem_ctx, + const char *servicename); WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri ); bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer); -WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u); -WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u); -WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u); WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines ); -WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u); -WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u); -WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u); -WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u); -WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u); -WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u); -WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u); -WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u); -WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u); /* The following definitions come from rpc_server/srv_srvsvc_nt.c */ @@ -6724,6 +6591,8 @@ void msg_file_was_renamed(struct messaging_context *msg, struct case_semantics_state; struct case_semantics_state *set_posix_case_semantics(TALLOC_CTX *mem_ctx, connection_struct *conn); +NTSTATUS open_streams_for_delete(connection_struct *conn, + const char *fname); NTSTATUS create_file_default(connection_struct *conn, struct smb_request *req, uint16_t root_dir_fid, diff --git a/source3/include/rpc_client.h b/source3/include/rpc_client.h index afa18899ca..84ac8b17d4 100644 --- a/source3/include/rpc_client.h +++ b/source3/include/rpc_client.h @@ -41,34 +41,4 @@ #define prs_init_empty( _ps_, _ctx_, _io_ ) (void) prs_init((_ps_), 0, (_ctx_), (_io_)) -/* macro to expand cookie-cutter code in cli_xxx() using rpc_api_pipe_req() */ - -#define CLI_DO_RPC_WERR( pcli, ctx, interface, opnum, q_in, r_out, \ - q_ps, r_ps, q_io_fn, r_io_fn, default_error ) \ -{\ - SMB_ASSERT(ndr_syntax_id_equal(&pcli->abstract_syntax, interface)); \ - if (!prs_init( &q_ps, RPC_MAX_PDU_FRAG_LEN, ctx, MARSHALL )) { \ - return WERR_NOMEM;\ - }\ - if ( q_io_fn("", &q_in, &q_ps, 0) ) {\ - NTSTATUS _smb_pipe_stat_ = rpc_api_pipe_req(ctx, pcli, opnum, &q_ps, &r_ps); \ - if (!NT_STATUS_IS_OK(_smb_pipe_stat_)) {\ - prs_mem_free( &q_ps );\ - prs_mem_free( &r_ps );\ - return ntstatus_to_werror(_smb_pipe_stat_);\ - }\ - if (!r_io_fn("", &r_out, &r_ps, 0)) {\ - prs_mem_free( &q_ps );\ - prs_mem_free( &r_ps );\ - return default_error;\ - }\ - } else {\ - prs_mem_free( &q_ps );\ - prs_mem_free( &r_ps );\ - return default_error;\ - }\ - prs_mem_free( &q_ps );\ - prs_mem_free( &r_ps );\ -} - #endif /* _RPC_CLIENT_H */ diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h index b63f0eac5e..580b14f1d8 100644 --- a/source3/include/rpc_dce.h +++ b/source3/include/rpc_dce.h @@ -159,8 +159,6 @@ enum schannel_direction { /* RPC_IFACE */ typedef struct ndr_syntax_id RPC_IFACE; -extern const struct ndr_syntax_id syntax_spoolss; - #define RPC_IFACE_LEN (UUID_SIZE + 4) /* RPC_HDR - dce rpc header */ diff --git a/source3/include/rpc_misc.h b/source3/include/rpc_misc.h index 1e9d43bfa0..797e1926db 100644 --- a/source3/include/rpc_misc.h +++ b/source3/include/rpc_misc.h @@ -90,8 +90,6 @@ enum unistr2_term_codes { UNI_FLAGS_NONE = 0, UNI_STR_TERMINATE = 1, UNI_MAXLEN_ /********************************************************************** * RPC policy handle used pretty much everywhere **********************************************************************/ - -typedef struct policy_handle POLICY_HND; #define OUR_HANDLE(hnd) (((hnd)==NULL) ? "NULL" :\ ( IVAL((hnd)->uuid.node,2) == (uint32)sys_getpid() ? "OURS" : \ @@ -100,17 +98,6 @@ typedef struct policy_handle POLICY_HND; /********************************************************************** - * Buffers use by spoolss (i might be able to replace it with - * an RPC_DATA_BLOB) - **********************************************************************/ - -typedef struct { - uint32 buf_len; - uint16 *buffer; /* data */ -} BUFFER5; - - -/********************************************************************** * UNICODE string variations **********************************************************************/ @@ -130,12 +117,23 @@ typedef struct { /* UNISTR2 - unicode string size (in should include the NULL character */ } UNISTR2; -/* i think this is the same as a BUFFER5 used in the spoolss code --jerry */ -/* not sure about how the termination matches between the uint16 buffers thought */ - -typedef struct { /* UNISTR3 - XXXX not sure about this structure */ - uint32 uni_str_len; - UNISTR str; -} UNISTR3; +/* + * I'm really wondering how many different time formats + * I will have to cope with + * + * JFM, 09/13/98 In a mad mood ;-( +*/ +typedef struct systemtime +{ + uint16 year; + uint16 month; + uint16 dayofweek; + uint16 day; + uint16 hour; + uint16 minute; + uint16 second; + uint16 milliseconds; +} +SYSTEMTIME; #endif /* _RPC_MISC_H */ diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h deleted file mode 100644 index 798bbf922c..0000000000 --- a/source3/include/rpc_spoolss.h +++ /dev/null @@ -1,1038 +0,0 @@ -/* - Unix SMB/Netbios implementation. - - Copyright (C) Andrew Tridgell 1992-2000, - Copyright (C) Luke Kenneth Casson Leighton 1996-2000, - Copyright (C) Jean Francois Micouleau 1998-2000. - Copyright (C) Gerald Carter 2001-2006. - - 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 3 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, see <http://www.gnu.org/licenses/>. -*/ - -#include "librpc/gen_ndr/spoolss.h" - -#ifndef _RPC_SPOOLSS_H /* _RPC_SPOOLSS_H */ -#define _RPC_SPOOLSS_H - -/* spoolss pipe: this are the calls which are not implemented ... -#define SPOOLSS_GETPRINTERDRIVER 0x0b -#define SPOOLSS_READPRINTER 0x16 -#define SPOOLSS_WAITFORPRINTERCHANGE 0x1c -#define SPOOLSS_ADDPORT 0x25 -#define SPOOLSS_CONFIGUREPORT 0x26 -#define SPOOLSS_DELETEPORT 0x27 -#define SPOOLSS_CREATEPRINTERIC 0x28 -#define SPOOLSS_PLAYGDISCRIPTONPRINTERIC 0x29 -#define SPOOLSS_DELETEPRINTERIC 0x2a -#define SPOOLSS_ADDPRINTERCONNECTION 0x2b -#define SPOOLSS_DELETEPRINTERCONNECTION 0x2c -#define SPOOLSS_PRINTERMESSAGEBOX 0x2d -#define SPOOLSS_ADDMONITOR 0x2e -#define SPOOLSS_DELETEMONITOR 0x2f -#define SPOOLSS_DELETEPRINTPROCESSOR 0x30 -#define SPOOLSS_ADDPRINTPROVIDOR 0x31 -#define SPOOLSS_DELETEPRINTPROVIDOR 0x32 -#define SPOOLSS_FINDFIRSTPRINTERCHANGENOTIFICATION 0x36 -#define SPOOLSS_FINDNEXTPRINTERCHANGENOTIFICATION 0x37 -#define SPOOLSS_ROUTERFINDFIRSTPRINTERNOTIFICATIONOLD 0x39 -#define SPOOLSS_ADDPORTEX 0x3d -#define SPOOLSS_REMOTEFINDFIRSTPRINTERCHANGENOTIFICATION0x3e -#define SPOOLSS_SPOOLERINIT 0x3f -#define SPOOLSS_RESETPRINTEREX 0x40 -*/ - -/* those are implemented */ -#define SPOOLSS_ENUMPRINTERS 0x00 -#define SPOOLSS_OPENPRINTER 0x01 -#define SPOOLSS_SETJOB 0x02 -#define SPOOLSS_GETJOB 0x03 -#define SPOOLSS_ENUMJOBS 0x04 -#define SPOOLSS_ADDPRINTER 0x05 -#define SPOOLSS_DELETEPRINTER 0x06 -#define SPOOLSS_SETPRINTER 0x07 -#define SPOOLSS_GETPRINTER 0x08 -#define SPOOLSS_ADDPRINTERDRIVER 0x09 -#define SPOOLSS_ENUMPRINTERDRIVERS 0x0a -#define SPOOLSS_GETPRINTERDRIVERDIRECTORY 0x0c -#define SPOOLSS_DELETEPRINTERDRIVER 0x0d -#define SPOOLSS_ADDPRINTPROCESSOR 0x0e -#define SPOOLSS_ENUMPRINTPROCESSORS 0x0f -#define SPOOLSS_GETPRINTPROCESSORDIRECTORY 0x10 -#define SPOOLSS_STARTDOCPRINTER 0x11 -#define SPOOLSS_STARTPAGEPRINTER 0x12 -#define SPOOLSS_WRITEPRINTER 0x13 -#define SPOOLSS_ENDPAGEPRINTER 0x14 -#define SPOOLSS_ABORTPRINTER 0x15 -#define SPOOLSS_ENDDOCPRINTER 0x17 -#define SPOOLSS_ADDJOB 0x18 -#define SPOOLSS_SCHEDULEJOB 0x19 -#define SPOOLSS_GETPRINTERDATA 0x1a -#define SPOOLSS_SETPRINTERDATA 0x1b -#define SPOOLSS_CLOSEPRINTER 0x1d -#define SPOOLSS_ADDFORM 0x1e -#define SPOOLSS_DELETEFORM 0x1f -#define SPOOLSS_GETFORM 0x20 -#define SPOOLSS_SETFORM 0x21 -#define SPOOLSS_ENUMFORMS 0x22 -#define SPOOLSS_ENUMPORTS 0x23 -#define SPOOLSS_ENUMMONITORS 0x24 -#define SPOOLSS_ENUMPRINTPROCDATATYPES 0x33 -#define SPOOLSS_RESETPRINTER 0x34 -#define SPOOLSS_GETPRINTERDRIVER2 0x35 -#define SPOOLSS_FCPN 0x38 /* FindClosePrinterNotify */ -#define SPOOLSS_REPLYOPENPRINTER 0x3a -#define SPOOLSS_ROUTERREPLYPRINTER 0x3b -#define SPOOLSS_REPLYCLOSEPRINTER 0x3c -#define SPOOLSS_RFFPCNEX 0x41 /* RemoteFindFirstPrinterChangeNotifyEx */ -#define SPOOLSS_RRPCN 0x42 /* RouteRefreshPrinterChangeNotification */ -#define SPOOLSS_RFNPCNEX 0x43 /* RemoteFindNextPrinterChangeNotifyEx */ -#define SPOOLSS_OPENPRINTEREX 0x45 -#define SPOOLSS_ADDPRINTEREX 0x46 -#define SPOOLSS_ENUMPRINTERDATA 0x48 -#define SPOOLSS_DELETEPRINTERDATA 0x49 -#define SPOOLSS_SETPRINTERDATAEX 0x4d -#define SPOOLSS_GETPRINTERDATAEX 0x4e -#define SPOOLSS_ENUMPRINTERDATAEX 0x4f -#define SPOOLSS_ENUMPRINTERKEY 0x50 -#define SPOOLSS_DELETEPRINTERDATAEX 0x51 -#define SPOOLSS_DELETEPRINTERKEY 0x52 -#define SPOOLSS_DELETEPRINTERDRIVEREX 0x54 -#define SPOOLSS_XCVDATAPORT 0x58 -#define SPOOLSS_ADDPRINTERDRIVEREX 0x59 - -/* - * Special strings for the OpenPrinter() call. See the MSDN DDK - * docs on the XcvDataPort() for more details. - */ - -#define SPL_LOCAL_PORT "Local Port" -#define SPL_TCPIP_PORT "Standard TCP/IP Port" -#define SPL_XCV_MONITOR_LOCALMON ",XcvMonitor Local Port" -#define SPL_XCV_MONITOR_TCPMON ",XcvMonitor Standard TCP/IP Port" - - -#define PRINTER_STATUS_OK 0x00000000 - -/* Notify field types */ - -#define PRINTER_NOTIFY_TYPE 0x00 -#define JOB_NOTIFY_TYPE 0x01 - -#define PRINTER_NOTIFY_SERVER_NAME 0x00 -#define PRINTER_NOTIFY_PRINTER_NAME 0x01 -#define PRINTER_NOTIFY_SHARE_NAME 0x02 -#define PRINTER_NOTIFY_PORT_NAME 0x03 -#define PRINTER_NOTIFY_DRIVER_NAME 0x04 -#define PRINTER_NOTIFY_COMMENT 0x05 -#define PRINTER_NOTIFY_LOCATION 0x06 -#define PRINTER_NOTIFY_DEVMODE 0x07 -#define PRINTER_NOTIFY_SEPFILE 0x08 -#define PRINTER_NOTIFY_PRINT_PROCESSOR 0x09 -#define PRINTER_NOTIFY_PARAMETERS 0x0A -#define PRINTER_NOTIFY_DATATYPE 0x0B -#define PRINTER_NOTIFY_SECURITY_DESCRIPTOR 0x0C -#define PRINTER_NOTIFY_ATTRIBUTES 0x0D -#define PRINTER_NOTIFY_PRIORITY 0x0E -#define PRINTER_NOTIFY_DEFAULT_PRIORITY 0x0F -#define PRINTER_NOTIFY_START_TIME 0x10 -#define PRINTER_NOTIFY_UNTIL_TIME 0x11 -#define PRINTER_NOTIFY_STATUS 0x12 -#define PRINTER_NOTIFY_STATUS_STRING 0x13 -#define PRINTER_NOTIFY_CJOBS 0x14 -#define PRINTER_NOTIFY_AVERAGE_PPM 0x15 -#define PRINTER_NOTIFY_TOTAL_PAGES 0x16 -#define PRINTER_NOTIFY_PAGES_PRINTED 0x17 -#define PRINTER_NOTIFY_TOTAL_BYTES 0x18 -#define PRINTER_NOTIFY_BYTES_PRINTED 0x19 - -#define JOB_NOTIFY_PRINTER_NAME 0x00 -#define JOB_NOTIFY_MACHINE_NAME 0x01 -#define JOB_NOTIFY_PORT_NAME 0x02 -#define JOB_NOTIFY_USER_NAME 0x03 -#define JOB_NOTIFY_NOTIFY_NAME 0x04 -#define JOB_NOTIFY_DATATYPE 0x05 -#define JOB_NOTIFY_PRINT_PROCESSOR 0x06 -#define JOB_NOTIFY_PARAMETERS 0x07 -#define JOB_NOTIFY_DRIVER_NAME 0x08 -#define JOB_NOTIFY_DEVMODE 0x09 -#define JOB_NOTIFY_STATUS 0x0A -#define JOB_NOTIFY_STATUS_STRING 0x0B -#define JOB_NOTIFY_SECURITY_DESCRIPTOR 0x0C -#define JOB_NOTIFY_DOCUMENT 0x0D -#define JOB_NOTIFY_PRIORITY 0x0E -#define JOB_NOTIFY_POSITION 0x0F -#define JOB_NOTIFY_SUBMITTED 0x10 -#define JOB_NOTIFY_START_TIME 0x11 -#define JOB_NOTIFY_UNTIL_TIME 0x12 -#define JOB_NOTIFY_TIME 0x13 -#define JOB_NOTIFY_TOTAL_PAGES 0x14 -#define JOB_NOTIFY_PAGES_PRINTED 0x15 -#define JOB_NOTIFY_TOTAL_BYTES 0x16 -#define JOB_NOTIFY_BYTES_PRINTED 0x17 - -/* - * Set of macros for flagging what changed in the PRINTER_INFO_2 struct - * when sending messages to other smbd's - */ -#define PRINTER_MESSAGE_NULL 0x00000000 -#define PRINTER_MESSAGE_DRIVER 0x00000001 -#define PRINTER_MESSAGE_COMMENT 0x00000002 -#define PRINTER_MESSAGE_PRINTERNAME 0x00000004 -#define PRINTER_MESSAGE_LOCATION 0x00000008 -#define PRINTER_MESSAGE_DEVMODE 0x00000010 /* not curently supported */ -#define PRINTER_MESSAGE_SEPFILE 0x00000020 -#define PRINTER_MESSAGE_PRINTPROC 0x00000040 -#define PRINTER_MESSAGE_PARAMS 0x00000080 -#define PRINTER_MESSAGE_DATATYPE 0x00000100 -#define PRINTER_MESSAGE_SECDESC 0x00000200 -#define PRINTER_MESSAGE_CJOBS 0x00000400 -#define PRINTER_MESSAGE_PORT 0x00000800 -#define PRINTER_MESSAGE_SHARENAME 0x00001000 -#define PRINTER_MESSAGE_ATTRIBUTES 0x00002000 - -typedef struct printer_message_info { - uint32 low; /* PRINTER_CHANGE_XXX */ - uint32 high; /* PRINTER_CHANGE_XXX */ - fstring printer_name; - uint32 flags; /* PRINTER_MESSAGE_XXX */ -} -PRINTER_MESSAGE_INFO; - -/* - * The printer attributes. - * I #defined all of them (grabbed form MSDN) - * I'm only using: - * ( SHARED | NETWORK | RAW_ONLY ) - * RAW_ONLY _MUST_ be present otherwise NT will send an EMF file - */ - -#define PRINTER_ATTRIBUTE_SAMBA (PRINTER_ATTRIBUTE_RAW_ONLY|\ - PRINTER_ATTRIBUTE_SHARED|\ - PRINTER_ATTRIBUTE_LOCAL) -#define PRINTER_ATTRIBUTE_NOT_SAMBA (PRINTER_ATTRIBUTE_NETWORK) - -#define NO_PRIORITY 0 -#define MAX_PRIORITY 99 -#define MIN_PRIORITY 1 -#define DEF_PRIORITY 1 - -/* the flags of each printers */ - -#define DRIVER_ANY_VERSION 0xffffffff -#define DRIVER_MAX_VERSION 4 - - -/* - * Devicemode structure - */ - -typedef struct devicemode -{ - UNISTR devicename; - uint16 specversion; - uint16 driverversion; - uint16 size; - uint16 driverextra; - uint32 fields; - uint16 orientation; - uint16 papersize; - uint16 paperlength; - uint16 paperwidth; - uint16 scale; - uint16 copies; - uint16 defaultsource; - uint16 printquality; - uint16 color; - uint16 duplex; - uint16 yresolution; - uint16 ttoption; - uint16 collate; - UNISTR formname; - uint16 logpixels; - uint32 bitsperpel; - uint32 pelswidth; - uint32 pelsheight; - uint32 displayflags; - uint32 displayfrequency; - uint32 icmmethod; - uint32 icmintent; - uint32 mediatype; - uint32 dithertype; - uint32 reserved1; - uint32 reserved2; - uint32 panningwidth; - uint32 panningheight; - uint8 *dev_private; -} -DEVICEMODE; - -typedef struct _devmode_cont -{ - uint32 size; - uint32 devmode_ptr; - DEVICEMODE *devmode; -} -DEVMODE_CTR; - -typedef struct _printer_default -{ - uint32 datatype_ptr; - UNISTR2 datatype; - DEVMODE_CTR devmode_cont; - uint32 access_required; -} -PRINTER_DEFAULT; - -/********************************************/ - -typedef struct spool_q_getprinterdata -{ - POLICY_HND handle; - UNISTR2 valuename; - uint32 size; -} -SPOOL_Q_GETPRINTERDATA; - -typedef struct spool_r_getprinterdata -{ - uint32 type; - uint32 size; - uint8 *data; - uint32 needed; - WERROR status; -} -SPOOL_R_GETPRINTERDATA; - -typedef struct printer_info_0 -{ - UNISTR printername; - UNISTR servername; - uint32 cjobs; - uint32 total_jobs; - uint32 total_bytes; - - uint16 year; - uint16 month; - uint16 dayofweek; - uint16 day; - uint16 hour; - uint16 minute; - uint16 second; - uint16 milliseconds; - - uint32 global_counter; - uint32 total_pages; - - uint16 major_version; - uint16 build_version; - - uint32 unknown7; - uint32 unknown8; - uint32 unknown9; - uint32 session_counter; - uint32 unknown11; - uint32 printer_errors; - uint32 unknown13; - uint32 unknown14; - uint32 unknown15; - uint32 unknown16; - uint32 change_id; - uint32 unknown18; - uint32 status; - uint32 unknown20; - uint32 c_setprinter; - - uint16 unknown22; - uint16 unknown23; - uint16 unknown24; - uint16 unknown25; - uint16 unknown26; - uint16 unknown27; - uint16 unknown28; - uint16 unknown29; -} PRINTER_INFO_0; - -typedef struct printer_info_1 -{ - uint32 flags; - UNISTR description; - UNISTR name; - UNISTR comment; -} -PRINTER_INFO_1; - -typedef struct printer_info_2 -{ - UNISTR servername; - UNISTR printername; - UNISTR sharename; - UNISTR portname; - UNISTR drivername; - UNISTR comment; - UNISTR location; - DEVICEMODE *devmode; - UNISTR sepfile; - UNISTR printprocessor; - UNISTR datatype; - UNISTR parameters; - SEC_DESC *secdesc; - uint32 attributes; - uint32 priority; - uint32 defaultpriority; - uint32 starttime; - uint32 untiltime; - uint32 status; - uint32 cjobs; - uint32 averageppm; -} -PRINTER_INFO_2; - -typedef struct printer_info_3 -{ - SEC_DESC *secdesc; -} -PRINTER_INFO_3; - -typedef struct printer_info_4 -{ - UNISTR printername; - UNISTR servername; - uint32 attributes; -} -PRINTER_INFO_4; - -typedef struct printer_info_5 -{ - UNISTR printername; - UNISTR portname; - uint32 attributes; - uint32 device_not_selected_timeout; - uint32 transmission_retry_timeout; -} -PRINTER_INFO_5; - -typedef struct printer_info_6 -{ - uint32 status; -} -PRINTER_INFO_6; - -typedef struct printer_info_7 -{ - UNISTR guid; /* text form of printer guid */ - uint32 action; -} -PRINTER_INFO_7; - -typedef struct spool_q_enumprinters -{ - uint32 flags; - uint32 servername_ptr; - UNISTR2 servername; - uint32 level; - RPC_BUFFER *buffer; - uint32 offered; -} -SPOOL_Q_ENUMPRINTERS; - -typedef struct printer_info_ctr_info -{ - PRINTER_INFO_0 *printers_0; - PRINTER_INFO_1 *printers_1; - PRINTER_INFO_2 *printers_2; - PRINTER_INFO_3 *printers_3; - PRINTER_INFO_4 *printers_4; - PRINTER_INFO_5 *printers_5; - PRINTER_INFO_7 *printers_7; -} -PRINTER_INFO_CTR; - -typedef struct spool_r_enumprinters -{ - RPC_BUFFER *buffer; - uint32 needed; /* bytes needed */ - uint32 returned; /* number of printers */ - WERROR status; -} -SPOOL_R_ENUMPRINTERS; - - -typedef struct spool_q_getprinter -{ - POLICY_HND handle; - uint32 level; - RPC_BUFFER *buffer; - uint32 offered; -} -SPOOL_Q_GETPRINTER; - -typedef struct printer_info_info -{ - union - { - PRINTER_INFO_0 *info0; - PRINTER_INFO_1 *info1; - PRINTER_INFO_2 *info2; - void *info; - } printer; -} PRINTER_INFO; - -typedef struct spool_r_getprinter -{ - RPC_BUFFER *buffer; - uint32 needed; - WERROR status; -} SPOOL_R_GETPRINTER; - -typedef struct driver_info_1 -{ - UNISTR name; -} DRIVER_INFO_1; - -typedef struct driver_info_2 -{ - uint32 version; - UNISTR name; - UNISTR architecture; - UNISTR driverpath; - UNISTR datafile; - UNISTR configfile; -} DRIVER_INFO_2; - -typedef struct driver_info_3 -{ - uint32 version; - UNISTR name; - UNISTR architecture; - UNISTR driverpath; - UNISTR datafile; - UNISTR configfile; - UNISTR helpfile; - uint16 *dependentfiles; - UNISTR monitorname; - UNISTR defaultdatatype; -} -DRIVER_INFO_3; - -typedef struct driver_info_6 -{ - uint32 version; - UNISTR name; - UNISTR architecture; - UNISTR driverpath; - UNISTR datafile; - UNISTR configfile; - UNISTR helpfile; - uint16 *dependentfiles; - UNISTR monitorname; - UNISTR defaultdatatype; - uint16* previousdrivernames; - NTTIME driver_date; - uint32 padding; - uint32 driver_version_low; - uint32 driver_version_high; - UNISTR mfgname; - UNISTR oem_url; - UNISTR hardware_id; - UNISTR provider; -} -DRIVER_INFO_6; - -typedef struct driver_info_info -{ - DRIVER_INFO_1 *info1; - DRIVER_INFO_2 *info2; - DRIVER_INFO_3 *info3; - DRIVER_INFO_6 *info6; -} -PRINTER_DRIVER_CTR; - -typedef struct spool_q_getprinterdriver2 -{ - POLICY_HND handle; - uint32 architecture_ptr; - UNISTR2 architecture; - uint32 level; - RPC_BUFFER *buffer; - uint32 offered; - uint32 clientmajorversion; - uint32 clientminorversion; -} -SPOOL_Q_GETPRINTERDRIVER2; - -typedef struct spool_r_getprinterdriver2 -{ - RPC_BUFFER *buffer; - uint32 needed; - uint32 servermajorversion; - uint32 serverminorversion; - WERROR status; -} -SPOOL_R_GETPRINTERDRIVER2; - - -typedef struct add_jobinfo_1 -{ - UNISTR path; - uint32 job_number; -} -ADD_JOBINFO_1; - - -/* - * I'm really wondering how many different time formats - * I will have to cope with - * - * JFM, 09/13/98 In a mad mood ;-( -*/ -typedef struct systemtime -{ - uint16 year; - uint16 month; - uint16 dayofweek; - uint16 day; - uint16 hour; - uint16 minute; - uint16 second; - uint16 milliseconds; -} -SYSTEMTIME; - -typedef struct s_job_info_1 -{ - uint32 jobid; - UNISTR printername; - UNISTR machinename; - UNISTR username; - UNISTR document; - UNISTR datatype; - UNISTR text_status; - uint32 status; - uint32 priority; - uint32 position; - uint32 totalpages; - uint32 pagesprinted; - SYSTEMTIME submitted; -} -JOB_INFO_1; - -typedef struct s_job_info_2 -{ - uint32 jobid; - UNISTR printername; - UNISTR machinename; - UNISTR username; - UNISTR document; - UNISTR notifyname; - UNISTR datatype; - UNISTR printprocessor; - UNISTR parameters; - UNISTR drivername; - DEVICEMODE *devmode; - UNISTR text_status; -/* SEC_DESC sec_desc;*/ - uint32 status; - uint32 priority; - uint32 position; - uint32 starttime; - uint32 untiltime; - uint32 totalpages; - uint32 size; - SYSTEMTIME submitted; - uint32 timeelapsed; - uint32 pagesprinted; -} -JOB_INFO_2; - -typedef struct spool_q_enumjobs -{ - POLICY_HND handle; - uint32 firstjob; - uint32 numofjobs; - uint32 level; - RPC_BUFFER *buffer; - uint32 offered; -} -SPOOL_Q_ENUMJOBS; - -typedef struct job_info_ctr_info -{ - union - { - JOB_INFO_1 *job_info_1; - JOB_INFO_2 *job_info_2; - void *info; - } job; - -} JOB_INFO_CTR; - -typedef struct spool_r_enumjobs -{ - RPC_BUFFER *buffer; - uint32 needed; - uint32 returned; - WERROR status; -} -SPOOL_R_ENUMJOBS; - -typedef struct s_port_info_1 -{ - UNISTR port_name; -} -PORT_INFO_1; - -typedef struct s_port_info_2 -{ - UNISTR port_name; - UNISTR monitor_name; - UNISTR description; - uint32 port_type; - uint32 reserved; -} -PORT_INFO_2; - -/* Port Type bits */ -#define PORT_TYPE_WRITE 0x0001 -#define PORT_TYPE_READ 0x0002 -#define PORT_TYPE_REDIRECTED 0x0004 -#define PORT_TYPE_NET_ATTACHED 0x0008 - -typedef struct spool_q_enumports -{ - uint32 name_ptr; - UNISTR2 name; - uint32 level; - RPC_BUFFER *buffer; - uint32 offered; -} -SPOOL_Q_ENUMPORTS; - -typedef struct port_info_ctr_info -{ - union - { - PORT_INFO_1 *info_1; - PORT_INFO_2 *info_2; - } - port; - -} -PORT_INFO_CTR; - -typedef struct spool_r_enumports -{ - RPC_BUFFER *buffer; - uint32 needed; /* bytes needed */ - uint32 returned; /* number of printers */ - WERROR status; -} -SPOOL_R_ENUMPORTS; - -typedef struct job_info_info -{ - union - { - JOB_INFO_1 job_info_1; - JOB_INFO_2 job_info_2; - } - job; - -} -JOB_INFO; - -typedef struct spool_q_enumprinterdrivers -{ - uint32 name_ptr; - UNISTR2 name; - uint32 environment_ptr; - UNISTR2 environment; - uint32 level; - RPC_BUFFER *buffer; - uint32 offered; -} -SPOOL_Q_ENUMPRINTERDRIVERS; - -typedef struct spool_r_enumprinterdrivers -{ - RPC_BUFFER *buffer; - uint32 needed; - uint32 returned; - WERROR status; -} -SPOOL_R_ENUMPRINTERDRIVERS; - -#define FORM_USER 0 -#define FORM_BUILTIN 1 -#define FORM_PRINTER 2 - -typedef struct spool_form_1 -{ - uint32 flag; - UNISTR name; - uint32 width; - uint32 length; - uint32 left; - uint32 top; - uint32 right; - uint32 bottom; -} -FORM_1; - -typedef struct spool_q_enumforms -{ - POLICY_HND handle; - uint32 level; - RPC_BUFFER *buffer; - uint32 offered; -} -SPOOL_Q_ENUMFORMS; - -typedef struct spool_r_enumforms -{ - RPC_BUFFER *buffer; - uint32 needed; - uint32 numofforms; - WERROR status; -} -SPOOL_R_ENUMFORMS; - -/********************************************/ - -typedef struct spool_q_enumprintprocessors -{ - uint32 name_ptr; - UNISTR2 name; - uint32 environment_ptr; - UNISTR2 environment; - uint32 level; - RPC_BUFFER *buffer; - uint32 offered; -} -SPOOL_Q_ENUMPRINTPROCESSORS; - -typedef struct printprocessor_1 -{ - UNISTR name; -} -PRINTPROCESSOR_1; - -typedef struct spool_r_enumprintprocessors -{ - RPC_BUFFER *buffer; - uint32 needed; - uint32 returned; - WERROR status; -} -SPOOL_R_ENUMPRINTPROCESSORS; - -typedef struct spool_q_enumprintprocdatatypes -{ - uint32 name_ptr; - UNISTR2 name; - uint32 processor_ptr; - UNISTR2 processor; - uint32 level; - RPC_BUFFER *buffer; - uint32 offered; -} -SPOOL_Q_ENUMPRINTPROCDATATYPES; - -typedef struct ppdatatype_1 -{ - UNISTR name; -} -PRINTPROCDATATYPE_1; - -typedef struct spool_r_enumprintprocdatatypes -{ - RPC_BUFFER *buffer; - uint32 needed; - uint32 returned; - WERROR status; -} -SPOOL_R_ENUMPRINTPROCDATATYPES; - -typedef struct printmonitor_1 -{ - UNISTR name; -} -PRINTMONITOR_1; - -typedef struct printmonitor_2 -{ - UNISTR name; - UNISTR environment; - UNISTR dll_name; -} -PRINTMONITOR_2; - -typedef struct spool_q_enumprintmonitors -{ - uint32 name_ptr; - UNISTR2 name; - uint32 level; - RPC_BUFFER *buffer; - uint32 offered; -} -SPOOL_Q_ENUMPRINTMONITORS; - -typedef struct spool_r_enumprintmonitors -{ - RPC_BUFFER *buffer; - uint32 needed; - uint32 returned; - WERROR status; -} -SPOOL_R_ENUMPRINTMONITORS; - - -typedef struct spool_q_enumprinterdata -{ - POLICY_HND handle; - uint32 index; - uint32 valuesize; - uint32 datasize; -} -SPOOL_Q_ENUMPRINTERDATA; - -typedef struct spool_r_enumprinterdata -{ - uint32 valuesize; - uint16 *value; - uint32 realvaluesize; - uint32 type; - uint32 datasize; - uint8 *data; - uint32 realdatasize; - WERROR status; -} -SPOOL_R_ENUMPRINTERDATA; - -typedef struct spool_q_setprinterdata -{ - POLICY_HND handle; - UNISTR2 value; - uint32 type; - uint32 max_len; - uint8 *data; - uint32 real_len; - uint32 numeric_data; -} -SPOOL_Q_SETPRINTERDATA; - -typedef struct spool_r_setprinterdata -{ - WERROR status; -} -SPOOL_R_SETPRINTERDATA; - -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; - -typedef struct spool_q_getjob -{ - POLICY_HND handle; - uint32 jobid; - uint32 level; - RPC_BUFFER *buffer; - uint32 offered; -} -SPOOL_Q_GETJOB; - -typedef struct pjob_info_info -{ - union - { - JOB_INFO_1 *job_info_1; - JOB_INFO_2 *job_info_2; - void *info; - } - job; - -} -PJOB_INFO; - -typedef struct spool_r_getjob -{ - RPC_BUFFER *buffer; - uint32 needed; - WERROR status; -} -SPOOL_R_GETJOB; - -typedef struct spool_q_enumprinterkey -{ - POLICY_HND handle; - UNISTR2 key; - uint32 size; -} -SPOOL_Q_ENUMPRINTERKEY; - -typedef struct spool_r_enumprinterkey -{ - BUFFER5 keys; - uint32 needed; /* in bytes */ - WERROR status; -} -SPOOL_R_ENUMPRINTERKEY; - -typedef struct printer_enum_values -{ - UNISTR valuename; - uint32 value_len; - uint32 type; - uint8 *data; - uint32 data_len; - -} -PRINTER_ENUM_VALUES; - -typedef struct printer_enum_values_ctr -{ - uint32 size; - uint32 size_of_array; - PRINTER_ENUM_VALUES *values; -} -PRINTER_ENUM_VALUES_CTR; - -typedef struct spool_q_enumprinterdataex -{ - POLICY_HND handle; - UNISTR2 key; - uint32 size; -} -SPOOL_Q_ENUMPRINTERDATAEX; - -typedef struct spool_r_enumprinterdataex -{ - PRINTER_ENUM_VALUES_CTR ctr; - uint32 needed; - uint32 returned; - WERROR status; -} -SPOOL_R_ENUMPRINTERDATAEX; - -#endif /* _RPC_SPOOLSS_H */ - diff --git a/source3/include/smb.h b/source3/include/smb.h index 59c3c32346..281a218256 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -573,6 +573,12 @@ typedef struct connection_struct { */ struct auth_serversupplied_info *server_info; + /* + * If the "force group" parameter is set, this is the primary gid that + * may be used in the users token, depending on the vuid using this tid. + */ + gid_t force_group_gid; + char client_address[INET6_ADDRSTRLEN]; /* String version of client IP address. */ uint16 vuid; /* vuid of user who *opened* this connection, or UID_FIELD_INVALID */ @@ -1753,13 +1759,6 @@ struct node_status_extra { /* There really is more here ... */ }; -struct pwd_info { - bool null_pwd; - bool cleartext; - - fstring password; -}; - /* For split krb5 SPNEGO blobs. */ struct pending_auth_data { struct pending_auth_data *prev, *next; diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h index fd1bba16a7..22cfaaf581 100644 --- a/source3/include/smb_macros.h +++ b/source3/include/smb_macros.h @@ -256,7 +256,9 @@ NULL returns on zero request. JRA. #define TALLOC_REALLOC(ctx, ptr, count) _talloc_realloc(ctx, ptr, count, __location__) #define TALLOC_REALLOC_ARRAY(ctx, ptr, type, count) (type *)_talloc_realloc_array(ctx, ptr, sizeof(type), count, #type) #define talloc_destroy(ctx) talloc_free(ctx) +#ifndef TALLOC_FREE #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) +#endif /* only define PARANOID_MALLOC_CHECKER with --enable-developer */ diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h index f9a0436546..5b52bad8c1 100644 --- a/source3/include/smbprofile.h +++ b/source3/include/smbprofile.h @@ -243,6 +243,14 @@ enum profile_stats_values #define syscall_brl_cancel_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, count) #define syscall_brl_cancel_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, time) + PR_VALUE_SYSCALL_STRICT_LOCK, +#define syscall_strict_lock_count __profile_stats_value(PR_VALUE_SYSCALL_STRICT_LOCK, count) +#define syscall_strict_lock_time __profile_stats_value(PR_VALUE_SYSCALL_STRICT_LOCK, time) + + PR_VALUE_SYSCALL_STRICT_UNLOCK, +#define syscall_strict_unlock_count __profile_stats_value(PR_VALUE_SYSCALL_STRICT_UNLOCK, count) +#define syscall_strict_unlock_time __profile_stats_value(PR_VALUE_SYSCALL_STRICT_UNLOCK, time) + /* counters for individual SMB types */ PR_VALUE_SMBMKDIR, #define SMBmkdir_count __profile_stats_value(PR_VALUE_SMBMKDIR, count) diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 0ee7f236b0..0c0e0938bd 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -116,6 +116,7 @@ /* Leave at 25 - not yet released. Add SMB_STRUCT_STAT to readdir. - sdann */ /* Leave at 25 - not yet released. Add init_search_op call. - sdann */ /* Leave at 25 - not yet released. Add locking calls. -- zkirsch. */ +/* Leave at 25 - not yet released. Add strict locking calls. -- drichards. */ #define SMB_VFS_INTERFACE_VERSION 25 @@ -223,6 +224,8 @@ typedef enum _vfs_op_type { SMB_VFS_OP_BRL_LOCK_WINDOWS, SMB_VFS_OP_BRL_UNLOCK_WINDOWS, SMB_VFS_OP_BRL_CANCEL_WINDOWS, + SMB_VFS_OP_STRICT_LOCK, + SMB_VFS_OP_STRICT_UNLOCK, /* NT ACL operations. */ @@ -415,6 +418,14 @@ struct vfs_ops { struct lock_struct *plock, struct blocking_lock_record *blr); + bool (*strict_lock)(struct vfs_handle_struct *handle, + struct files_struct *fsp, + struct lock_struct *plock); + + void (*strict_unlock)(struct vfs_handle_struct *handle, + struct files_struct *fsp, + struct lock_struct *plock); + /* NT ACL operations. */ NTSTATUS (*fget_nt_acl)(struct vfs_handle_struct *handle, @@ -556,6 +567,8 @@ struct vfs_ops { struct vfs_handle_struct *brl_lock_windows; struct vfs_handle_struct *brl_unlock_windows; struct vfs_handle_struct *brl_cancel_windows; + struct vfs_handle_struct *strict_lock; + struct vfs_handle_struct *strict_unlock; /* NT ACL operations. */ diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index 7dacd2319a..acb158e3a5 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -91,6 +91,8 @@ #define SMB_VFS_BRL_LOCK_WINDOWS(conn, br_lck, plock, blocking_lock, blr) ((conn)->vfs.ops.brl_lock_windows((conn)->vfs.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr))) #define SMB_VFS_BRL_UNLOCK_WINDOWS(conn, msg_ctx, br_lck, plock) ((conn)->vfs.ops.brl_unlock_windows((conn)->vfs.handles.brl_unlock_windows, (msg_ctx), (br_lck), (plock))) #define SMB_VFS_BRL_CANCEL_WINDOWS(conn, br_lck, plock, blr) ((conn)->vfs.ops.brl_cancel_windows((conn)->vfs.handles.brl_cancel_windows, (br_lck), (plock), (blr))) +#define SMB_VFS_STRICT_LOCK(conn, fsp, plock) ((conn)->vfs.ops.strict_lock((conn)->vfs.handles.strict_lock, (fsp), (plock))) +#define SMB_VFS_STRICT_UNLOCK(conn, fsp, plock) ((conn)->vfs.ops.strict_unlock((conn)->vfs.handles.strict_unlock, (fsp), (plock))) /* NT ACL operations. */ #define SMB_VFS_FGET_NT_ACL(fsp, security_info, ppdesc) ((fsp)->conn->vfs.ops.fget_nt_acl((fsp)->conn->vfs.handles.fget_nt_acl, (fsp), (security_info), (ppdesc))) @@ -223,6 +225,8 @@ #define SMB_VFS_OPAQUE_BRL_LOCK_WINDOWS(conn, br_lck, plock, blocking_lock, blr) ((conn)->vfs_opaque.ops.brl_lock_windows((conn)->vfs_opaque.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr))) #define SMB_VFS_OPAQUE_BRL_UNLOCK_WINDOWS(conn, msg_ctx, br_lck, plock) ((conn)->vfs_opaque.ops.brl_unlock_windows((conn)->vfs_opaque.handles.brl_unlock_windows, (msg_ctx), (br_lck), (plock))) #define SMB_VFS_OPAQUE_BRL_CANCEL_WINDOWS(conn, br_lck, plock, blr) ((conn)->vfs_opaque.ops.brl_cancel_windows((conn)->vfs_opaque.handles.brl_cancel_windows, (br_lck), (plock), (blr))) +#define SMB_VFS_OPAQUE_STRICT_LOCK(conn, fsp, plock) ((conn)->vfs_opaque.ops.strict_lock((conn)->vfs_opaque.handles.strict_lock, (fsp), (plock))) +#define SMB_VFS_OPAQUE_STRICT_UNLOCK(conn, fsp, plock) ((conn)->vfs_opaque.ops.strict_unlock((conn)->vfs_opaque.handles.strict_unlock, (fsp), (plock))) /* NT ACL operations. */ #define SMB_VFS_OPAQUE_FGET_NT_ACL(fsp, security_info, ppdesc) ((fsp)->conn->vfs_opaque.ops.fget_nt_acl((fsp)->conn->vfs_opaque.handles.fget_nt_acl, (fsp), (security_info), (ppdesc))) @@ -356,6 +360,8 @@ #define SMB_VFS_NEXT_BRL_LOCK_WINDOWS(handle, br_lck, plock, blocking_lock, blr) ((handle)->vfs_next.ops.brl_lock_windows((handle)->vfs_next.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr))) #define SMB_VFS_NEXT_BRL_UNLOCK_WINDOWS(handle, msg_ctx, br_lck, plock) ((handle)->vfs_next.ops.brl_unlock_windows((handle)->vfs_next.handles.brl_unlock_windows, (msg_ctx), (br_lck), (plock))) #define SMB_VFS_NEXT_BRL_CANCEL_WINDOWS(handle, br_lck, plock, blr) ((handle)->vfs_next.ops.brl_cancel_windows((handle)->vfs_next.handles.brl_cancel_windows, (br_lck), (plock), (blr))) +#define SMB_VFS_NEXT_STRICT_LOCK(handle, fsp, plock) ((handle)->vfs_next.ops.strict_lock((handle)->vfs_next.handles.strict_lock, (fsp), (plock))) +#define SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock) ((handle)->vfs_next.ops.strict_unlock((handle)->vfs_next.handles.strict_unlock, (fsp), (plock))) /* NT ACL operations. */ #define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc) ((handle)->vfs_next.ops.fget_nt_acl((handle)->vfs_next.handles.fget_nt_acl, (fsp), (security_info), (ppdesc))) diff --git a/source3/include/wbc_async.h b/source3/include/wbc_async.h index 7a8768029a..eaec0d11da 100644 --- a/source3/include/wbc_async.h +++ b/source3/include/wbc_async.h @@ -22,47 +22,43 @@ #include "nsswitch/libwbclient/wbclient.h" -struct wb_context { - struct async_req_queue *queue; - int fd; - bool is_priv; -}; +struct wb_context; -struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct wb_context *wb_ctx, bool need_priv, - const struct winbindd_request *wb_req); -wbcErr wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx, +struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct wb_context *wb_ctx, bool need_priv, + struct winbindd_request *wb_req); +wbcErr wb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct winbindd_response **presponse); struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx); /* Definitions from wb_reqtrans.c */ -bool async_req_is_wbcerr(struct async_req *req, wbcErr *pwbc_err); wbcErr map_wbc_err_from_errno(int error); -wbcErr async_req_simple_recv_wbcerr(struct async_req *req); -struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd, size_t max_extra_data); +bool tevent_req_is_wbcerr(struct tevent_req *req, wbcErr *pwbc_err); +wbcErr tevent_req_simple_recv_wbcerr(struct tevent_req *req); -wbcErr wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx, +struct tevent_req *wb_req_read_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, size_t max_extra_data); +wbcErr wb_req_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct winbindd_request **preq); -struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, int fd, - struct winbindd_request *wb_req); +struct tevent_req *wb_req_write_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tevent_queue *queue, int fd, + struct winbindd_request *wb_req); +wbcErr wb_req_write_recv(struct tevent_req *req); -wbcErr wb_req_write_recv(struct async_req *req); - -struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, int fd); - -wbcErr wb_resp_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx, +struct tevent_req *wb_resp_read_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, int fd); +wbcErr wb_resp_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct winbindd_response **presp); -struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, int fd, - struct winbindd_response *wb_resp); - -wbcErr wb_resp_write_recv(struct async_req *req); +struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tevent_queue *queue, int fd, + struct winbindd_response *wb_resp); +wbcErr wb_resp_write_recv(struct tevent_req *req); #endif /*_WBC_ASYNC_H_*/ diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 81cb9a5094..c3b345142f 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -763,7 +763,7 @@ bool convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to, * converted. */ bool convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to, - void const *src, size_t srclen, void **dst, + void const *src, size_t srclen, void *dst, size_t *converted_size, bool allow_bad_conv) { void **dest = (void **)dst; diff --git a/source3/lib/dbwrap_ctdb.c b/source3/lib/dbwrap_ctdb.c index 03667ff355..4a5bf6d81a 100644 --- a/source3/lib/dbwrap_ctdb.c +++ b/source3/lib/dbwrap_ctdb.c @@ -121,9 +121,9 @@ static struct ctdb_marshall_buffer *db_ctdb_marshall_add(TALLOC_CTX *mem_ctx, { struct ctdb_rec_data *r; size_t m_size, r_size; - struct ctdb_marshall_buffer *m2; + struct ctdb_marshall_buffer *m2 = NULL; - r = db_ctdb_marshall_record(mem_ctx, reqid, key, header, data); + r = db_ctdb_marshall_record(talloc_tos(), reqid, key, header, data); if (r == NULL) { talloc_free(m); return NULL; @@ -133,7 +133,7 @@ static struct ctdb_marshall_buffer *db_ctdb_marshall_add(TALLOC_CTX *mem_ctx, m = (struct ctdb_marshall_buffer *)talloc_zero_size( mem_ctx, offsetof(struct ctdb_marshall_buffer, data)); if (m == NULL) { - return NULL; + goto done; } m->db_id = db_id; } @@ -145,15 +145,15 @@ static struct ctdb_marshall_buffer *db_ctdb_marshall_add(TALLOC_CTX *mem_ctx, mem_ctx, m, m_size + r_size); if (m2 == NULL) { talloc_free(m); - return NULL; + goto done; } memcpy(m_size + (uint8_t *)m2, r, r_size); - talloc_free(r); - m2->count++; +done: + talloc_free(r); return m2; } diff --git a/source3/lib/dbwrap_rbt.c b/source3/lib/dbwrap_rbt.c index 6e09627223..cf4faa25b9 100644 --- a/source3/lib/dbwrap_rbt.c +++ b/source3/lib/dbwrap_rbt.c @@ -131,12 +131,12 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) */ } - node = (struct db_rbt_node *)SMB_MALLOC( + node = (struct db_rbt_node *)talloc_size(rec_priv->db_ctx, offsetof(struct db_rbt_node, data) + rec->key.dsize + data.dsize); if (node == NULL) { - SAFE_FREE(rec_priv->node); + TALLOC_FREE(rec_priv->node); return NT_STATUS_NO_MEMORY; } @@ -148,7 +148,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) db_rbt_parse_node(node, &this_key, &this_val); memcpy(this_key.dptr, rec->key.dptr, node->keysize); - SAFE_FREE(rec_priv->node); + TALLOC_FREE(rec_priv->node); memcpy(this_val.dptr, data.dptr, node->valuesize); @@ -194,7 +194,7 @@ static NTSTATUS db_rbt_delete(struct db_record *rec) } rb_erase(&rec_priv->node->rb_node, &rec_priv->db_ctx->tree); - SAFE_FREE(rec_priv->node); + TALLOC_FREE(rec_priv->node); return NT_STATUS_OK; } diff --git a/source3/lib/errmap_unix.c b/source3/lib/errmap_unix.c index 9adb237096..bb09726ee0 100644 --- a/source3/lib/errmap_unix.c +++ b/source3/lib/errmap_unix.c @@ -95,6 +95,9 @@ const struct unix_error_map unix_dos_nt_errmap[] = { #ifdef ENOATTR { ENOATTR, ERRDOS, ERRbadfile, NT_STATUS_NOT_FOUND }, #endif +#ifdef ECANCELED + { ECANCELED, ERRDOS, ERRbadfid, NT_STATUS_CANCELLED}, +#endif { 0, 0, 0, NT_STATUS_OK } }; diff --git a/source3/lib/events.c b/source3/lib/events.c index 9e81a47796..90d86c6c79 100644 --- a/source3/lib/events.c +++ b/source3/lib/events.c @@ -91,6 +91,11 @@ bool run_events(struct tevent_context *ev, return true; } + if (ev->immediate_events && + tevent_common_loop_immediate(ev)) { + return true; + } + GetTimeOfDay(&now); if ((ev->timer_events != NULL) @@ -145,7 +150,7 @@ struct timeval *get_timed_events_timeout(struct tevent_context *ev, return to_ret; } -static int s3_event_loop_once(struct tevent_context *ev) +static int s3_event_loop_once(struct tevent_context *ev, const char *location) { struct timeval now, to; fd_set r_fds, w_fds; @@ -181,17 +186,6 @@ static int s3_event_loop_once(struct tevent_context *ev) return 0; } -static int s3_event_loop_wait(struct tevent_context *ev) -{ - int ret = 0; - - while (ret == 0) { - ret = s3_event_loop_once(ev); - } - - return ret; -} - void event_context_reinit(struct tevent_context *ev) { tevent_common_context_destructor(ev); @@ -238,15 +232,16 @@ void dump_event_list(struct tevent_context *ev) } static const struct tevent_ops s3_event_ops = { - .context_init = s3_event_context_init, - .add_fd = tevent_common_add_fd, - .set_fd_close_fn= tevent_common_fd_set_close_fn, - .get_fd_flags = tevent_common_fd_get_flags, - .set_fd_flags = tevent_common_fd_set_flags, - .add_timer = tevent_common_add_timer, - .add_signal = tevent_common_add_signal, - .loop_once = s3_event_loop_once, - .loop_wait = s3_event_loop_wait, + .context_init = s3_event_context_init, + .add_fd = tevent_common_add_fd, + .set_fd_close_fn = tevent_common_fd_set_close_fn, + .get_fd_flags = tevent_common_fd_get_flags, + .set_fd_flags = tevent_common_fd_set_flags, + .add_timer = tevent_common_add_timer, + .schedule_immediate = tevent_common_schedule_immediate, + .add_signal = tevent_common_add_signal, + .loop_once = s3_event_loop_once, + .loop_wait = tevent_common_loop_wait, }; static bool s3_tevent_init(void) @@ -286,8 +281,9 @@ static void s3_event_debug(void *context, enum tevent_debug_level level, break; }; - vasprintf(&s, fmt, ap); - if (!s) return; + if (vasprintf(&s, fmt, ap) == -1) { + return; + } DEBUG(samba_level, ("s3_event: %s", s)); free(s); } diff --git a/source3/lib/iconv.c b/source3/lib/iconv.c index fa213a37c0..44500542f2 100644 --- a/source3/lib/iconv.c +++ b/source3/lib/iconv.c @@ -207,12 +207,12 @@ smb_iconv_t smb_iconv_open(const char *tocode, const char *fromcode) from = charsets; to = charsets; - ret = SMB_MALLOC_P(smb_iconv_t); + ret = SMB_MALLOC_P(struct smb_iconv_s); if (!ret) { errno = ENOMEM; return (smb_iconv_t)-1; } - memset(ret, 0, sizeof(smb_iconv_t)); + memset(ret, 0, sizeof(struct smb_iconv_s)); ret->from_name = SMB_STRDUP(fromcode); ret->to_name = SMB_STRDUP(tocode); diff --git a/source3/lib/interfaces.c b/source3/lib/interfaces.c index 4567fe457b..2535418d99 100644 --- a/source3/lib/interfaces.c +++ b/source3/lib/interfaces.c @@ -18,79 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* working out the interfaces for a OS is an incredibly non-portable - thing. We have several possible implementations below, and autoconf - tries each of them to see what works - - Note that this file does _not_ include includes.h. That is so this code - can be called directly from the autoconf tests. That also means - this code cannot use any of the normal Samba debug stuff or defines. - This is standalone code. - -*/ - -#ifndef AUTOCONF_TEST -#include "config.h" -#endif - -#include <unistd.h> -#include <stdio.h> -#include <sys/types.h> -#include <netdb.h> -#include <sys/ioctl.h> -#include <netdb.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#ifdef HAVE_IFADDRS_H -#include <ifaddrs.h> -#endif - -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif - -#ifndef SIOCGIFCONF -#ifdef HAVE_SYS_SOCKIO_H -#include <sys/sockio.h> -#endif -#endif - -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif - -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -#ifdef HAVE_STRINGS_H -#include <strings.h> -#endif - -#ifdef __COMPAR_FN_T -#define QSORT_CAST (__compar_fn_t) -#endif - -#ifndef QSORT_CAST -#define QSORT_CAST (int (*)(const void *, const void *)) -#endif - -#ifdef HAVE_NET_IF_H -#include <net/if.h> -#endif - -#define SOCKET_WRAPPER_NOT_REPLACE -#include "interfaces.h" -#include "../replace/replace.h" - -/**************************************************************************** - Utility functions. -****************************************************************************/ +#include "includes.h" /**************************************************************************** Create a struct sockaddr_storage with the netmask bits set to 1. diff --git a/source3/lib/messages.c b/source3/lib/messages.c index e4b20c7493..5e11dd4e25 100644 --- a/source3/lib/messages.c +++ b/source3/lib/messages.c @@ -286,7 +286,15 @@ NTSTATUS messaging_register(struct messaging_context *msg_ctx, */ for (cb = msg_ctx->callbacks; cb != NULL; cb = cb->next) { - if (cb->msg_type == msg_type) { + /* we allow a second registration of the same message + type if it has a different private pointer. This is + needed in, for example, the internal notify code, + which creates a new notify context for each tree + connect, and expects to receive messages to each of + them. */ + if (cb->msg_type == msg_type && private_data == cb->private_data) { + DEBUG(5,("Overriding messaging pointer for type %u - private_data=%p\n", + (unsigned)msg_type, private_data)); cb->fn = fn; cb->private_data = private_data; return NT_STATUS_OK; @@ -317,6 +325,8 @@ void messaging_deregister(struct messaging_context *ctx, uint32_t msg_type, next = cb->next; if ((cb->msg_type == msg_type) && (cb->private_data == private_data)) { + DEBUG(5,("Deregistering messaging pointer for type %u - private_data=%p\n", + (unsigned)msg_type, private_data)); DLIST_REMOVE(ctx->callbacks, cb); TALLOC_FREE(cb); } @@ -362,7 +372,11 @@ void messaging_dispatch_rec(struct messaging_context *msg_ctx, if (cb->msg_type == rec->msg_type) { cb->fn(msg_ctx, cb->private_data, rec->msg_type, rec->src, &rec->buf); - return; + /* we continue looking for matching messages + after finding one. This matters for + subsystems like the internal notify code + which register more than one handler for + the same message type */ } } return; diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c index 233255fed4..b676ae63dd 100644 --- a/source3/lib/netapi/cm.c +++ b/source3/lib/netapi/cm.c @@ -29,36 +29,36 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx, const char *server_name, struct cli_state **cli) { + struct user_auth_info *auth_info = NULL; struct cli_state *cli_ipc = NULL; if (!ctx || !cli || !server_name) { return WERR_INVALID_PARAM; } - cli_cm_set_signing_state(Undefined); - - if (ctx->use_kerberos) { - cli_cm_set_use_kerberos(); - } - - if (ctx->password) { - cli_cm_set_password(ctx->password); - } - if (ctx->username) { - cli_cm_set_username(ctx->username); + auth_info = user_auth_info_init(NULL); + if (!auth_info) { + return WERR_NOMEM; } + auth_info->signing_state = Undefined; + set_cmdline_auth_info_use_kerberos(auth_info, ctx->use_kerberos); + set_cmdline_auth_info_password(auth_info, ctx->password); + set_cmdline_auth_info_username(auth_info, ctx->username); if (ctx->username && ctx->username[0] && ctx->password && ctx->password[0] && ctx->use_kerberos) { - cli_cm_set_fallback_after_kerberos(); + set_cmdline_auth_info_fallback_after_kerberos(auth_info, true); } cli_ipc = cli_cm_open(ctx, NULL, - server_name, "IPC$", - false, false, - PROTOCOL_NT1, - 0, 0x20); + server_name, "IPC$", + auth_info, + false, false, + PROTOCOL_NT1, + 0, 0x20); + TALLOC_FREE(auth_info); + if (!cli_ipc) { libnetapi_set_error_string(ctx, "Failed to connect to IPC$ share on %s", server_name); @@ -73,19 +73,10 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx, /******************************************************************** ********************************************************************/ -WERROR libnetapi_shutdown_cm(struct libnetapi_ctx *ctx) -{ - cli_cm_shutdown(); - - return WERR_OK; -} - -/******************************************************************** -********************************************************************/ - struct client_pipe_connection { struct client_pipe_connection *prev, *next; struct rpc_pipe_client *pipe; + struct cli_state *cli; }; static struct client_pipe_connection *pipe_connections; @@ -93,6 +84,20 @@ static struct client_pipe_connection *pipe_connections; /******************************************************************** ********************************************************************/ +WERROR libnetapi_shutdown_cm(struct libnetapi_ctx *ctx) +{ + struct client_pipe_connection *p; + + for (p = pipe_connections; p; p = p->next) { + cli_shutdown(p->cli); + } + + return WERR_OK; +} + +/******************************************************************** +********************************************************************/ + static NTSTATUS pipe_cm_find(struct cli_state *cli, const struct ndr_syntax_id *interface, struct rpc_pipe_client **presult) @@ -138,6 +143,7 @@ static NTSTATUS pipe_cm_connect(TALLOC_CTX *mem_ctx, return status; } + p->cli = cli; DLIST_ADD(pipe_connections, p); *presult = p->pipe; @@ -193,5 +199,3 @@ WERROR libnetapi_open_pipe(struct libnetapi_ctx *ctx, return WERR_OK; } - - diff --git a/source3/lib/netapi/group.c b/source3/lib/netapi/group.c index 617bde2c9a..189902a78e 100644 --- a/source3/lib/netapi/group.c +++ b/source3/lib/netapi/group.c @@ -33,7 +33,7 @@ WERROR NetGroupAdd_r(struct libnetapi_ctx *ctx, struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; - POLICY_HND connect_handle, domain_handle, group_handle; + struct policy_handle connect_handle, domain_handle, group_handle; struct lsa_String lsa_group_name; struct dom_sid2 *domain_sid = NULL; uint32_t rid = 0; @@ -223,7 +223,7 @@ WERROR NetGroupDel_r(struct libnetapi_ctx *ctx, struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; - POLICY_HND connect_handle, domain_handle, group_handle; + struct policy_handle connect_handle, domain_handle, group_handle; struct lsa_String lsa_group_name; struct dom_sid2 *domain_sid = NULL; int i = 0; @@ -384,7 +384,7 @@ WERROR NetGroupSetInfo_r(struct libnetapi_ctx *ctx, struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; - POLICY_HND connect_handle, domain_handle, group_handle; + struct policy_handle connect_handle, domain_handle, group_handle; struct lsa_String lsa_group_name; struct dom_sid2 *domain_sid = NULL; @@ -624,7 +624,7 @@ WERROR NetGroupGetInfo_r(struct libnetapi_ctx *ctx, struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; - POLICY_HND connect_handle, domain_handle, group_handle; + struct policy_handle connect_handle, domain_handle, group_handle; struct lsa_String lsa_group_name; struct dom_sid2 *domain_sid = NULL; @@ -742,7 +742,7 @@ WERROR NetGroupAddUser_r(struct libnetapi_ctx *ctx, struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; - POLICY_HND connect_handle, domain_handle, group_handle; + struct policy_handle connect_handle, domain_handle, group_handle; struct lsa_String lsa_group_name, lsa_user_name; struct dom_sid2 *domain_sid = NULL; @@ -863,7 +863,7 @@ WERROR NetGroupDelUser_r(struct libnetapi_ctx *ctx, struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; - POLICY_HND connect_handle, domain_handle, group_handle; + struct policy_handle connect_handle, domain_handle, group_handle; struct lsa_String lsa_group_name, lsa_user_name; struct dom_sid2 *domain_sid = NULL; diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c index 9d7f299f59..8cc65a6e9e 100644 --- a/source3/lib/netapi/user.c +++ b/source3/lib/netapi/user.c @@ -352,7 +352,7 @@ WERROR NetUserAdd_r(struct libnetapi_ctx *ctx, struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; - POLICY_HND connect_handle, domain_handle, user_handle; + struct policy_handle connect_handle, domain_handle, user_handle; struct lsa_String lsa_account_name; struct dom_sid2 *domain_sid = NULL; union samr_UserInfo *user_info = NULL; @@ -496,7 +496,7 @@ WERROR NetUserDel_r(struct libnetapi_ctx *ctx, struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; - POLICY_HND connect_handle, builtin_handle, domain_handle, user_handle; + struct policy_handle connect_handle, builtin_handle, domain_handle, user_handle; struct lsa_String lsa_account_name; struct samr_Ids user_rids, name_types; struct dom_sid2 *domain_sid = NULL; diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 5a5c0ead65..ae6a41151d 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -80,12 +80,20 @@ static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx, uint32 desired_access, struct registry_key **key) { + WERROR werr; + if (servicename == NULL) { *key = rpd(ctx)->base_key; return WERR_OK; } - return reg_openkey(mem_ctx, rpd(ctx)->base_key, servicename, + werr = reg_openkey(mem_ctx, rpd(ctx)->base_key, servicename, desired_access, key); + + if (W_ERROR_EQUAL(werr, WERR_BADFILE)) { + werr = WERR_NO_SUCH_SERVICE; + } + + return werr; } /** @@ -828,9 +836,6 @@ static WERROR smbconf_reg_get_share(struct smbconf_ctx *ctx, werr = smbconf_reg_open_service_key(tmp_ctx, ctx, servicename, REG_KEY_READ, &key); if (!W_ERROR_IS_OK(werr)) { - if (W_ERROR_EQUAL(werr, WERR_BADFILE)) { - werr = WERR_NO_SUCH_SERVICE; - } goto done; } diff --git a/source3/lib/smbconf/testsuite.c b/source3/lib/smbconf/testsuite.c index b31dec0438..c83eeb805d 100644 --- a/source3/lib/smbconf/testsuite.c +++ b/source3/lib/smbconf/testsuite.c @@ -214,7 +214,7 @@ static bool torture_smbconf_txt(void) printf("TEST: init\n"); werr = smbconf_init_txt(mem_ctx, &conf_ctx, filename); if (!W_ERROR_IS_OK(werr)) { - printf("FAIL: text backend\[ failed: %s\n", win_errstr(werr)); + printf("FAIL: text backend failed: %s\n", win_errstr(werr)); ret = false; goto done; } diff --git a/source3/lib/util.c b/source3/lib/util.c index 89f7be8e6c..75fd82709a 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -290,7 +290,7 @@ struct user_auth_info *user_auth_info_init(TALLOC_CTX *mem_ctx) return result; } -const char *get_cmdline_auth_info_username(struct user_auth_info *auth_info) +const char *get_cmdline_auth_info_username(const struct user_auth_info *auth_info) { if (!auth_info->username) { return ""; @@ -308,7 +308,7 @@ void set_cmdline_auth_info_username(struct user_auth_info *auth_info, } } -const char *get_cmdline_auth_info_password(struct user_auth_info *auth_info) +const char *get_cmdline_auth_info_password(const struct user_auth_info *auth_info) { if (!auth_info->password) { return ""; @@ -320,6 +320,9 @@ void set_cmdline_auth_info_password(struct user_auth_info *auth_info, const char *password) { TALLOC_FREE(auth_info->password); + if (password == NULL) { + password = ""; + } auth_info->password = talloc_strdup(auth_info, password); if (!auth_info->password) { exit(ENOMEM); @@ -346,7 +349,7 @@ bool set_cmdline_auth_info_signing_state(struct user_auth_info *auth_info, return true; } -int get_cmdline_auth_info_signing_state(struct user_auth_info *auth_info) +int get_cmdline_auth_info_signing_state(const struct user_auth_info *auth_info) { return auth_info->signing_state; } @@ -357,11 +360,22 @@ void set_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info, auth_info->use_kerberos = b; } -bool get_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info) +bool get_cmdline_auth_info_use_kerberos(const struct user_auth_info *auth_info) { return auth_info->use_kerberos; } +void set_cmdline_auth_info_fallback_after_kerberos(struct user_auth_info *auth_info, + bool b) +{ + auth_info->fallback_after_kerberos = b; +} + +bool get_cmdline_auth_info_fallback_after_kerberos(const struct user_auth_info *auth_info) +{ + return auth_info->fallback_after_kerberos; +} + /* This should only be used by lib/popt_common.c JRA */ void set_cmdline_auth_info_use_krb5_ticket(struct user_auth_info *auth_info) { @@ -380,23 +394,23 @@ void set_cmdline_auth_info_use_machine_account(struct user_auth_info *auth_info) auth_info->use_machine_account = true; } -bool get_cmdline_auth_info_got_pass(struct user_auth_info *auth_info) +bool get_cmdline_auth_info_got_pass(const struct user_auth_info *auth_info) { return auth_info->got_pass; } -bool get_cmdline_auth_info_smb_encrypt(struct user_auth_info *auth_info) +bool get_cmdline_auth_info_smb_encrypt(const struct user_auth_info *auth_info) { return auth_info->smb_encrypt; } -bool get_cmdline_auth_info_use_machine_account(struct user_auth_info *auth_info) +bool get_cmdline_auth_info_use_machine_account(const struct user_auth_info *auth_info) { return auth_info->use_machine_account; } struct user_auth_info *get_cmdline_auth_info_copy(TALLOC_CTX *mem_ctx, - struct user_auth_info *src) + const struct user_auth_info *src) { struct user_auth_info *result; @@ -456,6 +470,32 @@ bool set_cmdline_auth_info_machine_account_creds(struct user_auth_info *auth_inf } /**************************************************************************** + Ensure we have a password if one not given. +****************************************************************************/ + +void set_cmdline_auth_info_getpass(struct user_auth_info *auth_info) +{ + char *label = NULL; + char *pass; + TALLOC_CTX *frame; + + if (get_cmdline_auth_info_got_pass(auth_info) || + get_cmdline_auth_info_use_kerberos(auth_info)) { + /* Already got one... */ + return; + } + + frame = talloc_stackframe(); + label = talloc_asprintf(frame, "Enter %s's password: ", + get_cmdline_auth_info_username(auth_info)); + pass = getpass(label); + if (pass) { + set_cmdline_auth_info_password(auth_info, pass); + } + TALLOC_FREE(frame); +} + +/**************************************************************************** Add a gid to an array of gids if it's not already there. ****************************************************************************/ @@ -899,13 +939,6 @@ bool reinit_after_fork(struct messaging_context *msg_ctx, * numbers as each other */ set_need_random_reseed(); -#ifdef WITH_MADVISE_PROTECTED - /* Protect parent process from being killed by kernel when system - * memory is low. Child processes can still be killed */ - if(!parent_longlived) - madvise(NULL,0,MADV_PROTECT); -#endif - /* tdb needs special fork handling */ if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) { DEBUG(0,("tdb_reopen_all failed.\n")); @@ -3109,9 +3142,9 @@ NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname, return NT_STATUS_OK; } -bool is_valid_policy_hnd(const POLICY_HND *hnd) +bool is_valid_policy_hnd(const struct policy_handle *hnd) { - POLICY_HND tmp; + struct policy_handle tmp; ZERO_STRUCT(tmp); return (memcmp(&tmp, hnd, sizeof(tmp)) != 0); } diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 6e75a67a85..a0dbca1a00 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -519,7 +519,7 @@ NTSTATUS read_socket_with_timeout(int fd, char *buf, } while (nread < mincnt) { - readret = sys_read(fd, buf + nread, maxcnt - nread); + readret = sys_recv(fd, buf + nread, maxcnt - nread, 0); if (readret == 0) { DEBUG(5,("read_socket_with_timeout: " @@ -588,7 +588,7 @@ NTSTATUS read_socket_with_timeout(int fd, char *buf, return NT_STATUS_IO_TIMEOUT; } - readret = sys_read(fd, buf+nread, maxcnt-nread); + readret = sys_recv(fd, buf+nread, maxcnt-nread, 0); if (readret == 0) { /* we got EOF on the file descriptor */ @@ -1033,8 +1033,7 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx, timeval_current_ofs(0, state->wait_nsec))) { goto fail; } - subreq->async.fn = open_socket_out_connected; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, open_socket_out_connected, result); return result; post_status: @@ -1047,10 +1046,10 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx, static void open_socket_out_connected(struct tevent_req *subreq) { - struct tevent_req *req = talloc_get_type_abort( - subreq->async.private_data, struct tevent_req); - struct open_socket_out_state *state = talloc_get_type_abort( - req->private_state, struct open_socket_out_state); + struct tevent_req *req = + tevent_req_callback_data(subreq, struct tevent_req); + struct open_socket_out_state *state = + tevent_req_data(req, struct open_socket_out_state); int ret; int sys_errno; @@ -1089,8 +1088,7 @@ static void open_socket_out_connected(struct tevent_req *subreq) tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } - subreq->async.fn = open_socket_out_connected; - subreq->async.private_data = req; + tevent_req_set_callback(subreq, open_socket_out_connected, req); return; } @@ -1107,8 +1105,8 @@ static void open_socket_out_connected(struct tevent_req *subreq) NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd) { - struct open_socket_out_state *state = talloc_get_type_abort( - req->private_state, struct open_socket_out_state); + struct open_socket_out_state *state = + tevent_req_data(req, struct open_socket_out_state); NTSTATUS status; if (tevent_req_is_nterror(req, &status)) { @@ -1154,22 +1152,22 @@ struct open_socket_out_defer_state { int fd; }; -static void open_socket_out_defer_waited(struct async_req *subreq); +static void open_socket_out_defer_waited(struct tevent_req *subreq); static void open_socket_out_defer_connected(struct tevent_req *subreq); -struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct timeval wait_time, - const struct sockaddr_storage *pss, - uint16_t port, - int timeout) +struct tevent_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct timeval wait_time, + const struct sockaddr_storage *pss, + uint16_t port, + int timeout) { - struct async_req *result, *subreq; + struct tevent_req *req, *subreq; struct open_socket_out_defer_state *state; - NTSTATUS status; - if (!async_req_setup(mem_ctx, &result, &state, - struct open_socket_out_defer_state)) { + req = tevent_req_create(mem_ctx, &state, + struct open_socket_out_defer_state); + if (req == NULL) { return NULL; } state->ev = ev; @@ -1177,74 +1175,66 @@ struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx, state->port = port; state->timeout = timeout; - subreq = async_wait_send(state, ev, wait_time); + subreq = tevent_wakeup_send( + state, ev, + timeval_current_ofs(wait_time.tv_sec, wait_time.tv_usec)); if (subreq == NULL) { - status = NT_STATUS_NO_MEMORY; - goto post_status; - } - subreq->async.fn = open_socket_out_defer_waited; - subreq->async.priv = result; - return result; - - post_status: - if (!async_post_ntstatus(result, ev, status)) { goto fail; } - return result; + tevent_req_set_callback(subreq, open_socket_out_defer_waited, req); + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } -static void open_socket_out_defer_waited(struct async_req *subreq) +static void open_socket_out_defer_waited(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct open_socket_out_defer_state *state = talloc_get_type_abort( - req->private_data, struct open_socket_out_defer_state); - struct tevent_req *subreq2; + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct open_socket_out_defer_state *state = tevent_req_data( + req, struct open_socket_out_defer_state); bool ret; - ret = async_wait_recv(subreq); + ret = tevent_wakeup_recv(subreq); TALLOC_FREE(subreq); if (!ret) { - async_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); return; } - subreq2 = open_socket_out_send(state, state->ev, &state->ss, - state->port, state->timeout); - if (async_req_nomem(subreq2, req)) { + subreq = open_socket_out_send(state, state->ev, &state->ss, + state->port, state->timeout); + if (tevent_req_nomem(subreq, req)) { return; } - subreq2->async.fn = open_socket_out_defer_connected; - subreq2->async.private_data = req; + tevent_req_set_callback(subreq, open_socket_out_defer_connected, req); } static void open_socket_out_defer_connected(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); - struct open_socket_out_defer_state *state = talloc_get_type_abort( - req->private_data, struct open_socket_out_defer_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct open_socket_out_defer_state *state = tevent_req_data( + req, struct open_socket_out_defer_state); NTSTATUS status; status = open_socket_out_recv(subreq, &state->fd); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } -NTSTATUS open_socket_out_defer_recv(struct async_req *req, int *pfd) +NTSTATUS open_socket_out_defer_recv(struct tevent_req *req, int *pfd) { - struct open_socket_out_defer_state *state = talloc_get_type_abort( - req->private_data, struct open_socket_out_defer_state); + struct open_socket_out_defer_state *state = tevent_req_data( + req, struct open_socket_out_defer_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *pfd = state->fd; diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c index 4e78d1b064..840e8e06da 100644 --- a/source3/lib/util_unistr.c +++ b/source3/lib/util_unistr.c @@ -383,22 +383,6 @@ void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen) pull_ucs2(NULL, dest, str->buffer, maxlen, str->uni_str_len*2, STR_NOALIGN); } -#if 0 -/******************************************************************* - Convert a (little-endian) UNISTR3 structure to an ASCII string. -********************************************************************/ - -void unistr3_to_ascii(char *dest, const UNISTR3 *str, size_t maxlen) -{ - if ((str == NULL) || (str->uni_str_len == 0)) { - *dest='\0'; - return; - } - pull_ucs2(NULL, dest, str->str.buffer, maxlen, str->uni_str_len*2, - STR_NOALIGN); -} -#endif - /******************************************************************* Duplicate a UNISTR2 string into a null terminated char* using a talloc context. diff --git a/source3/lib/version_test.c b/source3/lib/version_test.c new file mode 100644 index 0000000000..880cfeb084 --- /dev/null +++ b/source3/lib/version_test.c @@ -0,0 +1,26 @@ +/* + * Unix SMB/CIFS implementation. + * version_test - test program for samba_version_strion() + * Copyright (C) Michael Adam 2009 + * + * 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 3 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, see <http://www.gnu.org/licenses/>. + */ + +#include "includes.h" + +int main(void) +{ + printf("%s\n", samba_version_string()); + return 0; +} diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c index 65906dcb91..dbea8b6686 100644 --- a/source3/lib/wb_reqtrans.c +++ b/source3/lib/wb_reqtrans.c @@ -25,28 +25,37 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND -struct req_read_state { - struct winbindd_request *wb_req; - size_t max_extra_data; -}; +wbcErr map_wbc_err_from_errno(int error) +{ + switch(error) { + case EPERM: + case EACCES: + return WBC_ERR_AUTH_ERROR; + case ENOMEM: + return WBC_ERR_NO_MEMORY; + case EIO: + default: + return WBC_ERR_UNKNOWN_FAILURE; + } +} -bool async_req_is_wbcerr(struct async_req *req, wbcErr *pwbc_err) +bool tevent_req_is_wbcerr(struct tevent_req *req, wbcErr *pwbc_err) { - enum async_req_state state; + enum tevent_req_state state; uint64_t error; - if (!async_req_is_error(req, &state, &error)) { + if (!tevent_req_is_error(req, &state, &error)) { *pwbc_err = WBC_ERR_SUCCESS; return false; } switch (state) { - case ASYNC_REQ_USER_ERROR: + case TEVENT_REQ_USER_ERROR: *pwbc_err = error; break; - case ASYNC_REQ_TIMED_OUT: + case TEVENT_REQ_TIMED_OUT: *pwbc_err = WBC_ERR_UNKNOWN_FAILURE; break; - case ASYNC_REQ_NO_MEMORY: + case TEVENT_REQ_NO_MEMORY: *pwbc_err = WBC_ERR_NO_MEMORY; break; default: @@ -56,44 +65,34 @@ bool async_req_is_wbcerr(struct async_req *req, wbcErr *pwbc_err) return true; } -wbcErr map_wbc_err_from_errno(int error) -{ - switch(error) { - case EPERM: - case EACCES: - return WBC_ERR_AUTH_ERROR; - case ENOMEM: - return WBC_ERR_NO_MEMORY; - case EIO: - default: - return WBC_ERR_UNKNOWN_FAILURE; - } -} - -wbcErr async_req_simple_recv_wbcerr(struct async_req *req) +wbcErr tevent_req_simple_recv_wbcerr(struct tevent_req *req) { wbcErr wbc_err; - if (async_req_is_wbcerr(req, &wbc_err)) { + if (tevent_req_is_wbcerr(req, &wbc_err)) { return wbc_err; } return WBC_ERR_SUCCESS; } +struct req_read_state { + struct winbindd_request *wb_req; + size_t max_extra_data; +}; + static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data); static void wb_req_read_done(struct tevent_req *subreq); -struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd, size_t max_extra_data) +struct tevent_req *wb_req_read_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, size_t max_extra_data) { - struct async_req *result; - struct tevent_req *subreq; + struct tevent_req *result, *subreq; struct req_read_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct req_read_state)) { + result = tevent_req_create(mem_ctx, &state, struct req_read_state); + if (result == NULL) { return NULL; } state->max_extra_data = max_extra_data; @@ -103,8 +102,7 @@ struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx, goto nomem; } - subreq->async.fn = wb_req_read_done; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, wb_req_read_done, result); return result; nomem: TALLOC_FREE(result); @@ -140,10 +138,10 @@ static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data) static void wb_req_read_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); - struct req_read_state *state = talloc_get_type_abort( - req->private_data, struct req_read_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct req_read_state *state = tevent_req_data( + req, struct req_read_state); int err; ssize_t ret; uint8_t *buf; @@ -151,7 +149,7 @@ static void wb_req_read_done(struct tevent_req *subreq) ret = read_packet_recv(subreq, state, &buf, &err); TALLOC_FREE(subreq); if (ret == -1) { - async_req_error(req, map_wbc_err_from_errno(err)); + tevent_req_error(req, map_wbc_err_from_errno(err)); return; } @@ -163,17 +161,17 @@ static void wb_req_read_done(struct tevent_req *subreq) } else { state->wb_req->extra_data.data = NULL; } - async_req_done(req); + tevent_req_done(req); } -wbcErr wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx, +wbcErr wb_req_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct winbindd_request **preq) { - struct req_read_state *state = talloc_get_type_abort( - req->private_data, struct req_read_state); + struct req_read_state *state = tevent_req_data( + req, struct req_read_state); wbcErr wbc_err; - if (async_req_is_wbcerr(req, &wbc_err)) { + if (tevent_req_is_wbcerr(req, &wbc_err)) { return wbc_err; } *preq = talloc_move(mem_ctx, &state->wb_req); @@ -186,17 +184,17 @@ struct req_write_state { static void wb_req_write_done(struct tevent_req *subreq); -struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, int fd, - struct winbindd_request *wb_req) +struct tevent_req *wb_req_write_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tevent_queue *queue, int fd, + struct winbindd_request *wb_req) { - struct async_req *result; - struct tevent_req *subreq; + struct tevent_req *result, *subreq; struct req_write_state *state; int count = 1; - if (!async_req_setup(mem_ctx, &result, &state, - struct req_write_state)) { + result = tevent_req_create(mem_ctx, &state, struct req_write_state); + if (result == NULL) { return NULL; } @@ -209,12 +207,11 @@ struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx, count = 2; } - subreq = writev_send(state, ev, fd, state->iov, count); + subreq = writev_send(state, ev, queue, fd, state->iov, count); if (subreq == NULL) { goto fail; } - subreq->async.fn = wb_req_write_done; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, wb_req_write_done, result); return result; fail: @@ -224,23 +221,23 @@ struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx, static void wb_req_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); int err; ssize_t ret; ret = writev_recv(subreq, &err); TALLOC_FREE(subreq); if (ret < 0) { - async_req_error(req, map_wbc_err_from_errno(err)); + tevent_req_error(req, map_wbc_err_from_errno(err)); return; } - async_req_done(req); + tevent_req_done(req); } -wbcErr wb_req_write_recv(struct async_req *req) +wbcErr wb_req_write_recv(struct tevent_req *req) { - return async_req_simple_recv_wbcerr(req); + return tevent_req_simple_recv_wbcerr(req); } struct resp_read_state { @@ -250,15 +247,14 @@ struct resp_read_state { static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data); static void wb_resp_read_done(struct tevent_req *subreq); -struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, int fd) +struct tevent_req *wb_resp_read_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, int fd) { - struct async_req *result; - struct tevent_req *subreq; + struct tevent_req *result, *subreq; struct resp_read_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct resp_read_state)) { + result = tevent_req_create(mem_ctx, &state, struct resp_read_state); + if (result == NULL) { return NULL; } @@ -266,8 +262,7 @@ struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto nomem; } - subreq->async.fn = wb_resp_read_done; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, wb_resp_read_done, result); return result; nomem: @@ -293,10 +288,10 @@ static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data) static void wb_resp_read_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); - struct resp_read_state *state = talloc_get_type_abort( - req->private_data, struct resp_read_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct resp_read_state *state = tevent_req_data( + req, struct resp_read_state); uint8_t *buf; int err; ssize_t ret; @@ -304,7 +299,7 @@ static void wb_resp_read_done(struct tevent_req *subreq) ret = read_packet_recv(subreq, state, &buf, &err); TALLOC_FREE(subreq); if (ret == -1) { - async_req_error(req, map_wbc_err_from_errno(err)); + tevent_req_error(req, map_wbc_err_from_errno(err)); return; } @@ -316,17 +311,17 @@ static void wb_resp_read_done(struct tevent_req *subreq) } else { state->wb_resp->extra_data.data = NULL; } - async_req_done(req); + tevent_req_done(req); } -wbcErr wb_resp_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx, +wbcErr wb_resp_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct winbindd_response **presp) { - struct resp_read_state *state = talloc_get_type_abort( - req->private_data, struct resp_read_state); + struct resp_read_state *state = tevent_req_data( + req, struct resp_read_state); wbcErr wbc_err; - if (async_req_is_wbcerr(req, &wbc_err)) { + if (tevent_req_is_wbcerr(req, &wbc_err)) { return wbc_err; } *presp = talloc_move(mem_ctx, &state->wb_resp); @@ -339,17 +334,17 @@ struct resp_write_state { static void wb_resp_write_done(struct tevent_req *subreq); -struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, int fd, - struct winbindd_response *wb_resp) +struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tevent_queue *queue, int fd, + struct winbindd_response *wb_resp) { - struct async_req *result; - struct tevent_req *subreq; + struct tevent_req *result, *subreq; struct resp_write_state *state; int count = 1; - if (!async_req_setup(mem_ctx, &result, &state, - struct resp_write_state)) { + result = tevent_req_create(mem_ctx, &state, struct resp_write_state); + if (result == NULL) { return NULL; } @@ -363,12 +358,11 @@ struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, count = 2; } - subreq = writev_send(state, ev, fd, state->iov, count); + subreq = writev_send(state, ev, queue, fd, state->iov, count); if (subreq == NULL) { goto fail; } - subreq->async.fn = wb_resp_write_done; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, wb_resp_write_done, result); return result; fail: @@ -378,21 +372,21 @@ struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, static void wb_resp_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); int err; ssize_t ret; ret = writev_recv(subreq, &err); TALLOC_FREE(subreq); if (ret < 0) { - async_req_error(req, map_wbc_err_from_errno(err)); + tevent_req_error(req, map_wbc_err_from_errno(err)); return; } - async_req_done(req); + tevent_req_done(req); } -wbcErr wb_resp_write_recv(struct async_req *req) +wbcErr wb_resp_write_recv(struct tevent_req *req) { - return async_req_simple_recv_wbcerr(req); + return tevent_req_simple_recv_wbcerr(req); } diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c index b8d55a944a..3cf992c7de 100644 --- a/source3/lib/wbclient.c +++ b/source3/lib/wbclient.c @@ -20,6 +20,12 @@ #include "includes.h" #include "wbc_async.h" +struct wb_context { + struct tevent_queue *queue; + int fd; + bool is_priv; +}; + static int make_nonstd_fd(int fd) { int i; @@ -138,7 +144,7 @@ struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx) if (result == NULL) { return NULL; } - result->queue = async_req_queue_init(result); + result->queue = tevent_queue_create(result, "wb_trans"); if (result->queue == NULL) { TALLOC_FREE(result); return NULL; @@ -153,21 +159,20 @@ struct wb_connect_state { static void wbc_connect_connected(struct tevent_req *subreq); -static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx, +static struct tevent_req *wb_connect_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct wb_context *wb_ctx, const char *dir) { - struct async_req *result; - struct tevent_req *subreq; + struct tevent_req *result, *subreq; struct wb_connect_state *state; struct sockaddr_un sunaddr; struct stat st; char *path = NULL; wbcErr wbc_err; - if (!async_req_setup(mem_ctx, &result, &state, - struct wb_connect_state)) { + result = tevent_req_create(mem_ctx, &state, struct wb_connect_state); + if (result == NULL) { return NULL; } @@ -224,8 +229,7 @@ static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto nomem; } - subreq->async.fn = wbc_connect_connected; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, wbc_connect_connected, result); if (!tevent_req_set_endtime(subreq, ev, timeval_current_ofs(30, 0))) { goto nomem; @@ -233,59 +237,32 @@ static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx, return result; - nomem: - wbc_err = WBC_ERR_NO_MEMORY; post_status: - if (async_post_error(result, ev, wbc_err)) { - return result; - } + tevent_req_error(result, wbc_err); + return tevent_req_post(result, ev); + nomem: TALLOC_FREE(result); return NULL; } static void wbc_connect_connected(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); int res, err; res = async_connect_recv(subreq, &err); TALLOC_FREE(subreq); if (res == -1) { - async_req_error(req, map_wbc_err_from_errno(err)); + tevent_req_error(req, map_wbc_err_from_errno(err)); return; } - async_req_done(req); + tevent_req_done(req); } -static wbcErr wb_connect_recv(struct async_req *req) +static wbcErr wb_connect_recv(struct tevent_req *req) { - return async_req_simple_recv_wbcerr(req); -} - -static struct winbindd_request *winbindd_request_copy( - TALLOC_CTX *mem_ctx, - const struct winbindd_request *req) -{ - struct winbindd_request *result; - - result = (struct winbindd_request *)TALLOC_MEMDUP( - mem_ctx, req, sizeof(struct winbindd_request)); - if (result == NULL) { - return NULL; - } - - if (result->extra_len == 0) { - return result; - } - - result->extra_data.data = (char *)TALLOC_MEMDUP( - result, result->extra_data.data, result->extra_len); - if (result->extra_data.data == NULL) { - TALLOC_FREE(result); - return NULL; - } - return result; + return tevent_req_simple_recv_wbcerr(req); } struct wb_int_trans_state { @@ -295,43 +272,40 @@ struct wb_int_trans_state { struct winbindd_response *wb_resp; }; -static void wb_int_trans_write_done(struct async_req *subreq); -static void wb_int_trans_read_done(struct async_req *subreq); +static void wb_int_trans_write_done(struct tevent_req *subreq); +static void wb_int_trans_read_done(struct tevent_req *subreq); -static struct async_req *wb_int_trans_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, int fd, - struct winbindd_request *wb_req) +static struct tevent_req *wb_int_trans_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tevent_queue *queue, int fd, + struct winbindd_request *wb_req) { - struct async_req *result; - struct async_req *subreq; + struct tevent_req *result, *subreq; struct wb_int_trans_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct wb_int_trans_state)) { + result = tevent_req_create(mem_ctx, &state, + struct wb_int_trans_state); + if (result == NULL) { return NULL; } if (winbind_closed_fd(fd)) { - if (!async_post_error(result, ev, - WBC_ERR_WINBIND_NOT_AVAILABLE)) { - goto fail; - } - return result; + tevent_req_error(result, WBC_ERR_WINBIND_NOT_AVAILABLE); + return tevent_req_post(result, ev); } state->ev = ev; state->fd = fd; state->wb_req = wb_req; - state->wb_req->length = sizeof(struct winbindd_request); state->wb_req->pid = getpid(); - subreq = wb_req_write_send(state, state->ev, state->fd, state->wb_req); + subreq = wb_req_write_send(state, state->ev, queue, state->fd, + state->wb_req); if (subreq == NULL) { goto fail; } - subreq->async.fn = wb_int_trans_write_done; - subreq->async.priv = result; + tevent_req_set_callback(subreq, wb_int_trans_write_done, result); return result; @@ -340,56 +314,55 @@ static struct async_req *wb_int_trans_send(TALLOC_CTX *mem_ctx, return NULL; } -static void wb_int_trans_write_done(struct async_req *subreq) +static void wb_int_trans_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct wb_int_trans_state *state = talloc_get_type_abort( - req->private_data, struct wb_int_trans_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_int_trans_state *state = tevent_req_data( + req, struct wb_int_trans_state); wbcErr wbc_err; wbc_err = wb_req_write_recv(subreq); TALLOC_FREE(subreq); if (!WBC_ERROR_IS_OK(wbc_err)) { - async_req_error(req, wbc_err); + tevent_req_error(req, wbc_err); return; } subreq = wb_resp_read_send(state, state->ev, state->fd); - if (subreq == NULL) { - async_req_error(req, WBC_ERR_NO_MEMORY); + if (tevent_req_nomem(subreq, req)) { + return; } - subreq->async.fn = wb_int_trans_read_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, wb_int_trans_read_done, req); } -static void wb_int_trans_read_done(struct async_req *subreq) +static void wb_int_trans_read_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct wb_int_trans_state *state = talloc_get_type_abort( - req->private_data, struct wb_int_trans_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_int_trans_state *state = tevent_req_data( + req, struct wb_int_trans_state); wbcErr wbc_err; wbc_err = wb_resp_read_recv(subreq, state, &state->wb_resp); TALLOC_FREE(subreq); if (!WBC_ERROR_IS_OK(wbc_err)) { - async_req_error(req, wbc_err); + tevent_req_error(req, wbc_err); return; } - async_req_done(req); + tevent_req_done(req); } -static wbcErr wb_int_trans_recv(struct async_req *req, +static wbcErr wb_int_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct winbindd_response **presponse) { - struct wb_int_trans_state *state = talloc_get_type_abort( - req->private_data, struct wb_int_trans_state); + struct wb_int_trans_state *state = tevent_req_data( + req, struct wb_int_trans_state); wbcErr wbc_err; - if (async_req_is_wbcerr(req, &wbc_err)) { + if (tevent_req_is_wbcerr(req, &wbc_err)) { return wbc_err; } @@ -418,22 +391,21 @@ struct wb_open_pipe_state { struct winbindd_request wb_req; }; -static void wb_open_pipe_connect_nonpriv_done(struct async_req *subreq); -static void wb_open_pipe_ping_done(struct async_req *subreq); -static void wb_open_pipe_getpriv_done(struct async_req *subreq); -static void wb_open_pipe_connect_priv_done(struct async_req *subreq); +static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq); +static void wb_open_pipe_ping_done(struct tevent_req *subreq); +static void wb_open_pipe_getpriv_done(struct tevent_req *subreq); +static void wb_open_pipe_connect_priv_done(struct tevent_req *subreq); -static struct async_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct wb_context *wb_ctx, - bool need_priv) +static struct tevent_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct wb_context *wb_ctx, + bool need_priv) { - struct async_req *result; - struct async_req *subreq; + struct tevent_req *result, *subreq; struct wb_open_pipe_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct wb_open_pipe_state)) { + result = tevent_req_create(mem_ctx, &state, struct wb_open_pipe_state); + if (result == NULL) { return NULL; } state->wb_ctx = wb_ctx; @@ -449,9 +421,8 @@ static struct async_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - - subreq->async.fn = wb_open_pipe_connect_nonpriv_done; - subreq->async.priv = result; + tevent_req_set_callback(subreq, wb_open_pipe_connect_nonpriv_done, + result); return result; fail: @@ -459,81 +430,77 @@ static struct async_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx, return NULL; } -static void wb_open_pipe_connect_nonpriv_done(struct async_req *subreq) +static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct wb_open_pipe_state *state = talloc_get_type_abort( - req->private_data, struct wb_open_pipe_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_open_pipe_state *state = tevent_req_data( + req, struct wb_open_pipe_state); wbcErr wbc_err; wbc_err = wb_connect_recv(subreq); TALLOC_FREE(subreq); if (!WBC_ERROR_IS_OK(wbc_err)) { state->wb_ctx->is_priv = true; - async_req_error(req, wbc_err); + tevent_req_error(req, wbc_err); return; } ZERO_STRUCT(state->wb_req); state->wb_req.cmd = WINBINDD_INTERFACE_VERSION; - subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd, + subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd, &state->wb_req); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } - - subreq->async.fn = wb_open_pipe_ping_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, wb_open_pipe_ping_done, req); } -static void wb_open_pipe_ping_done(struct async_req *subreq) +static void wb_open_pipe_ping_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct wb_open_pipe_state *state = talloc_get_type_abort( - req->private_data, struct wb_open_pipe_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_open_pipe_state *state = tevent_req_data( + req, struct wb_open_pipe_state); struct winbindd_response *wb_resp; wbcErr wbc_err; wbc_err = wb_int_trans_recv(subreq, state, &wb_resp); TALLOC_FREE(subreq); if (!WBC_ERROR_IS_OK(wbc_err)) { - async_req_error(req, wbc_err); + tevent_req_error(req, wbc_err); return; } if (!state->need_priv) { - async_req_done(req); + tevent_req_done(req); return; } state->wb_req.cmd = WINBINDD_PRIV_PIPE_DIR; - subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd, + subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd, &state->wb_req); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } - - subreq->async.fn = wb_open_pipe_getpriv_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, wb_open_pipe_getpriv_done, req); } -static void wb_open_pipe_getpriv_done(struct async_req *subreq) +static void wb_open_pipe_getpriv_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct wb_open_pipe_state *state = talloc_get_type_abort( - req->private_data, struct wb_open_pipe_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_open_pipe_state *state = tevent_req_data( + req, struct wb_open_pipe_state); struct winbindd_response *wb_resp = NULL; wbcErr wbc_err; wbc_err = wb_int_trans_recv(subreq, state, &wb_resp); TALLOC_FREE(subreq); if (!WBC_ERROR_IS_OK(wbc_err)) { - async_req_error(req, wbc_err); + tevent_req_error(req, wbc_err); return; } @@ -541,37 +508,35 @@ static void wb_open_pipe_getpriv_done(struct async_req *subreq) state->wb_ctx->fd = -1; subreq = wb_connect_send(state, state->ev, state->wb_ctx, - (char *)wb_resp->extra_data.data); + (char *)wb_resp->extra_data.data); TALLOC_FREE(wb_resp); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } - - subreq->async.fn = wb_open_pipe_connect_priv_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, wb_open_pipe_connect_priv_done, req); } -static void wb_open_pipe_connect_priv_done(struct async_req *subreq) +static void wb_open_pipe_connect_priv_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct wb_open_pipe_state *state = talloc_get_type_abort( - req->private_data, struct wb_open_pipe_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_open_pipe_state *state = tevent_req_data( + req, struct wb_open_pipe_state); wbcErr wbc_err; wbc_err = wb_connect_recv(subreq); TALLOC_FREE(subreq); if (!WBC_ERROR_IS_OK(wbc_err)) { - async_req_error(req, wbc_err); + tevent_req_error(req, wbc_err); return; } state->wb_ctx->is_priv = true; - async_req_done(req); + tevent_req_done(req); } -static wbcErr wb_open_pipe_recv(struct async_req *req) +static wbcErr wb_open_pipe_recv(struct tevent_req *req) { - return async_req_simple_recv_wbcerr(req); + return tevent_req_simple_recv_wbcerr(req); } struct wb_trans_state { @@ -584,73 +549,54 @@ struct wb_trans_state { bool need_priv; }; -static void wb_trans_connect_done(struct async_req *subreq); -static void wb_trans_done(struct async_req *subreq); -static void wb_trans_retry_wait_done(struct async_req *subreq); - -static void wb_trigger_trans(struct async_req *req) -{ - struct wb_trans_state *state = talloc_get_type_abort( - req->private_data, struct wb_trans_state); - struct async_req *subreq; - - if ((state->wb_ctx->fd == -1) - || (state->need_priv && !state->wb_ctx->is_priv)) { - - subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx, - state->need_priv); - if (async_req_nomem(subreq, req)) { - return; - } - subreq->async.fn = wb_trans_connect_done; - subreq->async.priv = req; - return; - } - - subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd, - state->wb_req); - if (async_req_nomem(subreq, req)) { - return; - } - subreq->async.fn = wb_trans_done; - subreq->async.priv = req; -} +static void wb_trans_connect_done(struct tevent_req *subreq); +static void wb_trans_done(struct tevent_req *subreq); +static void wb_trans_retry_wait_done(struct tevent_req *subreq); -struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct wb_context *wb_ctx, bool need_priv, - const struct winbindd_request *wb_req) +struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct wb_context *wb_ctx, bool need_priv, + struct winbindd_request *wb_req) { - struct async_req *result; + struct tevent_req *req, *subreq; struct wb_trans_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct wb_trans_state)) { + req = tevent_req_create(mem_ctx, &state, struct wb_trans_state); + if (req == NULL) { return NULL; } state->wb_ctx = wb_ctx; state->ev = ev; - state->wb_req = winbindd_request_copy(state, wb_req); - if (state->wb_req == NULL) { - goto fail; - } + state->wb_req = wb_req; state->num_retries = 10; state->need_priv = need_priv; - if (!async_req_enqueue(wb_ctx->queue, ev, result, wb_trigger_trans)) { - goto fail; + if ((wb_ctx->fd == -1) || (need_priv && !wb_ctx->is_priv)) { + subreq = wb_open_pipe_send(state, ev, wb_ctx, need_priv); + if (subreq == NULL) { + goto fail; + } + tevent_req_set_callback(subreq, wb_trans_connect_done, req); + return req; } - return result; + subreq = wb_int_trans_send(state, ev, wb_ctx->queue, wb_ctx->fd, + wb_req); + if (subreq == NULL) { + goto fail; + } + tevent_req_set_callback(subreq, wb_trans_done, req); + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } -static bool wb_trans_retry(struct async_req *req, +static bool wb_trans_retry(struct tevent_req *req, struct wb_trans_state *state, wbcErr wbc_err) { - struct async_req *subreq; + struct tevent_req *subreq; if (WBC_ERROR_IS_OK(wbc_err)) { return false; @@ -661,13 +607,13 @@ static bool wb_trans_retry(struct async_req *req, * Winbind not around or we can't connect to the pipe. Fail * immediately. */ - async_req_error(req, wbc_err); + tevent_req_error(req, wbc_err); return true; } state->num_retries -= 1; if (state->num_retries == 0) { - async_req_error(req, wbc_err); + tevent_req_error(req, wbc_err); return true; } @@ -680,46 +626,44 @@ static bool wb_trans_retry(struct async_req *req, state->wb_ctx->fd = -1; } - subreq = async_wait_send(state, state->ev, timeval_set(1, 0)); - if (async_req_nomem(subreq, req)) { + subreq = tevent_wakeup_send(state, state->ev, + timeval_current_ofs(1, 0)); + if (tevent_req_nomem(subreq, req)) { return true; } - - subreq->async.fn = wb_trans_retry_wait_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, wb_trans_retry_wait_done, req); return true; } -static void wb_trans_retry_wait_done(struct async_req *subreq) +static void wb_trans_retry_wait_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct wb_trans_state *state = talloc_get_type_abort( - req->private_data, struct wb_trans_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_trans_state *state = tevent_req_data( + req, struct wb_trans_state); bool ret; - ret = async_wait_recv(subreq); + ret = tevent_wakeup_recv(subreq); TALLOC_FREE(subreq); - if (ret) { - async_req_error(req, WBC_ERR_UNKNOWN_FAILURE); + if (!ret) { + tevent_req_error(req, WBC_ERR_UNKNOWN_FAILURE); return; } subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx, state->need_priv); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } - subreq->async.fn = wb_trans_connect_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, wb_trans_connect_done, req); } -static void wb_trans_connect_done(struct async_req *subreq) +static void wb_trans_connect_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct wb_trans_state *state = talloc_get_type_abort( - req->private_data, struct wb_trans_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_trans_state *state = tevent_req_data( + req, struct wb_trans_state); wbcErr wbc_err; wbc_err = wb_open_pipe_recv(subreq); @@ -729,22 +673,20 @@ static void wb_trans_connect_done(struct async_req *subreq) return; } - subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd, + subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd, state->wb_req); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } - - subreq->async.fn = wb_trans_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, wb_trans_done, req); } -static void wb_trans_done(struct async_req *subreq) +static void wb_trans_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct wb_trans_state *state = talloc_get_type_abort( - req->private_data, struct wb_trans_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_trans_state *state = tevent_req_data( + req, struct wb_trans_state); wbcErr wbc_err; wbc_err = wb_int_trans_recv(subreq, state, &state->wb_resp); @@ -754,17 +696,17 @@ static void wb_trans_done(struct async_req *subreq) return; } - async_req_done(req); + tevent_req_done(req); } -wbcErr wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx, +wbcErr wb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct winbindd_response **presponse) { - struct wb_trans_state *state = talloc_get_type_abort( - req->private_data, struct wb_trans_state); + struct wb_trans_state *state = tevent_req_data( + req, struct wb_trans_state); wbcErr wbc_err; - if (async_req_is_wbcerr(req, &wbc_err)) { + if (tevent_req_is_wbcerr(req, &wbc_err)) { return wbc_err; } diff --git a/source3/lib/winbind_util.c b/source3/lib/winbind_util.c index 64f5fb421a..df095b9e91 100644 --- a/source3/lib/winbind_util.c +++ b/source3/lib/winbind_util.c @@ -322,7 +322,6 @@ bool winbind_get_sid_aliases(TALLOC_CTX *mem_ctx, &rids, &num_rids); if (ret != WBC_ERR_SUCCESS) { - wbcFreeMemory(rids); return false; } diff --git a/source3/libaddns/dns.h b/source3/libaddns/dns.h index 57a9b6a002..a04a13bfd9 100644 --- a/source3/libaddns/dns.h +++ b/source3/libaddns/dns.h @@ -133,7 +133,9 @@ void *talloc_zeronull(const void *context, size_t size, const char *name); #define TALLOC_REALLOC(ctx, ptr, count) _talloc_realloc(ctx, ptr, count, __location__) #define TALLOC_REALLOC_ARRAY(ctx, ptr, type, count) (type *)_talloc_realloc_array(ctx, ptr, sizeof(type), count, #type) #define talloc_destroy(ctx) talloc_free(ctx) +#ifndef TALLOC_FREE #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) +#endif /******************************************************************* Type definitions for int16, int32, uint16 and uint32. Needed diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index d66e35cacb..d941ba60cd 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -4,6 +4,7 @@ Copyright (C) 2001 Andrew Tridgell (tridge@samba.org) Copyright (C) 2003 Jim McDonough (jmcd@us.ibm.com) Copyright (C) 2008 Guenther Deschner (gd@samba.org) + Copyright (C) 2009 Stefan Metzmacher (metze@samba.org) 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 @@ -20,221 +21,8 @@ */ #include "includes.h" - -/* - do a cldap netlogon query -*/ -static int send_cldap_netlogon(TALLOC_CTX *mem_ctx, int sock, const char *domain, - const char *hostname, unsigned ntversion) -{ - ASN1_DATA *data; - char ntver[4]; -#ifdef CLDAP_USER_QUERY - char aac[4]; - - SIVAL(aac, 0, 0x00000180); -#endif - SIVAL(ntver, 0, ntversion); - - data = asn1_init(mem_ctx); - if (data == NULL) { - return -1; - } - - asn1_push_tag(data,ASN1_SEQUENCE(0)); - asn1_write_Integer(data, 4); - asn1_push_tag(data, ASN1_APPLICATION(3)); - asn1_write_OctetString(data, NULL, 0); - asn1_write_enumerated(data, 0); - asn1_write_enumerated(data, 0); - asn1_write_Integer(data, 0); - asn1_write_Integer(data, 0); - asn1_write_BOOLEAN(data, False); - asn1_push_tag(data, ASN1_CONTEXT(0)); - - if (domain) { - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, "DnsDomain", 9); - asn1_write_OctetString(data, domain, strlen(domain)); - asn1_pop_tag(data); - } - - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, "Host", 4); - asn1_write_OctetString(data, hostname, strlen(hostname)); - asn1_pop_tag(data); - -#ifdef CLDAP_USER_QUERY - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, "User", 4); - asn1_write_OctetString(data, "SAMBA$", 6); - asn1_pop_tag(data); - - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, "AAC", 4); - asn1_write_OctetString(data, aac, 4); - asn1_pop_tag(data); -#endif - - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, "NtVer", 5); - asn1_write_OctetString(data, ntver, 4); - asn1_pop_tag(data); - - asn1_pop_tag(data); - - asn1_push_tag(data,ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, "NetLogon", 8); - asn1_pop_tag(data); - asn1_pop_tag(data); - asn1_pop_tag(data); - - if (data->has_error) { - DEBUG(2,("Failed to build cldap netlogon at offset %d\n", (int)data->ofs)); - asn1_free(data); - return -1; - } - - if (write(sock, data->data, data->length) != (ssize_t)data->length) { - DEBUG(2,("failed to send cldap query (%s)\n", strerror(errno))); - asn1_free(data); - return -1; - } - - asn1_free(data); - - return 0; -} - -/* - receive a cldap netlogon reply -*/ -static int recv_cldap_netlogon(TALLOC_CTX *mem_ctx, - int sock, - uint32_t nt_version, - struct netlogon_samlogon_response **reply) -{ - int ret; - ASN1_DATA *data; - DATA_BLOB blob = data_blob_null; - DATA_BLOB os1 = data_blob_null; - DATA_BLOB os2 = data_blob_null; - DATA_BLOB os3 = data_blob_null; - int i1; - struct netlogon_samlogon_response *r = NULL; - NTSTATUS status; - - fd_set r_fds; - struct timeval timeout; - - blob = data_blob(NULL, 8192); - if (blob.data == NULL) { - DEBUG(1, ("data_blob failed\n")); - errno = ENOMEM; - return -1; - } - - FD_ZERO(&r_fds); - FD_SET(sock, &r_fds); - - /* - * half the time of a regular ldap timeout, not less than 3 seconds. - */ - timeout.tv_sec = MAX(3,lp_ldap_timeout()/2); - timeout.tv_usec = 0; - - ret = sys_select(sock+1, &r_fds, NULL, NULL, &timeout); - if (ret == -1) { - DEBUG(10, ("select failed: %s\n", strerror(errno))); - data_blob_free(&blob); - return -1; - } - - if (ret == 0) { - DEBUG(1,("no reply received to cldap netlogon\n")); - data_blob_free(&blob); - return -1; - } - - ret = read(sock, blob.data, blob.length); - if (ret <= 0) { - DEBUG(1,("no reply received to cldap netlogon\n")); - data_blob_free(&blob); - return -1; - } - blob.length = ret; - - data = asn1_init(mem_ctx); - if (data == NULL) { - data_blob_free(&blob); - return -1; - } - - asn1_load(data, blob); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_Integer(data, &i1); - asn1_start_tag(data, ASN1_APPLICATION(4)); - asn1_read_OctetString(data, NULL, &os1); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_OctetString(data, NULL, &os2); - asn1_start_tag(data, ASN1_SET); - asn1_read_OctetString(data, NULL, &os3); - asn1_end_tag(data); - asn1_end_tag(data); - asn1_end_tag(data); - asn1_end_tag(data); - asn1_end_tag(data); - - if (data->has_error) { - data_blob_free(&blob); - data_blob_free(&os1); - data_blob_free(&os2); - data_blob_free(&os3); - asn1_free(data); - DEBUG(1,("Failed to parse cldap reply\n")); - return -1; - } - - r = TALLOC_ZERO_P(mem_ctx, struct netlogon_samlogon_response); - if (!r) { - errno = ENOMEM; - data_blob_free(&os1); - data_blob_free(&os2); - data_blob_free(&os3); - data_blob_free(&blob); - asn1_free(data); - return -1; - } - - status = pull_netlogon_samlogon_response(&os3, mem_ctx, NULL, r); - if (!NT_STATUS_IS_OK(status)) { - data_blob_free(&os1); - data_blob_free(&os2); - data_blob_free(&os3); - data_blob_free(&blob); - asn1_free(data); - TALLOC_FREE(r); - return -1; - } - - map_netlogon_samlogon_response(r); - - data_blob_free(&os1); - data_blob_free(&os2); - data_blob_free(&os3); - data_blob_free(&blob); - - asn1_free(data); - - if (reply) { - *reply = r; - } else { - TALLOC_FREE(r); - } - - return 0; -} +#include "../libcli/cldap/cldap.h" +#include "../lib/tsocket/tsocket.h" /******************************************************************* do a cldap netlogon query. Always 389/udp @@ -244,31 +32,81 @@ bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx, const char *server, const char *realm, uint32_t nt_version, - struct netlogon_samlogon_response **reply) + struct netlogon_samlogon_response **_reply) { - int sock; + struct cldap_socket *cldap; + struct cldap_netlogon io; + struct netlogon_samlogon_response *reply; + NTSTATUS status; + struct in_addr addr; + char addrstr[INET_ADDRSTRLEN]; + const char *dest_str; int ret; + struct tsocket_address *dest_addr; - sock = open_udp_socket(server, LDAP_PORT ); - if (sock == -1) { - DEBUG(2,("ads_cldap_netlogon: Failed to open udp socket to %s\n", + addr = interpret_addr2(server); + dest_str = inet_ntop(AF_INET, &addr, + addrstr, sizeof(addrstr)); + if (!dest_str) { + DEBUG(2,("Failed to resolve[%s] into an address for cldap\n", server)); - return False; + return false; } - ret = send_cldap_netlogon(mem_ctx, sock, realm, global_myname(), nt_version); + ret = tsocket_address_inet_from_strings(mem_ctx, "ipv4", + dest_str, LDAP_PORT, + &dest_addr); if (ret != 0) { - close(sock); - return False; + status = map_nt_error_from_unix(errno); + DEBUG(2,("Failed to create cldap tsocket_address for %s - %s\n", + dest_str, nt_errstr(status))); + return false; + } + + /* + * as we use a connected udp socket + */ + status = cldap_socket_init(mem_ctx, NULL, NULL, dest_addr, &cldap); + TALLOC_FREE(dest_addr); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(2,("Failed to create cldap socket to %s: %s\n", + dest_str, nt_errstr(status))); + return false; } - ret = recv_cldap_netlogon(mem_ctx, sock, nt_version, reply); - close(sock); - if (ret == -1) { - return False; + reply = talloc(cldap, struct netlogon_samlogon_response); + if (!reply) { + goto failed; } - return True; + /* + * as we use a connected socket, so we don't need to specify the + * destination + */ + io.in.dest_address = NULL; + io.in.dest_port = 0; + io.in.realm = realm; + io.in.host = NULL; + io.in.user = NULL; + io.in.domain_guid = NULL; + io.in.domain_sid = NULL; + io.in.acct_control = 0; + io.in.version = nt_version; + io.in.map_response = false; + + status = cldap_netlogon(cldap, NULL, reply, &io); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(2,("cldap_netlogon() failed: %s\n", nt_errstr(status))); + goto failed; + } + + *reply = io.out.netlogon; + *_reply = talloc_move(mem_ctx, &reply); + TALLOC_FREE(cldap); + return true; +failed: + TALLOC_FREE(cldap); + return false; } /******************************************************************* diff --git a/source3/libads/krb5_errs.c b/source3/libads/krb5_errs.c index 53023cc75a..0e03ebb90d 100644 --- a/source3/libads/krb5_errs.c +++ b/source3/libads/krb5_errs.c @@ -30,12 +30,10 @@ static const struct { {KRB5KDC_ERR_CLIENT_REVOKED, NT_STATUS_ACCESS_DENIED}, {KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, NT_STATUS_INVALID_ACCOUNT_NAME}, {KRB5KDC_ERR_ETYPE_NOSUPP, NT_STATUS_LOGON_FAILURE}, -#if defined(KRB5KDC_ERR_KEY_EXPIRED) /* Heimdal */ - {KRB5KDC_ERR_KEY_EXPIRED, NT_STATUS_PASSWORD_EXPIRED}, -#elif defined(KRB5KDC_ERR_KEY_EXP) /* MIT */ +#if defined(KRB5KDC_ERR_KEY_EXP) /* MIT */ {KRB5KDC_ERR_KEY_EXP, NT_STATUS_PASSWORD_EXPIRED}, -#else -#error Neither KRB5KDC_ERR_KEY_EXPIRED nor KRB5KDC_ERR_KEY_EXP available +#else /* old Heimdal releases have it with different name only in an enum: */ + {KRB5KDC_ERR_KEY_EXPIRED, NT_STATUS_PASSWORD_EXPIRED}, #endif {25, NT_STATUS_PASSWORD_EXPIRED}, /* FIXME: bug in heimdal 0.7 krb5_get_init_creds_password (Inappropriate ioctl for device (25)) */ {KRB5KDC_ERR_NULL_KEY, NT_STATUS_LOGON_FAILURE}, diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index a61df3c9bd..9be366dc29 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -311,9 +311,10 @@ WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli, { WERROR result; char *printername; - REGVAL_CTR *dsdriver_ctr, *dsspooler_ctr; + struct spoolss_PrinterEnumValues *info; + uint32_t count; uint32 i; - POLICY_HND pol; + struct policy_handle pol; if ((asprintf(&printername, "%s\\%s", cli->srv_name_slash, printer) == -1)) { DEBUG(3, ("Insufficient memory\n")); @@ -330,48 +331,64 @@ WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli, SAFE_FREE(printername); return result; } - - if ( !(dsdriver_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) ) { - SAFE_FREE(printername); - return WERR_NOMEM; - } - result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, dsdriver_ctr); + result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, + SPOOL_DSDRIVER_KEY, + 0, + &count, + &info); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", printername, win_errstr(result))); } else { - uint32 num_values = regval_ctr_numvals( dsdriver_ctr ); - /* Have the data we need now, so start building */ - for (i=0; i < num_values; i++) { - map_regval_to_ads(mem_ctx, mods, dsdriver_ctr->values[i]); + for (i=0; i < count; i++) { + REGISTRY_VALUE v; + DATA_BLOB blob; + + result = push_spoolss_PrinterData(mem_ctx, &blob, + info[i].type, + info[i].data); + if (W_ERROR_IS_OK(result)) { + fstrcpy(v.valuename, info[i].value_name); + v.type = info[i].type; + v.data_p = blob.data; + v.size = blob.length; + + map_regval_to_ads(mem_ctx, mods, &v); + } } } - - if ( !(dsspooler_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) ) { - SAFE_FREE(printername); - return WERR_NOMEM; - } - - result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, dsspooler_ctr); + result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, + SPOOL_DSSPOOLER_KEY, + 0, + &count, + &info); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", printername, win_errstr(result))); } else { - uint32 num_values = regval_ctr_numvals( dsspooler_ctr ); - - for (i=0; i<num_values; i++) { - map_regval_to_ads(mem_ctx, mods, dsspooler_ctr->values[i]); + for (i=0; i < count; i++) { + REGISTRY_VALUE v; + DATA_BLOB blob; + + result = push_spoolss_PrinterData(mem_ctx, &blob, + info[i].type, + info[i].data); + if (W_ERROR_IS_OK(result)) { + fstrcpy(v.valuename, info[i].value_name); + v.type = info[i].type; + v.data_p = blob.data; + v.size = blob.length; + + map_regval_to_ads(mem_ctx, mods, &v); + } } } - - ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer); - TALLOC_FREE( dsdriver_ctr ); - TALLOC_FREE( dsspooler_ctr ); + ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer); rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); SAFE_FREE(printername); diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index 117178f376..ccfd943a8d 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -680,7 +680,7 @@ static NTSTATUS libnet_join_lookup_dc_rpc(TALLOC_CTX *mem_ctx, struct cli_state **cli) { struct rpc_pipe_client *pipe_hnd = NULL; - POLICY_HND lsa_pol; + struct policy_handle lsa_pol; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; union lsa_PolicyInformation *info = NULL; @@ -750,7 +750,7 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, struct cli_state *cli) { struct rpc_pipe_client *pipe_hnd = NULL; - POLICY_HND sam_pol, domain_pol, user_pol; + struct policy_handle sam_pol, domain_pol, user_pol; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; char *acct_name; struct lsa_String lsa_acct_name; @@ -1132,7 +1132,7 @@ static NTSTATUS libnet_join_unjoindomain_rpc(TALLOC_CTX *mem_ctx, { struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_hnd = NULL; - POLICY_HND sam_pol, domain_pol, user_pol; + struct policy_handle sam_pol, domain_pol, user_pol; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; char *acct_name; uint32_t user_rid; diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ad11ee0ed4..ebb01c44a6 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -61,6 +61,7 @@ static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, { DATA_BLOB session_key = data_blob_null; DATA_BLOB lm_response = data_blob_null; + NTSTATUS status; fstring pword; char *p; @@ -129,7 +130,10 @@ static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); - fstrcpy(cli->user_name, user); + status = cli_set_username(cli, user); + if (!NT_STATUS_IS_OK(status)) { + return status; + } if (session_key.data) { /* Have plaintext orginal */ @@ -237,7 +241,10 @@ NTSTATUS cli_session_setup_guest_recv(struct async_req *req) cli->is_samba = True; } - fstrcpy(cli->user_name, ""); + status = cli_set_username(cli, ""); + if (!NT_STATUS_IS_OK(status)) { + return status; + } return NT_STATUS_OK; } @@ -289,6 +296,7 @@ static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, { uint32 capabilities = cli_session_setup_capabilities(cli); char *p; + NTSTATUS status; fstring lanman; fstr_sprintf( lanman, "Samba %s", samba_version_string()); @@ -349,8 +357,10 @@ static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, -1, STR_TERMINATE); p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE); - fstrcpy(cli->user_name, user); - + status = cli_set_username(cli, user); + if (!NT_STATUS_IS_OK(status)) { + return status; + } if (strstr(cli->server_type, "Samba")) { cli->is_samba = True; } @@ -379,6 +389,7 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, DATA_BLOB session_key = data_blob_null; NTSTATUS result; char *p; + bool ok; if (passlen == 0) { /* do nothing - guest login */ @@ -436,11 +447,7 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); #endif } -#ifdef LANMAN_ONLY - cli_simple_set_signing(cli, session_key, lm_response); -#else - cli_simple_set_signing(cli, session_key, nt_response); -#endif + cli_temp_set_signing(cli); } else { /* pre-encrypted password supplied. Only used for security=server, can't do @@ -492,6 +499,22 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, goto end; } +#ifdef LANMAN_ONLY + ok = cli_simple_set_signing(cli, session_key, lm_response); +#else + ok = cli_simple_set_signing(cli, session_key, nt_response); +#endif + if (ok) { + /* 'resign' the last message, so we get the right sequence numbers + for checking the first reply from the server */ + cli_calculate_sign_mac(cli, cli->outbuf); + + if (!cli_check_sign_mac(cli, cli->inbuf)) { + result = NT_STATUS_ACCESS_DENIED; + goto end; + } + } + /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -507,7 +530,10 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, cli->is_samba = True; } - fstrcpy(cli->user_name, user); + result = cli_set_username(cli, user); + if (!NT_STATUS_IS_OK(result)) { + goto end; + } if (session_key.data) { /* Have plaintext orginal */ @@ -885,6 +911,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, DATA_BLOB blob; const char *p = NULL; char *account = NULL; + NTSTATUS status; DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length)); @@ -923,7 +950,10 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, DEBUG(3,("got principal=%s\n", principal ? principal : "<null>")); - fstrcpy(cli->user_name, user); + status = cli_set_username(cli, user); + if (!NT_STATUS_IS_OK(status)) { + return ADS_ERROR_NT(status); + } #ifdef HAVE_KRB5 /* If password is set we reauthenticate to kerberos server @@ -1284,10 +1314,17 @@ struct async_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx, return result; access_denied: - result = async_req_new(mem_ctx); - if (async_post_ntstatus(result, ev, NT_STATUS_ACCESS_DENIED)) { - return result; + { + struct cli_request *state; + if (!async_req_setup(mem_ctx, &result, &state, + struct cli_request)) { + goto fail; + } + if (async_post_ntstatus(result, ev, NT_STATUS_ACCESS_DENIED)) { + return result; + } } + fail: TALLOC_FREE(result); return NULL; } @@ -1748,15 +1785,20 @@ bool cli_session_request(struct cli_state *cli, return(True); } -static void smb_sock_connected(struct async_req *req) +struct fd_struct { + int fd; +}; + +static void smb_sock_connected(struct tevent_req *req) { - int *pfd = (int *)req->async.priv; + struct fd_struct *pfd = tevent_req_callback_data( + req, struct fd_struct); int fd; NTSTATUS status; status = open_socket_out_defer_recv(req, &fd); if (NT_STATUS_IS_OK(status)) { - *pfd = fd; + pfd->fd = fd; } } @@ -1764,10 +1806,9 @@ static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss, uint16_t *port, int timeout, int *pfd) { struct event_context *ev; - struct async_req *r139, *r445; - int fd139 = -1; - int fd445 = -1; - NTSTATUS status; + struct tevent_req *r139, *r445; + struct fd_struct *fd139, *fd445; + NTSTATUS status = NT_STATUS_NO_MEMORY; if (*port != 0) { return open_socket_out(pss, *port, timeout, pfd); @@ -1778,43 +1819,54 @@ static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss, return NT_STATUS_NO_MEMORY; } + fd139 = talloc(ev, struct fd_struct); + if (fd139 == NULL) { + goto done; + } + fd139->fd = -1; + + fd445 = talloc(ev, struct fd_struct); + if (fd445 == NULL) { + goto done; + } + fd445->fd = -1; + r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0), pss, 445, timeout); r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000), pss, 139, timeout); if ((r445 == NULL) || (r139 == NULL)) { - status = NT_STATUS_NO_MEMORY; goto done; } - r445->async.fn = smb_sock_connected; - r445->async.priv = &fd445; - r139->async.fn = smb_sock_connected; - r139->async.priv = &fd139; + tevent_req_set_callback(r445, smb_sock_connected, fd445); + tevent_req_set_callback(r139, smb_sock_connected, fd139); - while ((fd139 == -1) && (r139->state < ASYNC_REQ_DONE) - && (fd445 == -1) && (r445->state < ASYNC_REQ_DONE)) { + while ((fd139->fd == -1) + && tevent_req_is_in_progress(r139) + && (fd445->fd == -1) + && tevent_req_is_in_progress(r445)) { event_loop_once(ev); } - if ((fd139 != -1) && (fd445 != -1)) { - close(fd139); - fd139 = -1; + if ((fd139->fd != -1) && (fd445->fd != -1)) { + close(fd139->fd); + fd139->fd = -1; } - if (fd445 != -1) { + if (fd445->fd != -1) { *port = 445; - *pfd = fd445; + *pfd = fd445->fd; status = NT_STATUS_OK; goto done; } - if (fd139 != -1) { + if (fd139->fd != -1) { *port = 139; - *pfd = fd139; + *pfd = fd139->fd; status = NT_STATUS_OK; goto done; } - status = open_socket_out_defer_recv(r445, &fd445); + status = open_socket_out_defer_recv(r445, &fd445->fd); done: TALLOC_FREE(ev); return status; @@ -1936,7 +1988,7 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli, if (!my_name) my_name = global_myname(); - if (!(cli = cli_initialise())) { + if (!(cli = cli_initialise_ex(signing_state))) { return NT_STATUS_NO_MEMORY; } @@ -1984,8 +2036,6 @@ again: return NT_STATUS_BAD_NETWORK_NAME; } - cli_setup_signing_state(cli, signing_state); - if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) cli->use_spnego = False; else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) @@ -2083,7 +2133,11 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, } } - cli_init_creds(cli, user, domain, password); + nt_status = cli_init_creds(cli, user, domain, password); + if (!NT_STATUS_IS_OK(nt_status)) { + cli_shutdown(cli); + return nt_status; + } *output_cli = cli; return NT_STATUS_OK; diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index e642f169f9..430807eb7f 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -3,7 +3,7 @@ client connect/disconnect routines Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) Gerald (Jerry) Carter 2004 - Copyright (C) Jeremy Allison 2007 + Copyright (C) Jeremy Allison 2007-2009 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 @@ -32,25 +32,6 @@ as a separator when looking at the pathname part.... JRA. ********************************************************************/ -struct client_connection { - struct client_connection *prev, *next; - struct cli_state *cli; - char *mount; -}; - -static struct cm_cred_struct { - char *username; - char *password; - bool got_pass; - bool use_kerberos; - bool fallback_after_kerberos; - int signing_state; -} cm_creds; - -static void cm_set_password(const char *newpass); - -static struct client_connection *connections; - static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, struct cli_state *cli, const char *sharename, @@ -96,7 +77,7 @@ NTSTATUS cli_cm_force_encryption(struct cli_state *c, return status; } - + /******************************************************************** Return a connection to a server. ********************************************************************/ @@ -104,6 +85,7 @@ NTSTATUS cli_cm_force_encryption(struct cli_state *c, static struct cli_state *do_connect(TALLOC_CTX *ctx, const char *server, const char *share, + const struct user_auth_info *auth_info, bool show_sessetup, bool force_encrypt, int max_protocol, @@ -151,7 +133,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, zero_sockaddr(&ss); /* have to open a new connection */ - if (!(c=cli_initialise())) { + if (!(c=cli_initialise_ex(get_cmdline_auth_info_signing_state(auth_info)))) { d_printf("Connection to %s failed\n", server_n); if (c) { cli_shutdown(c); @@ -175,9 +157,9 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, max_protocol = PROTOCOL_NT1; } c->protocol = max_protocol; - c->use_kerberos = cm_creds.use_kerberos; - c->fallback_after_kerberos = cm_creds.fallback_after_kerberos; - cli_setup_signing_state(c, cm_creds.signing_state); + c->use_kerberos = get_cmdline_auth_info_use_kerberos(auth_info); + c->fallback_after_kerberos = + get_cmdline_auth_info_fallback_after_kerberos(auth_info); if (!cli_session_request(c, &calling, &called)) { char *p; @@ -207,20 +189,8 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, return NULL; } - if (!cm_creds.got_pass && !cm_creds.use_kerberos) { - char *label = NULL; - char *pass; - label = talloc_asprintf(ctx, "Enter %s's password: ", - cm_creds.username); - pass = getpass(label); - if (pass) { - cm_set_password(pass); - } - TALLOC_FREE(label); - } - - username = cm_creds.username ? cm_creds.username : ""; - password = cm_creds.password ? cm_creds.password : ""; + username = get_cmdline_auth_info_username(auth_info); + password = get_cmdline_auth_info_password(auth_info); if (!NT_STATUS_IS_OK(cli_session_setup(c, username, password, strlen(password), @@ -228,8 +198,9 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, lp_workgroup()))) { /* If a password was not supplied then * try again with a null username. */ - if (password[0] || !username[0] || cm_creds.use_kerberos || - !NT_STATUS_IS_OK(cli_session_setup(c, "", + if (password[0] || !username[0] || + get_cmdline_auth_info_use_kerberos(auth_info) || + !NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0, "", 0, lp_workgroup()))) { @@ -268,7 +239,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, lp_workgroup())) { cli_shutdown(c); return do_connect(ctx, newserver, - newshare, false, + newshare, auth_info, false, force_encrypt, max_protocol, port, name_type); } @@ -302,111 +273,90 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, /**************************************************************************** ****************************************************************************/ -static void cli_cm_set_mntpoint(struct cli_state *c, const char *mnt) +static void cli_set_mntpoint(struct cli_state *cli, const char *mnt) { - struct client_connection *p; - int i; - - for (p=connections,i=0; p; p=p->next,i++) { - if (strequal(p->cli->desthost, c->desthost) && - strequal(p->cli->share, c->share)) { - break; - } - } - - if (p) { - char *name = clean_name(NULL, mnt); - if (!name) { - return; - } - TALLOC_FREE(p->mount); - p->mount = talloc_strdup(p, name); - TALLOC_FREE(name); - } -} - -/**************************************************************************** -****************************************************************************/ - -const char *cli_cm_get_mntpoint(struct cli_state *c) -{ - struct client_connection *p; - int i; - - for (p=connections,i=0; p; p=p->next,i++) { - if (strequal(p->cli->desthost, c->desthost) && - strequal(p->cli->share, c->share)) { - break; - } - } - - if (p) { - return p->mount; + char *name = clean_name(NULL, mnt); + if (!name) { + return; } - return NULL; + TALLOC_FREE(cli->dfs_mountpoint); + cli->dfs_mountpoint = talloc_strdup(cli, name); + TALLOC_FREE(name); } /******************************************************************** - Add a new connection to the list + Add a new connection to the list. + referring_cli == NULL means a new initial connection. ********************************************************************/ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx, struct cli_state *referring_cli, const char *server, const char *share, + const struct user_auth_info *auth_info, bool show_hdr, bool force_encrypt, int max_protocol, int port, int name_type) { - struct client_connection *node; - - /* NB This must be the null context here... JRA. */ - node = TALLOC_ZERO_ARRAY(NULL, struct client_connection, 1); - if (!node) { - return NULL; - } + struct cli_state *cli; - node->cli = do_connect(ctx, server, share, + cli = do_connect(ctx, server, share, + auth_info, show_hdr, force_encrypt, max_protocol, port, name_type); - if ( !node->cli ) { - TALLOC_FREE( node ); + if (!cli ) { return NULL; } - DLIST_ADD( connections, node ); - - cli_cm_set_mntpoint(node->cli, ""); + /* Enter into the list. */ + if (referring_cli) { + DLIST_ADD_END(referring_cli, cli, struct cli_state *); + } if (referring_cli && referring_cli->posix_capabilities) { uint16 major, minor; uint32 caplow, caphigh; - if (cli_unix_extensions_version(node->cli, &major, + if (cli_unix_extensions_version(cli, &major, &minor, &caplow, &caphigh)) { - cli_set_unix_extensions_capabilities(node->cli, + cli_set_unix_extensions_capabilities(cli, major, minor, caplow, caphigh); } } - return node->cli; + return cli; } /******************************************************************** - Return a connection to a server. + Return a connection to a server on a particular share. ********************************************************************/ -static struct cli_state *cli_cm_find(const char *server, const char *share) +static struct cli_state *cli_cm_find(struct cli_state *cli, + const char *server, + const char *share) { - struct client_connection *p; + struct cli_state *p; - for (p=connections; p; p=p->next) { - if ( strequal(server, p->cli->desthost) && - strequal(share,p->cli->share)) { - return p->cli; + if (cli == NULL) { + return NULL; + } + + /* Search to the start of the list. */ + for (p = cli; p; p = p->prev) { + if (strequal(server, p->desthost) && + strequal(share,p->share)) { + return p; + } + } + + /* Search to the end of the list. */ + for (p = cli->next; p; p = p->next) { + if (strequal(server, p->desthost) && + strequal(share,p->share)) { + return p; } } @@ -414,82 +364,68 @@ static struct cli_state *cli_cm_find(const char *server, const char *share) } /**************************************************************************** - Open a client connection to a \\server\share. Set's the current *cli - global variable as a side-effect (but only if the connection is successful). + Open a client connection to a \\server\share. ****************************************************************************/ struct cli_state *cli_cm_open(TALLOC_CTX *ctx, struct cli_state *referring_cli, const char *server, const char *share, + const struct user_auth_info *auth_info, bool show_hdr, bool force_encrypt, int max_protocol, int port, int name_type) { - struct cli_state *c; + /* Try to reuse an existing connection in this list. */ + struct cli_state *c = cli_cm_find(referring_cli, server, share); - /* try to reuse an existing connection */ - - c = cli_cm_find(server, share); - if (!c) { - c = cli_cm_connect(ctx, referring_cli, - server, share, show_hdr, force_encrypt, - max_protocol, port, name_type); + if (c) { + return c; } - return c; -} - -/**************************************************************************** -****************************************************************************/ - -void cli_cm_shutdown(void) -{ - struct client_connection *p, *x; - - for (p=connections; p;) { - cli_shutdown(p->cli); - x = p; - p = p->next; - - TALLOC_FREE(x); + if (auth_info == NULL) { + /* Can't do a new connection + * without auth info. */ + d_printf("cli_cm_open() Unable to open connection [\\%s\\%s] " + "without auth info\n", + server, share ); + return NULL; } - connections = NULL; - return; + return cli_cm_connect(ctx, + referring_cli, + server, + share, + auth_info, + show_hdr, + force_encrypt, + max_protocol, + port, + name_type); } /**************************************************************************** ****************************************************************************/ -void cli_cm_display(void) +void cli_cm_display(const struct cli_state *cli) { - struct client_connection *p; int i; - for ( p=connections,i=0; p; p=p->next,i++ ) { + for (i=0; cli; cli = cli->next,i++ ) { d_printf("%d:\tserver=%s, share=%s\n", - i, p->cli->desthost, p->cli->share ); + i, cli->desthost, cli->share ); } } /**************************************************************************** ****************************************************************************/ -static void cm_set_password(const char *newpass) -{ - SAFE_FREE(cm_creds.password); - cm_creds.password = SMB_STRDUP(newpass); - if (cm_creds.password) { - cm_creds.got_pass = true; - } -} - /**************************************************************************** ****************************************************************************/ +#if 0 void cli_cm_set_credentials(struct user_auth_info *auth_info) { SAFE_FREE(cm_creds.username); @@ -504,51 +440,7 @@ void cli_cm_set_credentials(struct user_auth_info *auth_info) cm_creds.fallback_after_kerberos = false; cm_creds.signing_state = get_cmdline_auth_info_signing_state(auth_info); } - -/**************************************************************************** -****************************************************************************/ - -void cli_cm_set_signing_state(int state) -{ - cm_creds.signing_state = state; -} - -/**************************************************************************** -****************************************************************************/ - -void cli_cm_set_username(const char *username) -{ - SAFE_FREE(cm_creds.username); - cm_creds.username = SMB_STRDUP(username); -} - -/**************************************************************************** -****************************************************************************/ - -void cli_cm_set_password(const char *newpass) -{ - SAFE_FREE(cm_creds.password); - cm_creds.password = SMB_STRDUP(newpass); - if (cm_creds.password) { - cm_creds.got_pass = true; - } -} - -/**************************************************************************** -****************************************************************************/ - -void cli_cm_set_use_kerberos(void) -{ - cm_creds.use_kerberos = true; -} - -/**************************************************************************** -****************************************************************************/ - -void cli_cm_set_fallback_after_kerberos(void) -{ - cm_creds.fallback_after_kerberos = true; -} +#endif /********************************************************************** split a dfs path into the server, share name, and extrapath components @@ -659,13 +551,23 @@ static char *cli_dfs_make_full_path(TALLOC_CTX *ctx, struct cli_state *cli, const char *dir) { + char path_sep = '\\'; + /* Ensure the extrapath doesn't start with a separator. */ while (IS_DIRECTORY_SEP(*dir)) { dir++; } - return talloc_asprintf(ctx, "\\%s\\%s\\%s", - cli->desthost, cli->share, dir); + if (cli->posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP) { + path_sep = '/'; + } + return talloc_asprintf(ctx, "%c%s%c%s%c%s", + path_sep, + cli->desthost, + path_sep, + cli->share, + path_sep, + dir); } /******************************************************************** @@ -818,6 +720,7 @@ bool cli_dfs_get_referral(TALLOC_CTX *ctx, bool cli_resolve_path(TALLOC_CTX *ctx, const char *mountpt, + const struct user_auth_info *dfs_auth_info, struct cli_state *rootcli, const char *path, struct cli_state **targetcli, @@ -898,13 +801,16 @@ bool cli_resolve_path(TALLOC_CTX *ctx, /* Check for the referral. */ - if (!(cli_ipc = cli_cm_open(ctx, rootcli, - rootcli->desthost, - "IPC$", false, - (rootcli->trans_enc_state != NULL), - rootcli->protocol, - 0, - 0x20))) { + if (!(cli_ipc = cli_cm_open(ctx, + rootcli, + rootcli->desthost, + "IPC$", + dfs_auth_info, + false, + (rootcli->trans_enc_state != NULL), + rootcli->protocol, + 0, + 0x20))) { return false; } @@ -948,6 +854,7 @@ bool cli_resolve_path(TALLOC_CTX *ctx, if ((*targetcli = cli_cm_open(ctx, rootcli, server, share, + dfs_auth_info, false, (rootcli->trans_enc_state != NULL), rootcli->protocol, @@ -999,7 +906,7 @@ bool cli_resolve_path(TALLOC_CTX *ctx, return false; } - cli_cm_set_mntpoint(*targetcli, newmount); + cli_set_mntpoint(*targetcli, newmount); /* Check for another dfs referral, note that we are not checking for loops here. */ @@ -1007,6 +914,7 @@ bool cli_resolve_path(TALLOC_CTX *ctx, if (!strequal(*pp_targetpath, "\\") && !strequal(*pp_targetpath, "/")) { if (cli_resolve_path(ctx, newmount, + dfs_auth_info, *targetcli, *pp_targetpath, &newcli, diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0382ef5fae..c1ba4e5c4f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -409,49 +409,76 @@ void cli_setup_bcc(struct cli_state *cli, void *p) } /**************************************************************************** - Initialise credentials of a client structure. + Initialize Domain, user or password. ****************************************************************************/ -void cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password) +NTSTATUS cli_set_domain(struct cli_state *cli, const char *domain) { - fstrcpy(cli->domain, domain); - fstrcpy(cli->user_name, username); - pwd_set_cleartext(&cli->pwd, password); - if (!*username) { - cli->pwd.null_pwd = true; + TALLOC_FREE(cli->domain); + cli->domain = talloc_strdup(cli, domain ? domain : ""); + if (cli->domain == NULL) { + return NT_STATUS_NO_MEMORY; } + return NT_STATUS_OK; +} - DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain)); +NTSTATUS cli_set_username(struct cli_state *cli, const char *username) +{ + TALLOC_FREE(cli->user_name); + cli->user_name = talloc_strdup(cli, username ? username : ""); + if (cli->user_name == NULL) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +NTSTATUS cli_set_password(struct cli_state *cli, const char *password) +{ + TALLOC_FREE(cli->password); + + /* Password can be NULL. */ + if (password) { + cli->password = talloc_strdup(cli, password); + if (cli->password == NULL) { + return NT_STATUS_NO_MEMORY; + } + } else { + /* Use zero NTLMSSP hashes and session key. */ + cli->password = NULL; + } + + return NT_STATUS_OK; } /**************************************************************************** - Set the signing state (used from the command line). + Initialise credentials of a client structure. ****************************************************************************/ -void cli_setup_signing_state(struct cli_state *cli, int signing_state) +NTSTATUS cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password) { - if (signing_state == Undefined) - return; - - if (signing_state == false) { - cli->sign_info.allow_smb_signing = false; - cli->sign_info.mandatory_signing = false; - return; + NTSTATUS status = cli_set_username(cli, username); + if (!NT_STATUS_IS_OK(status)) { + return status; } + status = cli_set_domain(cli, domain); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain)); - cli->sign_info.allow_smb_signing = true; - - if (signing_state == Required) - cli->sign_info.mandatory_signing = true; + return cli_set_password(cli, password); } /**************************************************************************** - Initialise a client structure. Always returns a malloc'ed struct. + Initialise a client structure. Always returns a talloc'ed struct. + Set the signing state (used from the command line). ****************************************************************************/ -struct cli_state *cli_initialise(void) +struct cli_state *cli_initialise_ex(int signing_state) { struct cli_state *cli = NULL; + bool allow_smb_signing = false; + bool mandatory_signing = false; /* Check the effective uid - make sure we are not setuid */ if (is_setuid_root()) { @@ -464,6 +491,10 @@ struct cli_state *cli_initialise(void) return NULL; } + cli->dfs_mountpoint = talloc_strdup(cli, ""); + if (!cli->dfs_mountpoint) { + goto error; + } cli->port = 0; cli->fd = -1; cli->cnum = -1; @@ -490,12 +521,27 @@ struct cli_state *cli_initialise(void) if (getenv("CLI_FORCE_DOSERR")) cli->force_dos_errors = true; - if (lp_client_signing()) - cli->sign_info.allow_smb_signing = true; + if (lp_client_signing()) { + allow_smb_signing = true; + } + + if (lp_client_signing() == Required) { + mandatory_signing = true; + } + + if (signing_state != Undefined) { + allow_smb_signing = true; + } + + if (signing_state == false) { + allow_smb_signing = false; + mandatory_signing = false; + } + + if (signing_state == Required) { + mandatory_signing = true; + } - if (lp_client_signing() == Required) - cli->sign_info.mandatory_signing = true; - if (!cli->outbuf || !cli->inbuf) goto error; @@ -510,6 +556,8 @@ struct cli_state *cli_initialise(void) #endif /* initialise signing */ + cli->sign_info.allow_smb_signing = allow_smb_signing; + cli->sign_info.mandatory_signing = mandatory_signing; cli_null_set_signing(cli); cli->initialised = 1; @@ -522,10 +570,15 @@ struct cli_state *cli_initialise(void) SAFE_FREE(cli->inbuf); SAFE_FREE(cli->outbuf); - SAFE_FREE(cli); + TALLOC_FREE(cli); return NULL; } +struct cli_state *cli_initialise(void) +{ + return cli_initialise_ex(Undefined); +} + /**************************************************************************** Close all pipes open on this session. ****************************************************************************/ @@ -546,6 +599,27 @@ void cli_nt_pipes_close(struct cli_state *cli) void cli_shutdown(struct cli_state *cli) { + if (cli->prev == NULL) { + /* + * Possible head of a DFS list, + * shutdown all subsidiary DFS + * connections. + */ + struct cli_state *p, *next; + + for (p = cli->next; p; p = next) { + next = p->next; + cli_shutdown(p); + } + } else { + /* + * We're a subsidiary connection. + * Just remove ourselves from the + * DFS list. + */ + DLIST_REMOVE(cli->prev, cli); + } + cli_nt_pipes_close(cli); /* diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index e604725493..a84a64794b 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -244,7 +244,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, unsigned int param_len, data_len; uint16 setup; char *param; - const char *mnt; uint32 resume_key = 0; TALLOC_CTX *frame = talloc_stackframe(); DATA_BLOB last_name_raw = data_blob(NULL, 0); @@ -457,8 +456,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, First = False; } - mnt = cli_cm_get_mntpoint( cli ); - /* see if the server disconnected or the connection otherwise failed */ if (cli_is_error(cli)) { total_received = -1; @@ -479,7 +476,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, info_level)); break; } - fn(mnt,&finfo, Mask, state); + fn(cli->dfs_mountpoint, &finfo, Mask, state); } } diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 9d17ff86a5..f2f447b4c9 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -915,9 +915,15 @@ static NTSTATUS cli_writeall_recv(struct async_req *req) return async_req_simple_recv_ntstatus(req); } -struct cli_push_state { - struct async_req *req; +struct cli_push_write_state { + struct async_req *req;/* This is the main request! Not the subreq */ + uint32_t idx; + off_t ofs; + uint8_t *buf; + size_t size; +}; +struct cli_push_state { struct event_context *ev; struct cli_state *cli; uint16_t fnum; @@ -928,24 +934,70 @@ struct cli_push_state { size_t (*source)(uint8_t *buf, size_t n, void *priv); void *priv; - size_t chunk_size; - - size_t sent; bool eof; + size_t chunk_size; + off_t next_offset; + /* * Outstanding requests */ - int num_reqs; - struct async_req **reqs; - - int pending; - - uint8_t *buf; + uint32_t pending; + uint32_t num_reqs; + struct cli_push_write_state **reqs; }; static void cli_push_written(struct async_req *req); +static bool cli_push_write_setup(struct async_req *req, + struct cli_push_state *state, + uint32_t idx) +{ + struct cli_push_write_state *substate; + struct async_req *subreq; + + substate = talloc(state->reqs, struct cli_push_write_state); + if (!substate) { + return false; + } + substate->req = req; + substate->idx = idx; + substate->ofs = state->next_offset; + substate->buf = talloc_array(substate, uint8_t, state->chunk_size); + if (!substate->buf) { + talloc_free(substate); + return false; + } + substate->size = state->source(substate->buf, + state->chunk_size, + state->priv); + if (substate->size == 0) { + state->eof = true; + /* nothing to send */ + talloc_free(substate); + return true; + } + + subreq = cli_writeall_send(substate, + state->ev, state->cli, + state->fnum, state->mode, + substate->buf, + substate->ofs, + substate->size); + if (!subreq) { + talloc_free(substate); + return false; + } + subreq->async.fn = cli_push_written; + subreq->async.priv = substate; + + state->reqs[idx] = substate; + state->pending += 1; + state->next_offset += substate->size; + + return true; +} + struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct cli_state *cli, uint16_t fnum, uint16_t mode, @@ -954,16 +1006,14 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev, void *priv), void *priv) { - struct async_req *result; + struct async_req *req; struct cli_push_state *state; - int i; + uint32_t i; - if (!async_req_setup(mem_ctx, &result, &state, + if (!async_req_setup(mem_ctx, &req, &state, struct cli_push_state)) { return NULL; } - state->req = result; - state->cli = cli; state->ev = ev; state->fnum = fnum; @@ -972,124 +1022,83 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev, state->source = source; state->priv = priv; state->eof = false; - state->sent = 0; state->pending = 0; + state->next_offset = start_offset; state->chunk_size = cli_write_max_bufsize(cli, mode); - state->num_reqs = MAX(window_size/state->chunk_size, 1); + if (window_size == 0) { + window_size = cli->max_mux * state->chunk_size; + } + state->num_reqs = window_size/state->chunk_size; + if ((window_size % state->chunk_size) > 0) { + state->num_reqs += 1; + } state->num_reqs = MIN(state->num_reqs, cli->max_mux); + state->num_reqs = MAX(state->num_reqs, 1); - state->reqs = TALLOC_ZERO_ARRAY(state, struct async_req *, + state->reqs = TALLOC_ZERO_ARRAY(state, struct cli_push_write_state *, state->num_reqs); if (state->reqs == NULL) { goto failed; } - state->buf = TALLOC_ARRAY( - state, uint8_t, state->chunk_size * state->num_reqs); - if (state->buf == NULL) { - goto failed; - } - for (i=0; i<state->num_reqs; i++) { - size_t to_write; - uint8_t *buf = state->buf + i*state->chunk_size; - - to_write = state->source(buf, state->chunk_size, state->priv); - if (to_write == 0) { - state->eof = true; - break; - } - - state->reqs[i] = cli_writeall_send( - state->reqs, state->ev, state->cli, state->fnum, - state->mode, buf, state->start_offset + state->sent, - to_write); - if (state->reqs[i] == NULL) { + if (!cli_push_write_setup(req, state, i)) { goto failed; } - state->reqs[i]->async.fn = cli_push_written; - state->reqs[i]->async.priv = state; - - state->sent += to_write; - state->pending += 1; + if (state->eof) { + break; + } } - if (i == 0) { - if (!async_post_ntstatus(result, ev, NT_STATUS_OK)) { + if (state->pending == 0) { + if (!async_post_ntstatus(req, ev, NT_STATUS_OK)) { goto failed; } - return result; + return req; } - return result; + return req; failed: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } -static void cli_push_written(struct async_req *req) +static void cli_push_written(struct async_req *subreq) { + struct cli_push_write_state *substate = talloc_get_type_abort( + subreq->async.priv, struct cli_push_write_state); + struct async_req *req = substate->req; struct cli_push_state *state = talloc_get_type_abort( - req->async.priv, struct cli_push_state); + req->private_data, struct cli_push_state); NTSTATUS status; - int i; - uint8_t *buf; - size_t to_write; - - for (i=0; i<state->num_reqs; i++) { - if (state->reqs[i] == req) { - break; - } - } - - if (i == state->num_reqs) { - async_req_nterror(state->req, NT_STATUS_INTERNAL_ERROR); - return; - } - - status = cli_writeall_recv(req); - TALLOC_FREE(state->reqs[i]); - req = NULL; - if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(state->req, status); - return; - } + uint32_t idx = substate->idx; + state->reqs[idx] = NULL; state->pending -= 1; - if (state->pending == 0) { - async_req_done(state->req); - return; - } - if (state->eof) { + status = cli_writeall_recv(subreq); + TALLOC_FREE(subreq); + TALLOC_FREE(substate); + if (!NT_STATUS_IS_OK(status)) { + async_req_nterror(req, status); return; } - buf = state->buf + i * state->chunk_size; - - to_write = state->source(buf, state->chunk_size, state->priv); - if (to_write == 0) { - state->eof = true; - return; + if (!state->eof) { + if (!cli_push_write_setup(req, state, idx)) { + async_req_nomem(NULL, req); + return; + } } - state->reqs[i] = cli_writeall_send( - state->reqs, state->ev, state->cli, state->fnum, - state->mode, buf, state->start_offset + state->sent, to_write); - if (state->reqs[i] == NULL) { - async_req_nterror(state->req, NT_STATUS_NO_MEMORY); + if (state->pending == 0) { + async_req_done(req); return; } - - state->reqs[i]->async.fn = cli_push_written; - state->reqs[i]->async.priv = state; - - state->sent += to_write; - state->pending += 1; } NTSTATUS cli_push_recv(struct async_req *req) diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 69e2be3af7..0266c0307e 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -112,9 +112,6 @@ bool cli_send_trans(struct cli_state *cli, int trans, this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); - client_set_trans_sign_state_off(cli, mid); - client_set_trans_sign_state_on(cli, mid); - cli_set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); SCVAL(cli->outbuf,smb_com,(trans==SMBtrans ? SMBtranss : SMBtranss2)); @@ -138,20 +135,14 @@ bool cli_send_trans(struct cli_state *cli, int trans, memcpy(outdata,data+tot_data,this_ldata); cli_setup_bcc(cli, outdata+this_ldata); - /* - * Save the mid we're using. We need this for finding - * signing replies. - */ - mid = cli->mid; - show_msg(cli->outbuf); + + client_set_trans_sign_state_off(cli, mid); + cli->mid = mid; if (!cli_send_smb(cli)) { - client_set_trans_sign_state_off(cli, mid); return False; } - - /* Ensure we use the same mid for the secondaries. */ - cli->mid = mid; + client_set_trans_sign_state_on(cli, mid); tot_data += this_ldata; tot_param += this_lparam; @@ -461,21 +452,14 @@ bool cli_send_nt_trans(struct cli_state *cli, memcpy(outdata,data+tot_data,this_ldata); cli_setup_bcc(cli, outdata+this_ldata); - /* - * Save the mid we're using. We need this for finding - * signing replies. - */ - mid = cli->mid; - show_msg(cli->outbuf); + client_set_trans_sign_state_off(cli, mid); + cli->mid = mid; if (!cli_send_smb(cli)) { - client_set_trans_sign_state_off(cli, mid); return False; } - - /* Ensure we use the same mid for the secondaries. */ - cli->mid = mid; + client_set_trans_sign_state_on(cli, mid); tot_data += this_ldata; tot_param += this_lparam; @@ -747,6 +731,7 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx, uint16_t this_data = 0; uint32_t useable_space; uint8_t cmd; + uint8_t pad[3]; frame = talloc_stackframe(); @@ -759,9 +744,16 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx, param_offset = smb_size - 4; + bytes = TALLOC_ARRAY(talloc_tos(), uint8_t, 0); /* padding */ + if (bytes == NULL) { + goto fail; + } + switch (cmd) { case SMBtrans: - bytes = TALLOC_ZERO_P(talloc_tos(), uint8_t); /* padding */ + pad[0] = 0; + bytes = (uint8_t *)talloc_append_blob(talloc_tos(), bytes, + data_blob_const(pad, 1)); if (bytes == NULL) { goto fail; } @@ -775,13 +767,14 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx, param_offset += talloc_get_size(bytes); break; case SMBtrans2: - bytes = TALLOC_ARRAY(talloc_tos(), uint8_t, 3); /* padding */ + pad[0] = 0; + pad[1] = 'D'; /* Copy this from "old" 3.0 behaviour */ + pad[2] = ' '; + bytes = (uint8_t *)talloc_append_blob(talloc_tos(), bytes, + data_blob_const(pad, 3)); if (bytes == NULL) { goto fail; } - bytes[0] = 0; - bytes[1] = 'D'; /* Copy this from "old" 3.0 behaviour */ - bytes[2] = ' '; wct = 14 + state->num_setup; param_offset += talloc_get_size(bytes); break; diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index 4c12d18ab7..f09e9c6287 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -203,6 +203,9 @@ smbc_free_context(SMBCCTX *context, DEBUG(3, ("Context %p successfully freed\n", context)); + /* Free any DFS auth context. */ + TALLOC_FREE(context->internal->auth_info); + SAFE_FREE(context->internal); SAFE_FREE(context); @@ -625,32 +628,20 @@ smbc_version(void) return samba_version_string(); } - /* * Set the credentials so DFS will work when following referrals. + * This function is broken and must be removed. No SMBCCTX arg... + * JRA. */ + void smbc_set_credentials(const char *workgroup, - const char *user, - const char *password, - smbc_bool use_kerberos, - const char *signing_state) + const char *user, + const char *password, + smbc_bool use_kerberos, + const char *signing_state) { - struct user_auth_info *auth_info; - - auth_info = user_auth_info_init(talloc_tos()); - if (auth_info == NULL) { - return; - } - set_cmdline_auth_info_username(auth_info, user); - set_cmdline_auth_info_password(auth_info, password); - set_cmdline_auth_info_use_kerberos(auth_info, use_kerberos); - if (! set_cmdline_auth_info_signing_state(auth_info, signing_state)) { - DEBUG(0, ("Invalid signing state: %s", signing_state)); - } - set_global_myworkgroup(workgroup); - cli_cm_set_credentials(auth_info); - TALLOC_FREE(auth_info); + d_printf("smbc_set_credentials is obsolete. Replace with smbc_set_credentials_with_fallback().\n"); } void smbc_set_credentials_with_fallback(SMBCCTX *context, @@ -660,7 +651,11 @@ void smbc_set_credentials_with_fallback(SMBCCTX *context, { smbc_bool use_kerberos = false; const char *signing_state = "off"; - + struct user_auth_info *auth_info = user_auth_info_init(NULL); + + if (auth_info) { + } + if (! context || ! workgroup || ! *workgroup || ! user || ! *user || @@ -669,6 +664,13 @@ void smbc_set_credentials_with_fallback(SMBCCTX *context, return; } + auth_info = user_auth_info_init(NULL); + + if (auth_info) { + DEBUG(0, ("smbc_set_credentials_with_fallback: allocation fail\n")); + return; + } + if (smbc_getOptionUseKerberos(context)) { use_kerberos = True; } @@ -681,10 +683,15 @@ void smbc_set_credentials_with_fallback(SMBCCTX *context, signing_state = "force"; } - smbc_set_credentials(workgroup, user, password, - use_kerberos, signing_state); + set_cmdline_auth_info_username(auth_info, user); + set_cmdline_auth_info_password(auth_info, password); + set_cmdline_auth_info_use_kerberos(auth_info, use_kerberos); + set_cmdline_auth_info_signing_state(auth_info, signing_state); + set_cmdline_auth_info_fallback_after_kerberos(auth_info, + smbc_getOptionFallbackAfterKerberos(context)); + set_global_myworkgroup(workgroup); - if (smbc_getOptionFallbackAfterKerberos(context)) { - cli_cm_set_fallback_after_kerberos(); - } + TALLOC_FREE(context->internal->auth_info); + + context->internal->auth_info = auth_info; } diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index 56661af70b..2255db6617 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -770,8 +770,9 @@ SMBC_opendir_ctx(SMBCCTX *context, return NULL; } - if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { + if (!cli_resolve_path(frame, "", context->internal->auth_info, + srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); if (dir) { SAFE_FREE(dir->fname); @@ -1166,8 +1167,9 @@ SMBC_mkdir_ctx(SMBCCTX *context, } /*d_printf(">>>mkdir: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { + if (!cli_resolve_path(frame, "", context->internal->auth_info, + srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; @@ -1272,8 +1274,9 @@ SMBC_rmdir_ctx(SMBCCTX *context, } /*d_printf(">>>rmdir: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { + if (!cli_resolve_path(frame, "", context->internal->auth_info, + srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; @@ -1554,8 +1557,9 @@ SMBC_chmod_ctx(SMBCCTX *context, } /*d_printf(">>>unlink: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { + if (!cli_resolve_path(frame, "", context->internal->auth_info, + srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; @@ -1745,8 +1749,9 @@ SMBC_unlink_ctx(SMBCCTX *context, } /*d_printf(">>>unlink: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { + if (!cli_resolve_path(frame, "", context->internal->auth_info, + srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; @@ -1917,8 +1922,10 @@ SMBC_rename_ctx(SMBCCTX *ocontext, password1); /*d_printf(">>>rename: resolving %s\n", path1);*/ - if (!cli_resolve_path(frame, "", srv->cli, path1, - &targetcli1, &targetpath1)) { + if (!cli_resolve_path(frame, "", ocontext->internal->auth_info, + srv->cli, + path1, + &targetcli1, &targetpath1)) { d_printf("Could not resolve %s\n", path1); TALLOC_FREE(frame); return -1; @@ -1932,8 +1939,10 @@ SMBC_rename_ctx(SMBCCTX *ocontext, /*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/ /*d_printf(">>>rename: resolving %s\n", path2);*/ - if (!cli_resolve_path(frame, "", srv->cli, path2, - &targetcli2, &targetpath2)) { + if (!cli_resolve_path(frame, "", ncontext->internal->auth_info, + srv->cli, + path2, + &targetcli2, &targetpath2)) { d_printf("Could not resolve %s\n", path2); TALLOC_FREE(frame); return -1; diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index 28256bb241..06e41ad21e 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/libsmb/libsmb_file.c @@ -115,8 +115,9 @@ SMBC_open_ctx(SMBCCTX *context, ZERO_STRUCTP(file); /*d_printf(">>>open: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { + if (!cli_resolve_path(frame, "", context->internal->auth_info, + srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); SAFE_FREE(file); TALLOC_FREE(frame); @@ -295,8 +296,9 @@ SMBC_read_ctx(SMBCCTX *context, } /*d_printf(">>>read: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { + if (!cli_resolve_path(frame, "", context->internal->auth_info, + file->srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; @@ -384,8 +386,9 @@ SMBC_write_ctx(SMBCCTX *context, } /*d_printf(">>>write: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { + if (!cli_resolve_path(frame, "", context->internal->auth_info, + file->srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; @@ -459,8 +462,9 @@ SMBC_close_ctx(SMBCCTX *context, } /*d_printf(">>>close: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { + if (!cli_resolve_path(frame, "", context->internal->auth_info, + file->srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; @@ -541,8 +545,9 @@ SMBC_getatr(SMBCCTX * context, } DEBUG(4,("SMBC_getatr: sending qpathinfo\n")); - if (!cli_resolve_path(frame, "", srv->cli, fixedpath, - &targetcli, &targetpath)) { + if (!cli_resolve_path(frame, "", context->internal->auth_info, + srv->cli, fixedpath, + &targetcli, &targetpath)) { d_printf("Couldn't resolve %s\n", path); TALLOC_FREE(frame); return False; @@ -753,8 +758,9 @@ SMBC_lseek_ctx(SMBCCTX *context, } /*d_printf(">>>lseek: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { + if (!cli_resolve_path(frame, "", context->internal->auth_info, + file->srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; @@ -844,8 +850,9 @@ SMBC_ftruncate_ctx(SMBCCTX *context, } /*d_printf(">>>fstat: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { + if (!cli_resolve_path(frame, "", context->internal->auth_info, + file->srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c index f8571ff110..dc904d2753 100644 --- a/source3/libsmb/libsmb_stat.c +++ b/source3/libsmb/libsmb_stat.c @@ -257,8 +257,9 @@ SMBC_fstat_ctx(SMBCCTX *context, } /*d_printf(">>>fstat: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { + if (!cli_resolve_path(frame, "", context->internal->auth_info, + file->srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c index 70fbc27883..e4a0a05586 100644 --- a/source3/libsmb/libsmb_xattr.c +++ b/source3/libsmb/libsmb_xattr.c @@ -166,7 +166,7 @@ sort_acl(SEC_ACL *the_acl) /* convert a SID to a string, either numeric or username/group */ static void convert_sid_to_string(struct cli_state *ipc_cli, - POLICY_HND *pol, + struct policy_handle *pol, fstring str, bool numeric, DOM_SID *sid) @@ -211,7 +211,7 @@ convert_sid_to_string(struct cli_state *ipc_cli, /* convert a string to a SID, either numeric or username/group */ static bool convert_string_to_sid(struct cli_state *ipc_cli, - POLICY_HND *pol, + struct policy_handle *pol, bool numeric, DOM_SID *sid, const char *str) @@ -255,7 +255,7 @@ done: /* parse an ACE in the same format as print_ace() */ static bool parse_ace(struct cli_state *ipc_cli, - POLICY_HND *pol, + struct policy_handle *pol, SEC_ACE *ace, bool numeric, char *str) @@ -422,7 +422,7 @@ add_ace(SEC_ACL **the_acl, static SEC_DESC * sec_desc_parse(TALLOC_CTX *ctx, struct cli_state *ipc_cli, - POLICY_HND *pol, + struct policy_handle *pol, bool numeric, const char *str) { @@ -702,7 +702,7 @@ cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, struct cli_state *ipc_cli, - POLICY_HND *pol, + struct policy_handle *pol, char *filename, char *attr_name, char *buf, @@ -891,7 +891,8 @@ cacl_get(SMBCCTX *context, /* Point to the portion after "system.nt_sec_desc." */ name += 19; /* if (all) this will be invalid but unused */ - if (!cli_resolve_path(ctx, "", cli, filename, + if (!cli_resolve_path(ctx, "", context->internal->auth_info, + cli, filename, &targetcli, &targetpath)) { DEBUG(5, ("cacl_get Could not resolve %s\n", filename)); @@ -1496,14 +1497,15 @@ cacl_get(SMBCCTX *context, set the ACLs on a file given an ascii description *******************************************************/ static int -cacl_set(TALLOC_CTX *ctx, - struct cli_state *cli, - struct cli_state *ipc_cli, - POLICY_HND *pol, - const char *filename, - char *the_acl, - int mode, - int flags) +cacl_set(SMBCCTX *context, + TALLOC_CTX *ctx, + struct cli_state *cli, + struct cli_state *ipc_cli, + struct policy_handle *pol, + const char *filename, + char *the_acl, + int mode, + int flags) { int fnum; int err = 0; @@ -1547,8 +1549,9 @@ cacl_set(TALLOC_CTX *ctx, return -1; } - if (!cli_resolve_path(ctx, "", cli, filename, - &targetcli, &targetpath)) { + if (!cli_resolve_path(ctx, "", context->internal->auth_info, + cli, filename, + &targetcli, &targetpath)) { DEBUG(5,("cacl_set: Could not resolve %s\n", filename)); errno = ENOENT; return -1; @@ -1793,7 +1796,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, } if (ipc_srv) { - ret = cacl_set(talloc_tos(), srv->cli, + ret = cacl_set(context, talloc_tos(), srv->cli, ipc_srv->cli, &ipc_srv->pol, path, namevalue, (*namevalue == '*' @@ -1857,7 +1860,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, errno = ENOMEM; ret = -1; } else { - ret = cacl_set(talloc_tos(), srv->cli, + ret = cacl_set(context, talloc_tos(), srv->cli, ipc_srv->cli, &ipc_srv->pol, path, namevalue, (*namevalue == '*' @@ -1887,7 +1890,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, errno = ENOMEM; ret = -1; } else { - ret = cacl_set(talloc_tos(), srv->cli, + ret = cacl_set(context, talloc_tos(), srv->cli, ipc_srv->cli, &ipc_srv->pol, path, namevalue, SMBC_XATTR_MODE_CHOWN, 0); } @@ -1914,7 +1917,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, errno = ENOMEM; ret = -1; } else { - ret = cacl_set(talloc_tos(), srv->cli, + ret = cacl_set(context, talloc_tos(), srv->cli, ipc_srv->cli, &ipc_srv->pol, path, namevalue, SMBC_XATTR_MODE_CHGRP, 0); } @@ -2216,7 +2219,7 @@ SMBC_removexattr_ctx(SMBCCTX *context, StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) { /* Yup. */ - ret = cacl_set(talloc_tos(), srv->cli, + ret = cacl_set(context, talloc_tos(), srv->cli, ipc_srv->cli, &ipc_srv->pol, path, NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0); TALLOC_FREE(frame); @@ -2236,7 +2239,7 @@ SMBC_removexattr_ctx(SMBCCTX *context, StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { /* Yup. */ - ret = cacl_set(talloc_tos(), srv->cli, + ret = cacl_set(context, talloc_tos(), srv->cli, ipc_srv->cli, &ipc_srv->pol, path, CONST_DISCARD(char *, name) + 19, SMBC_XATTR_MODE_REMOVE, 0); diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index f9ff4b3191..45cd392a5a 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -133,9 +133,17 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam return result; } - cli_init_creds(cli, "", "", NULL); + result = cli_init_creds(cli, "", "", NULL); + if (!NT_STATUS_IS_OK(result)) { + cli_shutdown(cli); + return result; + } } else { - cli_init_creds(cli, user_name, "", old_passwd); + result = cli_init_creds(cli, user_name, "", old_passwd); + if (!NT_STATUS_IS_OK(result)) { + cli_shutdown(cli); + return result; + } } result = cli_tcon_andx(cli, "IPC$", "IPC", "", 1); @@ -222,7 +230,11 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam TALLOC_FREE(pipe_hnd); /* Try anonymous NTLMSSP... */ - cli_init_creds(cli, "", "", NULL); + result = cli_init_creds(cli, "", "", NULL); + if (!NT_STATUS_IS_OK(result)) { + cli_shutdown(cli); + return result; + } result = NT_STATUS_UNSUCCESSFUL; diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c deleted file mode 100644 index 071e729e8c..0000000000 --- a/source3/libsmb/pwd_cache.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Password cacheing. obfuscation is planned - Copyright (C) Luke Kenneth Casson Leighton 1996-1998 - - 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 3 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, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" - -/**************************************************************************** - Initialises a password structure. -****************************************************************************/ - -static void pwd_init(struct pwd_info *pwd) -{ - memset((char *)pwd->password , '\0', sizeof(pwd->password )); - - pwd->null_pwd = True; /* safest option... */ -} - -/**************************************************************************** - Stores a cleartext password. -****************************************************************************/ - -void pwd_set_cleartext(struct pwd_info *pwd, const char *clr) -{ - pwd_init(pwd); - if (clr) { - fstrcpy(pwd->password, clr); - pwd->null_pwd = False; - } else { - pwd->null_pwd = True; - } - - pwd->cleartext = True; -} - -/**************************************************************************** - Gets a cleartext password. -****************************************************************************/ - -void pwd_get_cleartext(struct pwd_info *pwd, fstring clr) -{ - if (pwd->cleartext) - fstrcpy(clr, pwd->password); - else - clr[0] = 0; - -} diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index ea1eb05cfb..a3ed0e7572 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -3,17 +3,17 @@ SMB Signing Code Copyright (C) Jeremy Allison 2003. Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003 - + 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -119,14 +119,14 @@ static bool cli_set_smb_signing_common(struct cli_state *cli) if (cli->sign_info.doing_signing) { return False; } - + if (cli->sign_info.free_signing_context) cli->sign_info.free_signing_context(&cli->sign_info); /* These calls are INCOMPATIBLE with SMB signing */ cli->readbraw_supported = False; cli->writebraw_supported = False; - + return True; } @@ -196,7 +196,7 @@ static void null_free_signing_context(struct smb_sign_info *si) static bool null_set_signing(struct smb_sign_info *si) { si->signing_context = NULL; - + si->sign_outgoing_message = null_sign_outgoing_message; si->check_incoming_message = null_check_incoming_message; si->free_signing_context = null_free_signing_context; @@ -207,7 +207,7 @@ static bool null_set_signing(struct smb_sign_info *si) /** * Free the signing context */ - + static void free_signing_context(struct smb_sign_info *si) { if (si->free_signing_context) { @@ -227,7 +227,7 @@ static bool signing_good(const char *inbuf, struct smb_sign_info *si, if (!si->doing_signing) { si->doing_signing = True; } - + if (!si->seen_valid) { si->seen_valid = True; } @@ -289,7 +289,7 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, /* Calculate the 16 byte MAC - but don't alter the data in the incoming packet. - + This makes for a bit of fussing about, but it's not too bad. */ MD5Init(&md5_ctx); @@ -368,7 +368,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) I can isolate the fix here rather than re-adding the trans signing on/off calls in libsmb/clitrans2.c JRA. */ - + if (store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), data->send_seq_num + 1)) { data->send_seq_num += 2; } @@ -409,11 +409,11 @@ static bool client_check_incoming_message(const char *inbuf, server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); - + if (!good) { DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n")); dump_data(5, calc_md5_mac, 8); - + DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); #if 1 /* JRATEST */ @@ -447,7 +447,7 @@ static void simple_free_signing_context(struct smb_sign_info *si) (struct smb_basic_signing_context *)si->signing_context; struct outstanding_packet_lookup *list; struct outstanding_packet_lookup *next; - + for (list = data->outstanding_packet_list; list; list = next) { next = list->next; DLIST_REMOVE(data->outstanding_packet_list, list); @@ -486,7 +486,7 @@ bool cli_simple_set_signing(struct cli_state *cli, memset(data, '\0', sizeof(*data)); cli->sign_info.signing_context = data; - + data->mac_key = data_blob(NULL, response.length + user_session_key.length); memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); @@ -571,7 +571,7 @@ bool cli_temp_set_signing(struct cli_state *cli) } cli->sign_info.signing_context = NULL; - + cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message; cli->sign_info.check_incoming_message = temp_check_incoming_message; cli->sign_info.free_signing_context = temp_free_signing_context; @@ -587,7 +587,7 @@ void cli_free_signing_context(struct cli_state *cli) /** * Sign a packet with the current mechanism */ - + void cli_calculate_sign_mac(struct cli_state *cli, char *buf) { cli->sign_info.sign_outgoing_message(buf, &cli->sign_info); @@ -598,7 +598,7 @@ void cli_calculate_sign_mac(struct cli_state *cli, char *buf) * @return False if we had an established signing connection * which had a bad checksum, True otherwise. */ - + bool cli_check_sign_mac(struct cli_state *cli, char *buf) { if (!cli->sign_info.check_incoming_message(buf, &cli->sign_info, True)) { @@ -746,7 +746,7 @@ static bool srv_check_incoming_message(const char *inbuf, server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); - + if (!good) { if (saved_seq) { @@ -758,7 +758,7 @@ static bool srv_check_incoming_message(const char *inbuf, (unsigned int)reply_seq_number)); dump_data(5, server_sent_mac, 8); } - + #if 1 /* JRATEST */ { int i; @@ -865,7 +865,7 @@ void srv_defer_sign_response(uint16 mid) cancelled by mid. This should never find one.... ************************************************************/ -void srv_cancel_sign_response(uint16 mid) +void srv_cancel_sign_response(uint16 mid, bool cancel) { struct smb_basic_signing_context *data; uint32 dummy_seq; @@ -884,7 +884,9 @@ void srv_cancel_sign_response(uint16 mid) ; /* cancel doesn't send a reply so doesn't burn a sequence number. */ - data->send_seq_num -= 1; + if (cancel) { + data->send_seq_num -= 1; + } } /*********************************************************** @@ -969,17 +971,17 @@ void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response) if (srv_sign_info.doing_signing) { return; } - + if (srv_sign_info.free_signing_context) srv_sign_info.free_signing_context(&srv_sign_info); - + srv_sign_info.doing_signing = True; data = SMB_XMALLOC_P(struct smb_basic_signing_context); memset(data, '\0', sizeof(*data)); srv_sign_info.signing_context = data; - + data->mac_key = data_blob(NULL, response.length + user_session_key.length); memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index f0595695d2..5b6bc00c57 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -99,7 +99,7 @@ bool enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, char ***domain_names, uint32 *num_domains, DOM_SID **sids ) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; fstring dc_name; struct sockaddr_storage dc_ss; diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 1737eab1c6..bafb89522a 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -75,69 +75,89 @@ const char *lock_flav_name(enum brl_flavour lock_flav) Called in the read/write codepath. ****************************************************************************/ -bool is_locked(files_struct *fsp, - uint32 smbpid, - uint64_t count, - uint64_t offset, - enum brl_type lock_type) +void init_strict_lock_struct(files_struct *fsp, + uint32 smbpid, + br_off start, + br_off size, + enum brl_type lock_type, + struct lock_struct *plock) +{ + SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK); + + plock->context.smbpid = smbpid; + plock->context.tid = fsp->conn->cnum; + plock->context.pid = procid_self(); + plock->start = start; + plock->size = size; + plock->fnum = fsp->fnum; + plock->lock_type = lock_type; + plock->lock_flav = lp_posix_cifsu_locktype(fsp); +} + +bool strict_lock_default(files_struct *fsp, struct lock_struct *plock) { int strict_locking = lp_strict_locking(fsp->conn->params); - enum brl_flavour lock_flav = lp_posix_cifsu_locktype(fsp); - bool ret = True; - - if (count == 0) { - return False; + bool ret = False; + + if (plock->size == 0) { + return True; } if (!lp_locking(fsp->conn->params) || !strict_locking) { - return False; + return True; } if (strict_locking == Auto) { - if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) { + if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) { DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name )); - ret = False; + ret = True; } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) && - (lock_type == READ_LOCK)) { + (plock->lock_type == READ_LOCK)) { DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name )); - ret = False; + ret = True; } else { struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp); if (!br_lck) { - return False; + return True; } - ret = !brl_locktest(br_lck, - smbpid, - procid_self(), - offset, - count, - lock_type, - lock_flav); + ret = brl_locktest(br_lck, + plock->context.smbpid, + plock->context.pid, + plock->start, + plock->size, + plock->lock_type, + plock->lock_flav); TALLOC_FREE(br_lck); } } else { struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp); if (!br_lck) { - return False; + return True; } - ret = !brl_locktest(br_lck, - smbpid, - procid_self(), - offset, - count, - lock_type, - lock_flav); + ret = brl_locktest(br_lck, + plock->context.smbpid, + plock->context.pid, + plock->start, + plock->size, + plock->lock_type, + plock->lock_flav); TALLOC_FREE(br_lck); } - DEBUG(10,("is_locked: flavour = %s brl start=%.0f len=%.0f %s for fnum %d file %s\n", - lock_flav_name(lock_flav), - (double)offset, (double)count, ret ? "locked" : "unlocked", - fsp->fnum, fsp->fsp_name )); + DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f " + "len=%.0f %s for fnum %d file %s\n", + lock_flav_name(plock->lock_flav), + (double)plock->start, (double)plock->size, + ret ? "unlocked" : "locked", + plock->fnum, fsp->fsp_name )); return ret; } +void strict_unlock_default(files_struct *fsp, struct lock_struct *plock) +{ +} + /**************************************************************************** Find out if a lock could be granted - return who is blocking us if we can't. ****************************************************************************/ @@ -1295,7 +1315,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close, (Should this be in locking.c.... ?). *************************************************************************/ -static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, UNIX_USER_TOKEN *tok) +static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, const UNIX_USER_TOKEN *tok) { UNIX_USER_TOKEN *cpy; @@ -1326,7 +1346,7 @@ static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, UNIX_USER_TOKEN *tok) Replace the delete on close token. ****************************************************************************/ -void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok) +void set_delete_on_close_token(struct share_mode_lock *lck, const UNIX_USER_TOKEN *tok) { TALLOC_FREE(lck->delete_token); /* Also deletes groups... */ @@ -1346,7 +1366,7 @@ void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok lck entry. This function is used when the lock is already granted. ****************************************************************************/ -void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, UNIX_USER_TOKEN *tok) +void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, const UNIX_USER_TOKEN *tok) { if (lck->delete_on_close != delete_on_close) { set_delete_on_close_token(lck, tok); @@ -1358,8 +1378,9 @@ void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, } } -bool set_delete_on_close(files_struct *fsp, bool delete_on_close, UNIX_USER_TOKEN *tok) +bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USER_TOKEN *tok) { + UNIX_USER_TOKEN *tok_copy = NULL; struct share_mode_lock *lck; DEBUG(10,("set_delete_on_close: %s delete on close flag for " @@ -1373,6 +1394,16 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, UNIX_USER_TOKE return False; } + if (fsp->conn->admin_user) { + tok_copy = copy_unix_token(lck, tok); + tok_copy->uid = (uid_t)0; + if (tok_copy == NULL) { + TALLOC_FREE(lck); + return false; + } + tok = tok_copy; + } + set_delete_on_close_lck(lck, delete_on_close, tok); if (fsp->is_directory) { diff --git a/source3/m4/aclocal.m4 b/source3/m4/aclocal.m4 index aae729c825..dff4970b2c 100644 --- a/source3/m4/aclocal.m4 +++ b/source3/m4/aclocal.m4 @@ -386,11 +386,17 @@ AC_DEFUN(LIB_REMOVE_USR_LIB,[ case [$]l[$]i in -L/usr/lib) ;; -L/usr/lib/) ;; - -Wl,-rpath,/usr/lib) ;; - -Wl,-rpath,/usr/lib/) ;; + -L/usr/lib64) ;; + -L/usr/lib64/) ;; + -Wl,-rpath,/usr/lib) l="";; + -Wl,-rpath,/usr/lib/) l="";; + -Wl,-rpath,/usr/lib64) l="";; + -Wl,-rpath,/usr/lib64/) l="";; -Wl,-rpath) l=[$]i;; -Wl,-rpath-Wl,/usr/lib) l="";; -Wl,-rpath-Wl,/usr/lib/) l="";; + -Wl,-rpath-Wl,/usr/lib64) l="";; + -Wl,-rpath-Wl,/usr/lib64/) l="";; *) s=" " if test x"[$]ac_new_flags" = x""; then diff --git a/source3/modules/gpfs.c b/source3/modules/gpfs.c index 16599005b9..9fc4524654 100644 --- a/source3/modules/gpfs.c +++ b/source3/modules/gpfs.c @@ -26,6 +26,7 @@ static bool gpfs_share_modes; static bool gpfs_leases; +static bool gpfs_getrealfilename; static int (*gpfs_set_share_fn)(int fd, unsigned int allow, unsigned int deny); static int (*gpfs_set_lease_fn)(int fd, unsigned int leaseType); @@ -139,7 +140,8 @@ int smbd_gpfs_putacl(char *pathname, int flags, void *acl) int smbd_gpfs_get_realfilename_path(char *pathname, char *filenamep, int *buflen) { - if (gpfs_get_realfilename_path_fn == NULL) { + if ((!gpfs_getrealfilename) + || (gpfs_get_realfilename_path_fn == NULL)) { errno = ENOSYS; return -1; } @@ -208,6 +210,8 @@ void init_gpfs(void) gpfs_share_modes = lp_parm_bool(-1, "gpfs", "sharemodes", True); gpfs_leases = lp_parm_bool(-1, "gpfs", "leases", True); + gpfs_getrealfilename = lp_parm_bool(-1, "gpfs", "getrealfilename", + True); return; } diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h index ebeece40ad..bb7695800e 100644 --- a/source3/modules/onefs.h +++ b/source3/modules/onefs.h @@ -106,6 +106,14 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, struct lock_struct *plock, struct blocking_lock_record *blr); +bool onefs_strict_lock(vfs_handle_struct *handle, + files_struct *fsp, + struct lock_struct *plock); + +void onefs_strict_unlock(vfs_handle_struct *handle, + files_struct *fsp, + struct lock_struct *plock); + NTSTATUS onefs_notify_watch(vfs_handle_struct *vfs_handle, struct sys_notify_context *ctx, struct notify_entry *e, diff --git a/source3/modules/onefs_cbrl.c b/source3/modules/onefs_cbrl.c index 7311e1961e..a6178a9751 100644 --- a/source3/modules/onefs_cbrl.c +++ b/source3/modules/onefs_cbrl.c @@ -248,7 +248,7 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, { int fd = br_lck->fsp->fh->fd; uint64_t id = 0; - bool exclusive = false; + enum cbrl_lock_type type; bool async = false; bool pending = false; bool pending_async = false; @@ -268,20 +268,22 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, switch (plock->lock_type) { case WRITE_LOCK: - exclusive = true; + type = CBRL_LK_EX; break; case READ_LOCK: + type = CBRL_LK_SH; break; case PENDING_WRITE_LOCK: /* Called when a blocking lock request is added - do an * async lock. */ + type = CBRL_LK_EX; pending = true; async = true; - exclusive = true; break; case PENDING_READ_LOCK: /* Called when a blocking lock request is added - do an * async lock. */ + type = CBRL_LK_SH; pending = true; async = true; break; @@ -323,7 +325,7 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, } DEBUG(10, ("Calling ifs_cbrl(LOCK)...")); - error = ifs_cbrl(fd, CBRL_OP_LOCK, exclusive, plock->start, + error = ifs_cbrl(fd, CBRL_OP_LOCK, type, plock->start, plock->size, async, id, plock->context.smbpid, plock->context.tid, plock->fnum); if (!error) { @@ -373,8 +375,6 @@ success: return NT_STATUS_OK; } -#define CBRL_NOTYPE true - bool onefs_brl_unlock_windows(vfs_handle_struct *handle, struct messaging_context *msg_ctx, struct byte_range_lock *br_lck, @@ -389,8 +389,8 @@ bool onefs_brl_unlock_windows(vfs_handle_struct *handle, SMB_ASSERT(plock->lock_type == UNLOCK_LOCK); DEBUG(10, ("Calling ifs_cbrl(UNLOCK)...")); - error = ifs_cbrl(fd, CBRL_OP_UNLOCK, CBRL_NOTYPE, - plock->start, plock->size, CBRL_NOTYPE, 0, plock->context.smbpid, + error = ifs_cbrl(fd, CBRL_OP_UNLOCK, CBRL_LK_SH, + plock->start, plock->size, false, 0, plock->context.smbpid, plock->context.tid, plock->fnum); END_PROFILE(syscall_brl_unlock); @@ -444,8 +444,8 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, /* A real cancel. */ DEBUG(10, ("Calling ifs_cbrl(CANCEL)...")); - error = ifs_cbrl(fd, CBRL_OP_CANCEL, CBRL_NOTYPE, plock->start, - plock->size, CBRL_NOTYPE, bs->id, plock->context.smbpid, + error = ifs_cbrl(fd, CBRL_OP_CANCEL, CBRL_LK_UNSPEC, plock->start, + plock->size, false, bs->id, plock->context.smbpid, plock->context.tid, plock->fnum); END_PROFILE(syscall_brl_cancel); @@ -462,6 +462,79 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, return true; } +bool onefs_strict_lock(vfs_handle_struct *handle, + files_struct *fsp, + struct lock_struct *plock) +{ + int error; + + START_PROFILE(syscall_strict_lock); + + SMB_ASSERT(plock->lock_type == READ_LOCK || + plock->lock_type == WRITE_LOCK); + + if (!lp_locking(handle->conn->params) || + !lp_strict_locking(handle->conn->params)) { + END_PROFILE(syscall_strict_lock); + return True; + } + + if (plock->lock_flav == POSIX_LOCK) { + END_PROFILE(syscall_strict_lock); + return SMB_VFS_NEXT_STRICT_LOCK(handle, fsp, plock); + } + + if (plock->size == 0) { + END_PROFILE(syscall_strict_lock); + return True; + } + + error = ifs_cbrl(fsp->fh->fd, CBRL_OP_LOCK, + plock->lock_type == READ_LOCK ? CBRL_LK_RD : CBRL_LK_WR, + plock->start, plock->size, 0, 0, plock->context.smbpid, + plock->context.tid, plock->fnum); + + END_PROFILE(syscall_strict_lock); + + return (error == 0); +} + +void onefs_strict_unlock(vfs_handle_struct *handle, + files_struct *fsp, + struct lock_struct *plock) +{ + START_PROFILE(syscall_strict_unlock); + + SMB_ASSERT(plock->lock_type == READ_LOCK || + plock->lock_type == WRITE_LOCK); + + if (!lp_locking(handle->conn->params) || + !lp_strict_locking(handle->conn->params)) { + END_PROFILE(syscall_strict_unlock); + return; + } + + if (plock->lock_flav == POSIX_LOCK) { + SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock); + END_PROFILE(syscall_strict_unlock); + return; + } + + if (plock->size == 0) { + END_PROFILE(syscall_strict_unlock); + return; + } + + if (fsp->fh) { + ifs_cbrl(fsp->fh->fd, CBRL_OP_UNLOCK, + plock->lock_type == READ_LOCK ? CBRL_LK_RD : CBRL_LK_WR, + plock->start, plock->size, 0, 0, plock->context.smbpid, + plock->context.tid, plock->fnum); + } + + END_PROFILE(syscall_strict_unlock); +} + /* TODO Optimization: Abstract out brl_get_locks() in the Windows case. * We'll malloc some memory or whatever (can't return NULL), but not actually * touch the TDB. */ diff --git a/source3/modules/onefs_config.h b/source3/modules/onefs_config.h index 27cbb0ad74..f0f48e6379 100644 --- a/source3/modules/onefs_config.h +++ b/source3/modules/onefs_config.h @@ -64,6 +64,8 @@ enum onefs_acl_wire_format #define PARM_DOT_SNAP_TILDE_DEFAULT true #define PARM_IGNORE_SACLS "ignore sacls" #define PARM_IGNORE_SACLS_DEFAULT false +#define PARM_IGNORE_STREAMS "ignore streams" +#define PARM_IGNORE_STREAMS_DEFAULT false #define PARM_MTIME_NOW "mtime now files" #define PARM_MTIME_NOW_DEFAULT NULL #define PARM_MTIME_STATIC "mtime static files" diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c index 9043be8e19..c5030f4ab8 100644 --- a/source3/modules/onefs_open.c +++ b/source3/modules/onefs_open.c @@ -196,7 +196,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp, &base, &stream); } /* It's a stream, so pass in the base_fd */ - if (stream != NULL) { + if ((conn->fs_capabilities & FILE_NAMED_STREAMS) && stream != NULL) { SMB_ASSERT(fsp->base_fsp); /* @@ -1649,119 +1649,6 @@ static NTSTATUS onefs_open_directory(connection_struct *conn, } /* - * If a main file is opened for delete, all streams need to be checked for - * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS. - * If that works, delete them all by setting the delete on close and close. - */ - -static NTSTATUS open_streams_for_delete(connection_struct *conn, - const char *fname) -{ - struct stream_struct *stream_info; - files_struct **streams; - int i; - unsigned int num_streams; - TALLOC_CTX *frame = talloc_stackframe(); - NTSTATUS status; - - status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(), - &num_streams, &stream_info); - - if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED) - || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - DEBUG(10, ("no streams around\n")); - TALLOC_FREE(frame); - return NT_STATUS_OK; - } - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n", - nt_errstr(status))); - goto fail; - } - - DEBUG(10, ("open_streams_for_delete found %d streams\n", - num_streams)); - - if (num_streams == 0) { - TALLOC_FREE(frame); - return NT_STATUS_OK; - } - - streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams); - if (streams == NULL) { - DEBUG(0, ("talloc failed\n")); - status = NT_STATUS_NO_MEMORY; - goto fail; - } - - /* Open the base file */ - - for (i=0; i<num_streams; i++) { - char *streamname; - - if (strequal(stream_info[i].name, "::$DATA")) { - streams[i] = NULL; - continue; - } - - streamname = talloc_asprintf(talloc_tos(), "%s%s", fname, - stream_info[i].name); - - if (streamname == NULL) { - DEBUG(0, ("talloc_aprintf failed\n")); - status = NT_STATUS_NO_MEMORY; - goto fail; - } - - status = onefs_create_file_unixpath - (conn, /* conn */ - NULL, /* req */ - streamname, /* fname */ - DELETE_ACCESS, /* access_mask */ - FILE_SHARE_READ | FILE_SHARE_WRITE - | FILE_SHARE_DELETE, /* share_access */ - FILE_OPEN, /* create_disposition*/ - NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* create_options */ - FILE_ATTRIBUTE_NORMAL, /* file_attributes */ - 0, /* oplock_request */ - 0, /* allocation_size */ - NULL, /* sd */ - NULL, /* ea_list */ - &streams[i], /* result */ - NULL, /* pinfo */ - NULL, /* fsp_data */ - NULL); /* psbuf */ - - TALLOC_FREE(streamname); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("Could not open stream %s: %s\n", - streamname, nt_errstr(status))); - break; - } - } - - /* - * don't touch the variable "status" beyond this point :-) - */ - - for (i -= 1 ; i >= 0; i--) { - if (streams[i] == NULL) { - continue; - } - - DEBUG(10, ("Closing stream # %d, %s\n", i, - streams[i]->fsp_name)); - close_file(NULL, streams[i], NORMAL_CLOSE); - } - - fail: - TALLOC_FREE(frame); - return status; -} - -/* * Wrapper around onefs_open_file_ntcreate and onefs_open_directory. */ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn, diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c index 9f5d5e2284..05b36d7d3c 100644 --- a/source3/modules/onefs_streams.c +++ b/source3/modules/onefs_streams.c @@ -671,6 +671,11 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle, state.streams = NULL; state.num_streams = 0; + if (lp_parm_bool(SNUM(handle->conn), PARM_ONEFS_TYPE, + PARM_IGNORE_STREAMS, PARM_IGNORE_STREAMS_DEFAULT)) { + goto out; + } + /* Add the default stream. */ if (S_ISREG(sbuf.st_mode)) { if (!add_one_stream(mem_ctx, @@ -702,7 +707,7 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle, return state.status; } } - + out: *num_streams = state.num_streams; *streams = state.streams; return NT_STATUS_OK; diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c index b8b059bce9..46f38265b1 100644 --- a/source3/modules/onefs_system.c +++ b/source3/modules/onefs_system.c @@ -591,8 +591,8 @@ ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset, */ while (total_rbytes < count) { - DEBUG(0, ("shallow recvfile, reading %llu\n", - count - total_rbytes)); + DEBUG(0, ("shallow recvfile (%s), reading %llu\n", + strerror(errno), count - total_rbytes)); /* * Read the remaining data into the spill buffer. recvfile @@ -603,9 +603,13 @@ ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset, spill_buffer + (total_rbytes - total_wbytes), count - total_rbytes); - if (ret == -1) { - DEBUG(0, ("shallow recvfile read failed: %s\n", - strerror(errno))); + if (ret <= 0) { + if (ret == 0) { + DEBUG(0, ("shallow recvfile read: EOF\n")); + } else { + DEBUG(0, ("shallow recvfile read failed: %s\n", + strerror(errno))); + } /* Socket is dead, so treat as if it were drained. */ socket_drained = true; goto out; diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index 73dbca4809..a77f6d60f4 100644 --- a/source3/modules/vfs_acl_tdb.c +++ b/source3/modules/vfs_acl_tdb.c @@ -195,7 +195,7 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, if (fsp && fsp->fh->fd != -1) { ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - if (fsp->posix_open) { + if (fsp && fsp->posix_open) { ret = SMB_VFS_LSTAT(handle->conn, name, &sbuf); } else { ret = SMB_VFS_STAT(handle->conn, name, &sbuf); @@ -513,7 +513,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, if (fsp && !fsp->is_directory && fsp->fh->fd != -1) { ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - if (fsp->posix_open) { + if (fsp && fsp->posix_open) { ret = SMB_VFS_LSTAT(handle->conn,fname, &sbuf); } else { ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index 039e469426..49e4899879 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -381,7 +381,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, if (fsp && !fsp->is_directory && fsp->fh->fd != -1) { ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - if (fsp->posix_open) { + if (fsp && fsp->posix_open) { ret = SMB_VFS_LSTAT(handle->conn,fname, &sbuf); } else { ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 7384268dae..bb01f98588 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -1157,6 +1157,26 @@ static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct *handle, return brl_lock_cancel_default(br_lck, plock); } +static bool vfswrap_strict_lock(struct vfs_handle_struct *handle, + files_struct *fsp, + struct lock_struct *plock) +{ + SMB_ASSERT(plock->lock_type == READ_LOCK || + plock->lock_type == WRITE_LOCK); + + return strict_lock_default(fsp, plock); +} + +static void vfswrap_strict_unlock(struct vfs_handle_struct *handle, + files_struct *fsp, + struct lock_struct *plock) +{ + SMB_ASSERT(plock->lock_type == READ_LOCK || + plock->lock_type == WRITE_LOCK); + + strict_unlock_default(fsp, plock); +} + /* NT ACL operations. */ static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle, @@ -1592,6 +1612,10 @@ static vfs_op_tuple vfs_default_ops[] = { SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(vfswrap_brl_cancel_windows),SMB_VFS_OP_BRL_CANCEL_WINDOWS, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_strict_lock), SMB_VFS_OP_STRICT_LOCK, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_strict_unlock), SMB_VFS_OP_STRICT_UNLOCK, + SMB_VFS_LAYER_OPAQUE}, /* NT ACL operations. */ diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 3c159f10eb..ebe89ec5fd 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -234,6 +234,12 @@ static bool smb_full_audit_brl_cancel_windows(struct vfs_handle_struct *handle, struct byte_range_lock *br_lck, struct lock_struct *plock, struct blocking_lock_record *blr); +static bool smb_full_audit_strict_lock(struct vfs_handle_struct *handle, + struct files_struct *fsp, + struct lock_struct *plock); +static void smb_full_audit_strict_unlock(struct vfs_handle_struct *handle, + struct files_struct *fsp, + struct lock_struct *plock); static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc); @@ -483,6 +489,10 @@ static vfs_op_tuple audit_op_tuples[] = { SMB_VFS_LAYER_LOGGER}, {SMB_VFS_OP(smb_full_audit_brl_cancel_windows), SMB_VFS_OP_BRL_CANCEL_WINDOWS, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_full_audit_strict_lock), SMB_VFS_OP_STRICT_LOCK, + SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_full_audit_strict_unlock), SMB_VFS_OP_STRICT_UNLOCK, + SMB_VFS_LAYER_LOGGER}, /* NT ACL operations. */ @@ -660,6 +670,8 @@ static struct { { SMB_VFS_OP_BRL_LOCK_WINDOWS, "brl_lock_windows" }, { SMB_VFS_OP_BRL_UNLOCK_WINDOWS, "brl_unlock_windows" }, { SMB_VFS_OP_BRL_CANCEL_WINDOWS, "brl_cancel_windows" }, + { SMB_VFS_OP_STRICT_LOCK, "strict_lock" }, + { SMB_VFS_OP_STRICT_UNLOCK, "strict_unlock" }, { SMB_VFS_OP_FGET_NT_ACL, "fget_nt_acl" }, { SMB_VFS_OP_GET_NT_ACL, "get_nt_acl" }, { SMB_VFS_OP_FSET_NT_ACL, "fset_nt_acl" }, @@ -1766,6 +1778,34 @@ static bool smb_full_audit_brl_cancel_windows(struct vfs_handle_struct *handle, return result; } +static bool smb_full_audit_strict_lock(struct vfs_handle_struct *handle, + struct files_struct *fsp, + struct lock_struct *plock) +{ + bool result; + + result = SMB_VFS_NEXT_STRICT_LOCK(handle, fsp, plock); + + do_log(SMB_VFS_OP_STRICT_LOCK, result, handle, + "%s:%llu-%llu:%d", fsp->fsp_name, plock->start, + plock->size); + + return result; +} + +static void smb_full_audit_strict_unlock(struct vfs_handle_struct *handle, + struct files_struct *fsp, + struct lock_struct *plock) +{ + SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock); + + do_log(SMB_VFS_OP_STRICT_UNLOCK, true, handle, + "%s:%llu-%llu:%d", fsp->fsp_name, plock->start, + plock->size); + + return; +} + static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 1d7cdba014..3c061ece79 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -96,6 +96,11 @@ static int vfs_gpfs_get_real_filename(struct vfs_handle_struct *handle, TALLOC_FREE(full_path); + if ((result == -1) && (errno == ENOSYS)) { + return SMB_VFS_NEXT_GET_REAL_FILENAME( + handle, path, name, mem_ctx, found_name); + } + if (result == -1) { DEBUG(10, ("smbd_gpfs_get_realfilename_path returned %s\n", strerror(errno))); diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c index f277245bdc..ad59c2b32d 100644 --- a/source3/modules/vfs_onefs.c +++ b/source3/modules/vfs_onefs.c @@ -222,7 +222,14 @@ static int onefs_ntimes(vfs_handle_struct *handle, const char *fname, static uint32_t onefs_fs_capabilities(struct vfs_handle_struct *handle) { - return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_NAMED_STREAMS; + uint32_t result = 0; + + if (!lp_parm_bool(SNUM(handle->conn), PARM_ONEFS_TYPE, + PARM_IGNORE_STREAMS, PARM_IGNORE_STREAMS_DEFAULT)) { + result |= FILE_NAMED_STREAMS; + } + + return result | SMB_VFS_NEXT_FS_CAPABILITIES(handle); } static vfs_op_tuple onefs_ops[] = { @@ -282,6 +289,10 @@ static vfs_op_tuple onefs_ops[] = { SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_brl_cancel_windows), SMB_VFS_OP_BRL_CANCEL_WINDOWS, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(onefs_strict_lock), SMB_VFS_OP_STRICT_LOCK, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(onefs_strict_unlock), SMB_VFS_OP_STRICT_UNLOCK, + SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_notify_watch), SMB_VFS_OP_NOTIFY_WATCH, SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL, diff --git a/source3/modules/vfs_preopen.c b/source3/modules/vfs_preopen.c new file mode 100644 index 0000000000..25b9e7f3e4 --- /dev/null +++ b/source3/modules/vfs_preopen.c @@ -0,0 +1,456 @@ +/* + * Force a readahead of files by opening them and reading the first bytes + * + * Copyright (C) Volker Lendecke 2008 + * + * 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. + */ + +#include "includes.h" + +struct preopen_state; + +struct preopen_helper { + struct preopen_state *state; + struct fd_event *fde; + pid_t pid; + int fd; + bool busy; +}; + +struct preopen_state { + int num_helpers; + struct preopen_helper *helpers; + + size_t to_read; /* How many bytes to read in children? */ + int queue_max; + + char *template_fname; /* Filename to be sent to children */ + size_t number_start; /* start offset into "template_fname" */ + int num_digits; /* How many digits is the number long? */ + + int fnum_sent; /* last fname sent to children */ + + int fnum_queue_end; /* last fname to be sent, based on + * last open call + preopen:queuelen + */ + + name_compare_entry *preopen_names; +}; + +static void preopen_helper_destroy(struct preopen_helper *c) +{ + int status; + close(c->fd); + c->fd = -1; + kill(c->pid, SIGKILL); + waitpid(c->pid, &status, 0); + c->busy = true; +} + +static void preopen_queue_run(struct preopen_state *state) +{ + char *pdelimiter; + char delimiter; + + pdelimiter = state->template_fname + state->number_start + + state->num_digits; + delimiter = *pdelimiter; + + while (state->fnum_sent < state->fnum_queue_end) { + + ssize_t written; + size_t to_write; + int helper; + + for (helper=0; helper<state->num_helpers; helper++) { + if (state->helpers[helper].busy) { + continue; + } + break; + } + if (helper == state->num_helpers) { + /* everyone is busy */ + return; + } + + snprintf(state->template_fname + state->number_start, + state->num_digits + 1, + "%.*lu", state->num_digits, + (long unsigned int)(state->fnum_sent + 1)); + *pdelimiter = delimiter; + + to_write = talloc_get_size(state->template_fname); + written = write_data(state->helpers[helper].fd, + state->template_fname, to_write); + state->helpers[helper].busy = true; + + if (written != to_write) { + preopen_helper_destroy(&state->helpers[helper]); + } + state->fnum_sent += 1; + } +} + +static void preopen_helper_readable(struct event_context *ev, + struct fd_event *fde, uint16_t flags, + void *priv) +{ + struct preopen_helper *helper = (struct preopen_helper *)priv; + struct preopen_state *state = helper->state; + ssize_t nread; + char c; + + if ((flags & EVENT_FD_READ) == 0) { + return; + } + + nread = read(helper->fd, &c, 1); + if (nread <= 0) { + preopen_helper_destroy(helper); + return; + } + + helper->busy = false; + + preopen_queue_run(state); +} + +static int preopen_helpers_destructor(struct preopen_state *c) +{ + int i; + + for (i=0; i<c->num_helpers; i++) { + if (c->helpers[i].fd == -1) { + continue; + } + preopen_helper_destroy(&c->helpers[i]); + } + + return 0; +} + +static bool preopen_helper_open_one(int sock_fd, char **pnamebuf, + size_t to_read, void *filebuf) +{ + char *namebuf = *pnamebuf; + ssize_t nwritten, nread; + char c = 0; + int fd; + + nread = 0; + + while ((nread == 0) || (namebuf[nread-1] != '\0')) { + ssize_t thistime; + + thistime = read(sock_fd, namebuf + nread, + talloc_get_size(namebuf) - nread); + if (thistime <= 0) { + return false; + } + + nread += thistime; + + if (nread == talloc_get_size(namebuf)) { + namebuf = TALLOC_REALLOC_ARRAY( + NULL, namebuf, char, + talloc_get_size(namebuf) * 2); + if (namebuf == NULL) { + return false; + } + *pnamebuf = namebuf; + } + } + + fd = open(namebuf, O_RDONLY); + if (fd == -1) { + goto done; + } + nread = read(fd, filebuf, to_read); + close(fd); + + done: + nwritten = write(sock_fd, &c, 1); + return true; +} + +static bool preopen_helper(int fd, size_t to_read) +{ + char *namebuf; + void *readbuf; + + namebuf = TALLOC_ARRAY(NULL, char, 1024); + if (namebuf == NULL) { + return false; + } + + readbuf = talloc_size(NULL, to_read); + if (readbuf == NULL) { + TALLOC_FREE(namebuf); + return false; + } + + while (preopen_helper_open_one(fd, &namebuf, to_read, readbuf)) { + ; + } + + TALLOC_FREE(readbuf); + TALLOC_FREE(namebuf); + return false; +} + +static NTSTATUS preopen_init_helper(struct preopen_helper *h) +{ + int fdpair[2]; + NTSTATUS status; + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair) == -1) { + status = map_nt_error_from_unix(errno); + DEBUG(10, ("socketpair() failed: %s\n", strerror(errno))); + return status; + } + + h->pid = sys_fork(); + + if (h->pid == -1) { + return map_nt_error_from_unix(errno); + } + + if (h->pid == 0) { + close(fdpair[0]); + preopen_helper(fdpair[1], h->state->to_read); + exit(0); + } + close(fdpair[1]); + h->fd = fdpair[0]; + h->fde = event_add_fd(smbd_event_context(), h->state, h->fd, + EVENT_FD_READ, preopen_helper_readable, h); + if (h->fde == NULL) { + close(h->fd); + h->fd = -1; + return NT_STATUS_NO_MEMORY; + } + h->busy = false; + return NT_STATUS_OK; +} + +static NTSTATUS preopen_init_helpers(TALLOC_CTX *mem_ctx, size_t to_read, + int num_helpers, int queue_max, + struct preopen_state **presult) +{ + struct preopen_state *result; + int i; + + result = talloc(mem_ctx, struct preopen_state); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + + result->num_helpers = num_helpers; + result->helpers = TALLOC_ARRAY(result, struct preopen_helper, + num_helpers); + if (result->helpers == NULL) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + result->to_read = to_read; + result->queue_max = queue_max; + result->template_fname = NULL; + result->fnum_sent = 0; + + for (i=0; i<num_helpers; i++) { + result->helpers[i].state = result; + result->helpers[i].fd = -1; + } + + talloc_set_destructor(result, preopen_helpers_destructor); + + for (i=0; i<num_helpers; i++) { + preopen_init_helper(&result->helpers[i]); + } + + *presult = result; + return NT_STATUS_OK; +} + +static void preopen_free_helpers(void **ptr) +{ + TALLOC_FREE(*ptr); +} + +static struct preopen_state *preopen_state_get(vfs_handle_struct *handle) +{ + struct preopen_state *state; + NTSTATUS status; + const char *namelist; + + if (SMB_VFS_HANDLE_TEST_DATA(handle)) { + SMB_VFS_HANDLE_GET_DATA(handle, state, struct preopen_state, + return NULL); + return state; + } + + namelist = lp_parm_const_string(SNUM(handle->conn), "preopen", "names", + NULL); + + if (namelist == NULL) { + return NULL; + } + + status = preopen_init_helpers( + NULL, + lp_parm_int(SNUM(handle->conn), "preopen", "num_bytes", 1), + lp_parm_int(SNUM(handle->conn), "preopen", "helpers", 1), + lp_parm_int(SNUM(handle->conn), "preopen", "queuelen", 10), + &state); + if (!NT_STATUS_IS_OK(status)) { + return NULL; + } + + set_namearray(&state->preopen_names, (char *)namelist); + + if (state->preopen_names == NULL) { + TALLOC_FREE(state); + return NULL; + } + + if (!SMB_VFS_HANDLE_TEST_DATA(handle)) { + SMB_VFS_HANDLE_SET_DATA(handle, state, preopen_free_helpers, + struct preopen_state, return NULL); + } + + return state; +} + +static bool preopen_parse_fname(const char *fname, unsigned long *pnum, + size_t *pstart_idx, int *pnum_digits) +{ + const char *p, *q; + unsigned long num; + + p = strrchr_m(fname, '/'); + if (p == NULL) { + p = fname; + } + + p += 1; + while (p[0] != '\0') { + if (isdigit(p[0]) && isdigit(p[1]) && isdigit(p[2])) { + break; + } + p += 1; + } + if (*p == '\0') { + /* no digits around */ + return false; + } + + num = strtoul(p, (char **)&q, 10); + + if (num+1 < num) { + /* overflow */ + return false; + } + + *pnum = num; + *pstart_idx = (p - fname); + *pnum_digits = (q - p); + return true; +} + +static int preopen_open(vfs_handle_struct *handle, const char *fname, + files_struct *fsp, int flags, mode_t mode) +{ + struct preopen_state *state; + int res; + unsigned long num; + + DEBUG(10, ("preopen_open called on %s\n", fname)); + + state = preopen_state_get(handle); + if (state == NULL) { + return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); + } + + res = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); + if (res == -1) { + return -1; + } + + if (flags != O_RDONLY) { + return res; + } + + if (!is_in_path(fname, state->preopen_names, true)) { + DEBUG(10, ("%s does not match the preopen:names list\n", + fname)); + return res; + } + + TALLOC_FREE(state->template_fname); + state->template_fname = talloc_asprintf( + state, "%s/%s", fsp->conn->connectpath, fname); + + if (state->template_fname == NULL) { + return res; + } + + if (!preopen_parse_fname(state->template_fname, &num, + &state->number_start, &state->num_digits)) { + TALLOC_FREE(state->template_fname); + return res; + } + + if (num > state->fnum_sent) { + /* + * Helpers were too slow, there's no point in reading + * files in helpers that we already read in the + * parent. + */ + state->fnum_sent = num; + } + + if ((state->fnum_queue_end != 0) /* Something was started earlier */ + && (num < (state->fnum_queue_end - state->queue_max))) { + /* + * "num" is before the queue we announced. This means + * a new run is started. + */ + state->fnum_sent = num; + } + + state->fnum_queue_end = num + state->queue_max; + + preopen_queue_run(state); + + return res; +} + +/* VFS operations structure */ + +static vfs_op_tuple preopen_ops[] = { + {SMB_VFS_OP(preopen_open), SMB_VFS_OP_OPEN, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, + SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS vfs_preopen_init(void); +NTSTATUS vfs_preopen_init(void) +{ + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, + "preopen", preopen_ops); +} diff --git a/source3/nmbd/nmbd_nameregister.c b/source3/nmbd/nmbd_nameregister.c index 98f129aa89..d4359aab37 100644 --- a/source3/nmbd/nmbd_nameregister.c +++ b/source3/nmbd/nmbd_nameregister.c @@ -104,6 +104,14 @@ static void register_name_response(struct subnet_record *subrec, subrec->subnet_name, nmb->header.rcode, inet_ntoa(p->ip))); success = False; } else { + if (!ip_equal_v4(rrec->packet->ip, p->ip)) { + DEBUG(5,("register_name_response: Ignoring WINS server response " + "from IP %s, for name %s. We sent to IP %s\n", + inet_ntoa(p->ip), + nmb_namestr(answer_name), + inet_ntoa(rrec->packet->ip))); + return; + } /* Unicast - check to see if the response allows us to have the name. */ if (nmb->header.opcode == NMB_WACK_OPCODE) { /* WINS server is telling us to wait. Pretend we didn't get diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 89c706d874..f49a1bc4c9 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4668,7 +4668,9 @@ static int max_open_files(void) #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)) { - struct rlimit rl = {}; + struct rlimit rl; + + ZERO_STRUCT(rl); if (getrlimit(RLIMIT_NOFILE, &rl) == 0) rlimit_max = rl.rlim_cur; diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c index 53845117e2..9c20042a62 100644 --- a/source3/passdb/lookup_sid.c +++ b/source3/passdb/lookup_sid.c @@ -1308,13 +1308,20 @@ void uid_to_sid(DOM_SID *psid, uid_t uid) if (!ret || expired) { /* Not in cache. Ask winbindd. */ if (!winbind_uid_to_sid(psid, uid)) { - if (!winbind_ping()) { - legacy_uid_to_sid(psid, uid); - return; - } + /* + * We shouldn't return the NULL SID + * here if winbind was running and + * couldn't map, as winbind will have + * added a negative entry that will + * cause us to go though the + * legacy_uid_to_sid() + * function anyway in the case above + * the next time we ask. + */ + DEBUG(5, ("uid_to_sid: winbind failed to find a sid " + "for uid %u\n", uid)); - DEBUG(5, ("uid_to_sid: winbind failed to find a sid for uid %u\n", - uid)); + legacy_uid_to_sid(psid, uid); return; } } @@ -1354,13 +1361,20 @@ void gid_to_sid(DOM_SID *psid, gid_t gid) if (!ret || expired) { /* Not in cache. Ask winbindd. */ if (!winbind_gid_to_sid(psid, gid)) { - if (!winbind_ping()) { - legacy_gid_to_sid(psid, gid); - return; - } + /* + * We shouldn't return the NULL SID + * here if winbind was running and + * couldn't map, as winbind will have + * added a negative entry that will + * cause us to go though the + * legacy_gid_to_sid() + * function anyway in the case above + * the next time we ask. + */ + DEBUG(5, ("gid_to_sid: winbind failed to find a sid " + "for gid %u\n", gid)); - DEBUG(5, ("gid_to_sid: winbind failed to find a sid for gid %u\n", - gid)); + legacy_gid_to_sid(psid, gid); return; } } diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index e618b425e0..1909bd0da4 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -1709,24 +1709,25 @@ static NTSTATUS pdb_default_lookup_names(struct pdb_methods *methods, } #endif -struct pdb_search *pdb_search_init(enum pdb_search_type type) +static int pdb_search_destructor(struct pdb_search *search) { - TALLOC_CTX *mem_ctx; - struct pdb_search *result; - - mem_ctx = talloc_init("pdb_search"); - if (mem_ctx == NULL) { - DEBUG(0, ("talloc_init failed\n")); - return NULL; + if (!search->search_ended) { + search->search_end(search); } + return 0; +} - result = TALLOC_P(mem_ctx, struct pdb_search); +struct pdb_search *pdb_search_init(TALLOC_CTX *mem_ctx, + enum pdb_search_type type) +{ + struct pdb_search *result; + + result = talloc(mem_ctx, struct pdb_search); if (result == NULL) { DEBUG(0, ("talloc failed\n")); return NULL; } - result->mem_ctx = mem_ctx; result->type = type; result->cache = NULL; result->num_entries = 0; @@ -1737,6 +1738,8 @@ struct pdb_search *pdb_search_init(enum pdb_search_type type) result->next_entry = NULL; result->search_end = NULL; + talloc_set_destructor(result, pdb_search_destructor); + return result; } @@ -1783,8 +1786,7 @@ static bool next_entry_groups(struct pdb_search *s, sid_peek_rid(&map->sid, &rid); - fill_displayentry(s->mem_ctx, rid, 0, map->nt_name, NULL, map->comment, - entry); + fill_displayentry(s, rid, 0, map->nt_name, NULL, map->comment, entry); state->current_group += 1; return True; @@ -1802,7 +1804,7 @@ static bool pdb_search_grouptype(struct pdb_search *search, { struct group_search *state; - state = TALLOC_P(search->mem_ctx, struct group_search); + state = talloc(search, struct group_search); if (state == NULL) { DEBUG(0, ("talloc failed\n")); return False; @@ -1853,7 +1855,7 @@ static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search, break; } - ADD_TO_LARGE_ARRAY(search->mem_ctx, struct samr_displayentry, + ADD_TO_LARGE_ARRAY(search, struct samr_displayentry, entry, &search->cache, &search->num_entries, &search->cache_size); } @@ -1861,52 +1863,54 @@ static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search, return (search->num_entries > idx) ? &search->cache[idx] : NULL; } -struct pdb_search *pdb_search_users(uint32 acct_flags) +struct pdb_search *pdb_search_users(TALLOC_CTX *mem_ctx, uint32 acct_flags) { struct pdb_methods *pdb = pdb_get_methods(); struct pdb_search *result; - result = pdb_search_init(PDB_USER_SEARCH); + result = pdb_search_init(mem_ctx, PDB_USER_SEARCH); if (result == NULL) { return NULL; } if (!pdb->search_users(pdb, result, acct_flags)) { - talloc_destroy(result->mem_ctx); + TALLOC_FREE(result); return NULL; } return result; } -struct pdb_search *pdb_search_groups(void) +struct pdb_search *pdb_search_groups(TALLOC_CTX *mem_ctx) { struct pdb_methods *pdb = pdb_get_methods(); struct pdb_search *result; - result = pdb_search_init(PDB_GROUP_SEARCH); + result = pdb_search_init(mem_ctx, PDB_GROUP_SEARCH); if (result == NULL) { return NULL; } if (!pdb->search_groups(pdb, result)) { - talloc_destroy(result->mem_ctx); + TALLOC_FREE(result); return NULL; } return result; } -struct pdb_search *pdb_search_aliases(const DOM_SID *sid) +struct pdb_search *pdb_search_aliases(TALLOC_CTX *mem_ctx, const DOM_SID *sid) { struct pdb_methods *pdb = pdb_get_methods(); struct pdb_search *result; if (pdb == NULL) return NULL; - result = pdb_search_init(PDB_ALIAS_SEARCH); - if (result == NULL) return NULL; + result = pdb_search_init(mem_ctx, PDB_ALIAS_SEARCH); + if (result == NULL) { + return NULL; + } if (!pdb->search_aliases(pdb, result, sid)) { - talloc_destroy(result->mem_ctx); + TALLOC_FREE(result); return NULL; } return result; @@ -1935,17 +1939,6 @@ uint32 pdb_search_entries(struct pdb_search *search, return search->num_entries - start_idx; } -void pdb_search_destroy(struct pdb_search *search) -{ - if (search == NULL) - return; - - if (!search->search_ended) - search->search_end(search); - - talloc_destroy(search->mem_ctx); -} - /******************************************************************* trustdom methods *******************************************************************/ diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 70a1c62bef..77b19e3de9 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -4349,7 +4349,8 @@ static bool ldapsam_search_next_entry(struct pdb_search *search, !ldapsam_search_nextpage(search)) return False; - result = state->ldap2displayentry(state, search->mem_ctx, state->connection->ldap_struct, + result = state->ldap2displayentry(state, search, + state->connection->ldap_struct, state->current_entry, entry); if (!result) { @@ -4508,7 +4509,7 @@ static bool ldapsam_search_users(struct pdb_methods *methods, (struct ldapsam_privates *)methods->private_data; struct ldap_search_state *state; - state = TALLOC_P(search->mem_ctx, struct ldap_search_state); + state = talloc(search, struct ldap_search_state); if (state == NULL) { DEBUG(0, ("talloc failed\n")); return False; @@ -4525,10 +4526,10 @@ static bool ldapsam_search_users(struct pdb_methods *methods, state->base = lp_ldap_suffix(); state->acct_flags = acct_flags; - state->base = talloc_strdup(search->mem_ctx, state->base); + state->base = talloc_strdup(search, state->base); state->scope = LDAP_SCOPE_SUBTREE; - state->filter = get_ldap_filter(search->mem_ctx, "*"); - state->attrs = talloc_attrs(search->mem_ctx, "uid", "sambaSid", + state->filter = get_ldap_filter(search, "*"); + state->attrs = talloc_attrs(search, "uid", "sambaSid", "displayName", "description", "sambaAcctFlags", NULL); state->attrsonly = 0; @@ -4682,7 +4683,7 @@ static bool ldapsam_search_grouptype(struct pdb_methods *methods, struct ldap_search_state *state; fstring tmp; - state = TALLOC_P(search->mem_ctx, struct ldap_search_state); + state = talloc(search, struct ldap_search_state); if (state == NULL) { DEBUG(0, ("talloc failed\n")); return False; @@ -4690,15 +4691,14 @@ static bool ldapsam_search_grouptype(struct pdb_methods *methods, state->connection = ldap_state->smbldap_state; - state->base = talloc_strdup(search->mem_ctx, lp_ldap_group_suffix()); + state->base = talloc_strdup(search, lp_ldap_group_suffix()); state->connection = ldap_state->smbldap_state; state->scope = LDAP_SCOPE_SUBTREE; - state->filter = talloc_asprintf(search->mem_ctx, - "(&(objectclass=%s)" + state->filter = talloc_asprintf(search, "(&(objectclass=%s)" "(sambaGroupType=%d)(sambaSID=%s*))", LDAP_OBJ_GROUPMAP, type, sid_to_fstring(tmp, sid)); - state->attrs = talloc_attrs(search->mem_ctx, "cn", "sambaSid", + state->attrs = talloc_attrs(search, "cn", "sambaSid", "displayName", "description", "sambaGroupType", NULL); state->attrsonly = 0; diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index b72e0f2cba..d663c7f0b2 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -1566,11 +1566,11 @@ static bool smbpasswd_search_next_entry(struct pdb_search *search, entry->acct_flags = state->entries[state->current].acct_flags; entry->account_name = talloc_strdup( - search->mem_ctx, state->entries[state->current].account_name); + search, state->entries[state->current].account_name); entry->fullname = talloc_strdup( - search->mem_ctx, state->entries[state->current].fullname); + search, state->entries[state->current].fullname); entry->description = talloc_strdup( - search->mem_ctx, state->entries[state->current].description); + search, state->entries[state->current].description); if ((entry->account_name == NULL) || (entry->fullname == NULL) || (entry->description == NULL)) { @@ -1593,8 +1593,7 @@ static bool smbpasswd_search_users(struct pdb_methods *methods, struct smb_passwd *pwd; FILE *fp; - search_state = TALLOC_ZERO_P(search->mem_ctx, - struct smbpasswd_search_state); + search_state = talloc_zero(search, struct smbpasswd_search_state); if (search_state == NULL) { DEBUG(0, ("talloc failed\n")); return false; diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 143a2e2390..73fcfee4b3 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -102,6 +102,7 @@ static int tdbsam_convert_one(struct db_record *rec, void *priv) ret = init_samu_from_buffer(user, SAMU_BUFFER_V3, (uint8 *)rec->value.dptr, rec->value.dsize); + break; case 4: ret = init_samu_from_buffer(user, SAMU_BUFFER_V4, (uint8 *)rec->value.dptr, @@ -141,6 +142,149 @@ static int tdbsam_convert_one(struct db_record *rec, void *priv) return 0; } +/********************************************************************** + Struct and function to backup an old record. + *********************************************************************/ + +struct tdbsam_backup_state { + struct db_context *new_db; + bool success; +}; + +static int backup_copy_fn(struct db_record *orig_rec, void *state) +{ + struct tdbsam_backup_state *bs = (struct tdbsam_backup_state *)state; + struct db_record *new_rec; + NTSTATUS status; + + new_rec = bs->new_db->fetch_locked(bs->new_db, talloc_tos(), orig_rec->key); + if (new_rec == NULL) { + bs->success = false; + return 1; + } + + status = new_rec->store(new_rec, orig_rec->value, TDB_INSERT); + + TALLOC_FREE(new_rec); + + if (!NT_STATUS_IS_OK(status)) { + bs->success = false; + return 1; + } + return 0; +} + +/********************************************************************** + Make a backup of an old passdb and replace the new one with it. We + have to do this as between 3.0.x and 3.2.x the hash function changed + by mistake (used unsigned char * instead of char *). This means the + previous simple update code will fail due to not being able to find + existing records to replace in the tdbsam_convert_one() function. JRA. + *********************************************************************/ + +static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db) +{ + TALLOC_CTX *frame = talloc_stackframe(); + const char *tmp_fname = NULL; + struct db_context *tmp_db = NULL; + struct db_context *orig_db = *pp_db; + struct tdbsam_backup_state bs; + int ret; + + tmp_fname = talloc_asprintf(frame, "%s.tmp", dbname); + if (!tmp_fname) { + TALLOC_FREE(frame); + return false; + } + + unlink(tmp_fname); + + /* Remember to open this on the NULL context. We need + * it to stay around after we return from here. */ + + tmp_db = db_open(NULL, tmp_fname, 0, + TDB_DEFAULT, O_CREAT|O_RDWR, 0600); + if (tmp_db == NULL) { + DEBUG(0, ("tdbsam_convert_backup: Failed to create backup TDB passwd " + "[%s]\n", tmp_fname)); + TALLOC_FREE(frame); + return false; + } + + if (orig_db->transaction_start(orig_db) != 0) { + DEBUG(0, ("tdbsam_convert_backup: Could not start transaction (1)\n")); + unlink(tmp_fname); + TALLOC_FREE(tmp_db); + TALLOC_FREE(frame); + return false; + } + if (tmp_db->transaction_start(tmp_db) != 0) { + DEBUG(0, ("tdbsam_convert_backup: Could not start transaction (2)\n")); + orig_db->transaction_cancel(orig_db); + unlink(tmp_fname); + TALLOC_FREE(tmp_db); + TALLOC_FREE(frame); + return false; + } + + bs.new_db = tmp_db; + bs.success = true; + + ret = orig_db->traverse(orig_db, backup_copy_fn, (void *)&bs); + if (ret < 0) { + DEBUG(0, ("tdbsam_convert_backup: traverse failed\n")); + goto cancel; + } + + if (!bs.success) { + DEBUG(0, ("tdbsam_convert_backup: Rewriting records failed\n")); + goto cancel; + } + + if (orig_db->transaction_commit(orig_db) != 0) { + smb_panic("tdbsam_convert_backup: orig commit failed\n"); + } + if (tmp_db->transaction_commit(tmp_db) != 0) { + smb_panic("tdbsam_convert_backup: orig commit failed\n"); + } + + /* This is safe from other users as we know we're + * under a mutex here. */ + + if (rename(tmp_fname, dbname) == -1) { + DEBUG(0, ("tdbsam_convert_backup: rename of %s to %s failed %s\n", + tmp_fname, + dbname, + strerror(errno))); + smb_panic("tdbsam_convert_backup: replace passdb failed\n"); + } + + TALLOC_FREE(frame); + TALLOC_FREE(orig_db); + + DEBUG(1, ("tdbsam_convert_backup: updated %s file.\n", + dbname )); + + /* Replace the global db pointer. */ + *pp_db = tmp_db; + return true; + + cancel: + + if (orig_db->transaction_cancel(orig_db) != 0) { + smb_panic("tdbsam_convert: transaction_cancel failed"); + } + + if (tmp_db->transaction_cancel(tmp_db) != 0) { + smb_panic("tdbsam_convert: transaction_cancel failed"); + } + + unlink(tmp_fname); + TALLOC_FREE(tmp_db); + TALLOC_FREE(frame); + return false; +} + static bool tdbsam_upgrade_next_rid(struct db_context *db) { TDB_CONTEXT *tdb; @@ -172,43 +316,50 @@ static bool tdbsam_upgrade_next_rid(struct db_context *db) return true; } -static bool tdbsam_convert(struct db_context *db, int32 from) +static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32 from) { struct tdbsam_convert_state state; + struct db_context *db = NULL; int ret; + if (!tdbsam_convert_backup(name, pp_db)) { + DEBUG(0, ("tdbsam_convert: Could not backup %s\n", name)); + return false; + } + + db = *pp_db; state.from = from; state.success = true; if (db->transaction_start(db) != 0) { - DEBUG(0, ("Could not start transaction\n")); + DEBUG(0, ("tdbsam_convert: Could not start transaction\n")); return false; } if (!tdbsam_upgrade_next_rid(db)) { - DEBUG(0, ("tdbsam_upgrade_next_rid failed\n")); + DEBUG(0, ("tdbsam_convert: tdbsam_upgrade_next_rid failed\n")); goto cancel; } ret = db->traverse(db, tdbsam_convert_one, &state); if (ret < 0) { - DEBUG(0, ("traverse failed\n")); + DEBUG(0, ("tdbsam_convert: traverse failed\n")); goto cancel; } if (!state.success) { - DEBUG(0, ("Converting records failed\n")); + DEBUG(0, ("tdbsam_convert: Converting records failed\n")); goto cancel; } if (dbwrap_store_int32(db, TDBSAM_VERSION_STRING, TDBSAM_VERSION) != 0) { - DEBUG(0, ("Could not store tdbsam version\n")); + DEBUG(0, ("tdbsam_convert: Could not store tdbsam version\n")); goto cancel; } if (db->transaction_commit(db) != 0) { - DEBUG(0, ("Could not commit transaction\n")); + DEBUG(0, ("tdbsam_convert: Could not commit transaction\n")); return false; } @@ -216,7 +367,7 @@ static bool tdbsam_convert(struct db_context *db, int32 from) cancel: if (db->transaction_cancel(db) != 0) { - smb_panic("transaction_cancel failed"); + smb_panic("tdbsam_convert: transaction_cancel failed"); } return false; @@ -261,17 +412,54 @@ static bool tdbsam_open( const char *name ) } if ( version < TDBSAM_VERSION ) { - DEBUG(1, ("tdbsam_open: Converting version %d database to " - "version %d.\n", version, TDBSAM_VERSION)); + /* + * Ok - we think we're going to have to convert. + * Due to the backup process we now must do to + * upgrade we have to get a mutex and re-check + * the version. Someone else may have upgraded + * whilst we were checking. + */ + + struct named_mutex *mtx = grab_named_mutex(NULL, + "tdbsam_upgrade_mutex", + 600); - if ( !tdbsam_convert(db_sam, version) ) { - DEBUG(0, ("tdbsam_open: Error when trying to convert " - "tdbsam [%s]\n",name)); + if (!mtx) { + DEBUG(0, ("tdbsam_open: failed to grab mutex.\n")); TALLOC_FREE(db_sam); return false; } - DEBUG(3, ("TDBSAM converted successfully.\n")); + /* Re-check the version */ + version = dbwrap_fetch_int32(db_sam, TDBSAM_VERSION_STRING); + if (version == -1) { + version = 0; /* Version not found, assume version 0 */ + } + + /* Compare the version */ + if (version > TDBSAM_VERSION) { + /* Version more recent than the latest known */ + DEBUG(0, ("tdbsam_open: unknown version => %d\n", version)); + TALLOC_FREE(db_sam); + TALLOC_FREE(mtx); + return false; + } + + if ( version < TDBSAM_VERSION ) { + DEBUG(1, ("tdbsam_open: Converting version %d database to " + "version %d.\n", version, TDBSAM_VERSION)); + + if ( !tdbsam_convert(&db_sam, name, version) ) { + DEBUG(0, ("tdbsam_open: Error when trying to convert " + "tdbsam [%s]\n",name)); + TALLOC_FREE(db_sam); + TALLOC_FREE(mtx); + return false; + } + + DEBUG(3, ("TDBSAM converted successfully.\n")); + } + TALLOC_FREE(mtx); } DEBUG(4,("tdbsam_open: successfully opened %s\n", name )); @@ -882,12 +1070,9 @@ static bool tdbsam_search_next_entry(struct pdb_search *search, entry->acct_flags = pdb_get_acct_ctrl(user); entry->rid = rid; - entry->account_name = talloc_strdup( - search->mem_ctx, pdb_get_username(user)); - entry->fullname = talloc_strdup( - search->mem_ctx, pdb_get_fullname(user)); - entry->description = talloc_strdup( - search->mem_ctx, pdb_get_acct_desc(user)); + entry->account_name = talloc_strdup(search, pdb_get_username(user)); + entry->fullname = talloc_strdup(search, pdb_get_fullname(user)); + entry->description = talloc_strdup(search, pdb_get_acct_desc(user)); TALLOC_FREE(user); @@ -912,7 +1097,7 @@ static bool tdbsam_search_users(struct pdb_methods *methods, return false; } - state = TALLOC_ZERO_P(search->mem_ctx, struct tdbsam_search_state); + state = talloc_zero(search, struct tdbsam_search_state); if (state == NULL) { DEBUG(0, ("talloc failed\n")); return false; diff --git a/source3/passdb/pdb_wbc_sam.c b/source3/passdb/pdb_wbc_sam.c index d2c7fda293..e8116d0995 100644 --- a/source3/passdb/pdb_wbc_sam.c +++ b/source3/passdb/pdb_wbc_sam.c @@ -150,7 +150,6 @@ static NTSTATUS pdb_wbc_sam_lookup_rids(struct pdb_methods *methods, NTSTATUS result = NT_STATUS_OK; char *domain = NULL; char **account_names = NULL; - char name[256]; enum lsa_SidType *attr_list = NULL; int i; @@ -168,16 +167,19 @@ static NTSTATUS pdb_wbc_sam_lookup_rids(struct pdb_methods *methods, if (attrs[i] == SID_NAME_UNKNOWN) { names[i] = NULL; } else { - snprintf(name, sizeof(name), "%s%c%s", domain, - *lp_winbind_separator(), account_names[i]); - names[i] = talloc_strdup(names, name); + names[i] = talloc_strdup(names, account_names[i]); + if (names[i] == NULL) { + result = NT_STATUS_NO_MEMORY; + goto done; + } + } } done: TALLOC_FREE(account_names); TALLOC_FREE(domain); - TALLOC_FREE(attrs); + TALLOC_FREE(attr_list); return result; } diff --git a/source3/printing/notify.c b/source3/printing/notify.c index e19212eea8..756a6c23b9 100644 --- a/source3/printing/notify.c +++ b/source3/printing/notify.c @@ -273,8 +273,8 @@ static void send_spoolss_notify2_msg(SPOOLSS_NOTIFY_MSG *msg) */ if ((num_messages < 100) && (msg->type == JOB_NOTIFY_TYPE) - && (msg->field == JOB_NOTIFY_TOTAL_BYTES - || msg->field == JOB_NOTIFY_TOTAL_PAGES )) + && (msg->field == JOB_NOTIFY_FIELD_TOTAL_BYTES + || msg->field == JOB_NOTIFY_FIELD_TOTAL_PAGES )) { for (tmp_ptr = notify_queue_head; tmp_ptr; tmp_ptr = tmp_ptr->next) @@ -400,7 +400,7 @@ void notify_printer_status_byname(const char *sharename, uint32 status) int snum = print_queue_snum(sharename); send_notify_field_values(sharename, PRINTER_NOTIFY_TYPE, - PRINTER_NOTIFY_STATUS, snum, + PRINTER_NOTIFY_FIELD_STATUS, snum, status, 0, 0); } @@ -418,7 +418,7 @@ void notify_job_status_byname(const char *sharename, uint32 jobid, uint32 status /* Job id stored in id field, status in value1 */ send_notify_field_values(sharename, JOB_NOTIFY_TYPE, - JOB_NOTIFY_STATUS, jobid, + JOB_NOTIFY_FIELD_STATUS, jobid, status, 0, flags); } @@ -433,7 +433,7 @@ void notify_job_total_bytes(const char *sharename, uint32 jobid, /* Job id stored in id field, status in value1 */ send_notify_field_values(sharename, JOB_NOTIFY_TYPE, - JOB_NOTIFY_TOTAL_BYTES, jobid, + JOB_NOTIFY_FIELD_TOTAL_BYTES, jobid, size, 0, 0); } @@ -443,21 +443,21 @@ void notify_job_total_pages(const char *sharename, uint32 jobid, /* Job id stored in id field, status in value1 */ send_notify_field_values(sharename, JOB_NOTIFY_TYPE, - JOB_NOTIFY_TOTAL_PAGES, jobid, + JOB_NOTIFY_FIELD_TOTAL_PAGES, jobid, pages, 0, 0); } void notify_job_username(const char *sharename, uint32 jobid, char *name) { send_notify_field_buffer( - sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, + sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, jobid, strlen(name) + 1, name); } void notify_job_name(const char *sharename, uint32 jobid, char *name) { send_notify_field_buffer( - sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, + sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, jobid, strlen(name) + 1, name); } @@ -465,7 +465,7 @@ void notify_job_submitted(const char *sharename, uint32 jobid, time_t submitted) { send_notify_field_buffer( - sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, + sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, jobid, sizeof(submitted), (char *)&submitted); } @@ -474,7 +474,7 @@ void notify_printer_driver(int snum, char *driver_name) const char *sharename = SERVICE(snum); send_notify_field_buffer( - sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, + sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, snum, strlen(driver_name) + 1, driver_name); } @@ -483,7 +483,7 @@ void notify_printer_comment(int snum, char *comment) const char *sharename = SERVICE(snum); send_notify_field_buffer( - sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, + sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, snum, strlen(comment) + 1, comment); } @@ -492,7 +492,7 @@ void notify_printer_sharename(int snum, char *share_name) const char *sharename = SERVICE(snum); send_notify_field_buffer( - sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, + sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, snum, strlen(share_name) + 1, share_name); } @@ -501,7 +501,7 @@ void notify_printer_printername(int snum, char *printername) const char *sharename = SERVICE(snum); send_notify_field_buffer( - sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, + sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, snum, strlen(printername) + 1, printername); } @@ -510,7 +510,7 @@ void notify_printer_port(int snum, char *port_name) const char *sharename = SERVICE(snum); send_notify_field_buffer( - sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, + sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, snum, strlen(port_name) + 1, port_name); } @@ -519,7 +519,7 @@ void notify_printer_location(int snum, char *location) const char *sharename = SERVICE(snum); send_notify_field_buffer( - sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, + sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, snum, strlen(location) + 1, location); } diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index d8658e9280..8e6fe1f364 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -343,7 +343,7 @@ static bool upgrade_to_version_3(void) static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA data, void *state ) { - prs_struct ps; + NTSTATUS status; SEC_DESC_BUF *sd_orig = NULL; SEC_DESC_BUF *sd_new, *sd_store; SEC_DESC *sec, *new_sec; @@ -362,22 +362,16 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key, /* upgrade the security descriptor */ - ZERO_STRUCT( ps ); - - prs_init_empty( &ps, ctx, UNMARSHALL ); - prs_give_memory( &ps, (char *)data.dptr, data.dsize, False ); - - if ( !sec_io_desc_buf( "sec_desc_upg_fn", &sd_orig, &ps, 1 ) ) { + status = unmarshall_sec_desc_buf(ctx, data.dptr, data.dsize, &sd_orig); + if (!NT_STATUS_IS_OK(status)) { /* delete bad entries */ DEBUG(0,("sec_desc_upg_fn: Failed to parse original sec_desc for %si. Deleting....\n", (const char *)key.dptr )); tdb_delete( tdb_printers, key ); - prs_mem_free( &ps ); return 0; } if (!sd_orig) { - prs_mem_free( &ps ); return 0; } sec = sd_orig->sd; @@ -385,7 +379,6 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key, /* is this even valid? */ if ( !sec->dacl ) { - prs_mem_free( &ps ); return 0; } @@ -416,45 +409,31 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key, &global_sid_Builtin_Administrators, NULL, NULL, &size_new_sec ); if (!new_sec) { - prs_mem_free( &ps ); return 0; } sd_new = make_sec_desc_buf( ctx, size_new_sec, new_sec ); if (!sd_new) { - prs_mem_free( &ps ); return 0; } if ( !(sd_store = sec_desc_merge( ctx, sd_new, sd_orig )) ) { DEBUG(0,("sec_desc_upg_fn: Failed to update sec_desc for %s\n", key.dptr )); - prs_mem_free( &ps ); return 0; } - prs_mem_free( &ps ); - /* store it back */ sd_size = ndr_size_security_descriptor(sd_store->sd, NULL, 0) + sizeof(SEC_DESC_BUF); - if ( !prs_init(&ps, sd_size, ctx, MARSHALL) ) { - DEBUG(0,("sec_desc_upg_fn: Failed to allocate prs memory for %s\n", key.dptr )); - return 0; - } - if ( !sec_io_desc_buf( "sec_desc_upg_fn", &sd_store, &ps, 1 ) ) { + status = marshall_sec_desc_buf(ctx, sd_store, &data.dptr, &data.dsize); + if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("sec_desc_upg_fn: Failed to parse new sec_desc for %s\n", key.dptr )); - prs_mem_free( &ps ); return 0; } - data.dptr = (uint8 *)prs_data_p( &ps ); - data.dsize = sd_size; - result = tdb_store( tdb_printers, key, data, TDB_REPLACE ); - prs_mem_free( &ps ); - /* 0 to continue and non-zero to stop traversal */ return (result == -1); @@ -789,13 +768,6 @@ bool get_a_builtin_ntform_by_string(const char *form_name, nt_forms_struct *form return (i !=count); } -bool get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form) -{ - fstring form_name; - unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)); - return get_a_builtin_ntform_by_string(form_name, form); -} - /**************************************************************************** get a form struct list. ****************************************************************************/ @@ -4590,24 +4562,25 @@ static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level) got to keep the endians happy :). ****************************************************************************/ -static bool convert_driver_init( TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode, uint8 *data, uint32 data_len ) +static bool convert_driver_init(TALLOC_CTX *mem_ctx, NT_DEVICEMODE *nt_devmode, + const uint8_t *data, uint32_t data_len) { - bool result = False; - prs_struct ps; - DEVICEMODE devmode; + struct spoolss_DeviceMode devmode; + enum ndr_err_code ndr_err; + DATA_BLOB blob; ZERO_STRUCT(devmode); - prs_init_empty(&ps, ctx, UNMARSHALL); - ps.data_p = (char *)data; - ps.buffer_size = data_len; + blob = data_blob_const(data, data_len); - if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode)) - result = convert_devicemode("", &devmode, &nt_devmode); - else - DEBUG(10,("convert_driver_init: error parsing DEVMODE\n")); + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &devmode, + (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(10,("convert_driver_init: error parsing spoolss_DeviceMode\n")); + return false; + } - return result; + return convert_devicemode("", &devmode, &nt_devmode); } /**************************************************************************** diff --git a/source3/printing/printing.c b/source3/printing/printing.c index fc3667ea3a..8524cfb2bd 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1387,6 +1387,18 @@ static void print_queue_receive(struct messaging_context *msg, return; } +static void printing_pause_fd_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, + void *private_data) +{ + /* + * If pause_pipe[1] is closed it means the parent smbd + * and children exited or aborted. + */ + exit_server_cleanly(NULL); +} + static pid_t background_lpq_updater_pid = -1; /**************************************************************************** @@ -1415,6 +1427,9 @@ void start_background_queue(void) } if(background_lpq_updater_pid == 0) { + struct tevent_fd *fde; + int ret; + /* Child. */ DEBUG(5,("start_background_queue: background LPQ thread started\n")); @@ -1440,60 +1455,21 @@ void start_background_queue(void) messaging_register(smbd_messaging_context(), NULL, MSG_PRINTER_UPDATE, print_queue_receive); - DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n")); - while (1) { - fd_set r_fds, w_fds; - int ret; - struct timeval to; - int maxfd = 0; - - /* Process a signal and timed events now... */ - if (run_events(smbd_event_context(), 0, NULL, NULL)) { - continue; - } - - to.tv_sec = SMBD_SELECT_TIMEOUT; - to.tv_usec = 0; - - /* - * Setup the select fd sets. - */ - - FD_ZERO(&r_fds); - FD_ZERO(&w_fds); - - /* - * Are there any timed events waiting ? If so, ensure we don't - * select for longer than it would take to wait for them. - */ - - { - struct timeval now; - GetTimeOfDay(&now); - - event_add_to_select_args(smbd_event_context(), &now, - &r_fds, &w_fds, &to, &maxfd); - } - - FD_SET(pause_pipe[1], &r_fds); - maxfd = MAX(pause_pipe[1], maxfd); - - ret = sys_select(maxfd, &r_fds, &w_fds, NULL, &to); - - /* - * If pause_pipe[1] is closed it means the parent smbd - * and children exited or aborted. If sys_select() - * failed, then something more sinister is wrong - */ - if ((ret < 0) || - (ret == 1 && FD_ISSET(pause_pipe[1], &r_fds))) { - exit_server_cleanly(NULL); - } - - if (run_events(smbd_event_context(), ret, &r_fds, &w_fds)) { - continue; - } + fde = tevent_add_fd(smbd_event_context(), smbd_event_context(), + pause_pipe[1], TEVENT_FD_READ, + printing_pause_fd_handler, + NULL); + if (!fde) { + DEBUG(0,("tevent_add_fd() failed for pause_pipe\n")); + smb_panic("tevent_add_fd() failed for pause_pipe"); } + + DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n")); + ret = tevent_loop_wait(smbd_event_context()); + /* should not be reached */ + DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n", + ret, (ret == 0) ? "out of events" : strerror(errno))); + exit(1); } close(pause_pipe[1]); @@ -2407,7 +2383,7 @@ static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid) ***************************************************************************/ uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum, - char *jobname, NT_DEVICEMODE *nt_devmode ) + const char *jobname, NT_DEVICEMODE *nt_devmode ) { uint32 jobid; char *path; diff --git a/source3/registry/reg_backend_printing.c b/source3/registry/reg_backend_printing.c index 192bc78e09..a02293e528 100644 --- a/source3/registry/reg_backend_printing.c +++ b/source3/registry/reg_backend_printing.c @@ -385,9 +385,7 @@ static bool key_printers_store_keys( const char *key, struct regsubkey_ctr *subk static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *values ) { - DEVICEMODE *devmode; - prs_struct prs; - uint32 offset; + struct spoolss_DeviceMode *devmode; UNISTR2 data; char *p; uint32 printer_status = PRINTER_STATUS_OK; @@ -438,40 +436,40 @@ static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR * 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 */ - - if (!prs_init( &prs, RPC_MAX_PDU_FRAG_LEN, values, MARSHALL)) - return; - /* stream the device mode */ - - if ( (devmode = construct_dev_mode( info2->sharename )) != 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 ); + + devmode = construct_dev_mode(values,info2->sharename); + if (devmode) { + DATA_BLOB blob; + enum ndr_err_code ndr_err; + + ndr_err = ndr_push_struct_blob(&blob, values, NULL, devmode, + (ndr_push_flags_fn_t)ndr_push_spoolss_DeviceMode); + + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + regval_ctr_addvalue(values, "Default Devmode", REG_BINARY, + (const char *)blob.data, blob.length); } } - - prs_mem_clear( &prs ); - prs_set_offset( &prs, 0 ); - + /* stream the printer security descriptor */ - - if ( info2->secdesc_buf && - info2->secdesc_buf->sd && - info2->secdesc_buf->sd_size ) + + if (info2->secdesc_buf && + info2->secdesc_buf->sd && + info2->secdesc_buf->sd_size) { - if ( sec_io_desc("sec_desc", &info2->secdesc_buf->sd, &prs, 0 ) ) { - offset = prs_offset( &prs ); - regval_ctr_addvalue( values, "Security", REG_BINARY, prs_data_p(&prs), offset ); + NTSTATUS status; + DATA_BLOB blob; + + status = marshall_sec_desc(values, info2->secdesc_buf->sd, + &blob.data, &blob.length); + if (NT_STATUS_IS_OK(status)) { + regval_ctr_addvalue(values, "Security", REG_BINARY, + (const char *)blob.data, blob.length); } } - prs_mem_free( &prs ); - - return; + return; } /********************************************************************** diff --git a/source3/registry/reg_perfcount.c b/source3/registry/reg_perfcount.c index fed3cbdd52..14716b2f53 100644 --- a/source3/registry/reg_perfcount.c +++ b/source3/registry/reg_perfcount.c @@ -1114,7 +1114,7 @@ static bool _reg_perfcount_marshall_perf_data_block(prs_struct *ps, PERF_DATA_BL return False; if(!prs_uint32("DefaultObject", ps, depth, &block.DefaultObject)) return False; - if(!spoolss_io_system_time("SystemTime", ps, depth, &block.SystemTime)) + if(!smb_io_system_time("SystemTime", ps, depth, &block.SystemTime)) return False; if(!prs_uint32("Padding", ps, depth, &block.Padding)) return False; diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index 33de986e78..68fd96faa8 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -44,7 +44,7 @@ NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, bool sec_qos, uint32 des_access, - POLICY_HND *pol) + struct policy_handle *pol) { struct lsa_ObjectAttribute attr; struct lsa_QosInfo qos; @@ -77,7 +77,7 @@ NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli, NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, bool sec_qos, - uint32 des_access, POLICY_HND *pol) + uint32 des_access, struct policy_handle *pol) { struct lsa_ObjectAttribute attr; struct lsa_QosInfo qos; @@ -109,7 +109,7 @@ NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli, static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, + struct policy_handle *pol, int num_sids, const DOM_SID *sids, char **domains, @@ -235,7 +235,7 @@ done: NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, + struct policy_handle *pol, int num_sids, const DOM_SID *sids, char ***pdomains, @@ -344,7 +344,7 @@ fail: NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_names, + struct policy_handle *pol, int num_names, const char **names, const char ***dom_names, int level, diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 24dbcb0193..57f49fb83a 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -65,7 +65,7 @@ static const struct pipe_id_info { { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id }, { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id }, { PIPE_WINREG, &ndr_table_winreg.syntax_id }, - { PIPE_SPOOLSS, &syntax_spoolss }, + { PIPE_SPOOLSS, &ndr_table_spoolss.syntax_id }, { PIPE_NETDFS, &ndr_table_netdfs.syntax_id }, { PIPE_ECHO, &ndr_table_rpcecho.syntax_id }, { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id }, @@ -2974,7 +2974,7 @@ bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16]) if (cli == NULL) { return false; } - E_md4hash(cli->pwd.password, nt_hash); + E_md4hash(cli->password ? cli->password : "", nt_hash); return true; } @@ -3699,7 +3699,7 @@ static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli, status = rpccli_ntlmssp_bind_data( result, auth_type, auth_level, domain, username, - cli->pwd.null_pwd ? NULL : password, &auth); + password, &auth); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n", nt_errstr(status))); diff --git a/source3/rpc_client/cli_reg.c b/source3/rpc_client/cli_reg.c index 2ed7119f4b..ec200a24ae 100644 --- a/source3/rpc_client/cli_reg.c +++ b/source3/rpc_client/cli_reg.c @@ -27,7 +27,7 @@ NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 reg_type, uint32 access_mask, - POLICY_HND *reg_hnd) + struct policy_handle *reg_hnd) { ZERO_STRUCTP(reg_hnd); diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c index ed42d56a02..86bc041374 100644 --- a/source3/rpc_client/cli_samr.c +++ b/source3/rpc_client/cli_samr.c @@ -282,7 +282,7 @@ void get_query_dispinfo_params(int loop_count, uint32 *max_entries, NTSTATUS rpccli_try_samr_connects(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32_t access_mask, - POLICY_HND *connect_pol) + struct policy_handle *connect_pol) { NTSTATUS status; union samr_ConnectInfo info_in, info_out; diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index d76d20c962..3f369bdab3 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -279,983 +279,548 @@ WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, return werror; } - -/********************************************************************* - Decode various spoolss rpc's and info levels - ********************************************************************/ - /********************************************************************** + convencience wrapper around rpccli_spoolss_EnumForms **********************************************************************/ -static bool decode_printer_info_0(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, PRINTER_INFO_0 **info) +WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_FormInfo **info) { - uint32 i; - PRINTER_INFO_0 *inf; - - if (returned) { - inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_0, returned); - if (!inf) { - return False; - } - memset(inf, 0, returned*sizeof(PRINTER_INFO_0)); - } else { - inf = NULL; - } - - prs_set_offset(&buffer->prs,0); + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; - for (i=0; i<returned; i++) { - if (!smb_io_printer_info_0("", buffer, &inf[i], 0)) { - return False; - } + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); } - *info=inf; - return True; -} - -/********************************************************************** -**********************************************************************/ - -static bool decode_printer_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, PRINTER_INFO_1 **info) -{ - uint32 i; - PRINTER_INFO_1 *inf; - - if (returned) { - inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_1, returned); - if (!inf) { - return False; - } - memset(inf, 0, returned*sizeof(PRINTER_INFO_1)); - } else { - inf = NULL; - } + status = rpccli_spoolss_EnumForms(cli, mem_ctx, + handle, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); - prs_set_offset(&buffer->prs,0); + if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { + offered = needed; + buffer = data_blob_talloc_zero(mem_ctx, needed); + W_ERROR_HAVE_NO_MEMORY(buffer.data); - for (i=0; i<returned; i++) { - if (!smb_io_printer_info_1("", buffer, &inf[i], 0)) { - return False; - } + status = rpccli_spoolss_EnumForms(cli, mem_ctx, + handle, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); } - *info=inf; - return True; + return werror; } /********************************************************************** + convencience wrapper around rpccli_spoolss_EnumPrintProcessors **********************************************************************/ -static bool decode_printer_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, PRINTER_INFO_2 **info) +WERROR rpccli_spoolss_enumprintprocessors(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *servername, + const char *environment, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_PrintProcessorInfo **info) { - uint32 i; - PRINTER_INFO_2 *inf; - - if (returned) { - inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_2, returned); - if (!inf) { - return False; - } - memset(inf, 0, returned*sizeof(PRINTER_INFO_2)); - } else { - inf = NULL; - } - - prs_set_offset(&buffer->prs,0); + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; - for (i=0; i<returned; i++) { - /* a little initialization as we go */ - inf[i].secdesc = NULL; - if (!smb_io_printer_info_2("", buffer, &inf[i], 0)) { - return False; - } + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); } - *info=inf; - return True; -} - -/********************************************************************** -**********************************************************************/ - -static bool decode_printer_info_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, PRINTER_INFO_3 **info) -{ - uint32 i; - PRINTER_INFO_3 *inf; - - if (returned) { - inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_3, returned); - if (!inf) { - return False; - } - memset(inf, 0, returned*sizeof(PRINTER_INFO_3)); - } else { - inf = NULL; - } + status = rpccli_spoolss_EnumPrintProcessors(cli, mem_ctx, + servername, + environment, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); - prs_set_offset(&buffer->prs,0); + if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { + offered = needed; + buffer = data_blob_talloc_zero(mem_ctx, needed); + W_ERROR_HAVE_NO_MEMORY(buffer.data); - for (i=0; i<returned; i++) { - inf[i].secdesc = NULL; - if (!smb_io_printer_info_3("", buffer, &inf[i], 0)) { - return False; - } + status = rpccli_spoolss_EnumPrintProcessors(cli, mem_ctx, + servername, + environment, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); } - *info=inf; - return True; + return werror; } /********************************************************************** + convencience wrapper around rpccli_spoolss_EnumPrintProcDataTypes **********************************************************************/ -static bool decode_port_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, PORT_INFO_1 **info) +WERROR rpccli_spoolss_enumprintprocessordatatypes(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *servername, + const char *print_processor_name, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_PrintProcDataTypesInfo **info) { - uint32 i; - PORT_INFO_1 *inf; - - if (returned) { - inf=TALLOC_ARRAY(mem_ctx, PORT_INFO_1, returned); - if (!inf) { - return False; - } - memset(inf, 0, returned*sizeof(PORT_INFO_1)); - } else { - inf = NULL; - } - - prs_set_offset(&buffer->prs, 0); + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; - for (i=0; i<returned; i++) { - if (!smb_io_port_info_1("", buffer, &(inf[i]), 0)) { - return False; - } + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); } - *info=inf; - return True; -} - -/********************************************************************** -**********************************************************************/ - -static bool decode_port_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, PORT_INFO_2 **info) -{ - uint32 i; - PORT_INFO_2 *inf; - - if (returned) { - inf=TALLOC_ARRAY(mem_ctx, PORT_INFO_2, returned); - if (!inf) { - return False; - } - memset(inf, 0, returned*sizeof(PORT_INFO_2)); - } else { - inf = NULL; - } + status = rpccli_spoolss_EnumPrintProcDataTypes(cli, mem_ctx, + servername, + print_processor_name, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); - prs_set_offset(&buffer->prs, 0); + if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { + offered = needed; + buffer = data_blob_talloc_zero(mem_ctx, needed); + W_ERROR_HAVE_NO_MEMORY(buffer.data); - for (i=0; i<returned; i++) { - if (!smb_io_port_info_2("", buffer, &(inf[i]), 0)) { - return False; - } + status = rpccli_spoolss_EnumPrintProcDataTypes(cli, mem_ctx, + servername, + print_processor_name, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); } - *info=inf; - return True; + return werror; } /********************************************************************** + convencience wrapper around rpccli_spoolss_EnumPorts **********************************************************************/ -static bool decode_printer_driver_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, DRIVER_INFO_1 **info) +WERROR rpccli_spoolss_enumports(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *servername, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_PortInfo **info) { - uint32 i; - DRIVER_INFO_1 *inf; - - if (returned) { - inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_1, returned); - if (!inf) { - return False; - } - memset(inf, 0, returned*sizeof(DRIVER_INFO_1)); - } else { - inf = NULL; - } - - prs_set_offset(&buffer->prs,0); + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; - for (i=0; i<returned; i++) { - if (!smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0)) { - return False; - } + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); } - *info=inf; - return True; -} - -/********************************************************************** -**********************************************************************/ - -static bool decode_printer_driver_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, DRIVER_INFO_2 **info) -{ - uint32 i; - DRIVER_INFO_2 *inf; - - if (returned) { - inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_2, returned); - if (!inf) { - return False; - } - memset(inf, 0, returned*sizeof(DRIVER_INFO_2)); - } else { - inf = NULL; - } + status = rpccli_spoolss_EnumPorts(cli, mem_ctx, + servername, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); - prs_set_offset(&buffer->prs,0); + if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { + offered = needed; + buffer = data_blob_talloc_zero(mem_ctx, needed); + W_ERROR_HAVE_NO_MEMORY(buffer.data); - for (i=0; i<returned; i++) { - if (!smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0)) { - return False; - } + status = rpccli_spoolss_EnumPorts(cli, mem_ctx, + servername, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); } - *info=inf; - return True; + return werror; } /********************************************************************** + convencience wrapper around rpccli_spoolss_EnumMonitors **********************************************************************/ -static bool decode_printer_driver_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, DRIVER_INFO_3 **info) +WERROR rpccli_spoolss_enummonitors(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *servername, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_MonitorInfo **info) { - uint32 i; - DRIVER_INFO_3 *inf; - - if (returned) { - inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_3, returned); - if (!inf) { - return False; - } - memset(inf, 0, returned*sizeof(DRIVER_INFO_3)); - } else { - inf = NULL; - } - - prs_set_offset(&buffer->prs,0); + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; - for (i=0; i<returned; i++) { - if (!smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0)) { - return False; - } + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); } - *info=inf; - return True; -} + status = rpccli_spoolss_EnumMonitors(cli, mem_ctx, + servername, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); -/********************************************************************** -**********************************************************************/ - -static bool decode_jobs_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 num_jobs, JOB_INFO_1 **jobs) -{ - uint32 i; - - if (num_jobs) { - *jobs = TALLOC_ARRAY(mem_ctx, JOB_INFO_1, num_jobs); - if (*jobs == NULL) { - return False; - } - } else { - *jobs = NULL; - } - prs_set_offset(&buffer->prs,0); + if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { + offered = needed; + buffer = data_blob_talloc_zero(mem_ctx, needed); + W_ERROR_HAVE_NO_MEMORY(buffer.data); - for (i = 0; i < num_jobs; i++) { - if (!smb_io_job_info_1("", buffer, &((*jobs)[i]), 0)) { - return False; - } + status = rpccli_spoolss_EnumMonitors(cli, mem_ctx, + servername, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); } - return True; + return werror; } /********************************************************************** + convencience wrapper around rpccli_spoolss_EnumJobs **********************************************************************/ -static bool decode_jobs_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 num_jobs, JOB_INFO_2 **jobs) +WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t firstjob, + uint32_t numjobs, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_JobInfo **info) { - uint32 i; - - if (num_jobs) { - *jobs = TALLOC_ARRAY(mem_ctx, JOB_INFO_2, num_jobs); - if (*jobs == NULL) { - return False; - } - } else { - *jobs = NULL; - } - prs_set_offset(&buffer->prs,0); + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; - for (i = 0; i < num_jobs; i++) { - if (!smb_io_job_info_2("", buffer, &((*jobs)[i]), 0)) { - return False; - } + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); } - return True; -} - -/********************************************************************** -**********************************************************************/ - -static bool decode_forms_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 num_forms, FORM_1 **forms) -{ - int i; - - if (num_forms) { - *forms = TALLOC_ARRAY(mem_ctx, FORM_1, num_forms); - if (*forms == NULL) { - return False; - } - } else { - *forms = NULL; - } + status = rpccli_spoolss_EnumJobs(cli, mem_ctx, + handle, + firstjob, + numjobs, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); - prs_set_offset(&buffer->prs,0); + if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { + offered = needed; + buffer = data_blob_talloc_zero(mem_ctx, needed); + W_ERROR_HAVE_NO_MEMORY(buffer.data); - for (i = 0; i < num_forms; i++) { - if (!smb_io_form_1("", buffer, &((*forms)[i]), 0)) { - return False; - } + status = rpccli_spoolss_EnumJobs(cli, mem_ctx, + handle, + firstjob, + numjobs, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); } - return True; + return werror; } /********************************************************************** + convencience wrapper around rpccli_spoolss_EnumPrinterDrivers **********************************************************************/ -WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - char *name, uint32 flags, uint32 level, - uint32 *num_printers, PRINTER_INFO_CTR *ctr) +WERROR rpccli_spoolss_enumprinterdrivers(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *server, + const char *environment, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_DriverInfo **info) { - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERS in; - SPOOL_R_ENUMPRINTERS out; - RPC_BUFFER buffer; - uint32 offered; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - offered = 0; - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_enumprinters( &in, flags, name, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERS, - in, out, - qbuf, rbuf, - spoolss_io_q_enumprinters, - spoolss_io_r_enumprinters, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_enumprinters( &in, flags, name, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERS, - in, out, - qbuf, rbuf, - spoolss_io_q_enumprinters, - spoolss_io_r_enumprinters, - WERR_GENERAL_FAILURE ); - } - - if ( !W_ERROR_IS_OK(out.status) ) - return out.status; - - switch (level) { - case 0: - if (!decode_printer_info_0(mem_ctx, out.buffer, out.returned, &ctr->printers_0)) { - return WERR_GENERAL_FAILURE; - } - break; - case 1: - if (!decode_printer_info_1(mem_ctx, out.buffer, out.returned, &ctr->printers_1)) { - return WERR_GENERAL_FAILURE; - } - break; - case 2: - if (!decode_printer_info_2(mem_ctx, out.buffer, out.returned, &ctr->printers_2)) { - return WERR_GENERAL_FAILURE; - } - break; - case 3: - if (!decode_printer_info_3(mem_ctx, out.buffer, out.returned, &ctr->printers_3)) { - return WERR_GENERAL_FAILURE; - } - break; - default: - return WERR_UNKNOWN_LEVEL; - } - - *num_printers = out.returned; - - return out.status; -} - -/********************************************************************** -**********************************************************************/ + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; -WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - uint32 level, uint32 *num_ports, PORT_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPORTS in; - SPOOL_R_ENUMPORTS out; - RPC_BUFFER buffer; - fstring server; - uint32 offered; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper_m(server); - - offered = 0; - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_enumports( &in, server, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPORTS, - in, out, - qbuf, rbuf, - spoolss_io_q_enumports, - spoolss_io_r_enumports, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_enumports( &in, server, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPORTS, - in, out, - qbuf, rbuf, - spoolss_io_q_enumports, - spoolss_io_r_enumports, - WERR_GENERAL_FAILURE ); - } - - if ( !W_ERROR_IS_OK(out.status) ) - return out.status; - - switch (level) { - case 1: - if (!decode_port_info_1(mem_ctx, out.buffer, out.returned, &ctr->port.info_1)) { - return WERR_GENERAL_FAILURE; - } - break; - case 2: - if (!decode_port_info_2(mem_ctx, out.buffer, out.returned, &ctr->port.info_2)) { - return WERR_GENERAL_FAILURE; - } - break; - default: - return WERR_UNKNOWN_LEVEL; + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); } - *num_ports = out.returned; - - return out.status; -} + status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx, + server, + environment, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); -/********************************************************************** -**********************************************************************/ + if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { + offered = needed; + buffer = data_blob_talloc_zero(mem_ctx, needed); + W_ERROR_HAVE_NO_MEMORY(buffer.data); -WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - uint32 level, const char *env, - uint32 *num_drivers, - PRINTER_DRIVER_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERDRIVERS in; - SPOOL_R_ENUMPRINTERDRIVERS out; - RPC_BUFFER buffer; - fstring server; - uint32 offered; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper_m(server); - - offered = 0; - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_enumprinterdrivers( &in, server, env, level, - &buffer, offered); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDRIVERS, - in, out, - qbuf, rbuf, - spoolss_io_q_enumprinterdrivers, - spoolss_io_r_enumprinterdrivers, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_enumprinterdrivers( &in, server, env, level, - &buffer, offered); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDRIVERS, - in, out, - qbuf, rbuf, - spoolss_io_q_enumprinterdrivers, - spoolss_io_r_enumprinterdrivers, - WERR_GENERAL_FAILURE ); - } - - *num_drivers = out.returned; - - if ( !W_ERROR_IS_OK(out.status) ) - return out.status; - - if ( out.returned ) { - - switch (level) { - case 1: - if (!decode_printer_driver_1(mem_ctx, out.buffer, out.returned, &ctr->info1)) { - return WERR_GENERAL_FAILURE; - } - break; - case 2: - if (!decode_printer_driver_2(mem_ctx, out.buffer, out.returned, &ctr->info2)) { - return WERR_GENERAL_FAILURE; - } - break; - case 3: - if (!decode_printer_driver_3(mem_ctx, out.buffer, out.returned, &ctr->info3)) { - return WERR_GENERAL_FAILURE; - } - break; - default: - return WERR_UNKNOWN_LEVEL; - } + status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx, + server, + environment, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); } - return out.status; + return werror; } /********************************************************************** + convencience wrapper around rpccli_spoolss_EnumPrinters **********************************************************************/ -WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *handle, int level, uint32 *num_forms, - FORM_1 **forms) +WERROR rpccli_spoolss_enumprinters(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + uint32_t flags, + const char *server, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_PrinterInfo **info) { - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMFORMS in; - SPOOL_R_ENUMFORMS out; - RPC_BUFFER buffer; - uint32 offered; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - offered = 0; - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_enumforms( &in, handle, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMFORMS, - in, out, - qbuf, rbuf, - spoolss_io_q_enumforms, - spoolss_io_r_enumforms, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_enumforms( &in, handle, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMFORMS, - in, out, - qbuf, rbuf, - spoolss_io_q_enumforms, - spoolss_io_r_enumforms, - WERR_GENERAL_FAILURE ); - } - - if (!W_ERROR_IS_OK(out.status)) - return out.status; + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; - *num_forms = out.numofforms; - - if (!decode_forms_1(mem_ctx, out.buffer, *num_forms, forms)) { - return WERR_GENERAL_FAILURE; + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); } - return out.status; -} - -/********************************************************************** -**********************************************************************/ + status = rpccli_spoolss_EnumPrinters(cli, mem_ctx, + flags, + server, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); -WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 level, uint32 firstjob, - uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMJOBS in; - SPOOL_R_ENUMJOBS out; - RPC_BUFFER buffer; - uint32 offered; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - offered = 0; - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_enumjobs( &in, hnd, firstjob, num_jobs, level, - &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMJOBS, - in, out, - qbuf, rbuf, - spoolss_io_q_enumjobs, - spoolss_io_r_enumjobs, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_enumjobs( &in, hnd, firstjob, num_jobs, level, - &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMJOBS, - in, out, - qbuf, rbuf, - spoolss_io_q_enumjobs, - spoolss_io_r_enumjobs, - WERR_GENERAL_FAILURE ); - } + if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { + offered = needed; + buffer = data_blob_talloc_zero(mem_ctx, needed); + W_ERROR_HAVE_NO_MEMORY(buffer.data); - if (!W_ERROR_IS_OK(out.status)) - return out.status; - - switch(level) { - case 1: - if (!decode_jobs_1(mem_ctx, out.buffer, out.returned, &ctr->job.job_info_1)) { - return WERR_GENERAL_FAILURE; - } - break; - case 2: - if (!decode_jobs_2(mem_ctx, out.buffer, out.returned, &ctr->job.job_info_2)) { - return WERR_GENERAL_FAILURE; - } - break; - default: - DEBUG(3, ("unsupported info level %d", level)); - return WERR_UNKNOWN_LEVEL; + status = rpccli_spoolss_EnumPrinters(cli, mem_ctx, + flags, + server, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); } - - *returned = out.returned; - return out.status; + return werror; } /********************************************************************** + convencience wrapper around rpccli_spoolss_GetPrinterData **********************************************************************/ -WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, const char *valuename, - REGISTRY_VALUE *value) +WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + const char *value_name, + uint32_t offered, + enum winreg_Type *type, + union spoolss_PrinterData *data) { - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTERDATA in; - SPOOL_R_GETPRINTERDATA out; - uint32 offered; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - offered = 0; - make_spoolss_q_getprinterdata( &in, hnd, valuename, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDATA, - in, out, - qbuf, rbuf, - spoolss_io_q_getprinterdata, - spoolss_io_r_getprinterdata, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - make_spoolss_q_getprinterdata( &in, hnd, valuename, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDATA, - in, out, - qbuf, rbuf, - spoolss_io_q_getprinterdata, - spoolss_io_r_getprinterdata, - WERR_GENERAL_FAILURE ); - } + NTSTATUS status; + WERROR werror; + uint32_t needed; - if (!W_ERROR_IS_OK(out.status)) - return out.status; + status = rpccli_spoolss_GetPrinterData(cli, mem_ctx, + handle, + value_name, + offered, + type, + data, + &needed, + &werror); - /* Return output parameters */ + if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) { + offered = needed; - if (out.needed) { - value->data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, out.data, out.needed); - } else { - value->data_p = NULL; + status = rpccli_spoolss_GetPrinterData(cli, mem_ctx, + handle, + value_name, + offered, + type, + data, + &needed, + &werror); } - value->type = out.type; - value->size = out.size; - - return out.status; -} -/********************************************************************** -**********************************************************************/ - -WERROR rpccli_spoolss_setprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, REGISTRY_VALUE *value) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETPRINTERDATA in; - SPOOL_R_SETPRINTERDATA out; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - make_spoolss_q_setprinterdata( &in, hnd, value->valuename, - value->type, (char *)value->data_p, value->size); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETPRINTERDATA, - in, out, - qbuf, rbuf, - spoolss_io_q_setprinterdata, - spoolss_io_r_setprinterdata, - WERR_GENERAL_FAILURE ); - - return out.status; + return werror; } /********************************************************************** + convencience wrapper around rpccli_spoolss_EnumPrinterKey **********************************************************************/ -WERROR rpccli_spoolss_enumprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 ndx, - uint32 value_offered, uint32 data_offered, - uint32 *value_needed, uint32 *data_needed, - REGISTRY_VALUE *value) +WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + const char *key_name, + const char ***key_buffer, + uint32_t offered) { - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERDATA in; - SPOOL_R_ENUMPRINTERDATA out; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - make_spoolss_q_enumprinterdata( &in, hnd, ndx, value_offered, data_offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATA, - in, out, - qbuf, rbuf, - spoolss_io_q_enumprinterdata, - spoolss_io_r_enumprinterdata, - WERR_GENERAL_FAILURE ); - - if ( value_needed ) - *value_needed = out.realvaluesize; - if ( data_needed ) - *data_needed = out.realdatasize; - - if (!W_ERROR_IS_OK(out.status)) - return out.status; - - if (value) { - rpcstr_pull(value->valuename, out.value, sizeof(value->valuename), -1, - STR_TERMINATE); - if (out.realdatasize) { - value->data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, out.data, - out.realdatasize); - } else { - value->data_p = NULL; - } - value->type = out.type; - value->size = out.realdatasize; - } - - return out.status; -} - -/********************************************************************** -**********************************************************************/ + NTSTATUS status; + WERROR werror; + uint32_t needed; -WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, const char *keyname, - REGVAL_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERDATAEX in; - SPOOL_R_ENUMPRINTERDATAEX out; - int i; - uint32 offered; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - offered = 0; - make_spoolss_q_enumprinterdataex( &in, hnd, keyname, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATAEX, - in, out, - qbuf, rbuf, - spoolss_io_q_enumprinterdataex, - spoolss_io_r_enumprinterdataex, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - make_spoolss_q_enumprinterdataex( &in, hnd, keyname, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATAEX, - in, out, - qbuf, rbuf, - spoolss_io_q_enumprinterdataex, - spoolss_io_r_enumprinterdataex, - WERR_GENERAL_FAILURE ); - } - - if (!W_ERROR_IS_OK(out.status)) - return out.status; + status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx, + handle, + key_name, + key_buffer, + offered, + &needed, + &werror); - for (i = 0; i < out.returned; i++) { - PRINTER_ENUM_VALUES *v = &out.ctr.values[i]; - fstring name; + if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) { + offered = needed; - rpcstr_pull(name, v->valuename.buffer, sizeof(name), -1, - STR_TERMINATE); - regval_ctr_addvalue(ctr, name, v->type, (const char *)v->data, v->data_len); + status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx, + handle, + key_name, + key_buffer, + offered, + &needed, + &werror); } - return out.status; + return werror; } /********************************************************************** + convencience wrapper around rpccli_spoolss_EnumPrinterDataEx **********************************************************************/ -WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, const char *keyname, - uint16 **keylist, uint32 *len) +WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + const char *key_name, + uint32_t offered, + uint32_t *count, + struct spoolss_PrinterEnumValues **info) { - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERKEY in; - SPOOL_R_ENUMPRINTERKEY out; - uint32 offered = 0; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - make_spoolss_q_enumprinterkey( &in, hnd, keyname, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERKEY, - in, out, - qbuf, rbuf, - spoolss_io_q_enumprinterkey, - spoolss_io_r_enumprinterkey, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - make_spoolss_q_enumprinterkey( &in, hnd, keyname, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERKEY, - in, out, - qbuf, rbuf, - spoolss_io_q_enumprinterkey, - spoolss_io_r_enumprinterkey, - WERR_GENERAL_FAILURE ); - } + NTSTATUS status; + WERROR werror; + uint32_t needed; + + status = rpccli_spoolss_EnumPrinterDataEx(cli, mem_ctx, + handle, + key_name, + offered, + count, + info, + &needed, + &werror); - if ( !W_ERROR_IS_OK(out.status) ) - return out.status; - - if (keylist) { - *keylist = SMB_MALLOC_ARRAY(uint16, out.keys.buf_len); - if (!*keylist) { - return WERR_NOMEM; - } - memcpy(*keylist, out.keys.buffer, out.keys.buf_len * 2); - if (len) - *len = out.keys.buf_len * 2; + if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) { + offered = needed; + + status = rpccli_spoolss_EnumPrinterDataEx(cli, mem_ctx, + handle, + key_name, + offered, + count, + info, + &needed, + &werror); } - return out.status; + return werror; } -/** @} **/ diff --git a/source3/rpc_client/init_spoolss.c b/source3/rpc_client/init_spoolss.c index a6255adf3d..4c105ea3bc 100644 --- a/source3/rpc_client/init_spoolss.c +++ b/source3/rpc_client/init_spoolss.c @@ -40,3 +40,36 @@ bool init_systemtime(struct spoolss_Time *r, return true; } + +/******************************************************************* + ********************************************************************/ + +WERROR pull_spoolss_PrinterData(TALLOC_CTX *mem_ctx, + const DATA_BLOB *blob, + union spoolss_PrinterData *data, + enum winreg_Type type) +{ + enum ndr_err_code ndr_err; + ndr_err = ndr_pull_union_blob(blob, mem_ctx, NULL, data, type, + (ndr_pull_flags_fn_t)ndr_pull_spoolss_PrinterData); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return WERR_GENERAL_FAILURE; + } + return WERR_OK; +} + +/******************************************************************* + ********************************************************************/ + +WERROR push_spoolss_PrinterData(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, + enum winreg_Type type, + union spoolss_PrinterData *data) +{ + enum ndr_err_code ndr_err; + ndr_err = ndr_push_union_blob(blob, mem_ctx, NULL, data, type, + (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterData); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return WERR_GENERAL_FAILURE; + } + return WERR_OK; +} diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c index 658ffe30d6..b1d9d8fbe1 100644 --- a/source3/rpc_client/rpc_transport_sock.c +++ b/source3/rpc_client/rpc_transport_sock.c @@ -61,8 +61,7 @@ static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - subreq->async.fn = rpc_sock_read_done; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, rpc_sock_read_done, result); return result; fail: TALLOC_FREE(result); @@ -71,8 +70,8 @@ static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, static void rpc_sock_read_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); struct rpc_sock_read_state *state = talloc_get_type_abort( req->private_data, struct rpc_sock_read_state); int err; @@ -123,8 +122,7 @@ static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - subreq->async.fn = rpc_sock_write_done; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, rpc_sock_write_done, result); return result; fail: TALLOC_FREE(result); @@ -133,8 +131,8 @@ static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, static void rpc_sock_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); struct rpc_sock_write_state *state = talloc_get_type_abort( req->private_data, struct rpc_sock_write_state); int err; diff --git a/source3/rpc_parse/parse_buffer.c b/source3/rpc_parse/parse_buffer.c deleted file mode 100644 index 99546ef3fb..0000000000 --- a/source3/rpc_parse/parse_buffer.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines - * - * Copyright (C) Andrew Tridgell 1992-2000, - * Copyright (C) Luke Kenneth Casson Leighton 1996-2000, - * Copyright (C) Jean François Micouleau 1998-2000, - * Copyright (C) Gerald Carter 2000-2005, - * Copyright (C) Tim Potter 2001-2002. - * - * 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 3 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, see <http://www.gnu.org/licenses/>. - */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_PARSE - -/********************************************************************** - Initialize a new spoolss buff for use by a client rpc -**********************************************************************/ -bool rpcbuf_init(RPC_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx) -{ - buffer->size = size; - buffer->string_at_end = size; - if (!prs_init(&buffer->prs, size, ctx, MARSHALL)) - return false; - - buffer->struct_start = prs_offset(&buffer->prs); - return true; -} - -/******************************************************************* - Read/write a RPC_BUFFER struct. -********************************************************************/ - -bool prs_rpcbuffer(const char *desc, prs_struct *ps, int depth, RPC_BUFFER *buffer) -{ - prs_debug(ps, depth, desc, "prs_rpcbuffer"); - depth++; - - /* reading */ - if (UNMARSHALLING(ps)) { - buffer->size=0; - buffer->string_at_end=0; - - if (!prs_uint32("size", ps, depth, &buffer->size)) - return False; - - /* - * JRA. I'm not sure if the data in here is in big-endian format if - * the client is big-endian. Leave as default (little endian) for now. - */ - - if (!prs_init(&buffer->prs, buffer->size, prs_get_mem_context(ps), UNMARSHALL)) - return False; - - if (!prs_append_some_prs_data(&buffer->prs, ps, prs_offset(ps), buffer->size)) - return False; - - if (!prs_set_offset(&buffer->prs, 0)) - return False; - - if (!prs_set_offset(ps, buffer->size+prs_offset(ps))) - return False; - - buffer->string_at_end=buffer->size; - - return True; - } - else { - bool ret = False; - - if (!prs_uint32("size", ps, depth, &buffer->size)) - goto out; - - if (!prs_append_some_prs_data(ps, &buffer->prs, 0, buffer->size)) - goto out; - - ret = True; - out: - - /* We have finished with the data in buffer->prs - free it. */ - prs_mem_free(&buffer->prs); - - return ret; - } -} - -/******************************************************************* - Read/write an RPC_BUFFER* struct.(allocate memory if unmarshalling) -********************************************************************/ - -bool prs_rpcbuffer_p(const char *desc, prs_struct *ps, int depth, RPC_BUFFER **buffer) -{ - uint32 data_p; - - /* caputure the pointer value to stream */ - - data_p = *buffer ? 0xf000baaa : 0; - - if ( !prs_uint32("ptr", ps, depth, &data_p )) - return False; - - /* we're done if there is no data */ - - if ( !data_p ) - return True; - - if ( UNMARSHALLING(ps) ) { - if ( !(*buffer = PRS_ALLOC_MEM(ps, RPC_BUFFER, 1)) ) - return False; - } else { - /* Marshalling case. - coverity paranoia - should already be ok if data_p != 0 */ - if (!*buffer) { - return True; - } - } - - return prs_rpcbuffer( desc, ps, depth, *buffer); -} - -/**************************************************************************** - Allocate more memory for a RPC_BUFFER. -****************************************************************************/ - -bool rpcbuf_alloc_size(RPC_BUFFER *buffer, uint32 buffer_size) -{ - prs_struct *ps; - uint32 extra_space; - uint32 old_offset; - - /* if we don't need anything. don't do anything */ - - if ( buffer_size == 0x0 ) - return True; - - if (!buffer) { - return False; - } - - ps= &buffer->prs; - - /* damn, I'm doing the reverse operation of prs_grow() :) */ - if (buffer_size < prs_data_size(ps)) - extra_space=0; - else - extra_space = buffer_size - prs_data_size(ps); - - /* - * save the offset and move to the end of the buffer - * prs_grow() checks the extra_space against the offset - */ - old_offset=prs_offset(ps); - prs_set_offset(ps, prs_data_size(ps)); - - if (!prs_grow(ps, extra_space)) - return False; - - prs_set_offset(ps, old_offset); - - buffer->string_at_end=prs_data_size(ps); - - return True; -} - -/******************************************************************* - move a BUFFER from the query to the reply. - As the data pointers in RPC_BUFFER are malloc'ed, not talloc'ed, - this is ok. This is an OPTIMIZATION and is not strictly neccessary. - Clears the memory to zero also. -********************************************************************/ - -void rpcbuf_move(RPC_BUFFER *src, RPC_BUFFER **dest) -{ - if ( !src ) { - *dest = NULL; - return; - } - - prs_switch_type( &src->prs, MARSHALL ); - - if ( !prs_set_offset(&src->prs, 0) ) - return; - - prs_force_dynamic( &src->prs ); - prs_mem_clear( &src->prs ); - - *dest = src; -} - -/******************************************************************* - Get the size of a BUFFER struct. -********************************************************************/ - -uint32 rpcbuf_get_size(RPC_BUFFER *buffer) -{ - return (buffer->size); -} - - -/******************************************************************* - * write a UNICODE string and its relative pointer. - * used by all the RPC structs passing a buffer - * - * As I'm a nice guy, I'm forcing myself to explain this code. - * MS did a good job in the overall spoolss code except in some - * functions where they are passing the API buffer directly in the - * RPC request/reply. That's to maintain compatiility at the API level. - * They could have done it the good way the first time. - * - * So what happen is: the strings are written at the buffer's end, - * in the reverse order of the original structure. Some pointers to - * the strings are also in the buffer. Those are relative to the - * buffer's start. - * - * If you don't understand or want to change that function, - * first get in touch with me: jfm@samba.org - * - ********************************************************************/ - -bool smb_io_relstr(const char *desc, RPC_BUFFER *buffer, int depth, UNISTR *string) -{ - prs_struct *ps=&buffer->prs; - - if (MARSHALLING(ps)) { - uint32 struct_offset = prs_offset(ps); - uint32 relative_offset; - - buffer->string_at_end -= (size_of_relative_string(string) - 4); - if(!prs_set_offset(ps, buffer->string_at_end)) - return False; -#if 0 /* JERRY */ - /* - * Win2k does not align strings in a buffer - * Tested against WinNT 4.0 SP 6a & 2k SP2 --jerry - */ - if (!prs_align(ps)) - return False; -#endif - buffer->string_at_end = prs_offset(ps); - - /* write the string */ - if (!smb_io_unistr(desc, string, ps, depth)) - return False; - - if(!prs_set_offset(ps, struct_offset)) - return False; - - relative_offset=buffer->string_at_end - buffer->struct_start; - /* write its offset */ - if (!prs_uint32("offset", ps, depth, &relative_offset)) - return False; - } - else { - uint32 old_offset; - - /* read the offset */ - if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end))) - return False; - - if (buffer->string_at_end == 0) - return True; - - old_offset = prs_offset(ps); - if(!prs_set_offset(ps, buffer->string_at_end+buffer->struct_start)) - return False; - - /* read the string */ - if (!smb_io_unistr(desc, string, ps, depth)) - return False; - - if(!prs_set_offset(ps, old_offset)) - return False; - } - return True; -} - -/******************************************************************* - * write a array of UNICODE strings and its relative pointer. - * used by 2 RPC structs - ********************************************************************/ - -bool smb_io_relarraystr(const char *desc, RPC_BUFFER *buffer, int depth, uint16 **string) -{ - UNISTR chaine; - - prs_struct *ps=&buffer->prs; - - if (MARSHALLING(ps)) { - uint32 struct_offset = prs_offset(ps); - uint32 relative_offset; - uint16 *p; - uint16 *q; - uint16 zero=0; - p=*string; - q=*string; - - /* first write the last 0 */ - buffer->string_at_end -= 2; - if(!prs_set_offset(ps, buffer->string_at_end)) - return False; - - if(!prs_uint16("leading zero", ps, depth, &zero)) - return False; - - while (p && (*p!=0)) { - while (*q!=0) - q++; - - /* Yes this should be malloc not talloc. Don't change. */ - - chaine.buffer = (uint16 *) - SMB_MALLOC((q-p+1)*sizeof(uint16)); - if (chaine.buffer == NULL) - return False; - - memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16)); - - buffer->string_at_end -= (q-p+1)*sizeof(uint16); - - if(!prs_set_offset(ps, buffer->string_at_end)) { - SAFE_FREE(chaine.buffer); - return False; - } - - /* write the string */ - if (!smb_io_unistr(desc, &chaine, ps, depth)) { - SAFE_FREE(chaine.buffer); - return False; - } - q++; - p=q; - - SAFE_FREE(chaine.buffer); - } - - if(!prs_set_offset(ps, struct_offset)) - return False; - - relative_offset=buffer->string_at_end - buffer->struct_start; - /* write its offset */ - if (!prs_uint32("offset", ps, depth, &relative_offset)) - return False; - - } else { - - /* UNMARSHALLING */ - - uint32 old_offset; - uint16 *chaine2=NULL; - int l_chaine=0; - int l_chaine2=0; - size_t realloc_size = 0; - - *string=NULL; - - /* read the offset */ - if (!prs_uint32("offset", ps, depth, &buffer->string_at_end)) - return False; - - old_offset = prs_offset(ps); - if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start)) - return False; - - do { - if (!smb_io_unistr(desc, &chaine, ps, depth)) { - SAFE_FREE(chaine2); - return False; - } - - l_chaine=str_len_uni(&chaine); - - /* we're going to add two more bytes here in case this - is the last string in the array and we need to add - an extra NULL for termination */ - if (l_chaine > 0) { - realloc_size = (l_chaine2+l_chaine+2)*sizeof(uint16); - - /* Yes this should be realloc - it's freed below. JRA */ - - if((chaine2=(uint16 *)SMB_REALLOC(chaine2, realloc_size)) == NULL) { - return False; - } - memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16)); - l_chaine2+=l_chaine+1; - } - - } while(l_chaine!=0); - - /* the end should be bould NULL terminated so add - the second one here */ - if (chaine2) - { - chaine2[l_chaine2] = '\0'; - *string=(uint16 *)TALLOC_MEMDUP(prs_get_mem_context(ps),chaine2,realloc_size); - SAFE_FREE(chaine2); - if (!*string) { - return False; - } - } - - if(!prs_set_offset(ps, old_offset)) - return False; - } - return True; -} - -/******************************************************************* - Parse a DEVMODE structure and its relative pointer. -********************************************************************/ - -bool smb_io_relsecdesc(const char *desc, RPC_BUFFER *buffer, int depth, SEC_DESC **secdesc) -{ - prs_struct *ps= &buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_relsecdesc"); - depth++; - - if (MARSHALLING(ps)) { - uint32 struct_offset = prs_offset(ps); - uint32 relative_offset; - - if (! *secdesc) { - relative_offset = 0; - if (!prs_uint32("offset", ps, depth, &relative_offset)) - return False; - return True; - } - - if (*secdesc != NULL) { - buffer->string_at_end -= ndr_size_security_descriptor(*secdesc, NULL, 0); - - if(!prs_set_offset(ps, buffer->string_at_end)) - return False; - /* write the secdesc */ - if (!sec_io_desc(desc, secdesc, ps, depth)) - return False; - - if(!prs_set_offset(ps, struct_offset)) - return False; - } - - relative_offset=buffer->string_at_end - buffer->struct_start; - /* write its offset */ - - if (!prs_uint32("offset", ps, depth, &relative_offset)) - return False; - } else { - uint32 old_offset; - - /* read the offset */ - if (!prs_uint32("offset", ps, depth, &buffer->string_at_end)) - return False; - - old_offset = prs_offset(ps); - if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start)) - return False; - - /* read the sd */ - if (!sec_io_desc(desc, secdesc, ps, depth)) - return False; - - if(!prs_set_offset(ps, old_offset)) - return False; - } - return True; -} - - - -/******************************************************************* - * return the length of a UNICODE string in number of char, includes: - * - the leading zero - * - the relative pointer size - ********************************************************************/ - -uint32 size_of_relative_string(UNISTR *string) -{ - uint32 size=0; - - size=str_len_uni(string); /* the string length */ - size=size+1; /* add the trailing zero */ - size=size*2; /* convert in char */ - size=size+4; /* add the size of the ptr */ - -#if 0 /* JERRY */ - /* - * Do not include alignment as Win2k does not align relative - * strings within a buffer --jerry - */ - /* Ensure size is 4 byte multiple (prs_align is being called...). */ - /* size += ((4 - (size & 3)) & 3); */ -#endif - - return size; -} - diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index 38d5b95376..8b4135a1e8 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -59,12 +59,45 @@ bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth) } /******************************************************************* - Reads or writes an NTTIME structure. ********************************************************************/ -bool smb_io_nttime(const char *desc, prs_struct *ps, int depth, NTTIME *nttime) +bool smb_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime) +{ + if(!prs_uint16("year", ps, depth, &systime->year)) + return False; + if(!prs_uint16("month", ps, depth, &systime->month)) + return False; + if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek)) + return False; + if(!prs_uint16("day", ps, depth, &systime->day)) + return False; + if(!prs_uint16("hour", ps, depth, &systime->hour)) + return False; + if(!prs_uint16("minute", ps, depth, &systime->minute)) + return False; + if(!prs_uint16("second", ps, depth, &systime->second)) + return False; + if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds)) + return False; + + return True; +} + +/******************************************************************* +********************************************************************/ + +bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime) { - return smb_io_time( desc, nttime, ps, depth ); + systime->year=unixtime->tm_year+1900; + systime->month=unixtime->tm_mon+1; + systime->dayofweek=unixtime->tm_wday; + systime->day=unixtime->tm_mday; + systime->hour=unixtime->tm_hour; + systime->minute=unixtime->tm_min; + systime->second=unixtime->tm_sec; + systime->milliseconds=0; + + return True; } /******************************************************************* @@ -153,100 +186,6 @@ void init_unistr(UNISTR *str, const char *buf) } /******************************************************************* -reads or writes a UNISTR structure. -XXXX NOTE: UNISTR structures NEED to be null-terminated. -********************************************************************/ - -bool smb_io_unistr(const char *desc, UNISTR *uni, prs_struct *ps, int depth) -{ - if (uni == NULL) - return False; - - prs_debug(ps, depth, desc, "smb_io_unistr"); - depth++; - - if(!prs_unistr("unistr", ps, depth, uni)) - return False; - - return True; -} - -/******************************************************************* -reads or writes a BUFFER5 structure. -the buf_len member tells you how large the buffer is. -********************************************************************/ -bool smb_io_buffer5(const char *desc, BUFFER5 *buf5, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "smb_io_buffer5"); - depth++; - - if (buf5 == NULL) return False; - - if(!prs_align(ps)) - return False; - if(!prs_uint32("buf_len", ps, depth, &buf5->buf_len)) - return False; - - if(buf5->buf_len) { - if(!prs_buffer5(True, "buffer" , ps, depth, buf5)) - return False; - } - - return True; -} - -/******************************************************************* -creates a UNISTR2 structure: sets up the buffer, too -********************************************************************/ - -void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf) -{ - if (buf != NULL) { - *ptr = 1; - init_unistr2(str, buf, UNI_STR_TERMINATE); - } else { - *ptr = 0; - init_unistr2(str, NULL, UNI_FLAGS_NONE); - - } -} - -/******************************************************************* - Copies a UNISTR2 structure. -********************************************************************/ - -void copy_unistr2(UNISTR2 *str, const UNISTR2 *from) -{ - if (from->buffer == NULL) { - ZERO_STRUCTP(str); - return; - } - - SMB_ASSERT(from->uni_max_len >= from->uni_str_len); - - str->uni_max_len = from->uni_max_len; - str->offset = from->offset; - str->uni_str_len = from->uni_str_len; - - /* the string buffer is allocated to the maximum size - (the the length of the source string) to prevent - reallocation of memory. */ - if (str->buffer == NULL) { - if (str->uni_max_len) { - str->buffer = (uint16 *)TALLOC_ZERO_ARRAY(talloc_tos(), uint16, str->uni_max_len); - if ((str->buffer == NULL)) { - smb_panic("copy_unistr2: talloc fail"); - return; - } - /* copy the string */ - memcpy(str->buffer, from->buffer, str->uni_max_len*sizeof(uint16)); - } else { - str->buffer = NULL; - } - } -} - -/******************************************************************* Inits a UNISTR2 structure. ********************************************************************/ @@ -301,343 +240,3 @@ void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags) if ( num_chars && ((flags == UNI_MAXLEN_TERMINATE) || (flags == UNI_BROKEN_NON_NULL)) ) str->uni_max_len++; } - -/** - * Inits a UNISTR2 structure. - * @param ctx talloc context to allocate string on - * @param str pointer to string to create - * @param buf UCS2 null-terminated buffer to init from -*/ - -void init_unistr2_w(TALLOC_CTX *ctx, UNISTR2 *str, const smb_ucs2_t *buf) -{ - uint32 len = buf ? strlen_w(buf) : 0; - - ZERO_STRUCTP(str); - - /* set up string lengths. */ - str->uni_max_len = len; - str->offset = 0; - str->uni_str_len = len; - - if (len + 1) { - str->buffer = TALLOC_ZERO_ARRAY(ctx, uint16, len + 1); - if (str->buffer == NULL) { - smb_panic("init_unistr2_w: talloc fail"); - return; - } - } else { - str->buffer = NULL; - } - - /* - * don't move this test above ! The UNISTR2 must be initialized !!! - * jfm, 7/7/2001. - */ - if (buf==NULL) - return; - - /* Yes, this is a strncpy( foo, bar, strlen(bar)) - but as - long as the buffer above is talloc()ed correctly then this - is the correct thing to do */ - if (len+1) { - strncpy_w(str->buffer, buf, len + 1); - } -} - -/******************************************************************* - Inits a UNISTR2 structure from a UNISTR -********************************************************************/ - -void init_unistr2_from_unistr(TALLOC_CTX *ctx, UNISTR2 *to, const UNISTR *from) -{ - uint32 i; - - /* the destination UNISTR2 should never be NULL. - if it is it is a programming error */ - - /* if the source UNISTR is NULL, then zero out - the destination string and return */ - ZERO_STRUCTP (to); - if ((from == NULL) || (from->buffer == NULL)) - return; - - /* get the length; UNISTR must be NULL terminated */ - i = 0; - while ((from->buffer)[i]!='\0') - i++; - i++; /* one more to catch the terminating NULL */ - /* is this necessary -- jerry? I need to think */ - - /* set up string lengths; uni_max_len is set to i+1 - because we need to account for the final NULL termination */ - to->uni_max_len = i; - to->offset = 0; - to->uni_str_len = i; - - /* allocate the space and copy the string buffer */ - if (i) { - to->buffer = TALLOC_ZERO_ARRAY(ctx, uint16, i); - if (to->buffer == NULL) - smb_panic("init_unistr2_from_unistr: talloc fail"); - memcpy(to->buffer, from->buffer, i*sizeof(uint16)); - } else { - to->buffer = NULL; - } - return; -} - -/******************************************************************* - Inits a UNISTR2 structure from a DATA_BLOB. - The length of the data_blob must count the bytes of the buffer. - Copies the blob data. -********************************************************************/ - -void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob) -{ - /* Allocs the unistring */ - init_unistr2(str, NULL, UNI_FLAGS_NONE); - - /* Sets the values */ - str->uni_str_len = blob->length / sizeof(uint16); - str->uni_max_len = str->uni_str_len; - str->offset = 0; - if (blob->length) { - str->buffer = (uint16 *) memdup(blob->data, blob->length); - } else { - str->buffer = NULL; - } - if ((str->buffer == NULL) && (blob->length > 0)) { - smb_panic("init_unistr2_from_datablob: malloc fail"); - } -} - -/******************************************************************* - UNISTR2* are a little different in that the pointer and the UNISTR2 - are not necessarily read/written back to back. So we break it up - into 2 separate functions. - See SPOOL_USER_1 in include/rpc_spoolss.h for an example. -********************************************************************/ - -bool prs_io_unistr2_p(const char *desc, prs_struct *ps, int depth, UNISTR2 **uni2) -{ - uint32 data_p; - - /* caputure the pointer value to stream */ - - data_p = *uni2 ? 0xf000baaa : 0; - - if ( !prs_uint32("ptr", ps, depth, &data_p )) - return False; - - /* we're done if there is no data */ - - if ( !data_p ) - return True; - - if (UNMARSHALLING(ps)) { - if ( !(*uni2 = PRS_ALLOC_MEM(ps, UNISTR2, 1)) ) - return False; - } - - return True; -} - -/******************************************************************* - now read/write the actual UNISTR2. Memory for the UNISTR2 (but - not UNISTR2.buffer) has been allocated previously by prs_unistr2_p() -********************************************************************/ - -bool prs_io_unistr2(const char *desc, prs_struct *ps, int depth, UNISTR2 *uni2 ) -{ - /* just return true if there is no pointer to deal with. - the memory must have been previously allocated on unmarshalling - by prs_unistr2_p() */ - - if ( !uni2 ) - return True; - - /* just pass off to smb_io_unstr2() passing the uni2 address as - the pointer (like you would expect) */ - - return smb_io_unistr2( desc, uni2, uni2 ? 1 : 0, ps, depth ); -} - -/******************************************************************* - Reads or writes a UNISTR2 structure. - XXXX NOTE: UNISTR2 structures need NOT be null-terminated. - the uni_str_len member tells you how long the string is; - the uni_max_len member tells you how large the buffer is. -********************************************************************/ - -bool smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth) -{ - if (uni2 == NULL) - return False; - - if (buffer) { - - prs_debug(ps, depth, desc, "smb_io_unistr2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("uni_max_len", ps, depth, &uni2->uni_max_len)) - return False; - if(!prs_uint32("offset ", ps, depth, &uni2->offset)) - return False; - if(!prs_uint32("uni_str_len", ps, depth, &uni2->uni_str_len)) - return False; - - /* buffer advanced by indicated length of string - NOT by searching for null-termination */ - if(!prs_unistr2(True, "buffer ", ps, depth, uni2)) - return False; - - } else { - - prs_debug(ps, depth, desc, "smb_io_unistr2 - NULL"); - depth++; - memset((char *)uni2, '\0', sizeof(*uni2)); - - } - - return True; -} - -/******************************************************************* - Reads or writes an POLICY_HND structure. -********************************************************************/ - -bool smb_io_pol_hnd(const char *desc, POLICY_HND *pol, prs_struct *ps, int depth) -{ - if (pol == NULL) - return False; - - prs_debug(ps, depth, desc, "smb_io_pol_hnd"); - depth++; - - if(!prs_align(ps)) - return False; - - if(UNMARSHALLING(ps)) - ZERO_STRUCTP(pol); - - if (!prs_uint32("handle_type", ps, depth, &pol->handle_type)) - return False; - if (!smb_io_uuid("uuid", (struct GUID*)&pol->uuid, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Create a UNISTR3. -********************************************************************/ - -void init_unistr3(UNISTR3 *str, const char *buf) -{ - if (buf == NULL) { - str->uni_str_len=0; - str->str.buffer = NULL; - return; - } - - str->uni_str_len = strlen(buf) + 1; - - if (str->uni_str_len) { - str->str.buffer = TALLOC_ZERO_ARRAY(talloc_tos(), uint16, str->uni_str_len); - if (str->str.buffer == NULL) - smb_panic("init_unistr3: malloc fail"); - - rpcstr_push((char *)str->str.buffer, buf, str->uni_str_len * sizeof(uint16), STR_TERMINATE); - } else { - str->str.buffer = NULL; - } -} - -/******************************************************************* - Reads or writes a UNISTR3 structure. -********************************************************************/ - -bool smb_io_unistr3(const char *desc, UNISTR3 *name, prs_struct *ps, int depth) -{ - if (name == NULL) - return False; - - prs_debug(ps, depth, desc, "smb_io_unistr3"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("uni_str_len", ps, depth, &name->uni_str_len)) - return False; - - /* we're done if there is no string */ - - if ( name->uni_str_len == 0 ) - return True; - - /* don't know if len is specified by uni_str_len member... */ - /* assume unicode string is unicode-null-terminated, instead */ - - if(!prs_unistr3(True, "unistr", name, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Stream a uint64_struct - ********************************************************************/ -bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64) -{ - if (UNMARSHALLING(ps)) { - uint32 high, low; - - if (!prs_uint32(name, ps, depth+1, &low)) - return False; - - if (!prs_uint32(name, ps, depth+1, &high)) - return False; - - *data64 = ((uint64_t)high << 32) + low; - - return True; - } else { - uint32 high = (*data64) >> 32, low = (*data64) & 0xFFFFFFFF; - return prs_uint32(name, ps, depth+1, &low) && - prs_uint32(name, ps, depth+1, &high); - } -} - -/******************************************************************* -return the length of a UNISTR string. -********************************************************************/ - -uint32 str_len_uni(UNISTR *source) -{ - uint32 i=0; - - if (!source->buffer) - return 0; - - while (source->buffer[i]) - i++; - - return i; -} - -/******************************************************************* - Verifies policy handle -********************************************************************/ - -bool policy_handle_is_valid(const POLICY_HND *hnd) -{ - POLICY_HND zero_pol; - - ZERO_STRUCT(zero_pol); - return ((memcmp(&zero_pol, hnd, sizeof(POLICY_HND)) == 0) ? false : true ); -} diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index bc9202cccc..94732b0a74 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -760,6 +760,30 @@ bool prs_int32(const char *name, prs_struct *ps, int depth, int32 *data32) } /******************************************************************* + Stream a uint64_struct + ********************************************************************/ +bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64) +{ + if (UNMARSHALLING(ps)) { + uint32 high, low; + + if (!prs_uint32(name, ps, depth+1, &low)) + return False; + + if (!prs_uint32(name, ps, depth+1, &high)) + return False; + + *data64 = ((uint64_t)high << 32) + low; + + return True; + } else { + uint32 high = (*data64) >> 32, low = (*data64) & 0xFFFFFFFF; + return prs_uint32(name, ps, depth+1, &low) && + prs_uint32(name, ps, depth+1, &high); + } +} + +/******************************************************************* Stream a NTSTATUS ********************************************************************/ @@ -1025,37 +1049,6 @@ bool prs_uint32s(bool charmode, const char *name, prs_struct *ps, int depth, uin } /****************************************************************** - Stream an array of unicode string, length/buffer specified separately, - in uint16 chars. The unicode string is already in little-endian format. - ********************************************************************/ - -bool prs_buffer5(bool charmode, const char *name, prs_struct *ps, int depth, BUFFER5 *str) -{ - char *p; - char *q = prs_mem_get(ps, str->buf_len * sizeof(uint16)); - if (q == NULL) - return False; - - /* If the string is empty, we don't have anything to stream */ - if (str->buf_len==0) - return True; - - if (UNMARSHALLING(ps)) { - str->buffer = PRS_ALLOC_MEM(ps,uint16,str->buf_len); - if (str->buffer == NULL) - return False; - } - - p = (char *)str->buffer; - - dbg_rw_punival(charmode, name, depth, ps, q, p, str->buf_len); - - ps->data_offset += (str->buf_len * sizeof(uint16)); - - return True; -} - -/****************************************************************** Stream a unicode string, length/buffer specified separately, in uint16 chars. The unicode string is already in little-endian format. ********************************************************************/ @@ -1093,36 +1086,6 @@ bool prs_unistr2(bool charmode, const char *name, prs_struct *ps, int depth, UNI return True; } -/****************************************************************** - Stream a unicode string, length/buffer specified separately, - in uint16 chars. The unicode string is already in little-endian format. - ********************************************************************/ - -bool prs_unistr3(bool charmode, const char *name, UNISTR3 *str, prs_struct *ps, int depth) -{ - char *p; - char *q = prs_mem_get(ps, str->uni_str_len * sizeof(uint16)); - if (q == NULL) - return False; - - if (UNMARSHALLING(ps)) { - if (str->uni_str_len) { - str->str.buffer = PRS_ALLOC_MEM(ps,uint16,str->uni_str_len); - if (str->str.buffer == NULL) - return False; - } else { - str->str.buffer = NULL; - } - } - - p = (char *)str->str.buffer; - - dbg_rw_punival(charmode, name, depth, ps, q, p, str->uni_str_len); - ps->data_offset += (str->uni_str_len * sizeof(uint16)); - - return True; -} - /******************************************************************* Stream a unicode null-terminated string. As the string is already in little-endian format then do it as a stream of bytes. diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c index 1477a4c81e..14a4effbf0 100644 --- a/source3/rpc_parse/parse_rpc.c +++ b/source3/rpc_parse/parse_rpc.c @@ -639,13 +639,3 @@ bool smb_io_rpc_auth_schannel_chk(const char *desc, int auth_len, return True; } - -const struct ndr_syntax_id syntax_spoolss = { - { - 0x12345678, 0x1234, 0xabcd, - { 0xef, 0x00 }, - { 0x01, 0x23, - 0x45, 0x67, 0x89, 0xab } - }, 0x01 -}; - diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c deleted file mode 100644 index 78c041f863..0000000000 --- a/source3/rpc_parse/parse_spoolss.c +++ /dev/null @@ -1,3101 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines - * Copyright (C) Andrew Tridgell 1992-2000, - * Copyright (C) Luke Kenneth Casson Leighton 1996-2000, - * Copyright (C) Jean François Micouleau 1998-2000, - * Copyright (C) Gerald Carter 2000-2002, - * Copyright (C) Tim Potter 2001-2002. - * - * 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 3 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, see <http://www.gnu.org/licenses/>. - */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_PARSE - - -/******************************************************************* -This should be moved in a more generic lib. -********************************************************************/ - -bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime) -{ - if(!prs_uint16("year", ps, depth, &systime->year)) - return False; - if(!prs_uint16("month", ps, depth, &systime->month)) - return False; - if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek)) - return False; - if(!prs_uint16("day", ps, depth, &systime->day)) - return False; - if(!prs_uint16("hour", ps, depth, &systime->hour)) - return False; - if(!prs_uint16("minute", ps, depth, &systime->minute)) - return False; - if(!prs_uint16("second", ps, depth, &systime->second)) - return False; - if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime) -{ - systime->year=unixtime->tm_year+1900; - systime->month=unixtime->tm_mon+1; - systime->dayofweek=unixtime->tm_wday; - systime->day=unixtime->tm_mday; - systime->hour=unixtime->tm_hour; - systime->minute=unixtime->tm_min; - systime->second=unixtime->tm_sec; - systime->milliseconds=0; - - return True; -} - -/******************************************************************* - * read or write a DEVICEMODE struct. - * on reading allocate memory for the private member - ********************************************************************/ - -#define DM_NUM_OPTIONAL_FIELDS 8 - -bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode) -{ - int available_space; /* size of the device mode left to parse */ - /* only important on unmarshalling */ - int i = 0; - uint16 *unistr_buffer; - int j; - - struct optional_fields { - fstring name; - uint32* field; - } opt_fields[DM_NUM_OPTIONAL_FIELDS] = { - { "icmmethod", NULL }, - { "icmintent", NULL }, - { "mediatype", NULL }, - { "dithertype", NULL }, - { "reserved1", NULL }, - { "reserved2", NULL }, - { "panningwidth", NULL }, - { "panningheight", NULL } - }; - - /* assign at run time to keep non-gcc compilers happy */ - - opt_fields[0].field = &devmode->icmmethod; - opt_fields[1].field = &devmode->icmintent; - opt_fields[2].field = &devmode->mediatype; - opt_fields[3].field = &devmode->dithertype; - opt_fields[4].field = &devmode->reserved1; - opt_fields[5].field = &devmode->reserved2; - opt_fields[6].field = &devmode->panningwidth; - opt_fields[7].field = &devmode->panningheight; - - - prs_debug(ps, depth, desc, "spoolss_io_devmode"); - depth++; - - if (UNMARSHALLING(ps)) { - devmode->devicename.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME); - if (devmode->devicename.buffer == NULL) - return False; - unistr_buffer = devmode->devicename.buffer; - } - else { - /* devicename is a static sized string but the buffer we set is not */ - unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME); - memset( unistr_buffer, 0x0, MAXDEVICENAME ); - for ( j=0; devmode->devicename.buffer[j]; j++ ) - unistr_buffer[j] = devmode->devicename.buffer[j]; - } - - if (!prs_uint16uni(True,"devicename", ps, depth, unistr_buffer, MAXDEVICENAME)) - return False; - - if (!prs_uint16("specversion", ps, depth, &devmode->specversion)) - return False; - - if (!prs_uint16("driverversion", ps, depth, &devmode->driverversion)) - return False; - if (!prs_uint16("size", ps, depth, &devmode->size)) - return False; - if (!prs_uint16("driverextra", ps, depth, &devmode->driverextra)) - return False; - if (!prs_uint32("fields", ps, depth, &devmode->fields)) - return False; - if (!prs_uint16("orientation", ps, depth, &devmode->orientation)) - return False; - if (!prs_uint16("papersize", ps, depth, &devmode->papersize)) - return False; - if (!prs_uint16("paperlength", ps, depth, &devmode->paperlength)) - return False; - if (!prs_uint16("paperwidth", ps, depth, &devmode->paperwidth)) - return False; - if (!prs_uint16("scale", ps, depth, &devmode->scale)) - return False; - if (!prs_uint16("copies", ps, depth, &devmode->copies)) - return False; - if (!prs_uint16("defaultsource", ps, depth, &devmode->defaultsource)) - return False; - if (!prs_uint16("printquality", ps, depth, &devmode->printquality)) - return False; - if (!prs_uint16("color", ps, depth, &devmode->color)) - return False; - if (!prs_uint16("duplex", ps, depth, &devmode->duplex)) - return False; - if (!prs_uint16("yresolution", ps, depth, &devmode->yresolution)) - return False; - if (!prs_uint16("ttoption", ps, depth, &devmode->ttoption)) - return False; - if (!prs_uint16("collate", ps, depth, &devmode->collate)) - return False; - - if (UNMARSHALLING(ps)) { - devmode->formname.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME); - if (devmode->formname.buffer == NULL) - return False; - unistr_buffer = devmode->formname.buffer; - } - else { - /* devicename is a static sized string but the buffer we set is not */ - unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME); - memset( unistr_buffer, 0x0, MAXDEVICENAME ); - for ( j=0; devmode->formname.buffer[j]; j++ ) - unistr_buffer[j] = devmode->formname.buffer[j]; - } - - if (!prs_uint16uni(True, "formname", ps, depth, unistr_buffer, MAXDEVICENAME)) - return False; - if (!prs_uint16("logpixels", ps, depth, &devmode->logpixels)) - return False; - if (!prs_uint32("bitsperpel", ps, depth, &devmode->bitsperpel)) - return False; - if (!prs_uint32("pelswidth", ps, depth, &devmode->pelswidth)) - return False; - if (!prs_uint32("pelsheight", ps, depth, &devmode->pelsheight)) - return False; - if (!prs_uint32("displayflags", ps, depth, &devmode->displayflags)) - return False; - if (!prs_uint32("displayfrequency", ps, depth, &devmode->displayfrequency)) - return False; - /* - * every device mode I've ever seen on the wire at least has up - * to the displayfrequency field. --jerry (05-09-2002) - */ - - /* add uint32's + uint16's + two UNICODE strings */ - - available_space = devmode->size - (sizeof(uint32)*6 + sizeof(uint16)*18 + sizeof(uint16)*64); - - /* Sanity check - we only have uint32's left tp parse */ - - if ( available_space && ((available_space % sizeof(uint32)) != 0) ) { - DEBUG(0,("spoolss_io_devmode: available_space [%d] no in multiple of 4 bytes (size = %d)!\n", - available_space, devmode->size)); - DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n")); - return False; - } - - /* - * Conditional parsing. Assume that the DeviceMode has been - * zero'd by the caller. - */ - - while ((available_space > 0) && (i < DM_NUM_OPTIONAL_FIELDS)) - { - DEBUG(11, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space)); - if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field)) - return False; - available_space -= sizeof(uint32); - i++; - } - - /* Sanity Check - we should no available space at this point unless - MS changes the device mode structure */ - - if (available_space) { - DEBUG(0,("spoolss_io_devmode: I've parsed all I know and there is still stuff left|\n")); - DEBUG(0,("spoolss_io_devmode: available_space = [%d], devmode_size = [%d]!\n", - available_space, devmode->size)); - DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n")); - return False; - } - - - if (devmode->driverextra!=0) { - if (UNMARSHALLING(ps)) { - 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 dev_private\n",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; - } - - return True; -} - -/******************************************************************* - * make a structure. - ********************************************************************/ - -bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, - const POLICY_HND *handle, - const char *valuename, uint32 size) -{ - if (q_u == NULL) return False; - - DEBUG(5,("make_spoolss_q_getprinterdata\n")); - - q_u->handle = *handle; - init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE); - q_u->size = size; - - return True; -} - -/******************************************************************* - * read a structure. - * called from spoolss_q_getprinterdata (srv_spoolss.c) - ********************************************************************/ - -bool spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth) -{ - if (q_u == NULL) - return False; - - prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata"); - depth++; - - if (!prs_align(ps)) - return False; - if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth)) - return False; - if (!prs_align(ps)) - return False; - if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth)) - return False; - if (!prs_align(ps)) - return False; - if (!prs_uint32("size", ps, depth, &q_u->size)) - return False; - - return True; -} - -/******************************************************************* - * write a structure. - * called from spoolss_r_getprinterdata (srv_spoolss.c) - ********************************************************************/ - -bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth) -{ - if (r_u == NULL) - return False; - - prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata"); - depth++; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("type", ps, depth, &r_u->type)) - return False; - if (!prs_uint32("size", ps, depth, &r_u->size)) - return False; - - if (UNMARSHALLING(ps) && r_u->size) { - r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size); - if(!r_u->data) - return False; - } - - if (!prs_uint8s( False, "data", ps, depth, r_u->data, r_u->size )) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("needed", ps, depth, &r_u->needed)) - return False; - if (!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* - * return the length of a uint16 (obvious, but the code is clean) - ********************************************************************/ - -static uint32 size_of_uint16(uint16 *value) -{ - return (sizeof(*value)); -} - -/******************************************************************* - * return the length of a uint32 (obvious, but the code is clean) - ********************************************************************/ - -static uint32 size_of_uint32(uint32 *value) -{ - return (sizeof(*value)); -} - -/******************************************************************* - * return the length of a NTTIME (obvious, but the code is clean) - ********************************************************************/ - -static uint32 size_of_nttime(NTTIME *value) -{ - return (sizeof(*value)); -} - -/******************************************************************* - * return the length of a uint32 (obvious, but the code is clean) - ********************************************************************/ - -static uint32 size_of_device_mode(DEVICEMODE *devmode) -{ - if (devmode==NULL) - return (4); - else - return (4+devmode->size+devmode->driverextra); -} - -/******************************************************************* - * return the length of a uint32 (obvious, but the code is clean) - ********************************************************************/ - -static uint32 size_of_systemtime(SYSTEMTIME *systime) -{ - if (systime==NULL) - return (4); - else - return (sizeof(SYSTEMTIME) +4); -} - -/******************************************************************* - Parse a DEVMODE structure and its relative pointer. -********************************************************************/ - -static bool smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_reldevmode"); - depth++; - - if (MARSHALLING(ps)) { - uint32 struct_offset = prs_offset(ps); - uint32 relative_offset; - - if (*devmode == NULL) { - relative_offset=0; - if (!prs_uint32("offset", ps, depth, &relative_offset)) - return False; - DEBUG(8, ("boing, the devmode was NULL\n")); - - return True; - } - - buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra); - - /* mz: we have to align the device mode for VISTA */ - if (buffer->string_at_end % 4) { - buffer->string_at_end += 4 - (buffer->string_at_end % 4); - } - - if(!prs_set_offset(ps, buffer->string_at_end)) - return False; - - /* write the DEVMODE */ - if (!spoolss_io_devmode(desc, ps, depth, *devmode)) - return False; - - if(!prs_set_offset(ps, struct_offset)) - return False; - - relative_offset=buffer->string_at_end - buffer->struct_start; - /* write its offset */ - if (!prs_uint32("offset", ps, depth, &relative_offset)) - return False; - } - else { - uint32 old_offset; - - /* read the offset */ - if (!prs_uint32("offset", ps, depth, &buffer->string_at_end)) - return False; - if (buffer->string_at_end == 0) { - *devmode = NULL; - return True; - } - - old_offset = prs_offset(ps); - if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start)) - return False; - - /* read the string */ - if((*devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1)) == NULL) - return False; - if (!spoolss_io_devmode(desc, ps, depth, *devmode)) - return False; - - if(!prs_set_offset(ps, old_offset)) - return False; - } - return True; -} - -/******************************************************************* - Parse a PRINTER_INFO_0 structure. -********************************************************************/ - -bool smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_printer_info_0"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!smb_io_relstr("printername", buffer, depth, &info->printername)) - return False; - if (!smb_io_relstr("servername", buffer, depth, &info->servername)) - return False; - - if(!prs_uint32("cjobs", ps, depth, &info->cjobs)) - return False; - if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs)) - return False; - if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes)) - return False; - - if(!prs_uint16("year", ps, depth, &info->year)) - return False; - if(!prs_uint16("month", ps, depth, &info->month)) - return False; - if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek)) - return False; - if(!prs_uint16("day", ps, depth, &info->day)) - return False; - if(!prs_uint16("hour", ps, depth, &info->hour)) - return False; - if(!prs_uint16("minute", ps, depth, &info->minute)) - return False; - if(!prs_uint16("second", ps, depth, &info->second)) - return False; - if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds)) - return False; - - if(!prs_uint32("global_counter", ps, depth, &info->global_counter)) - return False; - if(!prs_uint32("total_pages", ps, depth, &info->total_pages)) - return False; - - if(!prs_uint16("major_version", ps, depth, &info->major_version)) - return False; - if(!prs_uint16("build_version", ps, depth, &info->build_version)) - return False; - if(!prs_uint32("unknown7", ps, depth, &info->unknown7)) - return False; - if(!prs_uint32("unknown8", ps, depth, &info->unknown8)) - return False; - if(!prs_uint32("unknown9", ps, depth, &info->unknown9)) - return False; - if(!prs_uint32("session_counter", ps, depth, &info->session_counter)) - return False; - if(!prs_uint32("unknown11", ps, depth, &info->unknown11)) - return False; - if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors)) - return False; - if(!prs_uint32("unknown13", ps, depth, &info->unknown13)) - return False; - if(!prs_uint32("unknown14", ps, depth, &info->unknown14)) - return False; - if(!prs_uint32("unknown15", ps, depth, &info->unknown15)) - return False; - if(!prs_uint32("unknown16", ps, depth, &info->unknown16)) - return False; - if(!prs_uint32("change_id", ps, depth, &info->change_id)) - return False; - if(!prs_uint32("unknown18", ps, depth, &info->unknown18)) - return False; - if(!prs_uint32("status" , ps, depth, &info->status)) - return False; - if(!prs_uint32("unknown20", ps, depth, &info->unknown20)) - return False; - if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter)) - return False; - if(!prs_uint16("unknown22", ps, depth, &info->unknown22)) - return False; - if(!prs_uint16("unknown23", ps, depth, &info->unknown23)) - return False; - if(!prs_uint16("unknown24", ps, depth, &info->unknown24)) - return False; - if(!prs_uint16("unknown25", ps, depth, &info->unknown25)) - return False; - if(!prs_uint16("unknown26", ps, depth, &info->unknown26)) - return False; - if(!prs_uint16("unknown27", ps, depth, &info->unknown27)) - return False; - if(!prs_uint16("unknown28", ps, depth, &info->unknown28)) - return False; - if(!prs_uint16("unknown29", ps, depth, &info->unknown29)) - return False; - - return True; -} - -/******************************************************************* - Parse a PRINTER_INFO_1 structure. -********************************************************************/ - -bool smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_printer_info_1"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!prs_uint32("flags", ps, depth, &info->flags)) - return False; - if (!smb_io_relstr("description", buffer, depth, &info->description)) - return False; - if (!smb_io_relstr("name", buffer, depth, &info->name)) - return False; - if (!smb_io_relstr("comment", buffer, depth, &info->comment)) - return False; - - return True; -} - -/******************************************************************* - Parse a PRINTER_INFO_2 structure. -********************************************************************/ - -bool smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - uint32 dm_offset, sd_offset, current_offset; - uint32 dummy_value = 0, has_secdesc = 0; - - prs_debug(ps, depth, desc, "smb_io_printer_info_2"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!smb_io_relstr("servername", buffer, depth, &info->servername)) - return False; - if (!smb_io_relstr("printername", buffer, depth, &info->printername)) - return False; - if (!smb_io_relstr("sharename", buffer, depth, &info->sharename)) - return False; - if (!smb_io_relstr("portname", buffer, depth, &info->portname)) - return False; - if (!smb_io_relstr("drivername", buffer, depth, &info->drivername)) - return False; - if (!smb_io_relstr("comment", buffer, depth, &info->comment)) - return False; - if (!smb_io_relstr("location", buffer, depth, &info->location)) - return False; - - /* save current offset and wind forwared by a uint32 */ - dm_offset = prs_offset(ps); - if (!prs_uint32("devmode", ps, depth, &dummy_value)) - return False; - - if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile)) - return False; - if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor)) - return False; - if (!smb_io_relstr("datatype", buffer, depth, &info->datatype)) - return False; - if (!smb_io_relstr("parameters", buffer, depth, &info->parameters)) - return False; - - /* save current offset for the sec_desc */ - sd_offset = prs_offset(ps); - if (!prs_uint32("sec_desc", ps, depth, &has_secdesc)) - return False; - - - /* save current location so we can pick back up here */ - current_offset = prs_offset(ps); - - /* parse the devmode */ - if (!prs_set_offset(ps, dm_offset)) - return False; - if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode)) - return False; - - /* parse the sec_desc */ - if (info->secdesc) { - if (!prs_set_offset(ps, sd_offset)) - return False; - if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc)) - return False; - } - - /* pick up where we left off */ - if (!prs_set_offset(ps, current_offset)) - return False; - - if (!prs_uint32("attributes", ps, depth, &info->attributes)) - return False; - if (!prs_uint32("priority", ps, depth, &info->priority)) - return False; - if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority)) - return False; - if (!prs_uint32("starttime", ps, depth, &info->starttime)) - return False; - if (!prs_uint32("untiltime", ps, depth, &info->untiltime)) - return False; - if (!prs_uint32("status", ps, depth, &info->status)) - return False; - if (!prs_uint32("jobs", ps, depth, &info->cjobs)) - return False; - if (!prs_uint32("averageppm", ps, depth, &info->averageppm)) - return False; - - return True; -} - -/******************************************************************* - Parse a PRINTER_INFO_3 structure. -********************************************************************/ - -bool smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth) -{ - uint32 offset = 0; - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_printer_info_3"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (MARSHALLING(ps)) { - /* Ensure the SD is 8 byte aligned in the buffer. */ - uint32 start = prs_offset(ps); /* Remember the start position. */ - uint32 off_val = 0; - - /* Write a dummy value. */ - if (!prs_uint32("offset", ps, depth, &off_val)) - return False; - - /* 8 byte align. */ - if (!prs_align_uint64(ps)) - return False; - - /* Remember where we must seek back to write the SD. */ - offset = prs_offset(ps); - - /* Calculate the real offset for the SD. */ - - off_val = offset - start; - - /* Seek back to where we store the SD offset & store. */ - prs_set_offset(ps, start); - if (!prs_uint32("offset", ps, depth, &off_val)) - return False; - - /* Return to after the 8 byte align. */ - prs_set_offset(ps, offset); - - } else { - if (!prs_uint32("offset", ps, depth, &offset)) - return False; - /* Seek within the buffer. */ - if (!prs_set_offset(ps, offset)) - return False; - } - if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Parse a PRINTER_INFO_4 structure. -********************************************************************/ - -bool smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_printer_info_4"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!smb_io_relstr("printername", buffer, depth, &info->printername)) - return False; - if (!smb_io_relstr("servername", buffer, depth, &info->servername)) - return False; - if (!prs_uint32("attributes", ps, depth, &info->attributes)) - return False; - return True; -} - -/******************************************************************* - Parse a PRINTER_INFO_5 structure. -********************************************************************/ - -bool smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_printer_info_5"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!smb_io_relstr("printername", buffer, depth, &info->printername)) - return False; - if (!smb_io_relstr("portname", buffer, depth, &info->portname)) - return False; - if (!prs_uint32("attributes", ps, depth, &info->attributes)) - return False; - if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout)) - return False; - if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout)) - return False; - return True; -} - -/******************************************************************* - Parse a PRINTER_INFO_6 structure. -********************************************************************/ - -bool smb_io_printer_info_6(const char *desc, RPC_BUFFER *buffer, - PRINTER_INFO_6 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_printer_info_6"); - depth++; - - if (!prs_uint32("status", ps, depth, &info->status)) - return False; - - return True; -} - -/******************************************************************* - Parse a PRINTER_INFO_7 structure. -********************************************************************/ - -bool smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_printer_info_7"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!smb_io_relstr("guid", buffer, depth, &info->guid)) - return False; - if (!prs_uint32("action", ps, depth, &info->action)) - return False; - return True; -} - -/******************************************************************* - Parse a PORT_INFO_1 structure. -********************************************************************/ - -bool smb_io_port_info_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_port_info_1"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!smb_io_relstr("port_name", buffer, depth, &info->port_name)) - return False; - - return True; -} - -/******************************************************************* - Parse a PORT_INFO_2 structure. -********************************************************************/ - -bool smb_io_port_info_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_port_info_2"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!smb_io_relstr("port_name", buffer, depth, &info->port_name)) - return False; - if (!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name)) - return False; - if (!smb_io_relstr("description", buffer, depth, &info->description)) - return False; - if (!prs_uint32("port_type", ps, depth, &info->port_type)) - return False; - if (!prs_uint32("reserved", ps, depth, &info->reserved)) - return False; - - return True; -} - -/******************************************************************* - Parse a DRIVER_INFO_1 structure. -********************************************************************/ - -bool smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!smb_io_relstr("name", buffer, depth, &info->name)) - return False; - - return True; -} - -/******************************************************************* - Parse a DRIVER_INFO_2 structure. -********************************************************************/ - -bool smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_printer_driver_info_2"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!prs_uint32("version", ps, depth, &info->version)) - return False; - if (!smb_io_relstr("name", buffer, depth, &info->name)) - return False; - if (!smb_io_relstr("architecture", buffer, depth, &info->architecture)) - return False; - if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath)) - return False; - if (!smb_io_relstr("datafile", buffer, depth, &info->datafile)) - return False; - if (!smb_io_relstr("configfile", buffer, depth, &info->configfile)) - return False; - - return True; -} - -/******************************************************************* - Parse a DRIVER_INFO_3 structure. -********************************************************************/ - -bool smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!prs_uint32("version", ps, depth, &info->version)) - return False; - if (!smb_io_relstr("name", buffer, depth, &info->name)) - return False; - if (!smb_io_relstr("architecture", buffer, depth, &info->architecture)) - return False; - if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath)) - return False; - if (!smb_io_relstr("datafile", buffer, depth, &info->datafile)) - return False; - if (!smb_io_relstr("configfile", buffer, depth, &info->configfile)) - return False; - if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile)) - return False; - - if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles)) - return False; - - if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname)) - return False; - if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype)) - return False; - - return True; -} - -/******************************************************************* - Parse a DRIVER_INFO_6 structure. -********************************************************************/ - -bool smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_printer_driver_info_6"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!prs_uint32("version", ps, depth, &info->version)) - return False; - if (!smb_io_relstr("name", buffer, depth, &info->name)) - return False; - if (!smb_io_relstr("architecture", buffer, depth, &info->architecture)) - return False; - if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath)) - return False; - if (!smb_io_relstr("datafile", buffer, depth, &info->datafile)) - return False; - if (!smb_io_relstr("configfile", buffer, depth, &info->configfile)) - return False; - if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile)) - return False; - - if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles)) - return False; - - if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname)) - return False; - if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype)) - return False; - - if (!smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames)) - return False; - - if (!prs_uint64("date", ps, depth, &info->driver_date)) - return False; - - if (!prs_uint32("padding", ps, depth, &info->padding)) - return False; - - if (!prs_uint32("driver_version_low", ps, depth, &info->driver_version_low)) - return False; - - if (!prs_uint32("driver_version_high", ps, depth, &info->driver_version_high)) - return False; - - if (!smb_io_relstr("mfgname", buffer, depth, &info->mfgname)) - return False; - if (!smb_io_relstr("oem_url", buffer, depth, &info->oem_url)) - return False; - if (!smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id)) - return False; - if (!smb_io_relstr("provider", buffer, depth, &info->provider)) - return False; - - return True; -} - -/******************************************************************* - Parse a JOB_INFO_1 structure. -********************************************************************/ - -bool smb_io_job_info_1(const char *desc, RPC_BUFFER *buffer, JOB_INFO_1 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_job_info_1"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!prs_uint32("jobid", ps, depth, &info->jobid)) - return False; - if (!smb_io_relstr("printername", buffer, depth, &info->printername)) - return False; - if (!smb_io_relstr("machinename", buffer, depth, &info->machinename)) - return False; - if (!smb_io_relstr("username", buffer, depth, &info->username)) - return False; - if (!smb_io_relstr("document", buffer, depth, &info->document)) - return False; - if (!smb_io_relstr("datatype", buffer, depth, &info->datatype)) - return False; - if (!smb_io_relstr("text_status", buffer, depth, &info->text_status)) - return False; - if (!prs_uint32("status", ps, depth, &info->status)) - return False; - if (!prs_uint32("priority", ps, depth, &info->priority)) - return False; - if (!prs_uint32("position", ps, depth, &info->position)) - return False; - if (!prs_uint32("totalpages", ps, depth, &info->totalpages)) - return False; - if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted)) - return False; - if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted)) - return False; - - return True; -} - -/******************************************************************* - Parse a JOB_INFO_2 structure. -********************************************************************/ - -bool smb_io_job_info_2(const char *desc, RPC_BUFFER *buffer, JOB_INFO_2 *info, int depth) -{ - uint32 pipo=0; - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_job_info_2"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!prs_uint32("jobid",ps, depth, &info->jobid)) - return False; - if (!smb_io_relstr("printername", buffer, depth, &info->printername)) - return False; - if (!smb_io_relstr("machinename", buffer, depth, &info->machinename)) - return False; - if (!smb_io_relstr("username", buffer, depth, &info->username)) - return False; - if (!smb_io_relstr("document", buffer, depth, &info->document)) - return False; - if (!smb_io_relstr("notifyname", buffer, depth, &info->notifyname)) - return False; - if (!smb_io_relstr("datatype", buffer, depth, &info->datatype)) - return False; - - if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor)) - return False; - if (!smb_io_relstr("parameters", buffer, depth, &info->parameters)) - return False; - if (!smb_io_relstr("drivername", buffer, depth, &info->drivername)) - return False; - if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode)) - return False; - if (!smb_io_relstr("text_status", buffer, depth, &info->text_status)) - return False; - -/* SEC_DESC sec_desc;*/ - if (!prs_uint32("Hack! sec desc", ps, depth, &pipo)) - return False; - - if (!prs_uint32("status",ps, depth, &info->status)) - return False; - if (!prs_uint32("priority",ps, depth, &info->priority)) - return False; - if (!prs_uint32("position",ps, depth, &info->position)) - return False; - if (!prs_uint32("starttime",ps, depth, &info->starttime)) - return False; - if (!prs_uint32("untiltime",ps, depth, &info->untiltime)) - return False; - if (!prs_uint32("totalpages",ps, depth, &info->totalpages)) - return False; - if (!prs_uint32("size",ps, depth, &info->size)) - return False; - if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) ) - return False; - if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed)) - return False; - if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool smb_io_form_1(const char *desc, RPC_BUFFER *buffer, FORM_1 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_form_1"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!prs_uint32("flag", ps, depth, &info->flag)) - return False; - - if (!smb_io_relstr("name", buffer, depth, &info->name)) - return False; - - if (!prs_uint32("width", ps, depth, &info->width)) - return False; - if (!prs_uint32("length", ps, depth, &info->length)) - return False; - if (!prs_uint32("left", ps, depth, &info->left)) - return False; - if (!prs_uint32("top", ps, depth, &info->top)) - return False; - if (!prs_uint32("right", ps, depth, &info->right)) - return False; - if (!prs_uint32("bottom", ps, depth, &info->bottom)) - return False; - - return True; -} - -/******************************************************************* - Parse a PORT_INFO_1 structure. -********************************************************************/ - -bool smb_io_port_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_port_1"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if(!smb_io_relstr("port_name", buffer, depth, &info->port_name)) - return False; - - return True; -} - -/******************************************************************* - Parse a PORT_INFO_2 structure. -********************************************************************/ - -bool smb_io_port_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_port_2"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if(!smb_io_relstr("port_name", buffer, depth, &info->port_name)) - return False; - if(!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name)) - return False; - if(!smb_io_relstr("description", buffer, depth, &info->description)) - return False; - if(!prs_uint32("port_type", ps, depth, &info->port_type)) - return False; - if(!prs_uint32("reserved", ps, depth, &info->reserved)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool smb_io_printprocessor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (smb_io_relstr("name", buffer, depth, &info->name)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool smb_io_printprocdatatype_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (smb_io_relstr("name", buffer, depth, &info->name)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool smb_io_printmonitor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_1 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!smb_io_relstr("name", buffer, depth, &info->name)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool smb_io_printmonitor_info_2(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_2 *info, int depth) -{ - prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2"); - depth++; - - buffer->struct_start=prs_offset(ps); - - if (!smb_io_relstr("name", buffer, depth, &info->name)) - return False; - if (!smb_io_relstr("environment", buffer, depth, &info->environment)) - return False; - if (!smb_io_relstr("dll_name", buffer, depth, &info->dll_name)) - return False; - - return True; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info) -{ - int size=0; - - size+=size_of_relative_string( &info->printername ); - size+=size_of_relative_string( &info->servername ); - - size+=size_of_uint32( &info->cjobs); - size+=size_of_uint32( &info->total_jobs); - size+=size_of_uint32( &info->total_bytes); - - size+=size_of_uint16( &info->year); - size+=size_of_uint16( &info->month); - size+=size_of_uint16( &info->dayofweek); - size+=size_of_uint16( &info->day); - size+=size_of_uint16( &info->hour); - size+=size_of_uint16( &info->minute); - size+=size_of_uint16( &info->second); - size+=size_of_uint16( &info->milliseconds); - - size+=size_of_uint32( &info->global_counter); - size+=size_of_uint32( &info->total_pages); - - size+=size_of_uint16( &info->major_version); - size+=size_of_uint16( &info->build_version); - - size+=size_of_uint32( &info->unknown7); - size+=size_of_uint32( &info->unknown8); - size+=size_of_uint32( &info->unknown9); - size+=size_of_uint32( &info->session_counter); - size+=size_of_uint32( &info->unknown11); - size+=size_of_uint32( &info->printer_errors); - size+=size_of_uint32( &info->unknown13); - size+=size_of_uint32( &info->unknown14); - size+=size_of_uint32( &info->unknown15); - size+=size_of_uint32( &info->unknown16); - size+=size_of_uint32( &info->change_id); - size+=size_of_uint32( &info->unknown18); - size+=size_of_uint32( &info->status); - size+=size_of_uint32( &info->unknown20); - size+=size_of_uint32( &info->c_setprinter); - - size+=size_of_uint16( &info->unknown22); - size+=size_of_uint16( &info->unknown23); - size+=size_of_uint16( &info->unknown24); - size+=size_of_uint16( &info->unknown25); - size+=size_of_uint16( &info->unknown26); - size+=size_of_uint16( &info->unknown27); - size+=size_of_uint16( &info->unknown28); - size+=size_of_uint16( &info->unknown29); - - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info) -{ - int size=0; - - size+=size_of_uint32( &info->flags ); - size+=size_of_relative_string( &info->description ); - size+=size_of_relative_string( &info->name ); - size+=size_of_relative_string( &info->comment ); - - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info) -{ - uint32 size=0; - - size += 4; - - size += ndr_size_security_descriptor( info->secdesc, NULL, 0 ); - - size+=size_of_device_mode( info->devmode ); - - size+=size_of_relative_string( &info->servername ); - size+=size_of_relative_string( &info->printername ); - size+=size_of_relative_string( &info->sharename ); - size+=size_of_relative_string( &info->portname ); - size+=size_of_relative_string( &info->drivername ); - size+=size_of_relative_string( &info->comment ); - size+=size_of_relative_string( &info->location ); - - size+=size_of_relative_string( &info->sepfile ); - size+=size_of_relative_string( &info->printprocessor ); - size+=size_of_relative_string( &info->datatype ); - size+=size_of_relative_string( &info->parameters ); - - size+=size_of_uint32( &info->attributes ); - size+=size_of_uint32( &info->priority ); - size+=size_of_uint32( &info->defaultpriority ); - size+=size_of_uint32( &info->starttime ); - size+=size_of_uint32( &info->untiltime ); - size+=size_of_uint32( &info->status ); - size+=size_of_uint32( &info->cjobs ); - size+=size_of_uint32( &info->averageppm ); - - /* - * add any adjustments for alignment. This is - * not optimal since we could be calling this - * function from a loop (e.g. enumprinters), but - * it is easier to maintain the calculation here and - * not place the burden on the caller to remember. --jerry - */ - if ((size % 4) != 0) - size += 4 - (size % 4); - - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info) -{ - uint32 size=0; - - size+=size_of_relative_string( &info->printername ); - size+=size_of_relative_string( &info->servername ); - - size+=size_of_uint32( &info->attributes ); - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info) -{ - uint32 size=0; - - size+=size_of_relative_string( &info->printername ); - size+=size_of_relative_string( &info->portname ); - - size+=size_of_uint32( &info->attributes ); - size+=size_of_uint32( &info->device_not_selected_timeout ); - size+=size_of_uint32( &info->transmission_retry_timeout ); - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_printer_info_6(PRINTER_INFO_6 *info) -{ - return sizeof(uint32); -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info) -{ - /* The 8 is for the self relative pointer - 8 byte aligned.. */ - return 8 + (uint32)ndr_size_security_descriptor( info->secdesc, NULL, 0 ); -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info) -{ - uint32 size=0; - - size+=size_of_relative_string( &info->guid ); - size+=size_of_uint32( &info->action ); - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info) -{ - int size=0; - size+=size_of_relative_string( &info->name ); - - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info) -{ - int size=0; - size+=size_of_uint32( &info->version ); - size+=size_of_relative_string( &info->name ); - size+=size_of_relative_string( &info->architecture ); - size+=size_of_relative_string( &info->driverpath ); - size+=size_of_relative_string( &info->datafile ); - size+=size_of_relative_string( &info->configfile ); - - return size; -} - -/******************************************************************* -return the size required by a string array. -********************************************************************/ - -uint32 spoolss_size_string_array(uint16 *string) -{ - uint32 i = 0; - - if (string) { - for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++); - } - i=i+2; /* to count all chars including the leading zero */ - i=2*i; /* because we need the value in bytes */ - i=i+4; /* the offset pointer size */ - - return i; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info) -{ - int size=0; - - size+=size_of_uint32( &info->version ); - size+=size_of_relative_string( &info->name ); - size+=size_of_relative_string( &info->architecture ); - size+=size_of_relative_string( &info->driverpath ); - size+=size_of_relative_string( &info->datafile ); - size+=size_of_relative_string( &info->configfile ); - size+=size_of_relative_string( &info->helpfile ); - size+=size_of_relative_string( &info->monitorname ); - size+=size_of_relative_string( &info->defaultdatatype ); - - size+=spoolss_size_string_array(info->dependentfiles); - - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info) -{ - uint32 size=0; - - size+=size_of_uint32( &info->version ); - size+=size_of_relative_string( &info->name ); - size+=size_of_relative_string( &info->architecture ); - size+=size_of_relative_string( &info->driverpath ); - size+=size_of_relative_string( &info->datafile ); - size+=size_of_relative_string( &info->configfile ); - size+=size_of_relative_string( &info->helpfile ); - - size+=spoolss_size_string_array(info->dependentfiles); - - size+=size_of_relative_string( &info->monitorname ); - size+=size_of_relative_string( &info->defaultdatatype ); - - size+=spoolss_size_string_array(info->previousdrivernames); - - size+=size_of_nttime(&info->driver_date); - size+=size_of_uint32( &info->padding ); - size+=size_of_uint32( &info->driver_version_low ); - size+=size_of_uint32( &info->driver_version_high ); - size+=size_of_relative_string( &info->mfgname ); - size+=size_of_relative_string( &info->oem_url ); - size+=size_of_relative_string( &info->hardware_id ); - size+=size_of_relative_string( &info->provider ); - - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_job_info_1(JOB_INFO_1 *info) -{ - int size=0; - size+=size_of_uint32( &info->jobid ); - size+=size_of_relative_string( &info->printername ); - size+=size_of_relative_string( &info->machinename ); - size+=size_of_relative_string( &info->username ); - size+=size_of_relative_string( &info->document ); - size+=size_of_relative_string( &info->datatype ); - size+=size_of_relative_string( &info->text_status ); - size+=size_of_uint32( &info->status ); - size+=size_of_uint32( &info->priority ); - size+=size_of_uint32( &info->position ); - size+=size_of_uint32( &info->totalpages ); - size+=size_of_uint32( &info->pagesprinted ); - size+=size_of_systemtime( &info->submitted ); - - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_job_info_2(JOB_INFO_2 *info) -{ - int size=0; - - size+=4; /* size of sec desc ptr */ - - size+=size_of_uint32( &info->jobid ); - size+=size_of_relative_string( &info->printername ); - size+=size_of_relative_string( &info->machinename ); - size+=size_of_relative_string( &info->username ); - size+=size_of_relative_string( &info->document ); - size+=size_of_relative_string( &info->notifyname ); - size+=size_of_relative_string( &info->datatype ); - size+=size_of_relative_string( &info->printprocessor ); - size+=size_of_relative_string( &info->parameters ); - size+=size_of_relative_string( &info->drivername ); - size+=size_of_device_mode( info->devmode ); - size+=size_of_relative_string( &info->text_status ); -/* SEC_DESC sec_desc;*/ - size+=size_of_uint32( &info->status ); - size+=size_of_uint32( &info->priority ); - size+=size_of_uint32( &info->position ); - size+=size_of_uint32( &info->starttime ); - size+=size_of_uint32( &info->untiltime ); - size+=size_of_uint32( &info->totalpages ); - size+=size_of_uint32( &info->size ); - size+=size_of_systemtime( &info->submitted ); - size+=size_of_uint32( &info->timeelapsed ); - size+=size_of_uint32( &info->pagesprinted ); - - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_form_1(FORM_1 *info) -{ - int size=0; - - size+=size_of_uint32( &info->flag ); - size+=size_of_relative_string( &info->name ); - size+=size_of_uint32( &info->width ); - size+=size_of_uint32( &info->length ); - size+=size_of_uint32( &info->left ); - size+=size_of_uint32( &info->top ); - size+=size_of_uint32( &info->right ); - size+=size_of_uint32( &info->bottom ); - - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_port_info_1(PORT_INFO_1 *info) -{ - int size=0; - - size+=size_of_relative_string( &info->port_name ); - - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_port_info_2(PORT_INFO_2 *info) -{ - int size=0; - - size+=size_of_relative_string( &info->port_name ); - size+=size_of_relative_string( &info->monitor_name ); - size+=size_of_relative_string( &info->description ); - - size+=size_of_uint32( &info->port_type ); - size+=size_of_uint32( &info->reserved ); - - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info) -{ - int size=0; - size+=size_of_relative_string( &info->name ); - - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info) -{ - int size=0; - size+=size_of_relative_string( &info->name ); - - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ -uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p) -{ - uint32 size = 0; - - if (!p) - return 0; - - /* uint32(offset) + uint32(length) + length) */ - size += (size_of_uint32(&p->value_len)*2) + p->value_len; - size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ; - - size += size_of_uint32(&p->type); - - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info) -{ - int size=0; - size+=size_of_relative_string( &info->name ); - - return size; -} - -/******************************************************************* -return the size required by a struct in the stream -********************************************************************/ - -uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info) -{ - int size=0; - size+=size_of_relative_string( &info->name); - size+=size_of_relative_string( &info->environment); - size+=size_of_relative_string( &info->dll_name); - - return size; -} - -/******************************************************************* - * read a structure. - * called from spoolss_getprinterdriver2 (srv_spoolss.c) - ********************************************************************/ - -bool spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth)) - return False; - if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr)) - return False; - if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - if(!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("offered", ps, depth, &q_u->offered)) - return False; - - if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion)) - return False; - if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion)) - return False; - - return True; -} - -/******************************************************************* - * read a structure. - * called from spoolss_getprinterdriver2 (srv_spoolss.c) - ********************************************************************/ - -bool spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("needed", ps, depth, &r_u->needed)) - return False; - if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion)) - return False; - if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion)) - return False; - if (!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* - * init a structure. - ********************************************************************/ - -bool make_spoolss_q_enumprinters( - SPOOL_Q_ENUMPRINTERS *q_u, - uint32 flags, - char *servername, - uint32 level, - RPC_BUFFER *buffer, - uint32 offered -) -{ - q_u->flags=flags; - - q_u->servername_ptr = (servername != NULL) ? 1 : 0; - init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername); - - q_u->level=level; - q_u->buffer=buffer; - q_u->offered=offered; - - return True; -} - -/******************************************************************* - * init a structure. - ********************************************************************/ - -bool make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, - fstring servername, uint32 level, - RPC_BUFFER *buffer, uint32 offered) -{ - q_u->name_ptr = (servername != NULL) ? 1 : 0; - init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername); - - q_u->level=level; - q_u->buffer=buffer; - q_u->offered=offered; - - return True; -} - -/******************************************************************* - * read a structure. - * called from spoolss_enumprinters (srv_spoolss.c) - ********************************************************************/ - -bool spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("flags", ps, depth, &q_u->flags)) - return False; - if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr)) - return False; - - if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth)) - return False; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("offered", ps, depth, &q_u->offered)) - return False; - - return True; -} - -/******************************************************************* - Parse a SPOOL_R_ENUMPRINTERS structure. - ********************************************************************/ - -bool spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("needed", ps, depth, &r_u->needed)) - return False; - - if (!prs_uint32("returned", ps, depth, &r_u->returned)) - return False; - - if (!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* - * write a structure. - * called from spoolss_r_enum_printers (srv_spoolss.c) - * - ********************************************************************/ - -bool spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_getprinter"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("needed", ps, depth, &r_u->needed)) - return False; - - if (!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* - * read a structure. - * called from spoolss_getprinter (srv_spoolss.c) - ********************************************************************/ - -bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_q_getprinter"); - depth++; - - if (!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth)) - return False; - if (!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("offered", ps, depth, &q_u->offered)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("needed", ps, depth, &r_u->needed)) - return False; - - if (!prs_uint32("returned", ps, depth, &r_u->returned)) - return False; - - if (!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd, - uint32 firstjob, - uint32 numofjobs, - uint32 level, - RPC_BUFFER *buffer, - uint32 offered) -{ - if (q_u == NULL) - { - return False; - } - memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); - q_u->firstjob = firstjob; - q_u->numofjobs = numofjobs; - q_u->level = level; - q_u->buffer= buffer; - q_u->offered = offered; - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth)) - return False; - - if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob)) - return False; - if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs)) - return False; - if (!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) - return False; - - if(!prs_align(ps)) - return False; - - if (!prs_uint32("offered", ps, depth, &q_u->offered)) - return False; - - return True; -} - -/******************************************************************* - Parse a SPOOL_R_ENUMPRINTERDRIVERS structure. -********************************************************************/ - -bool spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("needed", ps, depth, &r_u->needed)) - return False; - - if (!prs_uint32("returned", ps, depth, &r_u->returned)) - return False; - - if (!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* - * init a structure. - ********************************************************************/ - -bool make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u, - const char *name, - const char *environment, - uint32 level, - RPC_BUFFER *buffer, uint32 offered) -{ - init_buf_unistr2(&q_u->name, &q_u->name_ptr, name); - init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment); - - q_u->level=level; - q_u->buffer=buffer; - q_u->offered=offered; - - return True; -} - -/******************************************************************* - Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure. -********************************************************************/ - -bool spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth) -{ - - prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr)) - return False; - if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth)) - return False; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr)) - return False; - if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth)) - return False; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("offered", ps, depth, &q_u->offered)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth) -{ - - prs_debug(ps, depth, desc, "spoolss_io_q_enumforms"); - depth++; - - if (!prs_align(ps)) - return False; - if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth)) - return False; - if (!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("offered", ps, depth, &q_u->offered)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_enumforms"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed)) - return False; - - if (!prs_uint32("numofforms", ps, depth, &r_u->numofforms)) - return False; - - if (!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* - Parse a SPOOL_R_ENUMPORTS structure. -********************************************************************/ - -bool spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_enumports"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("needed", ps, depth, &r_u->needed)) - return False; - - if (!prs_uint32("returned", ps, depth, &r_u->returned)) - return False; - - if (!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, ""); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("", ps, depth, &q_u->name_ptr)) - return False; - if (!smb_io_unistr2("", &q_u->name,True,ps,depth)) - return False; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("offered", ps, depth, &q_u->offered)) - return False; - - return True; -} - -/******************************************************************* - make a BUFFER5 struct from a uint16* - ******************************************************************/ - -bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src) -{ - - buf5->buf_len = len; - if (src) { - if (len) { - if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) { - DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n")); - return False; - } - } else { - buf5->buffer = NULL; - } - } else { - buf5->buffer=NULL; - } - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("needed", ps, depth, &r_u->needed)) - return False; - - if (!prs_uint32("returned", ps, depth, &r_u->returned)) - return False; - - if (!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr)) - return False; - if (!smb_io_unistr2("name", &q_u->name, True, ps, depth)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("", ps, depth, &q_u->environment_ptr)) - return False; - if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("offered", ps, depth, &q_u->offered)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("needed", ps, depth, &r_u->needed)) - return False; - - if (!prs_uint32("returned", ps, depth, &r_u->returned)) - return False; - - if (!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr)) - return False; - if (!smb_io_unistr2("name", &q_u->name, True, ps, depth)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr)) - return False; - if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - if(!prs_rpcbuffer_p("buffer", ps, depth, &q_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("offered", ps, depth, &q_u->offered)) - return False; - - return True; -} - -/******************************************************************* - Parse a SPOOL_Q_ENUMPRINTMONITORS structure. -********************************************************************/ - -bool spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr)) - return False; - if (!smb_io_unistr2("name", &q_u->name, True, ps, depth)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("offered", ps, depth, &q_u->offered)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("needed", ps, depth, &r_u->needed)) - return False; - - if (!prs_uint32("returned", ps, depth, &r_u->returned)) - return False; - - if (!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata"); - depth++; - - if(!prs_align(ps)) - return False; - if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize)) - return False; - - if (UNMARSHALLING(ps) && r_u->valuesize) { - r_u->value = PRS_ALLOC_MEM(ps, uint16, r_u->valuesize); - if (!r_u->value) { - DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n")); - return False; - } - } - - if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize )) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize)) - return False; - - if(!prs_uint32("type", ps, depth, &r_u->type)) - return False; - - if(!prs_uint32("datasize", ps, depth, &r_u->datasize)) - return False; - - if (UNMARSHALLING(ps) && r_u->datasize) { - r_u->data = PRS_ALLOC_MEM(ps, uint8, r_u->datasize); - if (!r_u->data) { - DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n")); - return False; - } - } - - if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize)) - return False; - if(!prs_align(ps)) - return False; - - if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize)) - return False; - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata"); - depth++; - - if(!prs_align(ps)) - return False; - if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth)) - return False; - if(!prs_uint32("index", ps, depth, &q_u->index)) - return False; - if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize)) - return False; - if(!prs_uint32("datasize", ps, depth, &q_u->datasize)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u, - const POLICY_HND *hnd, - uint32 idx, uint32 valuelen, uint32 datalen) -{ - memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); - q_u->index=idx; - q_u->valuesize=valuelen; - q_u->datasize=datalen; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u, - const POLICY_HND *hnd, const char *key, - uint32 size) -{ - memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); - init_unistr2(&q_u->key, key, UNI_STR_TERMINATE); - q_u->size = size; - - return True; -} - -/******************************************************************* -********************************************************************/ -bool make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd, - char* value, uint32 data_type, char* data, uint32 data_size) -{ - memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); - q_u->type = data_type; - init_unistr2(&q_u->value, value, UNI_STR_TERMINATE); - - q_u->max_len = q_u->real_len = data_size; - q_u->data = (unsigned char *)data; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata"); - depth++; - - if(!prs_align(ps)) - return False; - if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth)) - return False; - if(!smb_io_unistr2("", &q_u->value, True, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("type", ps, depth, &q_u->type)) - return False; - - if(!prs_uint32("max_len", ps, depth, &q_u->max_len)) - return False; - - switch (q_u->type) - { - case REG_SZ: - case REG_BINARY: - case REG_DWORD: - case REG_MULTI_SZ: - if (q_u->max_len) { - if (UNMARSHALLING(ps)) - q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len); - if(q_u->data == NULL) - return False; - if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len)) - return False; - } - if(!prs_align(ps)) - return False; - break; - } - - if(!prs_uint32("real_len", ps, depth, &q_u->real_len)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata"); - depth++; - - if(!prs_align(ps)) - return False; - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* - Parse a SPOOL_R_GETJOB structure. -********************************************************************/ - -bool spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_getjob"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) - return False; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("needed", ps, depth, &r_u->needed)) - return False; - - if (!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* - Parse a SPOOL_Q_GETJOB structure. -********************************************************************/ - -bool spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, ""); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth)) - return False; - if(!prs_uint32("jobid", ps, depth, &q_u->jobid)) - return False; - if(!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("offered", ps, depth, &q_u->offered)) - return False; - - return True; -} - -void free_devmode(DEVICEMODE *devmode) -{ - if (devmode!=NULL) { - SAFE_FREE(devmode->dev_private); - SAFE_FREE(devmode); - } -} - -void free_printer_info_1(PRINTER_INFO_1 *printer) -{ - SAFE_FREE(printer); -} - -void free_printer_info_2(PRINTER_INFO_2 *printer) -{ - if (printer!=NULL) { - free_devmode(printer->devmode); - printer->devmode = NULL; - SAFE_FREE(printer); - } -} - -void free_printer_info_3(PRINTER_INFO_3 *printer) -{ - SAFE_FREE(printer); -} - -void free_printer_info_4(PRINTER_INFO_4 *printer) -{ - SAFE_FREE(printer); -} - -void free_printer_info_5(PRINTER_INFO_5 *printer) -{ - SAFE_FREE(printer); -} - -void free_printer_info_6(PRINTER_INFO_6 *printer) -{ - SAFE_FREE(printer); -} - -void free_printer_info_7(PRINTER_INFO_7 *printer) -{ - SAFE_FREE(printer); -} - -void free_job_info_2(JOB_INFO_2 *job) -{ - if (job!=NULL) - free_devmode(job->devmode); -} - -/******************************************************************* - * read a structure. - ********************************************************************/ -bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u, - POLICY_HND *hnd, const char *key, - uint32 size) -{ - DEBUG(5,("make_spoolss_q_enumprinterkey\n")); - - memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); - init_unistr2(&q_u->key, key, UNI_STR_TERMINATE); - q_u->size = size; - - return True; -} - -/******************************************************************* - * read a structure. - ********************************************************************/ - -bool spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey"); - depth++; - - if(!prs_align(ps)) - return False; - if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth)) - return False; - - if(!smb_io_unistr2("", &q_u->key, True, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("size", ps, depth, &q_u->size)) - return False; - - return True; -} - -/******************************************************************* - * write a structure. - ********************************************************************/ - -bool spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey"); - depth++; - - if(!prs_align(ps)) - return False; - - if (!smb_io_buffer5("", &r_u->keys, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("needed", ps, depth, &r_u->needed)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* - * read a structure. - ********************************************************************/ - -bool spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex"); - depth++; - - if(!prs_align(ps)) - return False; - if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth)) - return False; - - if(!smb_io_unistr2("", &q_u->key, True, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("size", ps, depth, &q_u->size)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -static bool spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, - PRINTER_ENUM_VALUES_CTR *ctr, int depth) -{ - int i; - uint32 valuename_offset, - data_offset, - current_offset; - const uint32 basic_unit = 20; /* size of static portion of enum_values */ - - prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr"); - depth++; - - /* - * offset data begins at 20 bytes per structure * size_of_array. - * Don't forget the uint32 at the beginning - * */ - - current_offset = basic_unit * ctr->size_of_array; - - /* first loop to write basic enum_value information */ - - if (UNMARSHALLING(ps) && ctr->size_of_array) { - ctr->values = PRS_ALLOC_MEM(ps, PRINTER_ENUM_VALUES, ctr->size_of_array); - if (!ctr->values) - return False; - } - - for (i=0; i<ctr->size_of_array; i++) { - uint32 base_offset, return_offset; - - base_offset = prs_offset(ps); - - valuename_offset = current_offset; - if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset)) - return False; - - /* Read or write the value. */ - - return_offset = prs_offset(ps); - - if (!prs_set_offset(ps, base_offset + valuename_offset)) { - return False; - } - - if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename)) - return False; - - /* And go back. */ - if (!prs_set_offset(ps, return_offset)) - return False; - - if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len)) - return False; - - if (!prs_uint32("type", ps, depth, &ctr->values[i].type)) - return False; - - data_offset = ctr->values[i].value_len + valuename_offset; - - if (!prs_uint32("data_offset", ps, depth, &data_offset)) - return False; - - if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len)) - return False; - - /* Read or write the data. */ - - return_offset = prs_offset(ps); - - if (!prs_set_offset(ps, base_offset + data_offset)) { - return False; - } - - if ( ctr->values[i].data_len ) { - if ( UNMARSHALLING(ps) ) { - ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len); - if (!ctr->values[i].data) - return False; - } - if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len)) - return False; - } - - current_offset = data_offset + ctr->values[i].data_len - basic_unit; - /* account for 2 byte alignment */ - current_offset += (current_offset % 2); - - /* Remember how far we got. */ - data_offset = prs_offset(ps); - - /* And go back. */ - if (!prs_set_offset(ps, return_offset)) - return False; - - } - - /* Go to the last data offset we got to. */ - - if (!prs_set_offset(ps, data_offset)) - return False; - - /* And ensure we're 2 byte aligned. */ - - if ( !prs_align_uint16(ps) ) - return False; - - return True; -} - -/******************************************************************* - * write a structure. - ********************************************************************/ - -bool spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth) -{ - uint32 data_offset, end_offset; - prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex"); - depth++; - - if(!prs_align(ps)) - return False; - - if (!prs_uint32("size", ps, depth, &r_u->ctr.size)) - return False; - - data_offset = prs_offset(ps); - - if (!prs_set_offset(ps, data_offset + r_u->ctr.size)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("needed", ps, depth, &r_u->needed)) - return False; - - if(!prs_uint32("returned", ps, depth, &r_u->returned)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - r_u->ctr.size_of_array = r_u->returned; - - end_offset = prs_offset(ps); - - if (!prs_set_offset(ps, data_offset)) - return False; - - if (r_u->ctr.size) - if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth )) - return False; - - if (!prs_set_offset(ps, end_offset)) - return False; - return True; -} - -/******************************************************************* - * init a structure. - ********************************************************************/ - -bool make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, - uint32 level, RPC_BUFFER *buffer, - uint32 offered) -{ - memcpy(&q_u->handle, handle, sizeof(POLICY_HND)); - q_u->level = level; - q_u->buffer=buffer; - q_u->offered=offered; - - return True; -} diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c index 2f163a379f..cf07d97fec 100644 --- a/source3/rpc_server/srv_eventlog_nt.c +++ b/source3/rpc_server/srv_eventlog_nt.c @@ -50,7 +50,7 @@ static int eventlog_info_destructor(EVENTLOG_INFO *elog) ********************************************************************/ static EVENTLOG_INFO *find_eventlog_info_by_hnd( pipes_struct * p, - POLICY_HND * handle ) + struct policy_handle * handle ) { EVENTLOG_INFO *info; @@ -174,7 +174,7 @@ static bool get_oldest_entry_hook( EVENTLOG_INFO * info ) /******************************************************************** ********************************************************************/ -static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hnd ) +static NTSTATUS elog_open( pipes_struct * p, const char *logname, struct policy_handle *hnd ) { EVENTLOG_INFO *elog; @@ -254,7 +254,7 @@ static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hn /******************************************************************** ********************************************************************/ -static NTSTATUS elog_close( pipes_struct *p, POLICY_HND *hnd ) +static NTSTATUS elog_close( pipes_struct *p, struct policy_handle *hnd ) { if ( !( close_policy_hnd( p, hnd ) ) ) { return NT_STATUS_INVALID_HANDLE; diff --git a/source3/rpc_server/srv_lsa_hnd.c b/source3/rpc_server/srv_lsa_hnd.c index 2779b8aa18..e853bb2047 100644 --- a/source3/rpc_server/srv_lsa_hnd.c +++ b/source3/rpc_server/srv_lsa_hnd.c @@ -112,7 +112,7 @@ bool init_pipe_handle_list(pipes_struct *p, const struct ndr_syntax_id *syntax) data_ptr is TALLOC_FREE()'ed ****************************************************************************/ -bool create_policy_hnd(pipes_struct *p, POLICY_HND *hnd, void *data_ptr) +bool create_policy_hnd(pipes_struct *p, struct policy_handle *hnd, void *data_ptr) { static uint32 pol_hnd_low = 0; static uint32 pol_hnd_high = 0; @@ -167,7 +167,7 @@ bool create_policy_hnd(pipes_struct *p, POLICY_HND *hnd, void *data_ptr) find policy by handle - internal version. ****************************************************************************/ -static struct policy *find_policy_by_hnd_internal(pipes_struct *p, POLICY_HND *hnd, void **data_p) +static struct policy *find_policy_by_hnd_internal(pipes_struct *p, struct policy_handle *hnd, void **data_p) { struct policy *pol; size_t i; @@ -197,7 +197,7 @@ static struct policy *find_policy_by_hnd_internal(pipes_struct *p, POLICY_HND *h find policy by handle ****************************************************************************/ -bool find_policy_by_hnd(pipes_struct *p, POLICY_HND *hnd, void **data_p) +bool find_policy_by_hnd(pipes_struct *p, struct policy_handle *hnd, void **data_p) { return find_policy_by_hnd_internal(p, hnd, data_p) == NULL ? False : True; } @@ -206,7 +206,7 @@ bool find_policy_by_hnd(pipes_struct *p, POLICY_HND *hnd, void **data_p) Close a policy. ****************************************************************************/ -bool close_policy_hnd(pipes_struct *p, POLICY_HND *hnd) +bool close_policy_hnd(pipes_struct *p, struct policy_handle *hnd) { struct policy *pol = find_policy_by_hnd_internal(p, hnd, NULL); diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 09b1f66440..f3ee18da5a 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2113,7 +2113,11 @@ bool api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss auth_len = p->hdr.auth_len; - if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) { + if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN || + auth_len > RPC_HEADER_LEN + + RPC_HDR_REQ_LEN + + RPC_HDR_AUTH_LEN + + auth_len) { DEBUG(0,("Incorrect auth_len %u.\n", (unsigned int)auth_len )); return False; } diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index 33e89c8acb..503e22b653 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -943,8 +943,8 @@ bool fsp_is_np(struct files_struct *fsp) } struct np_proxy_state { - struct async_req_queue *read_queue; - struct async_req_queue *write_queue; + struct tevent_queue *read_queue; + struct tevent_queue *write_queue; int fd; uint8_t *msg; @@ -1104,11 +1104,11 @@ static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx, result->msg = NULL; - result->read_queue = async_req_queue_init(result); + result->read_queue = tevent_queue_create(result, "np_read"); if (result->read_queue == NULL) { goto fail; } - result->write_queue = async_req_queue_init(result); + result->write_queue = tevent_queue_create(result, "np_write"); if (result->write_queue == NULL) { goto fail; } @@ -1175,22 +1175,21 @@ struct np_write_state { ssize_t nwritten; }; -static void np_write_trigger(struct async_req *req); static void np_write_done(struct tevent_req *subreq); -struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct fake_file_handle *handle, - const uint8_t *data, size_t len) +struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev, + struct fake_file_handle *handle, + const uint8_t *data, size_t len) { - struct async_req *result; + struct tevent_req *req; struct np_write_state *state; NTSTATUS status; DEBUG(6, ("np_write_send: len: %d\n", (int)len)); dump_data(50, data, len); - if (!async_req_setup(mem_ctx, &result, &state, - struct np_write_state)) { + req = tevent_req_create(mem_ctx, &state, struct np_write_state); + if (req == NULL) { return NULL; } @@ -1214,68 +1213,60 @@ struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev, if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) { struct np_proxy_state *p = talloc_get_type_abort( handle->private_data, struct np_proxy_state); + struct tevent_req *subreq; state->ev = ev; state->p = p; state->iov.iov_base = CONST_DISCARD(void *, data); state->iov.iov_len = len; - if (!async_req_enqueue(p->write_queue, ev, result, - np_write_trigger)) { + subreq = writev_send(state, ev, p->write_queue, p->fd, + &state->iov, 1); + if (subreq == NULL) { goto fail; } - return result; + tevent_req_set_callback(subreq, np_write_done, req); + return req; } status = NT_STATUS_INVALID_HANDLE; post_status: - if (async_post_ntstatus(result, ev, status)) { - return result; + if (NT_STATUS_IS_OK(status)) { + tevent_req_done(req); + } else { + tevent_req_nterror(req, status); } + return tevent_req_post(req, ev); fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } -static void np_write_trigger(struct async_req *req) -{ - struct np_write_state *state = talloc_get_type_abort( - req->private_data, struct np_write_state); - struct tevent_req *subreq; - - subreq = writev_send(state, state->ev, state->p->fd, &state->iov, 1); - if (async_req_nomem(subreq, req)) { - return; - } - subreq->async.fn = np_write_done; - subreq->async.private_data = req; -} - static void np_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); - struct np_write_state *state = talloc_get_type_abort( - req->private_data, struct np_write_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct np_write_state *state = tevent_req_data( + req, struct np_write_state); ssize_t received; int err; received = writev_recv(subreq, &err); if (received < 0) { - async_req_nterror(req, map_nt_error_from_unix(err)); + tevent_req_nterror(req, map_nt_error_from_unix(err)); return; } state->nwritten = received; - async_req_done(req); + tevent_req_done(req); } -NTSTATUS np_write_recv(struct async_req *req, ssize_t *pnwritten) +NTSTATUS np_write_recv(struct tevent_req *req, ssize_t *pnwritten) { - struct np_write_state *state = talloc_get_type_abort( - req->private_data, struct np_write_state); + struct np_write_state *state = tevent_req_data( + req, struct np_write_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *pnwritten = state->nwritten; @@ -1313,19 +1304,19 @@ struct np_read_state { bool is_data_outstanding; }; -static void np_read_trigger(struct async_req *req); +static void np_read_trigger(struct tevent_req *req, void *private_data); static void np_read_done(struct tevent_req *subreq); -struct async_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct fake_file_handle *handle, - uint8_t *data, size_t len) +struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev, + struct fake_file_handle *handle, + uint8_t *data, size_t len) { - struct async_req *result; + struct tevent_req *req; struct np_read_state *state; NTSTATUS status; - if (!async_req_setup(mem_ctx, &result, &state, - struct np_read_state)) { + req = tevent_req_create(mem_ctx, &state, struct np_read_state); + if (req == NULL) { return NULL; } @@ -1370,44 +1361,46 @@ struct async_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev, state->data = data; state->len = len; - if (!async_req_enqueue(p->read_queue, ev, result, - np_read_trigger)) { + if (!tevent_queue_add(p->read_queue, ev, req, np_read_trigger, + NULL)) { goto fail; } - return result; + return req; } status = NT_STATUS_INVALID_HANDLE; post_status: - if (async_post_ntstatus(result, ev, status)) { - return result; + if (NT_STATUS_IS_OK(status)) { + tevent_req_done(req); + } else { + tevent_req_nterror(req, status); } + return tevent_req_post(req, ev); fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } -static void np_read_trigger(struct async_req *req) +static void np_read_trigger(struct tevent_req *req, void *private_data) { - struct np_read_state *state = talloc_get_type_abort( - req->private_data, struct np_read_state); + struct np_read_state *state = tevent_req_callback_data( + req, struct np_read_state); struct tevent_req *subreq; subreq = read_packet_send(state, state->ev, state->p->fd, RPC_HEADER_LEN, rpc_frag_more_fn, NULL); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } - subreq->async.fn = np_read_done; - subreq->async.private_data = req; + tevent_req_set_callback(subreq, np_read_done, req); } static void np_read_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); - struct np_read_state *state = talloc_get_type_abort( - req->private_data, struct np_read_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct np_read_state *state = tevent_req_data( + req, struct np_read_state); ssize_t received; size_t thistime; int err; @@ -1415,7 +1408,7 @@ static void np_read_done(struct tevent_req *subreq) received = read_packet_recv(subreq, state->p, &state->p->msg, &err); TALLOC_FREE(subreq); if (received == -1) { - async_req_nterror(req, map_nt_error_from_unix(err)); + tevent_req_nterror(req, map_nt_error_from_unix(err)); return; } @@ -1432,18 +1425,18 @@ static void np_read_done(struct tevent_req *subreq) state->is_data_outstanding = false; } - async_req_done(req); + tevent_req_done(req); return; } -NTSTATUS np_read_recv(struct async_req *req, ssize_t *nread, +NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread, bool *is_data_outstanding) { - struct np_read_state *state = talloc_get_type_abort( - req->private_data, struct np_read_state); + struct np_read_state *state = tevent_req_data( + req, struct np_read_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *nread = state->nread; diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 0b8cb35a84..dcbd0963c4 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -319,8 +319,8 @@ static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid) * enumerate stuff, so just cache 2 entries. */ - static struct disp_info builtin_dispinfo; - static struct disp_info domain_dispinfo; + static struct disp_info *builtin_dispinfo; + static struct disp_info *domain_dispinfo; /* There are two cases to consider here: 1) The SID is a domain SID and we look for an equality match, or @@ -335,18 +335,32 @@ static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid) /* * Necessary only once, but it does not really hurt. */ - sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin); + if (builtin_dispinfo == NULL) { + builtin_dispinfo = talloc_zero( + talloc_autofree_context(), struct disp_info); + if (builtin_dispinfo == NULL) { + return NULL; + } + } + sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin); - return &builtin_dispinfo; + return builtin_dispinfo; } if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) { /* * Necessary only once, but it does not really hurt. */ - sid_copy(&domain_dispinfo.sid, get_global_sam_sid()); + if (domain_dispinfo == NULL) { + domain_dispinfo = talloc_zero( + talloc_autofree_context(), struct disp_info); + if (domain_dispinfo == NULL) { + return NULL; + } + } + sid_copy(&domain_dispinfo->sid, get_global_sam_sid()); - return &domain_dispinfo; + return domain_dispinfo; } return NULL; @@ -403,32 +417,11 @@ static void free_samr_cache(DISP_INFO *disp_info) become_root(); - if (disp_info->users) { - DEBUG(10,("free_samr_cache: deleting users cache\n")); - pdb_search_destroy(disp_info->users); - disp_info->users = NULL; - } - if (disp_info->machines) { - DEBUG(10,("free_samr_cache: deleting machines cache\n")); - pdb_search_destroy(disp_info->machines); - disp_info->machines = NULL; - } - if (disp_info->groups) { - DEBUG(10,("free_samr_cache: deleting groups cache\n")); - pdb_search_destroy(disp_info->groups); - disp_info->groups = NULL; - } - if (disp_info->aliases) { - DEBUG(10,("free_samr_cache: deleting aliases cache\n")); - pdb_search_destroy(disp_info->aliases); - disp_info->aliases = NULL; - } - if (disp_info->enum_users) { - DEBUG(10,("free_samr_cache: deleting enum_users cache\n")); - pdb_search_destroy(disp_info->enum_users); - disp_info->enum_users = NULL; - } - disp_info->enum_acb_mask = 0; + TALLOC_FREE(disp_info->users); + TALLOC_FREE(disp_info->machines); + TALLOC_FREE(disp_info->groups); + TALLOC_FREE(disp_info->aliases); + TALLOC_FREE(disp_info->enum_users); unbecome_root(); } @@ -524,7 +517,7 @@ static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags) } if (info->users == NULL) { - info->users = pdb_search_users(acct_flags); + info->users = pdb_search_users(info, acct_flags); if (info->users == NULL) { return 0; } @@ -548,7 +541,7 @@ static uint32 count_sam_groups(struct disp_info *info) } if (info->groups == NULL) { - info->groups = pdb_search_groups(); + info->groups = pdb_search_groups(info); if (info->groups == NULL) { return 0; } @@ -567,7 +560,7 @@ static uint32 count_sam_aliases(struct disp_info *info) struct samr_displayentry *entry; if (info->aliases == NULL) { - info->aliases = pdb_search_aliases(&info->sid); + info->aliases = pdb_search_aliases(info, &info->sid); if (info->aliases == NULL) { return 0; } @@ -726,7 +719,7 @@ NTSTATUS _samr_GetUserPwInfo(pipes_struct *p, /******************************************************************* ********************************************************************/ -static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol, +static bool get_lsa_policy_samr_sid( pipes_struct *p, struct policy_handle *pol, DOM_SID *sid, uint32 *acc_granted, DISP_INFO **ppdisp_info) { @@ -1012,12 +1005,12 @@ NTSTATUS _samr_EnumDomainUsers(pipes_struct *p, if ((info->disp_info->enum_users != NULL) && (info->disp_info->enum_acb_mask != r->in.acct_flags)) { - pdb_search_destroy(info->disp_info->enum_users); - info->disp_info->enum_users = NULL; + TALLOC_FREE(info->disp_info->enum_users); } if (info->disp_info->enum_users == NULL) { - info->disp_info->enum_users = pdb_search_users(r->in.acct_flags); + info->disp_info->enum_users = pdb_search_users( + info->disp_info, r->in.acct_flags); info->disp_info->enum_acb_mask = r->in.acct_flags; } @@ -1149,7 +1142,7 @@ NTSTATUS _samr_EnumDomainGroups(pipes_struct *p, become_root(); if (info->disp_info->groups == NULL) { - info->disp_info->groups = pdb_search_groups(); + info->disp_info->groups = pdb_search_groups(info->disp_info); if (info->disp_info->groups == NULL) { unbecome_root(); @@ -1216,7 +1209,8 @@ NTSTATUS _samr_EnumDomainAliases(pipes_struct *p, become_root(); if (info->disp_info->aliases == NULL) { - info->disp_info->aliases = pdb_search_aliases(&info->sid); + info->disp_info->aliases = pdb_search_aliases( + info->disp_info, &info->sid); if (info->disp_info->aliases == NULL) { unbecome_root(); return NT_STATUS_ACCESS_DENIED; @@ -1547,7 +1541,8 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p, case 0x1: case 0x4: if (info->disp_info->users == NULL) { - info->disp_info->users = pdb_search_users(ACB_NORMAL); + info->disp_info->users = pdb_search_users( + info->disp_info, ACB_NORMAL); if (info->disp_info->users == NULL) { unbecome_root(); return NT_STATUS_ACCESS_DENIED; @@ -1565,8 +1560,8 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p, break; case 0x2: if (info->disp_info->machines == NULL) { - info->disp_info->machines = - pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST); + info->disp_info->machines = pdb_search_users( + info->disp_info, ACB_WSTRUST|ACB_SVRTRUST); if (info->disp_info->machines == NULL) { unbecome_root(); return NT_STATUS_ACCESS_DENIED; @@ -1585,7 +1580,8 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p, case 0x3: case 0x5: if (info->disp_info->groups == NULL) { - info->disp_info->groups = pdb_search_groups(); + info->disp_info->groups = pdb_search_groups( + info->disp_info); if (info->disp_info->groups == NULL) { unbecome_root(); return NT_STATUS_ACCESS_DENIED; @@ -2126,8 +2122,6 @@ NTSTATUS _samr_OpenUser(pipes_struct *p, { struct samu *sampass=NULL; DOM_SID sid; - POLICY_HND domain_pol = *r->in.domain_handle; - POLICY_HND *user_pol = r->out.user_handle; struct samr_info *info = NULL; SEC_DESC *psd = NULL; uint32 acc_granted; @@ -2139,7 +2133,7 @@ NTSTATUS _samr_OpenUser(pipes_struct *p, /* find the domain policy handle and get domain SID / access bits in the domain policy. */ - if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) ) + if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) ) return NT_STATUS_INVALID_HANDLE; nt_status = access_check_samr_function(acc_granted, @@ -2192,7 +2186,7 @@ NTSTATUS _samr_OpenUser(pipes_struct *p, info->acc_granted = acc_granted; /* get a (unique) handle. open a policy on it. */ - if (!create_policy_hnd(p, user_pol, info)) + if (!create_policy_hnd(p, r->out.user_handle, info)) return NT_STATUS_OBJECT_NAME_NOT_FOUND; return NT_STATUS_OK; @@ -3036,9 +3030,7 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p, { const char *account = NULL; DOM_SID sid; - POLICY_HND dom_pol = *r->in.domain_handle; uint32_t acb_info = r->in.acct_flags; - POLICY_HND *user_pol = r->out.user_handle; struct samr_info *info = NULL; NTSTATUS nt_status; uint32 acc_granted; @@ -3051,7 +3043,7 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p, DISP_INFO *disp_info = NULL; /* Get the domain SID stored in the domain policy */ - if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted, + if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, &disp_info)) return NT_STATUS_INVALID_HANDLE; @@ -3163,7 +3155,7 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p, info->acc_granted = acc_granted; /* get a (unique) handle. open a policy on it. */ - if (!create_policy_hnd(p, user_pol, info)) { + if (!create_policy_hnd(p, r->out.user_handle, info)) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } @@ -3451,9 +3443,7 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p, struct samr_OpenAlias *r) { DOM_SID sid; - POLICY_HND domain_pol = *r->in.domain_handle; uint32 alias_rid = r->in.rid; - POLICY_HND *alias_pol = r->out.alias_handle; struct samr_info *info = NULL; SEC_DESC *psd = NULL; uint32 acc_granted; @@ -3464,7 +3454,7 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p, /* find the domain policy and get the SID / access bits stored in the domain policy */ - if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) ) + if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) ) return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, @@ -3525,7 +3515,7 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p, info->acc_granted = acc_granted; /* get a (unique) handle. open a policy on it. */ - if (!create_policy_hnd(p, alias_pol, info)) + if (!create_policy_hnd(p, r->out.alias_handle, info)) return NT_STATUS_OBJECT_NAME_NOT_FOUND; return NT_STATUS_OK; @@ -4000,7 +3990,6 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, NTSTATUS status; struct samu *pwd = NULL; DOM_SID sid; - POLICY_HND *pol = r->in.user_handle; union samr_UserInfo *info = r->in.info; uint16_t switch_value = r->in.level; uint32_t acc_granted; @@ -4013,7 +4002,7 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__)); /* find the policy handle. open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) { + if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, &disp_info)) { return NT_STATUS_INVALID_HANDLE; } @@ -5632,7 +5621,8 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p, switch (r->in.level) { case 1: if (info->disp_info->users == NULL) { - info->disp_info->users = pdb_search_users(ACB_NORMAL); + info->disp_info->users = pdb_search_users( + info->disp_info, ACB_NORMAL); if (info->disp_info->users == NULL) { unbecome_root(); return NT_STATUS_ACCESS_DENIED; @@ -5651,8 +5641,8 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p, break; case 2: if (info->disp_info->machines == NULL) { - info->disp_info->machines = - pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST); + info->disp_info->machines = pdb_search_users( + info->disp_info, ACB_WSTRUST|ACB_SVRTRUST); if (info->disp_info->machines == NULL) { unbecome_root(); return NT_STATUS_ACCESS_DENIED; @@ -5671,7 +5661,8 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p, break; case 3: if (info->disp_info->groups == NULL) { - info->disp_info->groups = pdb_search_groups(); + info->disp_info->groups = pdb_search_groups( + info->disp_info); if (info->disp_info->groups == NULL) { unbecome_root(); return NT_STATUS_ACCESS_DENIED; diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c deleted file mode 100644 index ee36f04c6d..0000000000 --- a/source3/rpc_server/srv_spoolss.c +++ /dev/null @@ -1,912 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines - * Copyright (C) Andrew Tridgell 1992-2000, - * Copyright (C) Luke Kenneth Casson Leighton 1996-2000, - * Copyright (C) Jean François Micouleau 1998-2000, - * Copyright (C) Jeremy Allison 2001, - * Copyright (C) Gerald Carter 2001-2002, - * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003. - * - * 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 3 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, see <http://www.gnu.org/licenses/>. - */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -/******************************************************************* - ********************************************************************/ - -static bool proxy_spoolss_call(pipes_struct *p, uint8_t opnum) -{ - struct api_struct *fns; - int n_fns; - - spoolss_get_pipe_fns(&fns, &n_fns); - - if (opnum >= n_fns) { - return false; - } - - if (fns[opnum].opnum != opnum) { - smb_panic("SPOOLSS function table not sorted"); - } - - return fns[opnum].fn(p); -} - -/******************************************************************** - * api_spoolss_open_printer_ex (rarely seen - older call) - ********************************************************************/ - -static bool api_spoolss_open_printer(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_OPENPRINTER); -} - -/******************************************************************** - * api_spoolss_open_printer_ex - ********************************************************************/ - -static bool api_spoolss_open_printer_ex(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_OPENPRINTEREX); -} - -/******************************************************************** - * api_spoolss_getprinterdata - * - * called from the spoolss dispatcher - ********************************************************************/ - -static bool api_spoolss_getprinterdata(pipes_struct *p) -{ - SPOOL_Q_GETPRINTERDATA q_u; - SPOOL_R_GETPRINTERDATA r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* read the stream and fill the struct */ - if (!spoolss_io_q_getprinterdata("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_getprinterdata: unable to unmarshall SPOOL_Q_GETPRINTERDATA.\n")); - return False; - } - - r_u.status = _spoolss_getprinterdata( p, &q_u, &r_u); - - if (!spoolss_io_r_getprinterdata("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_getprinterdata: unable to marshall SPOOL_R_GETPRINTERDATA.\n")); - return False; - } - - return True; -} - -/******************************************************************** - * api_spoolss_deleteprinterdata - * - * called from the spoolss dispatcher - ********************************************************************/ - -static bool api_spoolss_deleteprinterdata(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_DELETEPRINTERDATA); -} - -/******************************************************************** - * api_spoolss_closeprinter - * - * called from the spoolss dispatcher - ********************************************************************/ - -static bool api_spoolss_closeprinter(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_CLOSEPRINTER); -} - -/******************************************************************** - * api_spoolss_abortprinter - * - * called from the spoolss dispatcher - ********************************************************************/ - -static bool api_spoolss_abortprinter(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_ABORTPRINTER); -} - -/******************************************************************** - * api_spoolss_deleteprinter - * - * called from the spoolss dispatcher - ********************************************************************/ - -static bool api_spoolss_deleteprinter(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_DELETEPRINTER); -} - -/******************************************************************** - * api_spoolss_deleteprinterdriver - * - * called from the spoolss dispatcher - ********************************************************************/ - -static bool api_spoolss_deleteprinterdriver(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_DELETEPRINTERDRIVER); -} - - -/******************************************************************** - * api_spoolss_rffpcnex - * ReplyFindFirstPrinterChangeNotifyEx - ********************************************************************/ - -static bool api_spoolss_rffpcnex(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_REMOTEFINDFIRSTPRINTERCHANGENOTIFYEX); -} - - -/******************************************************************** - * api_spoolss_rfnpcnex - * ReplyFindNextPrinterChangeNotifyEx - * called from the spoolss dispatcher - - * Note - this is the *ONLY* function that breaks the RPC call - * symmetry in all the other calls. We need to do this to fix - * the massive memory allocation problem with thousands of jobs... - * JRA. - ********************************************************************/ - -static bool api_spoolss_rfnpcnex(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFY); -} - - -/******************************************************************** - * api_spoolss_enumprinters - * called from the spoolss dispatcher - * - ********************************************************************/ - -static bool api_spoolss_enumprinters(pipes_struct *p) -{ - SPOOL_Q_ENUMPRINTERS q_u; - SPOOL_R_ENUMPRINTERS 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 (!spoolss_io_q_enumprinters("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_enumprinters: unable to unmarshall SPOOL_Q_ENUMPRINTERS.\n")); - return False; - } - - r_u.status = _spoolss_enumprinters( p, &q_u, &r_u); - - if (!spoolss_io_r_enumprinters("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_enumprinters: unable to marshall SPOOL_R_ENUMPRINTERS.\n")); - return False; - } - - return True; -} - -/******************************************************************** - * api_spoolss_getprinter - * called from the spoolss dispatcher - * - ********************************************************************/ - -static bool api_spoolss_getprinter(pipes_struct *p) -{ - SPOOL_Q_GETPRINTER q_u; - SPOOL_R_GETPRINTER 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(!spoolss_io_q_getprinter("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_getprinter: unable to unmarshall SPOOL_Q_GETPRINTER.\n")); - return False; - } - - r_u.status = _spoolss_getprinter(p, &q_u, &r_u); - - if(!spoolss_io_r_getprinter("",&r_u,rdata,0)) { - DEBUG(0,("spoolss_io_r_getprinter: unable to marshall SPOOL_R_GETPRINTER.\n")); - return False; - } - - return True; -} - -/******************************************************************** - * api_spoolss_getprinter - * called from the spoolss dispatcher - * - ********************************************************************/ - -static bool api_spoolss_getprinterdriver2(pipes_struct *p) -{ - SPOOL_Q_GETPRINTERDRIVER2 q_u; - SPOOL_R_GETPRINTERDRIVER2 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(!spoolss_io_q_getprinterdriver2("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_getprinterdriver2: unable to unmarshall SPOOL_Q_GETPRINTERDRIVER2.\n")); - return False; - } - - r_u.status = _spoolss_getprinterdriver2(p, &q_u, &r_u); - - if(!spoolss_io_r_getprinterdriver2("",&r_u,rdata,0)) { - DEBUG(0,("spoolss_io_r_getprinterdriver2: unable to marshall SPOOL_R_GETPRINTERDRIVER2.\n")); - return False; - } - - return True; -} - -/******************************************************************** - * api_spoolss_getprinter - * called from the spoolss dispatcher - * - ********************************************************************/ - -static bool api_spoolss_startpageprinter(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_STARTPAGEPRINTER); -} - -/******************************************************************** - * api_spoolss_getprinter - * called from the spoolss dispatcher - * - ********************************************************************/ - -static bool api_spoolss_endpageprinter(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_ENDPAGEPRINTER); -} - -/******************************************************************** -********************************************************************/ - -static bool api_spoolss_startdocprinter(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_STARTDOCPRINTER); -} - -/******************************************************************** -********************************************************************/ - -static bool api_spoolss_enddocprinter(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_ENDDOCPRINTER); -} - -/******************************************************************** -********************************************************************/ - -static bool api_spoolss_writeprinter(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_WRITEPRINTER); -} - -/**************************************************************************** - -****************************************************************************/ - -static bool api_spoolss_setprinter(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_SETPRINTER); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_fcpn(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_FINDCLOSEPRINTERNOTIFY); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_addjob(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_ADDJOB); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_enumjobs(pipes_struct *p) -{ - SPOOL_Q_ENUMJOBS q_u; - SPOOL_R_ENUMJOBS 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 (!spoolss_io_q_enumjobs("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_enumjobs: unable to unmarshall SPOOL_Q_ENUMJOBS.\n")); - return False; - } - - r_u.status = _spoolss_enumjobs(p, &q_u, &r_u); - - if (!spoolss_io_r_enumjobs("",&r_u,rdata,0)) { - DEBUG(0,("spoolss_io_r_enumjobs: unable to marshall SPOOL_R_ENUMJOBS.\n")); - return False; - } - - return True; -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_schedulejob(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_SCHEDULEJOB); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_setjob(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_SETJOB); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_enumprinterdrivers(pipes_struct *p) -{ - SPOOL_Q_ENUMPRINTERDRIVERS q_u; - SPOOL_R_ENUMPRINTERDRIVERS 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 (!spoolss_io_q_enumprinterdrivers("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_enumprinterdrivers: unable to unmarshall SPOOL_Q_ENUMPRINTERDRIVERS.\n")); - return False; - } - - r_u.status = _spoolss_enumprinterdrivers(p, &q_u, &r_u); - - if (!spoolss_io_r_enumprinterdrivers("",&r_u,rdata,0)) { - DEBUG(0,("spoolss_io_r_enumprinterdrivers: unable to marshall SPOOL_R_ENUMPRINTERDRIVERS.\n")); - return False; - } - - return True; -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_getform(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_GETFORM); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_enumforms(pipes_struct *p) -{ - SPOOL_Q_ENUMFORMS q_u; - SPOOL_R_ENUMFORMS 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 (!spoolss_io_q_enumforms("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_enumforms: unable to unmarshall SPOOL_Q_ENUMFORMS.\n")); - return False; - } - - r_u.status = _spoolss_enumforms(p, &q_u, &r_u); - - if (!spoolss_io_r_enumforms("",&r_u,rdata,0)) { - DEBUG(0,("spoolss_io_r_enumforms: unable to marshall SPOOL_R_ENUMFORMS.\n")); - return False; - } - - return True; -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_enumports(pipes_struct *p) -{ - SPOOL_Q_ENUMPORTS q_u; - SPOOL_R_ENUMPORTS 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(!spoolss_io_q_enumports("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_enumports: unable to unmarshall SPOOL_Q_ENUMPORTS.\n")); - return False; - } - - r_u.status = _spoolss_enumports(p, &q_u, &r_u); - - if (!spoolss_io_r_enumports("",&r_u,rdata,0)) { - DEBUG(0,("spoolss_io_r_enumports: unable to marshall SPOOL_R_ENUMPORTS.\n")); - return False; - } - - return True; -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_addprinterex(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_ADDPRINTEREX); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_addprinterdriver(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_ADDPRINTERDRIVER); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_getprinterdriverdirectory(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_GETPRINTERDRIVERDIRECTORY); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_enumprinterdata(pipes_struct *p) -{ - SPOOL_Q_ENUMPRINTERDATA q_u; - SPOOL_R_ENUMPRINTERDATA 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(!spoolss_io_q_enumprinterdata("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_enumprinterdata: unable to unmarshall SPOOL_Q_ENUMPRINTERDATA.\n")); - return False; - } - - r_u.status = _spoolss_enumprinterdata(p, &q_u, &r_u); - - if(!spoolss_io_r_enumprinterdata("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_enumprinterdata: unable to marshall SPOOL_R_ENUMPRINTERDATA.\n")); - return False; - } - - return True; -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_setprinterdata(pipes_struct *p) -{ - SPOOL_Q_SETPRINTERDATA q_u; - SPOOL_R_SETPRINTERDATA 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(!spoolss_io_q_setprinterdata("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_setprinterdata: unable to unmarshall SPOOL_Q_SETPRINTERDATA.\n")); - return False; - } - - r_u.status = _spoolss_setprinterdata(p, &q_u, &r_u); - - if(!spoolss_io_r_setprinterdata("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_setprinterdata: unable to marshall SPOOL_R_SETPRINTERDATA.\n")); - return False; - } - - return True; -} - -/**************************************************************************** -****************************************************************************/ -static bool api_spoolss_reset_printer(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_RESETPRINTER); -} - -/**************************************************************************** -****************************************************************************/ -static bool api_spoolss_addform(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_ADDFORM); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_deleteform(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_DELETEFORM); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_setform(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_SETFORM); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_enumprintprocessors(pipes_struct *p) -{ - SPOOL_Q_ENUMPRINTPROCESSORS q_u; - SPOOL_R_ENUMPRINTPROCESSORS 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(!spoolss_io_q_enumprintprocessors("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_enumprintprocessors: unable to unmarshall SPOOL_Q_ENUMPRINTPROCESSORS.\n")); - return False; - } - - r_u.status = _spoolss_enumprintprocessors(p, &q_u, &r_u); - - if(!spoolss_io_r_enumprintprocessors("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_enumprintprocessors: unable to marshall SPOOL_R_ENUMPRINTPROCESSORS.\n")); - return False; - } - - return True; -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_addprintprocessor(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_ADDPRINTPROCESSOR); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_enumprintprocdatatypes(pipes_struct *p) -{ - SPOOL_Q_ENUMPRINTPROCDATATYPES q_u; - SPOOL_R_ENUMPRINTPROCDATATYPES 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(!spoolss_io_q_enumprintprocdatatypes("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_enumprintprocdatatypes: unable to unmarshall SPOOL_Q_ENUMPRINTPROCDATATYPES.\n")); - return False; - } - - r_u.status = _spoolss_enumprintprocdatatypes(p, &q_u, &r_u); - - if(!spoolss_io_r_enumprintprocdatatypes("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_enumprintprocdatatypes: unable to marshall SPOOL_R_ENUMPRINTPROCDATATYPES.\n")); - return False; - } - - return True; -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_enumprintmonitors(pipes_struct *p) -{ - SPOOL_Q_ENUMPRINTMONITORS q_u; - SPOOL_R_ENUMPRINTMONITORS 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 (!spoolss_io_q_enumprintmonitors("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_enumprintmonitors: unable to unmarshall SPOOL_Q_ENUMPRINTMONITORS.\n")); - return False; - } - - r_u.status = _spoolss_enumprintmonitors(p, &q_u, &r_u); - - if (!spoolss_io_r_enumprintmonitors("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_enumprintmonitors: unable to marshall SPOOL_R_ENUMPRINTMONITORS.\n")); - return False; - } - - return True; -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_getjob(pipes_struct *p) -{ - SPOOL_Q_GETJOB q_u; - SPOOL_R_GETJOB 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(!spoolss_io_q_getjob("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_getjob: unable to unmarshall SPOOL_Q_GETJOB.\n")); - return False; - } - - r_u.status = _spoolss_getjob(p, &q_u, &r_u); - - if(!spoolss_io_r_getjob("",&r_u,rdata,0)) { - DEBUG(0,("spoolss_io_r_getjob: unable to marshall SPOOL_R_GETJOB.\n")); - return False; - } - - return True; -} - -/******************************************************************** - * api_spoolss_getprinterdataex - * - * called from the spoolss dispatcher - ********************************************************************/ - -static bool api_spoolss_getprinterdataex(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_GETPRINTERDATAEX); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_setprinterdataex(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_SETPRINTERDATAEX); -} - - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_enumprinterkey(pipes_struct *p) -{ - SPOOL_Q_ENUMPRINTERKEY q_u; - SPOOL_R_ENUMPRINTERKEY 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(!spoolss_io_q_enumprinterkey("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_setprinterkey: unable to unmarshall SPOOL_Q_ENUMPRINTERKEY.\n")); - return False; - } - - r_u.status = _spoolss_enumprinterkey(p, &q_u, &r_u); - - if(!spoolss_io_r_enumprinterkey("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_enumprinterkey: unable to marshall SPOOL_R_ENUMPRINTERKEY.\n")); - return False; - } - - return True; -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_enumprinterdataex(pipes_struct *p) -{ - SPOOL_Q_ENUMPRINTERDATAEX q_u; - SPOOL_R_ENUMPRINTERDATAEX 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(!spoolss_io_q_enumprinterdataex("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_enumprinterdataex: unable to unmarshall SPOOL_Q_ENUMPRINTERDATAEX.\n")); - return False; - } - - r_u.status = _spoolss_enumprinterdataex(p, &q_u, &r_u); - - if(!spoolss_io_r_enumprinterdataex("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_enumprinterdataex: unable to marshall SPOOL_R_ENUMPRINTERDATAEX.\n")); - return False; - } - - return True; -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_getprintprocessordirectory(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_GETPRINTPROCESSORDIRECTORY); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_deleteprinterdataex(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_DELETEPRINTERDATAEX); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_deleteprinterkey(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_DELETEPRINTERKEY); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_addprinterdriverex(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_ADDPRINTERDRIVEREX); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_deleteprinterdriverex(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_DELETEPRINTERDRIVEREX); -} - -/**************************************************************************** -****************************************************************************/ - -static bool api_spoolss_xcvdataport(pipes_struct *p) -{ - return proxy_spoolss_call(p, NDR_SPOOLSS_XCVDATA); -} - -/******************************************************************* -\pipe\spoolss commands -********************************************************************/ - - struct api_struct api_spoolss_cmds[] = - { - {"SPOOLSS_OPENPRINTER", SPOOLSS_OPENPRINTER, api_spoolss_open_printer }, - {"SPOOLSS_OPENPRINTEREX", SPOOLSS_OPENPRINTEREX, api_spoolss_open_printer_ex }, - {"SPOOLSS_GETPRINTERDATA", SPOOLSS_GETPRINTERDATA, api_spoolss_getprinterdata }, - {"SPOOLSS_CLOSEPRINTER", SPOOLSS_CLOSEPRINTER, api_spoolss_closeprinter }, - {"SPOOLSS_DELETEPRINTER", SPOOLSS_DELETEPRINTER, api_spoolss_deleteprinter }, - {"SPOOLSS_ABORTPRINTER", SPOOLSS_ABORTPRINTER, api_spoolss_abortprinter }, - {"SPOOLSS_RFFPCNEX", SPOOLSS_RFFPCNEX, api_spoolss_rffpcnex }, - {"SPOOLSS_RFNPCNEX", SPOOLSS_RFNPCNEX, api_spoolss_rfnpcnex }, - {"SPOOLSS_ENUMPRINTERS", SPOOLSS_ENUMPRINTERS, api_spoolss_enumprinters }, - {"SPOOLSS_GETPRINTER", SPOOLSS_GETPRINTER, api_spoolss_getprinter }, - {"SPOOLSS_GETPRINTERDRIVER2", SPOOLSS_GETPRINTERDRIVER2, api_spoolss_getprinterdriver2 }, - {"SPOOLSS_STARTPAGEPRINTER", SPOOLSS_STARTPAGEPRINTER, api_spoolss_startpageprinter }, - {"SPOOLSS_ENDPAGEPRINTER", SPOOLSS_ENDPAGEPRINTER, api_spoolss_endpageprinter }, - {"SPOOLSS_STARTDOCPRINTER", SPOOLSS_STARTDOCPRINTER, api_spoolss_startdocprinter }, - {"SPOOLSS_ENDDOCPRINTER", SPOOLSS_ENDDOCPRINTER, api_spoolss_enddocprinter }, - {"SPOOLSS_WRITEPRINTER", SPOOLSS_WRITEPRINTER, api_spoolss_writeprinter }, - {"SPOOLSS_SETPRINTER", SPOOLSS_SETPRINTER, api_spoolss_setprinter }, - {"SPOOLSS_FCPN", SPOOLSS_FCPN, api_spoolss_fcpn }, - {"SPOOLSS_ADDJOB", SPOOLSS_ADDJOB, api_spoolss_addjob }, - {"SPOOLSS_ENUMJOBS", SPOOLSS_ENUMJOBS, api_spoolss_enumjobs }, - {"SPOOLSS_SCHEDULEJOB", SPOOLSS_SCHEDULEJOB, api_spoolss_schedulejob }, - {"SPOOLSS_SETJOB", SPOOLSS_SETJOB, api_spoolss_setjob }, - {"SPOOLSS_ENUMFORMS", SPOOLSS_ENUMFORMS, api_spoolss_enumforms }, - {"SPOOLSS_ENUMPORTS", SPOOLSS_ENUMPORTS, api_spoolss_enumports }, - {"SPOOLSS_ENUMPRINTERDRIVERS", SPOOLSS_ENUMPRINTERDRIVERS, api_spoolss_enumprinterdrivers }, - {"SPOOLSS_ADDPRINTEREX", SPOOLSS_ADDPRINTEREX, api_spoolss_addprinterex }, - {"SPOOLSS_ADDPRINTERDRIVER", SPOOLSS_ADDPRINTERDRIVER, api_spoolss_addprinterdriver }, - {"SPOOLSS_DELETEPRINTERDRIVER", SPOOLSS_DELETEPRINTERDRIVER, api_spoolss_deleteprinterdriver }, - {"SPOOLSS_GETPRINTERDRIVERDIRECTORY", SPOOLSS_GETPRINTERDRIVERDIRECTORY, api_spoolss_getprinterdriverdirectory }, - {"SPOOLSS_ENUMPRINTERDATA", SPOOLSS_ENUMPRINTERDATA, api_spoolss_enumprinterdata }, - {"SPOOLSS_SETPRINTERDATA", SPOOLSS_SETPRINTERDATA, api_spoolss_setprinterdata }, - {"SPOOLSS_RESETPRINTER", SPOOLSS_RESETPRINTER, api_spoolss_reset_printer }, - {"SPOOLSS_DELETEPRINTERDATA", SPOOLSS_DELETEPRINTERDATA, api_spoolss_deleteprinterdata }, - {"SPOOLSS_ADDFORM", SPOOLSS_ADDFORM, api_spoolss_addform }, - {"SPOOLSS_DELETEFORM", SPOOLSS_DELETEFORM, api_spoolss_deleteform }, - {"SPOOLSS_GETFORM", SPOOLSS_GETFORM, api_spoolss_getform }, - {"SPOOLSS_SETFORM", SPOOLSS_SETFORM, api_spoolss_setform }, - {"SPOOLSS_ADDPRINTPROCESSOR", SPOOLSS_ADDPRINTPROCESSOR, api_spoolss_addprintprocessor }, - {"SPOOLSS_ENUMPRINTPROCESSORS", SPOOLSS_ENUMPRINTPROCESSORS, api_spoolss_enumprintprocessors }, - {"SPOOLSS_ENUMMONITORS", SPOOLSS_ENUMMONITORS, api_spoolss_enumprintmonitors }, - {"SPOOLSS_GETJOB", SPOOLSS_GETJOB, api_spoolss_getjob }, - {"SPOOLSS_ENUMPRINTPROCDATATYPES", SPOOLSS_ENUMPRINTPROCDATATYPES, api_spoolss_enumprintprocdatatypes }, - {"SPOOLSS_GETPRINTERDATAEX", SPOOLSS_GETPRINTERDATAEX, api_spoolss_getprinterdataex }, - {"SPOOLSS_SETPRINTERDATAEX", SPOOLSS_SETPRINTERDATAEX, api_spoolss_setprinterdataex }, - {"SPOOLSS_DELETEPRINTERDATAEX", SPOOLSS_DELETEPRINTERDATAEX, api_spoolss_deleteprinterdataex }, - {"SPOOLSS_ENUMPRINTERDATAEX", SPOOLSS_ENUMPRINTERDATAEX, api_spoolss_enumprinterdataex }, - {"SPOOLSS_ENUMPRINTERKEY", SPOOLSS_ENUMPRINTERKEY, api_spoolss_enumprinterkey }, - {"SPOOLSS_DELETEPRINTERKEY", SPOOLSS_DELETEPRINTERKEY, api_spoolss_deleteprinterkey }, - {"SPOOLSS_GETPRINTPROCESSORDIRECTORY",SPOOLSS_GETPRINTPROCESSORDIRECTORY,api_spoolss_getprintprocessordirectory}, - {"SPOOLSS_ADDPRINTERDRIVEREX", SPOOLSS_ADDPRINTERDRIVEREX, api_spoolss_addprinterdriverex }, - {"SPOOLSS_DELETEPRINTERDRIVEREX", SPOOLSS_DELETEPRINTERDRIVEREX, api_spoolss_deleteprinterdriverex }, - {"SPOOLSS_XCVDATAPORT", SPOOLSS_XCVDATAPORT, api_spoolss_xcvdataport }, -}; - -void spoolss2_get_pipe_fns( struct api_struct **fns, int *n_fns ) -{ - *fns = api_spoolss_cmds; - *n_fns = sizeof(api_spoolss_cmds) / sizeof(struct api_struct); -} - -NTSTATUS rpc_spoolss2_init(void) -{ - return rpc_srv_register( - SMB_RPC_INTERFACE_VERSION, "spoolss", "spoolss", - &ndr_table_spoolss, - api_spoolss_cmds, - sizeof(api_spoolss_cmds) / sizeof(struct api_struct)); -} diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 814f406e87..ab15e5c5f6 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -7,6 +7,7 @@ * Copyright (C) Jeremy Allison 2001-2002, * Copyright (C) Gerald Carter 2000-2004, * Copyright (C) Tim Potter 2001-2002. + * Copyright (C) Guenther Deschner 2009. * * 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 @@ -27,6 +28,19 @@ #include "includes.h" +/* macros stolen from s4 spoolss server */ +#define SPOOLSS_BUFFER_UNION(fn,ic,info,level) \ + ((info)?ndr_size_##fn(info, level, ic, 0):0) + +#define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,ic,info,level,count) \ + ((info)?ndr_size_##fn##_info(mem_ctx, ic, level, count, info):0) + +#define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,ic,info,count) \ + ((info)?ndr_size_##fn##_info(mem_ctx, ic, count, info):0) + +#define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false) + + extern userdom_struct current_user_info; #undef DBGC_CLASS @@ -134,7 +148,7 @@ static int nt_printq_status(int v) Disconnect from the client ****************************************************************************/ -static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle) +static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle) { WERROR result; NTSTATUS status; @@ -217,7 +231,8 @@ static int printer_entry_destructor(Printer_entry *Printer) find printer index by handle ****************************************************************************/ -static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd) +static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, + struct policy_handle *hnd) { Printer_entry *find_printer = NULL; @@ -233,12 +248,13 @@ static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd Close printer index by handle. ****************************************************************************/ -static bool close_printer_handle(pipes_struct *p, POLICY_HND *hnd) +static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd) { Printer_entry *Printer = find_printer_index_by_hnd(p, hnd); if (!Printer) { - DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd))); + DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", + OUR_HANDLE(hnd))); return False; } @@ -311,12 +327,13 @@ WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sh Delete a printer given a handle. ****************************************************************************/ -static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd) +static WERROR delete_printer_handle(pipes_struct *p, struct policy_handle *hnd) { Printer_entry *Printer = find_printer_index_by_hnd(p, hnd); if (!Printer) { - DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd))); + DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", + OUR_HANDLE(hnd))); return WERR_BADFID; } @@ -348,13 +365,14 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd) Return the snum of a printer corresponding to an handle. ****************************************************************************/ -static bool get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number, - struct share_params **params) +static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd, + int *number, struct share_params **params) { Printer_entry *Printer = find_printer_index_by_hnd(p, hnd); if (!Printer) { - DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd))); + DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", + OUR_HANDLE(hnd))); return False; } @@ -537,7 +555,8 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) Find first available printer slot. creates a printer handle for you. ****************************************************************************/ -static bool open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint32 access_granted) +static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd, + char *name, uint32_t access_granted) { Printer_entry *new_printer; @@ -618,7 +637,7 @@ static bool is_monitoring_event(Printer_entry *p, uint16 notify_type, /* Check match for field */ for (j = 0; j < option->types[i].count; j++) { - if (option->types[i].fields[j] == notify_field) { + if (option->types[i].fields[j].field == notify_field) { return True; } } @@ -736,52 +755,52 @@ struct notify2_message_table { }; static struct notify2_message_table printer_notify_table[] = { - /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", notify_string }, - /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string }, - /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string }, - /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string }, - /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string }, - /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string }, - /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string }, - /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL }, - /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string }, - /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string }, - /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL }, - /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string }, - /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL }, - /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value }, - /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value }, - /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL }, - /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL }, - /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL }, - /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value }, + /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string }, + /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string }, + /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string }, + /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string }, + /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string }, + /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string }, + /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string }, + /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL }, + /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string }, + /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string }, + /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL }, + /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string }, + /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL }, + /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value }, + /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value }, + /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL }, + /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL }, + /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL }, + /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value }, }; static struct notify2_message_table job_notify_table[] = { - /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL }, - /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL }, - /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL }, - /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string }, - /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL }, - /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL }, - /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL }, - /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL }, - /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL }, - /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL }, - /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value }, - /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL }, - /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL }, - /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string }, - /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL }, - /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL }, - /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time }, - /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL }, - /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL }, - /* 0x13 */ { "JOB_NOTIFY_TIME", NULL }, - /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value }, - /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL }, - /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value }, - /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL }, + /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL }, + /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL }, + /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL }, + /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string }, + /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL }, + /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL }, + /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL }, + /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL }, + /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL }, + /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL }, + /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value }, + /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL }, + /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL }, + /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string }, + /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL }, + /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL }, + /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time }, + /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL }, + /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL }, + /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL }, + /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value }, + /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL }, + /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value }, + /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL }, }; @@ -1445,12 +1464,11 @@ WERROR _spoolss_OpenPrinter(pipes_struct *p, } /******************************************************************** - FIXME: temporary convert_devicemode_new function ********************************************************************/ -static bool convert_devicemode_new(const char *printername, - struct spoolss_DeviceMode *devmode, - NT_DEVICEMODE **pp_nt_devmode) +bool convert_devicemode(const char *printername, + const struct spoolss_DeviceMode *devmode, + NT_DEVICEMODE **pp_nt_devmode) { NT_DEVICEMODE *nt_devmode = *pp_nt_devmode; @@ -1460,7 +1478,7 @@ static bool convert_devicemode_new(const char *printername, */ if (nt_devmode == NULL) { - DEBUG(5, ("convert_devicemode_new: allocating a generic devmode\n")); + DEBUG(5, ("convert_devicemode: allocating a generic devmode\n")); if ((nt_devmode = construct_nt_devicemode(printername)) == NULL) return false; } @@ -1526,7 +1544,6 @@ static bool convert_devicemode_new(const char *printername, WERROR _spoolss_OpenPrinterEx(pipes_struct *p, struct spoolss_OpenPrinterEx *r) { - POLICY_HND *handle = r->out.handle; char *name = CONST_DISCARD(char *, r->in.printername); int snum; Printer_entry *Printer=NULL; @@ -1540,16 +1557,16 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p, DEBUGADD(3,("checking name: %s\n",name)); - if (!open_printer_hnd(p, handle, name, 0)) { + if (!open_printer_hnd(p, r->out.handle, name, 0)) { ZERO_STRUCTP(r->out.handle); return WERR_INVALID_PARAM; } - Printer=find_printer_index_by_hnd(p, handle); + Printer = find_printer_index_by_hnd(p, r->out.handle); if ( !Printer ) { DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer " "handle we created for printer %s\n", name )); - close_printer_handle(p,handle); + close_printer_handle(p, r->out.handle); ZERO_STRUCTP(r->out.handle); return WERR_INVALID_PARAM; } @@ -1600,7 +1617,7 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p, if (r->in.access_mask & ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) { DEBUG(3, ("access DENIED for non-printserver bits\n")); - close_printer_handle(p, handle); + close_printer_handle(p, r->out.handle); ZERO_STRUCTP(r->out.handle); return WERR_ACCESS_DENIED; } @@ -1612,7 +1629,7 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p, SE_PRIV se_printop = SE_PRINT_OPERATOR; if (!lp_ms_add_printer_wizard()) { - close_printer_handle(p, handle); + close_printer_handle(p, r->out.handle); ZERO_STRUCTP(r->out.handle); return WERR_ACCESS_DENIED; } @@ -1628,7 +1645,7 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p, NULL, NULL, p->server_info->ptok, lp_printer_admin(snum))) { - close_printer_handle(p, handle); + close_printer_handle(p, r->out.handle); ZERO_STRUCTP(r->out.handle); return WERR_ACCESS_DENIED; } @@ -1650,8 +1667,8 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p, /* NT doesn't let us connect to a printer if the connecting user doesn't have print permission. */ - if (!get_printer_snum(p, handle, &snum, NULL)) { - close_printer_handle(p, handle); + if (!get_printer_snum(p, r->out.handle, &snum, NULL)) { + close_printer_handle(p, r->out.handle); ZERO_STRUCTP(r->out.handle); return WERR_BADFID; } @@ -1687,14 +1704,14 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p, !print_access_check(p->server_info, snum, r->in.access_mask)) { DEBUG(3, ("access DENIED for printer open\n")); - close_printer_handle(p, handle); + close_printer_handle(p, r->out.handle); ZERO_STRUCTP(r->out.handle); return WERR_ACCESS_DENIED; } if ((r->in.access_mask & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) { DEBUG(3, ("access DENIED for printer open - unknown bits\n")); - close_printer_handle(p, handle); + close_printer_handle(p, r->out.handle); ZERO_STRUCTP(r->out.handle); return WERR_ACCESS_DENIED; } @@ -1722,12 +1739,11 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p, * save it here in case we get a job submission on this handle */ - if ( (Printer->printer_type != SPLHND_SERVER) - && r->in.devmode_ctr.devmode ) - { - convert_devicemode_new(Printer->sharename, - r->in.devmode_ctr.devmode, - &Printer->nt_devmode); + if ((Printer->printer_type != SPLHND_SERVER) && + r->in.devmode_ctr.devmode) { + convert_devicemode(Printer->sharename, + r->in.devmode_ctr.devmode, + &Printer->nt_devmode); } #if 0 /* JERRY -- I'm doubtful this is really effective */ @@ -1783,8 +1799,8 @@ static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2 *r, /**************************************************************************** ****************************************************************************/ -static bool convert_printer_info_new(struct spoolss_SetPrinterInfoCtr *info_ctr, - NT_PRINTER_INFO_LEVEL *printer) +static bool convert_printer_info(struct spoolss_SetPrinterInfoCtr *info_ctr, + NT_PRINTER_INFO_LEVEL *printer) { bool ret; @@ -1797,7 +1813,7 @@ static bool convert_printer_info_new(struct spoolss_SetPrinterInfoCtr *info_ctr, if (!printer->info_2) { printer->info_2 = TALLOC_ZERO_P(printer, NT_PRINTER_INFO_LEVEL_2); if (!printer->info_2) { - DEBUG(0,("convert_printer_info_new: " + DEBUG(0,("convert_printer_info: " "talloc() failed!\n")); return false; } @@ -1983,83 +1999,14 @@ static bool convert_printer_driver_info(const struct spoolss_AddDriverInfoCtr *r return true; } -bool convert_devicemode(const char *printername, const DEVICEMODE *devmode, - NT_DEVICEMODE **pp_nt_devmode) -{ - NT_DEVICEMODE *nt_devmode = *pp_nt_devmode; - - /* - * Ensure nt_devmode is a valid pointer - * as we will be overwriting it. - */ - - if (nt_devmode == NULL) { - DEBUG(5, ("convert_devicemode: allocating a generic devmode\n")); - if ((nt_devmode = construct_nt_devicemode(printername)) == NULL) - return False; - } - - rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0); - rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0); - - nt_devmode->specversion=devmode->specversion; - nt_devmode->driverversion=devmode->driverversion; - nt_devmode->size=devmode->size; - nt_devmode->fields=devmode->fields; - nt_devmode->orientation=devmode->orientation; - nt_devmode->papersize=devmode->papersize; - nt_devmode->paperlength=devmode->paperlength; - nt_devmode->paperwidth=devmode->paperwidth; - nt_devmode->scale=devmode->scale; - nt_devmode->copies=devmode->copies; - nt_devmode->defaultsource=devmode->defaultsource; - nt_devmode->printquality=devmode->printquality; - nt_devmode->color=devmode->color; - nt_devmode->duplex=devmode->duplex; - nt_devmode->yresolution=devmode->yresolution; - nt_devmode->ttoption=devmode->ttoption; - nt_devmode->collate=devmode->collate; - - nt_devmode->logpixels=devmode->logpixels; - nt_devmode->bitsperpel=devmode->bitsperpel; - nt_devmode->pelswidth=devmode->pelswidth; - nt_devmode->pelsheight=devmode->pelsheight; - nt_devmode->displayflags=devmode->displayflags; - nt_devmode->displayfrequency=devmode->displayfrequency; - nt_devmode->icmmethod=devmode->icmmethod; - nt_devmode->icmintent=devmode->icmintent; - nt_devmode->mediatype=devmode->mediatype; - nt_devmode->dithertype=devmode->dithertype; - nt_devmode->reserved1=devmode->reserved1; - nt_devmode->reserved2=devmode->reserved2; - nt_devmode->panningwidth=devmode->panningwidth; - nt_devmode->panningheight=devmode->panningheight; - - /* - * Only change private and driverextra if the incoming devmode - * has a new one. JRA. - */ - - if ((devmode->driverextra != 0) && (devmode->dev_private != NULL)) { - SAFE_FREE(nt_devmode->nt_dev_private); - nt_devmode->driverextra=devmode->driverextra; - if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL) - return False; - memcpy(nt_devmode->nt_dev_private, devmode->dev_private, nt_devmode->driverextra); - } - - *pp_nt_devmode = nt_devmode; - - return True; -} - /******************************************************************** * _spoolss_enddocprinter_internal. ********************************************************************/ -static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle) +static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, + struct policy_handle *handle) { - Printer_entry *Printer=find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, handle); int snum; if (!Printer) { @@ -2084,14 +2031,12 @@ static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handl WERROR _spoolss_ClosePrinter(pipes_struct *p, struct spoolss_ClosePrinter *r) { - POLICY_HND *handle = r->in.handle; - - Printer_entry *Printer=find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); if (Printer && Printer->document_started) - _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */ + _spoolss_enddocprinter_internal(p, r->in.handle); /* print job was not closed */ - if (!close_printer_handle(p, handle)) + if (!close_printer_handle(p, r->in.handle)) return WERR_BADFID; /* clear the returned printer handle. Observed behavior @@ -2111,14 +2056,13 @@ WERROR _spoolss_ClosePrinter(pipes_struct *p, WERROR _spoolss_DeletePrinter(pipes_struct *p, struct spoolss_DeletePrinter *r) { - POLICY_HND *handle = r->in.handle; - Printer_entry *Printer=find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); WERROR result; if (Printer && Printer->document_started) - _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */ + _spoolss_enddocprinter_internal(p, r->in.handle); /* print job was not closed */ - result = delete_printer_handle(p, handle); + result = delete_printer_handle(p, r->in.handle); update_c_setprinter(False); @@ -2385,52 +2329,6 @@ done: /**************************************************************************** - Internal routine for retreiving printerdata - ***************************************************************************/ - -static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer, - const char *key, const char *value, uint32 *type, uint8 **data, - uint32 *needed, uint32 in_size ) -{ - REGISTRY_VALUE *val; - uint32 size; - int data_len; - - if ( !(val = get_printer_data( printer->info_2, key, value)) ) - return WERR_BADFILE; - - *type = regval_type( val ); - - DEBUG(5,("get_printer_dataex: allocating %d\n", in_size)); - - size = regval_size( val ); - - /* copy the min(in_size, len) */ - - if ( in_size ) { - data_len = (size > in_size) ? in_size : size*sizeof(uint8); - - /* special case for 0 length values */ - if ( data_len ) { - if ( (*data = (uint8 *)TALLOC_MEMDUP(ctx, regval_data_p(val), data_len)) == NULL ) - return WERR_NOMEM; - } - else { - if ( (*data = (uint8 *)TALLOC_ZERO(ctx, in_size)) == NULL ) - return WERR_NOMEM; - } - } - else - *data = NULL; - - *needed = size; - - DEBUG(5,("get_printer_dataex: copy done\n")); - - return WERR_OK; -} - -/**************************************************************************** Internal routine for removing printerdata ***************************************************************************/ @@ -2455,74 +2353,58 @@ WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, cons GetPrinterData on a printer server Handle. ********************************************************************/ -static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size) +static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx, + const char *value, + enum winreg_Type *type, + union spoolss_PrinterData *data) { - int i; - DEBUG(8,("getprinterdata_printer_server:%s\n", value)); if (!StrCaseCmp(value, "W3SvcInstalled")) { *type = REG_DWORD; - if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) ) - return WERR_NOMEM; - SIVAL(*data, 0, 0x00); - *needed = 0x4; + data->value = 0x00; return WERR_OK; } if (!StrCaseCmp(value, "BeepEnabled")) { *type = REG_DWORD; - if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) ) - return WERR_NOMEM; - SIVAL(*data, 0, 0x00); - *needed = 0x4; + data->value = 0x00; return WERR_OK; } if (!StrCaseCmp(value, "EventLog")) { *type = REG_DWORD; - if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) ) - return WERR_NOMEM; /* formally was 0x1b */ - SIVAL(*data, 0, 0x0); - *needed = 0x4; + data->value = 0x00; return WERR_OK; } if (!StrCaseCmp(value, "NetPopup")) { *type = REG_DWORD; - if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) ) - return WERR_NOMEM; - SIVAL(*data, 0, 0x00); - *needed = 0x4; + data->value = 0x00; return WERR_OK; } if (!StrCaseCmp(value, "MajorVersion")) { *type = REG_DWORD; - if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) ) - return WERR_NOMEM; /* Windows NT 4.0 seems to not allow uploading of drivers to a server that reports 0x3 as the MajorVersion. need to investigate more how Win2k gets around this . -- jerry */ - if ( RA_WINNT == get_remote_arch() ) - SIVAL(*data, 0, 2); - else - SIVAL(*data, 0, 3); + if (RA_WINNT == get_remote_arch()) { + data->value = 0x02; + } else { + data->value = 0x03; + } - *needed = 0x4; return WERR_OK; } if (!StrCaseCmp(value, "MinorVersion")) { *type = REG_DWORD; - if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) ) - return WERR_NOMEM; - SIVAL(*data, 0, 0); - *needed = 0x4; + data->value = 0x00; return WERR_OK; } @@ -2534,109 +2416,88 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint * extra unicode string = e.g. "Service Pack 3" */ if (!StrCaseCmp(value, "OSVersion")) { - *type = REG_BINARY; - *needed = 0x114; - - if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) ) - return WERR_NOMEM; - - SIVAL(*data, 0, *needed); /* size */ - SIVAL(*data, 4, 5); /* Windows 2000 == 5.0 */ - SIVAL(*data, 8, 0); - SIVAL(*data, 12, 2195); /* build */ + DATA_BLOB blob; + enum ndr_err_code ndr_err; + struct spoolss_OSVersion os; + + os.major = 5; /* Windows 2000 == 5.0 */ + os.minor = 0; + os.build = 2195; /* build */ + os.extra_string = ""; /* leave extra string empty */ + + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &os, + (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return WERR_GENERAL_FAILURE; + } - /* leave extra string empty */ + *type = REG_BINARY; + data->binary = blob; return WERR_OK; } if (!StrCaseCmp(value, "DefaultSpoolDirectory")) { - const char *string="C:\\PRINTERS"; *type = REG_SZ; - *needed = 2*(strlen(string)+1); - if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL) - return WERR_NOMEM; - memset(*data, 0, (*needed > in_size) ? *needed:in_size); - /* it's done by hand ready to go on the wire */ - for (i=0; i<strlen(string); i++) { - (*data)[2*i]=string[i]; - (*data)[2*i+1]='\0'; - } + data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS"); + W_ERROR_HAVE_NO_MEMORY(data->string); + return WERR_OK; } if (!StrCaseCmp(value, "Architecture")) { - const char *string="Windows NT x86"; *type = REG_SZ; - *needed = 2*(strlen(string)+1); - if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL) - return WERR_NOMEM; - memset(*data, 0, (*needed > in_size) ? *needed:in_size); - for (i=0; i<strlen(string); i++) { - (*data)[2*i]=string[i]; - (*data)[2*i+1]='\0'; - } + + data->string = talloc_strdup(mem_ctx, "Windows NT x86"); + W_ERROR_HAVE_NO_MEMORY(data->string); + return WERR_OK; } if (!StrCaseCmp(value, "DsPresent")) { *type = REG_DWORD; - if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) ) - return WERR_NOMEM; /* only show the publish check box if we are a - memeber of a AD domain */ + member of a AD domain */ - if ( lp_security() == SEC_ADS ) - SIVAL(*data, 0, 0x01); - else - SIVAL(*data, 0, 0x00); - - *needed = 0x4; + if (lp_security() == SEC_ADS) { + data->value = 0x01; + } else { + data->value = 0x00; + } return WERR_OK; } if (!StrCaseCmp(value, "DNSMachineName")) { const char *hostname = get_mydnsfullname(); - if (!hostname) + if (!hostname) { return WERR_BADFILE; - *type = REG_SZ; - *needed = 2*(strlen(hostname)+1); - if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL) - return WERR_NOMEM; - memset(*data, 0, (*needed > in_size) ? *needed:in_size); - for (i=0; i<strlen(hostname); i++) { - (*data)[2*i]=hostname[i]; - (*data)[2*i+1]='\0'; } + + *type = REG_SZ; + data->string = talloc_strdup(mem_ctx, hostname); + W_ERROR_HAVE_NO_MEMORY(data->string); + return WERR_OK; } - - return WERR_BADFILE; + return WERR_INVALID_PARAM; } -/******************************************************************** - * spoolss_getprinterdata - ********************************************************************/ +/**************************************************************** + _spoolss_GetPrinterData +****************************************************************/ -WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u) -{ - POLICY_HND *handle = &q_u->handle; - UNISTR2 *valuename = &q_u->valuename; - uint32 in_size = q_u->size; - uint32 *type = &r_u->type; - uint32 *out_size = &r_u->size; - uint8 **data = &r_u->data; - uint32 *needed = &r_u->needed; - WERROR status; - fstring value; - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); - NT_PRINTER_INFO_LEVEL *printer = NULL; - int snum = 0; +WERROR _spoolss_GetPrinterData(pipes_struct *p, + struct spoolss_GetPrinterData *r) +{ + WERROR result; + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); + NT_PRINTER_INFO_LEVEL *printer = NULL; + int snum = 0; /* * Reminder: when it's a string, the length is in BYTES @@ -2645,79 +2506,80 @@ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO * JFM, 4/19/1999 */ - *out_size = in_size; - /* in case of problem, return some default values */ - *needed = 0; - *type = 0; + *r->out.needed = 0; + *r->out.type = 0; - DEBUG(4,("_spoolss_getprinterdata\n")); + DEBUG(4,("_spoolss_GetPrinterData\n")); - if ( !Printer ) { - DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); - status = WERR_BADFID; + if (!Printer) { + DEBUG(2,("_spoolss_GetPrinterData: Invalid handle (%s:%u:%u).\n", + OUR_HANDLE(r->in.handle))); + result = WERR_BADFID; goto done; } - unistr2_to_ascii(value, valuename, sizeof(value)); - - if ( Printer->printer_type == SPLHND_SERVER ) - status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size ); - else - { - if ( !get_printer_snum(p,handle, &snum, NULL) ) { - status = WERR_BADFID; + if (Printer->printer_type == SPLHND_SERVER) { + result = getprinterdata_printer_server(p->mem_ctx, + r->in.value_name, + r->out.type, + r->out.data); + } else { + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { + result = WERR_BADFID; goto done; } - status = get_a_printer(Printer, &printer, 2, lp_servicename(snum)); - if ( !W_ERROR_IS_OK(status) ) + result = get_a_printer(Printer, &printer, 2, lp_servicename(snum)); + if (!W_ERROR_IS_OK(result)) { goto done; + } /* XP sends this and wants to change id value from the PRINTER_INFO_0 */ - if ( strequal(value, "ChangeId") ) { - *type = REG_DWORD; - *needed = sizeof(uint32); - if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) { - status = WERR_NOMEM; + if (strequal(r->in.value_name, "ChangeId")) { + *r->out.type = REG_DWORD; + r->out.data->value = printer->info_2->changeid; + result = WERR_OK; + } else { + REGISTRY_VALUE *v; + DATA_BLOB blob; + + v = get_printer_data(printer->info_2, + SPOOL_PRINTERDATA_KEY, + r->in.value_name); + if (!v) { + result = WERR_BADFILE; goto done; } - SIVAL( *data, 0, printer->info_2->changeid ); - status = WERR_OK; - } - else - status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size ); - } - if (*needed > *out_size) - status = WERR_MORE_DATA; - -done: - if ( !W_ERROR_IS_OK(status) ) - { - DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size)); + *r->out.type = v->type; - /* reply this param doesn't exist */ + blob = data_blob_const(v->data_p, v->size); - if ( *out_size ) { - if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) { - if ( printer ) - free_a_printer( &printer, 2 ); - return WERR_NOMEM; - } - } else { - *data = NULL; + result = pull_spoolss_PrinterData(p->mem_ctx, &blob, + r->out.data, + *r->out.type); } } + done: /* cleanup & exit */ - if ( printer ) - free_a_printer( &printer, 2 ); + if (printer) { + free_a_printer(&printer, 2); + } - return status; + if (!W_ERROR_IS_OK(result)) { + return result; + } + + *r->out.needed = ndr_size_spoolss_PrinterData(r->out.data, *r->out.type, NULL, 0); + *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE); + r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data); + + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA); } /********************************************************* @@ -2775,7 +2637,7 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, * Now start the NT Domain stuff :-). */ - ret = cli_rpc_pipe_open_noauth(the_cli, &syntax_spoolss, pp_pipe); + ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe); if (!NT_STATUS_IS_OK(ret)) { DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n", remote_machine, nt_errstr(ret))); @@ -2792,7 +2654,8 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, static bool srv_spoolss_replyopenprinter(int snum, const char *printer, uint32 localprinter, uint32 type, - POLICY_HND *handle, struct sockaddr_storage *client_ss) + struct policy_handle *handle, + struct sockaddr_storage *client_ss) { WERROR result; NTSTATUS status; @@ -2878,7 +2741,7 @@ static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx if (option->types[i].count) { option->types[i].fields = talloc_zero_array(option, - enum spoolss_Field, option->types[i].count); + union spoolss_Field, option->types[i].count); if (!option->types[i].fields) { talloc_free(option); return NULL; @@ -2906,18 +2769,18 @@ static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p, struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r) { - POLICY_HND *handle = r->in.handle; int snum = -1; struct spoolss_NotifyOption *option = r->in.notify_options; struct sockaddr_storage client_ss; /* store the notify value in the printer struct */ - Printer_entry *Printer=find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); if (!Printer) { DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: " - "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); + "Invalid handle (%s:%u:%u).\n", + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } @@ -2935,7 +2798,7 @@ WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p, if ( Printer->printer_type == SPLHND_SERVER) snum = -1; else if ( (Printer->printer_type == SPLHND_PRINTER) && - !get_printer_snum(p, handle, &snum, NULL) ) + !get_printer_snum(p, r->in.handle, &snum, NULL) ) return WERR_BADFID; if (!interpret_string_addr(&client_ss, p->client_address, @@ -3423,7 +3286,7 @@ static void spoolss_notify_submitted_time(int snum, struct s_notify_info_data_table { enum spoolss_NotifyType type; - enum spoolss_Field field; + uint16_t field; const char *name; enum spoolss_NotifyTable variable_type; void (*fn) (int snum, struct spoolss_Notify *data, @@ -3437,55 +3300,55 @@ struct s_notify_info_data_table static const struct s_notify_info_data_table notify_info_data_table[] = { -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_TABLE_STRING, NULL }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size }, }; /******************************************************************* @@ -3493,7 +3356,7 @@ static const struct s_notify_info_data_table notify_info_data_table[] = ********************************************************************/ static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type, - enum spoolss_Field field) + uint16_t field) { int i=0; @@ -3513,7 +3376,7 @@ static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type, ****************************************************************************/ static bool search_notify(enum spoolss_NotifyType type, - enum spoolss_Field field, + uint16_t field, int *value) { int i; @@ -3535,11 +3398,11 @@ static bool search_notify(enum spoolss_NotifyType type, void construct_info_data(struct spoolss_Notify *info_data, enum spoolss_NotifyType type, - enum spoolss_Field field, + uint16_t field, int id) { info_data->type = type; - info_data->field = field; + info_data->field.field = field; info_data->variable_type = variable_type_of_notify_info_data(type, field); info_data->job_id = id; } @@ -3559,7 +3422,7 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, { int field_num,j; enum spoolss_NotifyType type; - enum spoolss_Field field; + uint16_t field; struct spoolss_Notify *current_data; NT_PRINTER_INFO_LEVEL *printer = NULL; @@ -3575,7 +3438,7 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, return False; for(field_num=0; field_num < option_type->count; field_num++) { - field = option_type->fields[field_num]; + field = option_type->fields[field_num].field; DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field)); @@ -3624,7 +3487,7 @@ static bool construct_notify_jobs_info(print_queue_struct *queue, { int field_num,j; enum spoolss_NotifyType type; - enum spoolss_Field field; + uint16_t field; struct spoolss_Notify *current_data; DEBUG(4,("construct_notify_jobs_info\n")); @@ -3636,7 +3499,7 @@ static bool construct_notify_jobs_info(print_queue_struct *queue, option_type->count)); for(field_num=0; field_num<option_type->count; field_num++) { - field = option_type->fields[field_num]; + field = option_type->fields[field_num].field; if (!search_notify(type, field, &j) ) continue; @@ -3690,12 +3553,13 @@ static bool construct_notify_jobs_info(print_queue_struct *queue, * ********************************************************************/ -static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd, +static WERROR printserver_notify_info(pipes_struct *p, + struct policy_handle *hnd, struct spoolss_NotifyInfo *info, TALLOC_CTX *mem_ctx) { int snum; - Printer_entry *Printer=find_printer_index_by_hnd(p, hnd); + Printer_entry *Printer = find_printer_index_by_hnd(p, hnd); int n_services=lp_numservices(); int i; struct spoolss_NotifyOption *option; @@ -3756,11 +3620,12 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd, * ********************************************************************/ -static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, struct spoolss_NotifyInfo *info, +static WERROR printer_notify_info(pipes_struct *p, struct policy_handle *hnd, + struct spoolss_NotifyInfo *info, TALLOC_CTX *mem_ctx) { int snum; - Printer_entry *Printer=find_printer_index_by_hnd(p, hnd); + Printer_entry *Printer = find_printer_index_by_hnd(p, hnd); int i; uint32 id; struct spoolss_NotifyOption *option; @@ -3849,10 +3714,9 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, struct spool WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p, struct spoolss_RouterRefreshPrinterChangeNotify *r) { - POLICY_HND *handle = r->in.handle; struct spoolss_NotifyInfo *info; - Printer_entry *Printer=find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); WERROR result = WERR_BADFID; /* we always have a spoolss_NotifyInfo struct */ @@ -3866,7 +3730,8 @@ WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p, if (!Printer) { DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: " - "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); + "Invalid handle (%s:%u:%u).\n", + OUR_HANDLE(r->in.handle))); goto done; } @@ -3895,11 +3760,13 @@ WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p, switch (Printer->printer_type) { case SPLHND_SERVER: - result = printserver_notify_info(p, handle, info, p->mem_ctx); + result = printserver_notify_info(p, r->in.handle, + info, p->mem_ctx); break; case SPLHND_PRINTER: - result = printer_notify_info(p, handle, info, p->mem_ctx); + result = printer_notify_info(p, r->in.handle, + info, p->mem_ctx); break; } @@ -3914,219 +3781,161 @@ done: * fill a printer_info_0 struct ********************************************************************/ -static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum) +static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx, + const NT_PRINTER_INFO_LEVEL *ntprinter, + struct spoolss_PrinterInfo0 *r, + int snum) { - char *chaine = NULL; int count; - NT_PRINTER_INFO_LEVEL *ntprinter = NULL; counter_printer_0 *session_counter; - uint32 global_counter; - struct tm *t; time_t setuptime; print_status_struct status; - TALLOC_CTX *ctx = talloc_tos(); - - if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) - return False; - init_unistr(&printer->printername, ntprinter->info_2->printername); + r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername); + W_ERROR_HAVE_NO_MEMORY(r->printername); - chaine = talloc_asprintf(ctx, "\\\\%s", get_server_name(print_hnd)); - if (!chaine) { - free_a_printer(&ntprinter,2); - return false; - } + r->servername = talloc_strdup(mem_ctx, ntprinter->info_2->servername); + W_ERROR_HAVE_NO_MEMORY(r->servername); count = print_queue_length(snum, &status); /* check if we already have a counter for this printer */ - for(session_counter = counter_list; session_counter; session_counter = session_counter->next) { + for (session_counter = counter_list; session_counter; session_counter = session_counter->next) { if (session_counter->snum == snum) break; } - init_unistr(&printer->servername, chaine); - /* it's the first time, add it to the list */ - if (session_counter==NULL) { - if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) { - free_a_printer(&ntprinter, 2); - return False; - } + if (session_counter == NULL) { + session_counter = SMB_MALLOC_P(counter_printer_0); + W_ERROR_HAVE_NO_MEMORY(session_counter); ZERO_STRUCTP(session_counter); - session_counter->snum=snum; - session_counter->counter=0; + session_counter->snum = snum; + session_counter->counter = 0; DLIST_ADD(counter_list, session_counter); } /* increment it */ session_counter->counter++; - /* JFM: - * the global_counter should be stored in a TDB as it's common to all the clients - * and should be zeroed on samba startup - */ - global_counter=session_counter->counter; - printer->cjobs = count; - printer->total_jobs = 0; - printer->total_bytes = 0; + r->cjobs = count; + r->total_jobs = 0; + r->total_bytes = 0; setuptime = (time_t)ntprinter->info_2->setuptime; - t=gmtime(&setuptime); - - printer->year = t->tm_year+1900; - printer->month = t->tm_mon+1; - printer->dayofweek = t->tm_wday; - printer->day = t->tm_mday; - printer->hour = t->tm_hour; - printer->minute = t->tm_min; - printer->second = t->tm_sec; - printer->milliseconds = 0; - printer->global_counter = global_counter; - printer->total_pages = 0; + init_systemtime(&r->time, gmtime(&setuptime)); + /* JFM: + * the global_counter should be stored in a TDB as it's common to all the clients + * and should be zeroed on samba startup + */ + r->global_counter = session_counter->counter; + r->total_pages = 0; /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */ - printer->major_version = 0x0005; /* NT 5 */ - printer->build_version = 0x0893; /* build 2195 */ - - printer->unknown7 = 0x1; - printer->unknown8 = 0x0; - printer->unknown9 = 0x0; - printer->session_counter = session_counter->counter; - printer->unknown11 = 0x0; - printer->printer_errors = 0x0; /* number of print failure */ - printer->unknown13 = 0x0; - printer->unknown14 = 0x1; - printer->unknown15 = 0x024a; /* 586 Pentium ? */ - printer->unknown16 = 0x0; - printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/ - printer->unknown18 = 0x0; - printer->status = nt_printq_status(status.status); - printer->unknown20 = 0x0; - printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */ - printer->unknown22 = 0x0; - printer->unknown23 = 0x6; /* 6 ???*/ - printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */ - printer->unknown25 = 0; - printer->unknown26 = 0; - printer->unknown27 = 0; - printer->unknown28 = 0; - printer->unknown29 = 0; - - free_a_printer(&ntprinter,2); - return (True); -} - -/******************************************************************** - * construct_printer_info_1 - * fill a printer_info_1 struct - ********************************************************************/ -static bool construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum) -{ - char *chaine = NULL; - NT_PRINTER_INFO_LEVEL *ntprinter = NULL; - TALLOC_CTX *ctx = talloc_tos(); - - if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) - return false; - - printer->flags=flags; - - if (*ntprinter->info_2->comment == '\0') { - init_unistr(&printer->comment, lp_comment(snum)); - chaine = talloc_asprintf(ctx, - "%s,%s,%s", ntprinter->info_2->printername, - ntprinter->info_2->drivername, lp_comment(snum)); - } - else { - init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */ - chaine = talloc_asprintf(ctx, - "%s,%s,%s", ntprinter->info_2->printername, - ntprinter->info_2->drivername, ntprinter->info_2->comment); - } - - if (!chaine) { - free_a_printer(&ntprinter,2); - return false; - } - - init_unistr(&printer->description, chaine); - init_unistr(&printer->name, ntprinter->info_2->printername); - - free_a_printer(&ntprinter,2); + r->version = 0x0005; /* NT 5 */ + r->free_build = 0x0893; /* build 2195 */ + r->spooling = 0; + r->max_spooling = 0; + r->session_counter = session_counter->counter; + r->num_error_out_of_paper = 0x0; + r->num_error_not_ready = 0x0; /* number of print failure */ + r->job_error = 0x0; + r->number_of_processors = 0x1; + r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */ + r->high_part_total_bytes = 0x0; + r->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/ + r->last_error = WERR_OK; + r->status = nt_printq_status(status.status); + r->enumerate_network_printers = 0x0; + r->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */ + r->processor_architecture = 0x0; + r->processor_level = 0x6; /* 6 ???*/ + r->ref_ic = 0; + r->reserved2 = 0; + r->reserved3 = 0; - return True; -} - -/**************************************************************************** - Free a DEVMODE struct. -****************************************************************************/ - -static void free_dev_mode(DEVICEMODE *dev) -{ - if (dev == NULL) - return; - - SAFE_FREE(dev->dev_private); - SAFE_FREE(dev); + return WERR_OK; } - /**************************************************************************** - Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers + Convert an NT_DEVICEMODE to a spoolss_DeviceMode structure. Both pointers should be valid upon entry ****************************************************************************/ -static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode ) +static WERROR convert_nt_devicemode(TALLOC_CTX *mem_ctx, + struct spoolss_DeviceMode *r, + const NT_DEVICEMODE *ntdevmode) { - if ( !devmode || !ntdevmode ) - return False; + if (!r || !ntdevmode) { + return WERR_INVALID_PARAM; + } - init_unistr(&devmode->devicename, ntdevmode->devicename); - - init_unistr(&devmode->formname, ntdevmode->formname); - - devmode->specversion = ntdevmode->specversion; - devmode->driverversion = ntdevmode->driverversion; - devmode->size = ntdevmode->size; - devmode->driverextra = ntdevmode->driverextra; - devmode->fields = ntdevmode->fields; - - devmode->orientation = ntdevmode->orientation; - devmode->papersize = ntdevmode->papersize; - devmode->paperlength = ntdevmode->paperlength; - devmode->paperwidth = ntdevmode->paperwidth; - devmode->scale = ntdevmode->scale; - devmode->copies = ntdevmode->copies; - devmode->defaultsource = ntdevmode->defaultsource; - devmode->printquality = ntdevmode->printquality; - devmode->color = ntdevmode->color; - devmode->duplex = ntdevmode->duplex; - devmode->yresolution = ntdevmode->yresolution; - devmode->ttoption = ntdevmode->ttoption; - devmode->collate = ntdevmode->collate; - devmode->icmmethod = ntdevmode->icmmethod; - devmode->icmintent = ntdevmode->icmintent; - devmode->mediatype = ntdevmode->mediatype; - devmode->dithertype = ntdevmode->dithertype; + r->devicename = talloc_strdup(mem_ctx, ntdevmode->devicename); + W_ERROR_HAVE_NO_MEMORY(r->devicename); + + r->specversion = ntdevmode->specversion; + r->driverversion = ntdevmode->driverversion; + r->size = ntdevmode->size; + r->__driverextra_length = ntdevmode->driverextra; + r->fields = ntdevmode->fields; + + r->orientation = ntdevmode->orientation; + r->papersize = ntdevmode->papersize; + r->paperlength = ntdevmode->paperlength; + r->paperwidth = ntdevmode->paperwidth; + r->scale = ntdevmode->scale; + r->copies = ntdevmode->copies; + r->defaultsource = ntdevmode->defaultsource; + r->printquality = ntdevmode->printquality; + r->color = ntdevmode->color; + r->duplex = ntdevmode->duplex; + r->yresolution = ntdevmode->yresolution; + r->ttoption = ntdevmode->ttoption; + r->collate = ntdevmode->collate; + + r->formname = talloc_strdup(mem_ctx, ntdevmode->formname); + W_ERROR_HAVE_NO_MEMORY(r->formname); + + /* all 0 below are values that have not been set in the old parsing/copy + * function, maybe they should... - gd */ + + r->logpixels = 0; + r->bitsperpel = 0; + r->pelswidth = 0; + r->pelsheight = 0; + r->displayflags = 0; + r->displayfrequency = 0; + r->icmmethod = ntdevmode->icmmethod; + r->icmintent = ntdevmode->icmintent; + r->mediatype = ntdevmode->mediatype; + r->dithertype = ntdevmode->dithertype; + r->reserved1 = 0; + r->reserved2 = 0; + r->panningwidth = 0; + r->panningheight = 0; if (ntdevmode->nt_dev_private != NULL) { - if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL) - return False; + r->driverextra_data = data_blob_talloc(mem_ctx, + ntdevmode->nt_dev_private, + ntdevmode->driverextra); + W_ERROR_HAVE_NO_MEMORY(r->driverextra_data.data); } - return True; + return WERR_OK; } + /**************************************************************************** - Create a DEVMODE struct. Returns malloced memory. + Create a spoolss_DeviceMode struct. Returns talloced memory. ****************************************************************************/ -DEVICEMODE *construct_dev_mode(const char *servicename) +struct spoolss_DeviceMode *construct_dev_mode(TALLOC_CTX *mem_ctx, + const char *servicename) { + WERROR result; NT_PRINTER_INFO_LEVEL *printer = NULL; - DEVICEMODE *devmode = NULL; + struct spoolss_DeviceMode *devmode = NULL; DEBUG(7,("construct_dev_mode\n")); @@ -4135,23 +3944,22 @@ DEVICEMODE *construct_dev_mode(const char *servicename) if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename))) return NULL; - if ( !printer->info_2->devmode ) { + if (!printer->info_2->devmode) { DEBUG(5, ("BONG! There was no device mode!\n")); goto done; } - if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) { - DEBUG(2,("construct_dev_mode: malloc fail.\n")); + devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode); + if (!devmode) { + DEBUG(2,("construct_dev_mode: talloc fail.\n")); goto done; } - ZERO_STRUCTP(devmode); - DEBUGADD(8,("loading DEVICEMODE\n")); - if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) { - free_dev_mode( devmode ); - devmode = NULL; + result = convert_nt_devicemode(mem_ctx, devmode, printer->info_2->devmode); + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(devmode); } done: @@ -4161,371 +3969,348 @@ done: } /******************************************************************** - * construct_printer_info_2 - * fill a printer_info_2 struct + * construct_printer_info3 + * fill a spoolss_PrinterInfo3 struct ********************************************************************/ -static bool construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum) +static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx, + const NT_PRINTER_INFO_LEVEL *ntprinter, + struct spoolss_PrinterInfo3 *r, + int snum) { - int count; - NT_PRINTER_INFO_LEVEL *ntprinter = NULL; - - print_status_struct status; - - if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) - return False; - - count = print_queue_length(snum, &status); - - init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/ - init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/ - init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */ - init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */ - init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */ - - if (*ntprinter->info_2->comment == '\0') - init_unistr(&printer->comment, lp_comment(snum)); /* comment */ - else - init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */ - - init_unistr(&printer->location, ntprinter->info_2->location); /* location */ - init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */ - init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */ - init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */ - init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */ - - printer->attributes = ntprinter->info_2->attributes; - - printer->priority = ntprinter->info_2->priority; /* priority */ - printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */ - printer->starttime = ntprinter->info_2->starttime; /* starttime */ - printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */ - printer->status = nt_printq_status(status.status); /* status */ - printer->cjobs = count; /* jobs */ - printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */ - - if ( !(printer->devmode = construct_dev_mode( - lp_const_servicename(snum))) ) - DEBUG(8, ("Returning NULL Devicemode!\n")); - - printer->secdesc = NULL; + /* These are the components of the SD we are returning. */ - if ( ntprinter->info_2->secdesc_buf - && ntprinter->info_2->secdesc_buf->sd_size != 0 ) - { + if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) { /* don't use talloc_steal() here unless you do a deep steal of all the SEC_DESC members */ - printer->secdesc = dup_sec_desc( talloc_tos(), - ntprinter->info_2->secdesc_buf->sd ); + r->secdesc = dup_sec_desc(mem_ctx, + ntprinter->info_2->secdesc_buf->sd); + W_ERROR_HAVE_NO_MEMORY(r->secdesc); } - free_a_printer(&ntprinter, 2); - - return True; + return WERR_OK; } /******************************************************************** - * construct_printer_info_3 - * fill a printer_info_3 struct + * construct_printer_info4 + * fill a spoolss_PrinterInfo4 struct ********************************************************************/ -static bool construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum) +static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx, + const NT_PRINTER_INFO_LEVEL *ntprinter, + struct spoolss_PrinterInfo4 *r, + int snum) { - NT_PRINTER_INFO_LEVEL *ntprinter = NULL; - PRINTER_INFO_3 *printer = NULL; + r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername); + W_ERROR_HAVE_NO_MEMORY(r->printername); + r->servername = talloc_strdup(mem_ctx, ntprinter->info_2->servername); + W_ERROR_HAVE_NO_MEMORY(r->servername); - if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) - return False; + r->attributes = ntprinter->info_2->attributes; - *pp_printer = NULL; - if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) { - DEBUG(2,("construct_printer_info_3: malloc fail.\n")); - free_a_printer(&ntprinter, 2); - return False; - } + return WERR_OK; +} - ZERO_STRUCTP(printer); +/******************************************************************** + * construct_printer_info5 + * fill a spoolss_PrinterInfo5 struct + ********************************************************************/ - /* These are the components of the SD we are returning. */ +static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx, + const NT_PRINTER_INFO_LEVEL *ntprinter, + struct spoolss_PrinterInfo5 *r, + int snum) +{ + r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername); + W_ERROR_HAVE_NO_MEMORY(r->printername); + r->portname = talloc_strdup(mem_ctx, ntprinter->info_2->portname); + W_ERROR_HAVE_NO_MEMORY(r->portname); - if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) { - /* don't use talloc_steal() here unless you do a deep steal of all - the SEC_DESC members */ + r->attributes = ntprinter->info_2->attributes; - printer->secdesc = dup_sec_desc( talloc_tos(), - ntprinter->info_2->secdesc_buf->sd ); - } + /* these two are not used by NT+ according to MSDN */ - free_a_printer(&ntprinter, 2); + r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */ + r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */ - *pp_printer = printer; - return True; + return WERR_OK; } /******************************************************************** - * construct_printer_info_4 - * fill a printer_info_4 struct + * construct_printer_info_6 + * fill a spoolss_PrinterInfo6 struct ********************************************************************/ -static bool construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum) +static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx, + const NT_PRINTER_INFO_LEVEL *ntprinter, + struct spoolss_PrinterInfo6 *r, + int snum) { - NT_PRINTER_INFO_LEVEL *ntprinter = NULL; + int count; + print_status_struct status; - if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) - return False; + count = print_queue_length(snum, &status); - init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/ - init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/ - printer->attributes = ntprinter->info_2->attributes; + r->status = nt_printq_status(status.status); - free_a_printer(&ntprinter, 2); - return True; + return WERR_OK; } /******************************************************************** - * construct_printer_info_5 - * fill a printer_info_5 struct + * construct_printer_info7 + * fill a spoolss_PrinterInfo7 struct ********************************************************************/ -static bool construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum) +static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx, + Printer_entry *print_hnd, + struct spoolss_PrinterInfo7 *r, + int snum) { - NT_PRINTER_INFO_LEVEL *ntprinter = NULL; + struct GUID guid; - if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) - return False; + if (is_printer_published(print_hnd, snum, &guid)) { + r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid)); + r->action = DSPRINT_PUBLISH; + } else { + r->guid = talloc_strdup(mem_ctx, ""); + r->action = DSPRINT_UNPUBLISH; + } + W_ERROR_HAVE_NO_MEMORY(r->guid); - init_unistr(&printer->printername, ntprinter->info_2->printername); - init_unistr(&printer->portname, ntprinter->info_2->portname); - printer->attributes = ntprinter->info_2->attributes; + return WERR_OK; +} - /* these two are not used by NT+ according to MSDN */ +/******************************************************************** + * construct_printer_info1 + * fill a spoolss_PrinterInfo1 struct +********************************************************************/ - printer->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */ - printer->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */ +static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx, + const NT_PRINTER_INFO_LEVEL *ntprinter, + uint32_t flags, + struct spoolss_PrinterInfo1 *r, + int snum) +{ + char *chaine = NULL; + r->flags = flags; - free_a_printer(&ntprinter, 2); + if (*ntprinter->info_2->comment == '\0') { + r->comment = talloc_strdup(mem_ctx, lp_comment(snum)); + chaine = talloc_asprintf(mem_ctx, + "%s,%s,%s", ntprinter->info_2->printername, + ntprinter->info_2->drivername, lp_comment(snum)); + } else { + r->comment = talloc_strdup(mem_ctx, ntprinter->info_2->comment); /* saved comment */ + chaine = talloc_asprintf(mem_ctx, + "%s,%s,%s", ntprinter->info_2->printername, + ntprinter->info_2->drivername, ntprinter->info_2->comment); + } + W_ERROR_HAVE_NO_MEMORY(chaine); + W_ERROR_HAVE_NO_MEMORY(r->comment); - return True; + r->description = talloc_strdup(mem_ctx, chaine); + W_ERROR_HAVE_NO_MEMORY(r->description); + r->name = talloc_strdup(mem_ctx, ntprinter->info_2->printername); + W_ERROR_HAVE_NO_MEMORY(r->name); + + return WERR_OK; } /******************************************************************** - * construct_printer_info_6 - * fill a printer_info_6 struct - ********************************************************************/ + * construct_printer_info2 + * fill a spoolss_PrinterInfo2 struct +********************************************************************/ -static bool construct_printer_info_6(Printer_entry *print_hnd, - PRINTER_INFO_6 *printer, - int snum) +static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx, + const NT_PRINTER_INFO_LEVEL *ntprinter, + struct spoolss_PrinterInfo2 *r, + int snum) { - NT_PRINTER_INFO_LEVEL *ntprinter = NULL; int count; - print_status_struct status; - if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, - lp_const_servicename(snum)))) - return False; + print_status_struct status; count = print_queue_length(snum, &status); - printer->status = nt_printq_status(status.status); + r->servername = talloc_strdup(mem_ctx, ntprinter->info_2->servername); + W_ERROR_HAVE_NO_MEMORY(r->servername); + r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername); + W_ERROR_HAVE_NO_MEMORY(r->printername); + r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum)); + W_ERROR_HAVE_NO_MEMORY(r->sharename); + r->portname = talloc_strdup(mem_ctx, ntprinter->info_2->portname); + W_ERROR_HAVE_NO_MEMORY(r->portname); + r->drivername = talloc_strdup(mem_ctx, ntprinter->info_2->drivername); + W_ERROR_HAVE_NO_MEMORY(r->drivername); - free_a_printer(&ntprinter, 2); + if (*ntprinter->info_2->comment == '\0') { + r->comment = talloc_strdup(mem_ctx, lp_comment(snum)); + } else { + r->comment = talloc_strdup(mem_ctx, ntprinter->info_2->comment); + } + W_ERROR_HAVE_NO_MEMORY(r->comment); - return True; -} + r->location = talloc_strdup(mem_ctx, ntprinter->info_2->location); + W_ERROR_HAVE_NO_MEMORY(r->location); + r->sepfile = talloc_strdup(mem_ctx, ntprinter->info_2->sepfile); + W_ERROR_HAVE_NO_MEMORY(r->sepfile); + r->printprocessor = talloc_strdup(mem_ctx, ntprinter->info_2->printprocessor); + W_ERROR_HAVE_NO_MEMORY(r->printprocessor); + r->datatype = talloc_strdup(mem_ctx, ntprinter->info_2->datatype); + W_ERROR_HAVE_NO_MEMORY(r->datatype); + r->parameters = talloc_strdup(mem_ctx, ntprinter->info_2->parameters); + W_ERROR_HAVE_NO_MEMORY(r->parameters); -/******************************************************************** - * construct_printer_info_7 - * fill a printer_info_7 struct - ********************************************************************/ + r->attributes = ntprinter->info_2->attributes; -static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum) -{ - char *guid_str = NULL; - struct GUID guid; + r->priority = ntprinter->info_2->priority; + r->defaultpriority = ntprinter->info_2->default_priority; + r->starttime = ntprinter->info_2->starttime; + r->untiltime = ntprinter->info_2->untiltime; + r->status = nt_printq_status(status.status); + r->cjobs = count; + r->averageppm = ntprinter->info_2->averageppm; - if (is_printer_published(print_hnd, snum, &guid)) { - if (asprintf(&guid_str, "{%s}", - GUID_string(talloc_tos(), &guid)) == -1) { - return false; - } - strupper_m(guid_str); - init_unistr(&printer->guid, guid_str); - SAFE_FREE(guid_str); - printer->action = DSPRINT_PUBLISH; - } else { - init_unistr(&printer->guid, ""); - printer->action = DSPRINT_UNPUBLISH; + r->devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum)); + if (!r->devmode) { + DEBUG(8,("Returning NULL Devicemode!\n")); } - return True; + r->secdesc = NULL; + + if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) { + /* don't use talloc_steal() here unless you do a deep steal of all + the SEC_DESC members */ + + r->secdesc = dup_sec_desc(mem_ctx, ntprinter->info_2->secdesc_buf->sd); + } + + return WERR_OK; +} + +/******************************************************************** +********************************************************************/ + +static bool snum_is_shared_printer(int snum) +{ + return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum)); } /******************************************************************** Spoolss_enumprinters. ********************************************************************/ -static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx, + uint32_t flags, + union spoolss_PrinterInfo **info_p, + uint32_t *count) { int snum; - int i; - int n_services=lp_numservices(); - PRINTER_INFO_1 *printers=NULL; - PRINTER_INFO_1 current_prt; + int n_services = lp_numservices(); + union spoolss_PrinterInfo *info = NULL; WERROR result = WERR_OK; DEBUG(4,("enum_all_printers_info_1\n")); + *count = 0; + for (snum=0; snum<n_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) { - DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum)); - - if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) { - if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) { - DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n")); - *returned=0; - return WERR_NOMEM; - } - DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned)); - memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1)); - (*returned)++; - } + NT_PRINTER_INFO_LEVEL *ntprinter = NULL; + struct spoolss_PrinterInfo1 info1; + + if (!snum_is_shared_printer(snum)) { + continue; } - } - /* check the required size. */ - for (i=0; i<*returned; i++) - (*needed) += spoolss_size_printer_info_1(&printers[i]); + DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum)); - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } + result = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum)); + if (!W_ERROR_IS_OK(result)) { + continue; + } - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; - } + result = construct_printer_info1(info, ntprinter, flags, &info1, snum); + free_a_printer(&ntprinter,2); + if (!W_ERROR_IS_OK(result)) { + continue; + } - /* fill the buffer with the structures */ - for (i=0; i<*returned; i++) - smb_io_printer_info_1("", buffer, &printers[i], 0); + info = TALLOC_REALLOC_ARRAY(mem_ctx, info, + union spoolss_PrinterInfo, + *count + 1); + if (!info) { + DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n")); + result = WERR_NOMEM; + goto out; + } -out: - /* clear memory */ + DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *count)); - SAFE_FREE(printers); + info[*count].info1 = info1; + (*count)++; + } + + out: + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(info); + *count = 0; + return result; + } - if ( !W_ERROR_IS_OK(result) ) - *returned = 0; + *info_p = info; - return result; + return WERR_OK; } /******************************************************************** enum_all_printers_info_1_local. *********************************************************************/ -static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx, + union spoolss_PrinterInfo **info, + uint32_t *count) { DEBUG(4,("enum_all_printers_info_1_local\n")); - return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned); + return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count); } /******************************************************************** enum_all_printers_info_1_name. *********************************************************************/ -static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx, + const char *name, + union spoolss_PrinterInfo **info, + uint32_t *count) { - char *s = name; + const char *s = name; DEBUG(4,("enum_all_printers_info_1_name\n")); - if ((name[0] == '\\') && (name[1] == '\\')) + if ((name[0] == '\\') && (name[1] == '\\')) { s = name + 2; - - if (is_myname_or_ipaddr(s)) { - return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned); - } - else - return WERR_INVALID_NAME; -} - -#if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */ -/******************************************************************** - enum_all_printers_info_1_remote. -*********************************************************************/ - -static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) -{ - PRINTER_INFO_1 *printer; - fstring printername; - fstring desc; - fstring comment; - DEBUG(4,("enum_all_printers_info_1_remote\n")); - WERROR result = WERR_OK; - - /* JFM: currently it's more a place holder than anything else. - * In the spooler world there is a notion of server registration. - * the print servers are registered on the PDC (in the same domain) - * - * We should have a TDB here. The registration is done thru an - * undocumented RPC call. - */ - - if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL) - return WERR_NOMEM; - - *returned=1; - - slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name); - slprintf(desc, sizeof(desc)-1,"%s", name); - slprintf(comment, sizeof(comment)-1, "Logged on Domain"); - - init_unistr(&printer->description, desc); - init_unistr(&printer->name, printername); - init_unistr(&printer->comment, comment); - printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER; - - /* check the required size. */ - *needed += spoolss_size_printer_info_1(printer); - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; } - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; + if (!is_myname_or_ipaddr(s)) { + return WERR_INVALID_NAME; } - /* fill the buffer with the structures */ - smb_io_printer_info_1("", buffer, printer, 0); - -out: - /* clear memory */ - SAFE_FREE(printer); - - if ( !W_ERROR_IS_OK(result) ) - *returned = 0; - - return result; + return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count); } -#endif - /******************************************************************** enum_all_printers_info_1_network. *********************************************************************/ -static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx, + const char *name, + union spoolss_PrinterInfo **info, + uint32_t *count) { - char *s = name; + const char *s = name; DEBUG(4,("enum_all_printers_info_1_network\n")); @@ -4537,13 +4322,15 @@ static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, listed. Windows responds to this call with a WERR_CAN_NOT_COMPLETE so we should do the same. */ - if (name[0] == '\\' && name[1] == '\\') + if (name[0] == '\\' && name[1] == '\\') { s = name + 2; + } - if (is_myname_or_ipaddr(s)) + if (is_myname_or_ipaddr(s)) { return WERR_CAN_NOT_COMPLETE; + } - return enum_all_printers_info_1(PRINTER_ENUM_NAME, buffer, offered, needed, returned); + return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_NAME, info, count); } /******************************************************************** @@ -4552,92 +4339,90 @@ static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, * called from api_spoolss_enumprinters (see this to understand) ********************************************************************/ -static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx, + union spoolss_PrinterInfo **info_p, + uint32_t *count) { int snum; - int i; - int n_services=lp_numservices(); - PRINTER_INFO_2 *printers=NULL; - PRINTER_INFO_2 current_prt; + int n_services = lp_numservices(); + union spoolss_PrinterInfo *info = NULL; WERROR result = WERR_OK; - *returned = 0; + *count = 0; for (snum=0; snum<n_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) { - DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum)); - - if (construct_printer_info_2(NULL, ¤t_prt, snum)) { - if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) { - DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n")); - *returned = 0; - return WERR_NOMEM; - } - - DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1)); - memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2)); + struct spoolss_PrinterInfo2 info2; + NT_PRINTER_INFO_LEVEL *ntprinter = NULL; - (*returned)++; - } + if (!snum_is_shared_printer(snum)) { + continue; } - } - /* check the required size. */ - for (i=0; i<*returned; i++) - (*needed) += spoolss_size_printer_info_2(&printers[i]); + DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum)); - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } + result = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum)); + if (!W_ERROR_IS_OK(result)) { + continue; + } - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; - } + result = construct_printer_info2(info, ntprinter, &info2, snum); + free_a_printer(&ntprinter, 2); + if (!W_ERROR_IS_OK(result)) { + continue; + } - /* fill the buffer with the structures */ - for (i=0; i<*returned; i++) - smb_io_printer_info_2("", buffer, &(printers[i]), 0); + info = TALLOC_REALLOC_ARRAY(mem_ctx, info, + union spoolss_PrinterInfo, + *count + 1); + if (!info) { + DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n")); + result = WERR_NOMEM; + goto out; + } -out: - /* clear memory */ + DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *count + 1)); - for (i=0; i<*returned; i++) - free_devmode(printers[i].devmode); + info[*count].info2 = info2; - SAFE_FREE(printers); + (*count)++; + } - if ( !W_ERROR_IS_OK(result) ) - *returned = 0; + out: + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(info); + *count = 0; + return result; + } - return result; + *info_p = info; + + return WERR_OK; } /******************************************************************** * handle enumeration of printers at level 1 ********************************************************************/ -static WERROR enumprinters_level1( uint32 flags, fstring name, - RPC_BUFFER *buffer, uint32 offered, - uint32 *needed, uint32 *returned) +static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx, + uint32_t flags, + const char *name, + union spoolss_PrinterInfo **info, + uint32_t *count) { /* Not all the flags are equals */ - if (flags & PRINTER_ENUM_LOCAL) - return enum_all_printers_info_1_local(buffer, offered, needed, returned); - - if (flags & PRINTER_ENUM_NAME) - return enum_all_printers_info_1_name(name, buffer, offered, needed, returned); + if (flags & PRINTER_ENUM_LOCAL) { + return enum_all_printers_info_1_local(mem_ctx, info, count); + } -#if 0 /* JERRY - disabled for now */ - if (flags & PRINTER_ENUM_REMOTE) - return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned); -#endif + if (flags & PRINTER_ENUM_NAME) { + return enum_all_printers_info_1_name(mem_ctx, name, info, count); + } - if (flags & PRINTER_ENUM_NETWORK) - return enum_all_printers_info_1_network(name, buffer, offered, needed, returned); + if (flags & PRINTER_ENUM_NETWORK) { + return enum_all_printers_info_1_network(mem_ctx, name, info, count); + } return WERR_OK; /* NT4sp5 does that */ } @@ -4646,23 +4431,27 @@ static WERROR enumprinters_level1( uint32 flags, fstring name, * handle enumeration of printers at level 2 ********************************************************************/ -static WERROR enumprinters_level2( uint32 flags, const char *servername, - RPC_BUFFER *buffer, uint32 offered, - uint32 *needed, uint32 *returned) +static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx, + uint32_t flags, + const char *servername, + union spoolss_PrinterInfo **info, + uint32_t *count) { if (flags & PRINTER_ENUM_LOCAL) { - return enum_all_printers_info_2(buffer, offered, needed, returned); + return enum_all_printers_info_2(mem_ctx, info, count); } if (flags & PRINTER_ENUM_NAME) { - if (is_myname_or_ipaddr(canon_servername(servername))) - return enum_all_printers_info_2(buffer, offered, needed, returned); - else + if (!is_myname_or_ipaddr(canon_servername(servername))) { return WERR_INVALID_NAME; + } + + return enum_all_printers_info_2(mem_ctx, info, count); } - if (flags & PRINTER_ENUM_REMOTE) + if (flags & PRINTER_ENUM_REMOTE) { return WERR_UNKNOWN_LEVEL; + } return WERR_OK; } @@ -4671,49 +4460,37 @@ static WERROR enumprinters_level2( uint32 flags, const char *servername, * handle enumeration of printers at level 5 ********************************************************************/ -static WERROR enumprinters_level5( uint32 flags, const char *servername, - RPC_BUFFER *buffer, uint32 offered, - uint32 *needed, uint32 *returned) +static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx, + uint32_t flags, + const char *servername, + union spoolss_PrinterInfo **info, + uint32_t *count) { -/* return enum_all_printers_info_5(buffer, offered, needed, returned);*/ +/* return enum_all_printers_info_5(mem_ctx, info, offered, needed, count);*/ return WERR_OK; } -/******************************************************************** - * api_spoolss_enumprinters - * - * called from api_spoolss_enumprinters (see this to understand) - ********************************************************************/ +/**************************************************************** + _spoolss_EnumPrinters +****************************************************************/ -WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u) +WERROR _spoolss_EnumPrinters(pipes_struct *p, + struct spoolss_EnumPrinters *r) { - uint32 flags = q_u->flags; - UNISTR2 *servername = &q_u->servername; - uint32 level = q_u->level; - RPC_BUFFER *buffer = NULL; - uint32 offered = q_u->offered; - uint32 *needed = &r_u->needed; - uint32 *returned = &r_u->returned; - - fstring name; + const char *name; + WERROR result; /* that's an [in out] buffer */ - if (!q_u->buffer && (offered!=0)) { - return WERR_INVALID_PARAM; - } - - if (offered > MAX_RPC_DATA_SIZE) { + if (!r->in.buffer && (r->in.offered != 0)) { return WERR_INVALID_PARAM; } - rpcbuf_move(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + DEBUG(4,("_spoolss_EnumPrinters\n")); - DEBUG(4,("_spoolss_enumprinters\n")); - - *needed=0; - *returned=0; + *r->out.needed = 0; + *r->out.count = 0; + *r->out.info = NULL; /* * Level 1: @@ -4728,392 +4505,376 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_ * Level 5: same as Level 2 */ - unistr2_to_ascii(name, servername, sizeof(name)); - strupper_m(name); + name = talloc_strdup_upper(p->mem_ctx, r->in.server); + W_ERROR_HAVE_NO_MEMORY(name); - switch (level) { + switch (r->in.level) { case 1: - return enumprinters_level1(flags, name, buffer, offered, needed, returned); + result = enumprinters_level1(p->mem_ctx, r->in.flags, name, + r->out.info, r->out.count); + break; case 2: - return enumprinters_level2(flags, name, buffer, offered, needed, returned); + result = enumprinters_level2(p->mem_ctx, r->in.flags, name, + r->out.info, r->out.count); + break; case 5: - return enumprinters_level5(flags, name, buffer, offered, needed, returned); + result = enumprinters_level5(p->mem_ctx, r->in.flags, name, + r->out.info, r->out.count); + break; case 3: case 4: + result = WERR_OK; /* ??? */ break; - } - return WERR_UNKNOWN_LEVEL; -} - -/**************************************************************************** -****************************************************************************/ - -static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) -{ - PRINTER_INFO_0 *printer=NULL; - WERROR result = WERR_OK; - - if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL) - return WERR_NOMEM; - - construct_printer_info_0(print_hnd, printer, snum); - - /* check the required size. */ - *needed += spoolss_size_printer_info_0(printer); - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; + default: + return WERR_UNKNOWN_LEVEL; } - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; + if (!W_ERROR_IS_OK(result)) { + return result; } - /* fill the buffer with the structures */ - smb_io_printer_info_0("", buffer, printer, 0); + *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx, + spoolss_EnumPrinters, NULL, + *r->out.info, r->in.level, + *r->out.count); + *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL); + *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0); -out: - /* clear memory */ - - SAFE_FREE(printer); - - return result; + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); } -/**************************************************************************** -****************************************************************************/ +/**************************************************************** + _spoolss_GetPrinter +****************************************************************/ -static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) +WERROR _spoolss_GetPrinter(pipes_struct *p, + struct spoolss_GetPrinter *r) { - PRINTER_INFO_1 *printer=NULL; + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); + NT_PRINTER_INFO_LEVEL *ntprinter = NULL; WERROR result = WERR_OK; - if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL) - return WERR_NOMEM; - - construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum); - - /* check the required size. */ - *needed += spoolss_size_printer_info_1(printer); + int snum; - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } + /* that's an [in out] buffer */ - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; + if (!r->in.buffer && (r->in.offered != 0)) { + return WERR_INVALID_PARAM; } - /* fill the buffer with the structures */ - smb_io_printer_info_1("", buffer, printer, 0); - -out: - /* clear memory */ - SAFE_FREE(printer); - - return result; -} - -/**************************************************************************** -****************************************************************************/ - -static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) -{ - PRINTER_INFO_2 *printer=NULL; - WERROR result = WERR_OK; - - if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL) - return WERR_NOMEM; - - construct_printer_info_2(print_hnd, printer, snum); - - /* check the required size. */ - *needed += spoolss_size_printer_info_2(printer); + *r->out.needed = 0; - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { + return WERR_BADFID; } - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; + result = get_a_printer(Printer, &ntprinter, 2, + lp_const_servicename(snum)); + if (!W_ERROR_IS_OK(result)) { + return result; } - /* fill the buffer with the structures */ - if (!smb_io_printer_info_2("", buffer, printer, 0)) - result = WERR_NOMEM; - -out: - /* clear memory */ - free_printer_info_2(printer); - - return result; -} - -/**************************************************************************** -****************************************************************************/ - -static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) -{ - PRINTER_INFO_3 *printer=NULL; - WERROR result = WERR_OK; - - if (!construct_printer_info_3(print_hnd, &printer, snum)) - return WERR_NOMEM; - - /* check the required size. */ - *needed += spoolss_size_printer_info_3(printer); - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; + switch (r->in.level) { + case 0: + result = construct_printer_info0(p->mem_ctx, ntprinter, + &r->out.info->info0, snum); + break; + case 1: + result = construct_printer_info1(p->mem_ctx, ntprinter, + PRINTER_ENUM_ICON8, + &r->out.info->info1, snum); + break; + case 2: + result = construct_printer_info2(p->mem_ctx, ntprinter, + &r->out.info->info2, snum); + break; + case 3: + result = construct_printer_info3(p->mem_ctx, ntprinter, + &r->out.info->info3, snum); + break; + case 4: + result = construct_printer_info4(p->mem_ctx, ntprinter, + &r->out.info->info4, snum); + break; + case 5: + result = construct_printer_info5(p->mem_ctx, ntprinter, + &r->out.info->info5, snum); + break; + case 6: + result = construct_printer_info6(p->mem_ctx, ntprinter, + &r->out.info->info6, snum); + break; + case 7: + result = construct_printer_info7(p->mem_ctx, Printer, + &r->out.info->info7, snum); + break; + default: + result = WERR_UNKNOWN_LEVEL; + break; } - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; + free_a_printer(&ntprinter, 2); + + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(r->out.info); + return result; } - /* fill the buffer with the structures */ - smb_io_printer_info_3("", buffer, printer, 0); + *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo, NULL, + r->out.info, r->in.level); + r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); -out: - /* clear memory */ - free_printer_info_3(printer); - - return result; + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); } -/**************************************************************************** -****************************************************************************/ +/******************************************************************** + ********************************************************************/ -static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) +static const char **string_array_from_driver_info(TALLOC_CTX *mem_ctx, + fstring *fstring_array, + const char *cservername) { - PRINTER_INFO_4 *printer=NULL; - WERROR result = WERR_OK; + int i, num_strings = 0; + const char **array = NULL; - if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL) - return WERR_NOMEM; + for (i=0; fstring_array && fstring_array[i][0] != '\0'; i++) { - if (!construct_printer_info_4(print_hnd, printer, snum)) { - SAFE_FREE(printer); - return WERR_NOMEM; - } + const char *str = talloc_asprintf(mem_ctx, "\\\\%s%s", + cservername, fstring_array[i]); + if (!str) { + TALLOC_FREE(array); + return NULL; + } - /* check the required size. */ - *needed += spoolss_size_printer_info_4(printer); - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; + if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) { + TALLOC_FREE(array); + return NULL; + } } - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; + if (i > 0) { + ADD_TO_ARRAY(mem_ctx, const char *, NULL, + &array, &num_strings); } - /* fill the buffer with the structures */ - smb_io_printer_info_4("", buffer, printer, 0); - -out: - /* clear memory */ - free_printer_info_4(printer); - - return result; + return array; } -/**************************************************************************** -****************************************************************************/ +/******************************************************************** + * fill a spoolss_DriverInfo1 struct + ********************************************************************/ -static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx, + struct spoolss_DriverInfo1 *r, + const NT_PRINTER_DRIVER_INFO_LEVEL *driver, + const char *servername, + const char *architecture) { - PRINTER_INFO_5 *printer=NULL; - WERROR result = WERR_OK; - - if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL) - return WERR_NOMEM; - - if (!construct_printer_info_5(print_hnd, printer, snum)) { - free_printer_info_5(printer); - return WERR_NOMEM; - } + r->driver_name = talloc_strdup(mem_ctx, driver->info_3->name); + W_ERROR_HAVE_NO_MEMORY(r->driver_name); - /* check the required size. */ - *needed += spoolss_size_printer_info_5(printer); - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; - } - - /* fill the buffer with the structures */ - smb_io_printer_info_5("", buffer, printer, 0); + return WERR_OK; +} -out: - /* clear memory */ - free_printer_info_5(printer); +/******************************************************************** + * fill a spoolss_DriverInfo2 struct + ********************************************************************/ - return result; -} +static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx, + struct spoolss_DriverInfo2 *r, + const NT_PRINTER_DRIVER_INFO_LEVEL *driver, + const char *servername) -static WERROR getprinter_level_6(Printer_entry *print_hnd, - int snum, - RPC_BUFFER *buffer, uint32 offered, - uint32 *needed) { - PRINTER_INFO_6 *printer; - WERROR result = WERR_OK; - - if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) { - return WERR_NOMEM; - } + const char *cservername = canon_servername(servername); - if (!construct_printer_info_6(print_hnd, printer, snum)) { - free_printer_info_6(printer); - return WERR_NOMEM; - } + r->version = driver->info_3->cversion; - /* check the required size. */ - *needed += spoolss_size_printer_info_6(printer); + r->driver_name = talloc_strdup(mem_ctx, driver->info_3->name); + W_ERROR_HAVE_NO_MEMORY(r->driver_name); + r->architecture = talloc_strdup(mem_ctx, driver->info_3->environment); + W_ERROR_HAVE_NO_MEMORY(r->architecture); - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; + if (strlen(driver->info_3->driverpath)) { + r->driver_path = talloc_asprintf(mem_ctx, "\\\\%s%s", + cservername, driver->info_3->driverpath); + } else { + r->driver_path = talloc_strdup(mem_ctx, ""); } + W_ERROR_HAVE_NO_MEMORY(r->driver_path); - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; + if (strlen(driver->info_3->datafile)) { + r->data_file = talloc_asprintf(mem_ctx, "\\\\%s%s", + cservername, driver->info_3->datafile); + } else { + r->data_file = talloc_strdup(mem_ctx, ""); } + W_ERROR_HAVE_NO_MEMORY(r->data_file); - /* fill the buffer with the structures */ - smb_io_printer_info_6("", buffer, printer, 0); - -out: - /* clear memory */ - free_printer_info_6(printer); + if (strlen(driver->info_3->configfile)) { + r->config_file = talloc_asprintf(mem_ctx, "\\\\%s%s", + cservername, driver->info_3->configfile); + } else { + r->config_file = talloc_strdup(mem_ctx, ""); + } + W_ERROR_HAVE_NO_MEMORY(r->config_file); - return result; + return WERR_OK; } -static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) +/******************************************************************** + * fill a spoolss_DriverInfo3 struct + ********************************************************************/ + +static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx, + struct spoolss_DriverInfo3 *r, + const NT_PRINTER_DRIVER_INFO_LEVEL *driver, + const char *servername) { - PRINTER_INFO_7 *printer=NULL; - WERROR result = WERR_OK; + const char *cservername = canon_servername(servername); - if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL) - return WERR_NOMEM; + r->version = driver->info_3->cversion; - if (!construct_printer_info_7(print_hnd, printer, snum)) { - result = WERR_NOMEM; - goto out; - } - - /* check the required size. */ - *needed += spoolss_size_printer_info_7(printer); + r->driver_name = talloc_strdup(mem_ctx, driver->info_3->name); + W_ERROR_HAVE_NO_MEMORY(r->driver_name); + r->architecture = talloc_strdup(mem_ctx, driver->info_3->environment); + W_ERROR_HAVE_NO_MEMORY(r->architecture); - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; + if (strlen(driver->info_3->driverpath)) { + r->driver_path = talloc_asprintf(mem_ctx, "\\\\%s%s", + cservername, driver->info_3->driverpath); + } else { + r->driver_path = talloc_strdup(mem_ctx, ""); } + W_ERROR_HAVE_NO_MEMORY(r->driver_path); - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; + if (strlen(driver->info_3->datafile)) { + r->data_file = talloc_asprintf(mem_ctx, "\\\\%s%s", + cservername, driver->info_3->datafile); + } else { + r->data_file = talloc_strdup(mem_ctx, ""); + } + W_ERROR_HAVE_NO_MEMORY(r->data_file); + if (strlen(driver->info_3->configfile)) { + r->config_file = talloc_asprintf(mem_ctx, "\\\\%s%s", + cservername, driver->info_3->configfile); + } else { + r->config_file = talloc_strdup(mem_ctx, ""); } + W_ERROR_HAVE_NO_MEMORY(r->config_file); - /* fill the buffer with the structures */ - smb_io_printer_info_7("", buffer, printer, 0); + if (strlen(driver->info_3->helpfile)) { + r->help_file = talloc_asprintf(mem_ctx, "\\\\%s%s", + cservername, driver->info_3->helpfile); + } else { + r->help_file = talloc_strdup(mem_ctx, ""); + } + W_ERROR_HAVE_NO_MEMORY(r->config_file); -out: - /* clear memory */ - free_printer_info_7(printer); + r->monitor_name = talloc_strdup(mem_ctx, driver->info_3->monitorname); + W_ERROR_HAVE_NO_MEMORY(r->monitor_name); + r->default_datatype = talloc_strdup(mem_ctx, driver->info_3->defaultdatatype); + W_ERROR_HAVE_NO_MEMORY(r->default_datatype); - return result; + r->dependent_files = string_array_from_driver_info(mem_ctx, + driver->info_3->dependentfiles, + cservername); + return WERR_OK; } -/**************************************************************************** -****************************************************************************/ +/******************************************************************** + * fill a spoolss_DriverInfo6 struct + ********************************************************************/ -WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u) +static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx, + struct spoolss_DriverInfo6 *r, + const NT_PRINTER_DRIVER_INFO_LEVEL *driver, + const char *servername) { - POLICY_HND *handle = &q_u->handle; - uint32 level = q_u->level; - RPC_BUFFER *buffer = NULL; - uint32 offered = q_u->offered; - uint32 *needed = &r_u->needed; - Printer_entry *Printer=find_printer_index_by_hnd(p, handle); + const char *cservername = canon_servername(servername); - int snum; + r->version = driver->info_3->cversion; - /* that's an [in out] buffer */ + r->driver_name = talloc_strdup(mem_ctx, driver->info_3->name); + W_ERROR_HAVE_NO_MEMORY(r->driver_name); + r->architecture = talloc_strdup(mem_ctx, driver->info_3->environment); + W_ERROR_HAVE_NO_MEMORY(r->architecture); - if (!q_u->buffer && (offered!=0)) { - return WERR_INVALID_PARAM; + if (strlen(driver->info_3->driverpath)) { + r->driver_path = talloc_asprintf(mem_ctx, "\\\\%s%s", + cservername, driver->info_3->driverpath); + } else { + r->driver_path = talloc_strdup(mem_ctx, ""); } + W_ERROR_HAVE_NO_MEMORY(r->driver_path); - if (offered > MAX_RPC_DATA_SIZE) { - return WERR_INVALID_PARAM; + if (strlen(driver->info_3->datafile)) { + r->data_file = talloc_asprintf(mem_ctx, "\\\\%s%s", + cservername, driver->info_3->datafile); + } else { + r->data_file = talloc_strdup(mem_ctx, ""); } + W_ERROR_HAVE_NO_MEMORY(r->data_file); - rpcbuf_move(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; - - *needed=0; - - if (!get_printer_snum(p, handle, &snum, NULL)) - return WERR_BADFID; - - switch (level) { - case 0: - return getprinter_level_0(Printer, snum, buffer, offered, needed); - case 1: - return getprinter_level_1(Printer, snum, buffer, offered, needed); - case 2: - return getprinter_level_2(Printer, snum, buffer, offered, needed); - case 3: - return getprinter_level_3(Printer, snum, buffer, offered, needed); - case 4: - return getprinter_level_4(Printer, snum, buffer, offered, needed); - case 5: - return getprinter_level_5(Printer, snum, buffer, offered, needed); - case 6: - return getprinter_level_6(Printer, snum, buffer, offered, needed); - case 7: - return getprinter_level_7(Printer, snum, buffer, offered, needed); + if (strlen(driver->info_3->configfile)) { + r->config_file = talloc_asprintf(mem_ctx, "\\\\%s%s", + cservername, driver->info_3->configfile); + } else { + r->config_file = talloc_strdup(mem_ctx, ""); } - return WERR_UNKNOWN_LEVEL; -} + W_ERROR_HAVE_NO_MEMORY(r->config_file); -/******************************************************************** - * fill a DRIVER_INFO_1 struct - ********************************************************************/ + if (strlen(driver->info_3->helpfile)) { + r->help_file = talloc_asprintf(mem_ctx, "\\\\%s%s", + cservername, driver->info_3->helpfile); + } else { + r->help_file = talloc_strdup(mem_ctx, ""); + } + W_ERROR_HAVE_NO_MEMORY(r->config_file); + + r->monitor_name = talloc_strdup(mem_ctx, driver->info_3->monitorname); + W_ERROR_HAVE_NO_MEMORY(r->monitor_name); + r->default_datatype = talloc_strdup(mem_ctx, driver->info_3->defaultdatatype); + W_ERROR_HAVE_NO_MEMORY(r->default_datatype); + + r->dependent_files = string_array_from_driver_info(mem_ctx, + driver->info_3->dependentfiles, + cservername); + r->previous_names = string_array_from_driver_info(mem_ctx, + NULL, + cservername); + + r->driver_date = 0; + r->driver_version = 0; + + r->manufacturer_name = talloc_strdup(mem_ctx, ""); + W_ERROR_HAVE_NO_MEMORY(r->manufacturer_name); + r->manufacturer_url = talloc_strdup(mem_ctx, ""); + W_ERROR_HAVE_NO_MEMORY(r->manufacturer_url); + r->hardware_id = talloc_strdup(mem_ctx, ""); + W_ERROR_HAVE_NO_MEMORY(r->hardware_id); + r->provider = talloc_strdup(mem_ctx, ""); + W_ERROR_HAVE_NO_MEMORY(r->provider); -static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture) -{ - init_unistr( &info->name, driver.info_3->name); + return WERR_OK; } /******************************************************************** * construct_printer_driver_info_1 ********************************************************************/ -static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version) +static WERROR construct_printer_driver_info_1(TALLOC_CTX *mem_ctx, + struct spoolss_DriverInfo1 *r, + int snum, + const char *servername, + const char *architecture, + uint32_t version) { NT_PRINTER_INFO_LEVEL *printer = NULL; NT_PRINTER_DRIVER_INFO_LEVEL driver; + WERROR result; ZERO_STRUCT(driver); @@ -5125,58 +4886,11 @@ static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, con return WERR_UNKNOWN_PRINTER_DRIVER; } - fill_printer_driver_info_1(info, driver, servername, architecture); + result = fill_printer_driver_info1(mem_ctx, r, &driver, servername, architecture); free_a_printer(&printer,2); - return WERR_OK; -} - -/******************************************************************** - * construct_printer_driver_info_2 - * fill a printer_info_2 struct - ********************************************************************/ - -static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername) -{ - TALLOC_CTX *ctx = talloc_tos(); - char *temp = NULL; - const char *cservername = canon_servername(servername); - - info->version=driver.info_3->cversion; - - init_unistr( &info->name, driver.info_3->name ); - init_unistr( &info->architecture, driver.info_3->environment ); - - if (strlen(driver.info_3->driverpath)) { - temp = talloc_asprintf(ctx, - "\\\\%s%s", - cservername, - driver.info_3->driverpath); - init_unistr( &info->driverpath, temp ); - } else { - init_unistr( &info->driverpath, "" ); - } - - TALLOC_FREE(temp); - if (strlen(driver.info_3->datafile)) { - temp = talloc_asprintf(ctx, - "\\\\%s%s", - cservername, - driver.info_3->datafile); - init_unistr( &info->datafile, temp ); - } else - init_unistr( &info->datafile, "" ); - - TALLOC_FREE(temp); - if (strlen(driver.info_3->configfile)) { - temp = talloc_asprintf(ctx, - "\\\\%s%s", - cservername, - driver.info_3->configfile); - init_unistr( &info->configfile, temp ); - } else - init_unistr( &info->configfile, "" ); + return result; } /******************************************************************** @@ -5184,10 +4898,16 @@ static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_IN * fill a printer_info_2 struct ********************************************************************/ -static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version) +static WERROR construct_printer_driver_info_2(TALLOC_CTX *mem_ctx, + struct spoolss_DriverInfo2 *r, + int snum, + const char *servername, + const char *architecture, + uint32_t version) { NT_PRINTER_INFO_LEVEL *printer = NULL; NT_PRINTER_DRIVER_INFO_LEVEL driver; + WERROR result; ZERO_STRUCT(printer); ZERO_STRUCT(driver); @@ -5200,149 +4920,11 @@ static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, con return WERR_UNKNOWN_PRINTER_DRIVER; } - fill_printer_driver_info_2(info, driver, servername); + result = fill_printer_driver_info2(mem_ctx, r, &driver, servername); free_a_printer(&printer,2); - return WERR_OK; -} - -/******************************************************************** - * copy a strings array and convert to UNICODE - * - * convert an array of ascii string to a UNICODE string - ********************************************************************/ - -static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername) -{ - int i=0; - int j=0; - const char *v; - char *line = NULL; - TALLOC_CTX *ctx = talloc_tos(); - - DEBUG(6,("init_unistr_array\n")); - *uni_array=NULL; - - while (true) { - if ( !char_array ) { - v = ""; - } else { - v = char_array[i]; - if (!v) - v = ""; /* hack to handle null lists */ - } - - /* hack to allow this to be used in places other than when generating - the list of dependent files */ - - TALLOC_FREE(line); - if ( servername ) { - line = talloc_asprintf(ctx, - "\\\\%s%s", - canon_servername(servername), - v); - } else { - line = talloc_strdup(ctx, v); - } - - if (!line) { - SAFE_FREE(*uni_array); - return 0; - } - DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line))); - - /* add one extra unit16 for the second terminating NULL */ - - if ( (*uni_array=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) { - DEBUG(2,("init_unistr_array: Realloc error\n" )); - return 0; - } - - if ( !strlen(v) ) - break; - - j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16)); - i++; - } - - if (*uni_array) { - /* special case for ""; we need to add both NULL's here */ - if (!j) - (*uni_array)[j++]=0x0000; - (*uni_array)[j]=0x0000; - } - - DEBUGADD(6,("last one:done\n")); - - /* return size of array in uint16's */ - - return j+1; -} - -/******************************************************************** - * construct_printer_info_3 - * fill a printer_info_3 struct - ********************************************************************/ - -static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername) -{ - char *temp = NULL; - TALLOC_CTX *ctx = talloc_tos(); - const char *cservername = canon_servername(servername); - - ZERO_STRUCTP(info); - - info->version=driver.info_3->cversion; - - init_unistr( &info->name, driver.info_3->name ); - init_unistr( &info->architecture, driver.info_3->environment ); - - if (strlen(driver.info_3->driverpath)) { - temp = talloc_asprintf(ctx, - "\\\\%s%s", - cservername, - driver.info_3->driverpath); - init_unistr( &info->driverpath, temp ); - } else - init_unistr( &info->driverpath, "" ); - - TALLOC_FREE(temp); - if (strlen(driver.info_3->datafile)) { - temp = talloc_asprintf(ctx, - "\\\\%s%s", - cservername, - driver.info_3->datafile); - init_unistr( &info->datafile, temp ); - } else - init_unistr( &info->datafile, "" ); - - TALLOC_FREE(temp); - if (strlen(driver.info_3->configfile)) { - temp = talloc_asprintf(ctx, - "\\\\%s%s", - cservername, - driver.info_3->configfile); - init_unistr( &info->configfile, temp ); - } else - init_unistr( &info->configfile, "" ); - - TALLOC_FREE(temp); - if (strlen(driver.info_3->helpfile)) { - temp = talloc_asprintf(ctx, - "\\\\%s%s", - cservername, - driver.info_3->helpfile); - init_unistr( &info->helpfile, temp ); - } else - init_unistr( &info->helpfile, "" ); - - TALLOC_FREE(temp); - init_unistr( &info->monitorname, driver.info_3->monitorname ); - init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype ); - - info->dependentfiles=NULL; - init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername); + return result; } /******************************************************************** @@ -5350,7 +4932,12 @@ static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_IN * fill a printer_info_3 struct ********************************************************************/ -static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version) +static WERROR construct_printer_driver_info_3(TALLOC_CTX *mem_ctx, + struct spoolss_DriverInfo3 *r, + int snum, + const char *servername, + const char *architecture, + uint32_t version) { NT_PRINTER_INFO_LEVEL *printer = NULL; NT_PRINTER_DRIVER_INFO_LEVEL driver; @@ -5397,92 +4984,11 @@ static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, con #endif - fill_printer_driver_info_3(info, driver, servername); + status = fill_printer_driver_info3(mem_ctx, r, &driver, servername); free_a_printer(&printer,2); - return WERR_OK; -} - -/******************************************************************** - * construct_printer_info_6 - * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA. - ********************************************************************/ - -static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername) -{ - char *temp = NULL; - fstring nullstr; - TALLOC_CTX *ctx = talloc_tos(); - const char *cservername = canon_servername(servername); - - ZERO_STRUCTP(info); - memset(&nullstr, '\0', sizeof(fstring)); - - info->version=driver.info_3->cversion; - - init_unistr( &info->name, driver.info_3->name ); - init_unistr( &info->architecture, driver.info_3->environment ); - - if (strlen(driver.info_3->driverpath)) { - temp = talloc_asprintf(ctx, - "\\\\%s%s", - cservername, - driver.info_3->driverpath); - init_unistr( &info->driverpath, temp ); - } else - init_unistr( &info->driverpath, "" ); - - TALLOC_FREE(temp); - if (strlen(driver.info_3->datafile)) { - temp = talloc_asprintf(ctx, - "\\\\%s%s", - cservername, - driver.info_3->datafile); - init_unistr( &info->datafile, temp ); - } else - init_unistr( &info->datafile, "" ); - - TALLOC_FREE(temp); - if (strlen(driver.info_3->configfile)) { - temp = talloc_asprintf(ctx, - "\\\\%s%s", - cservername, - driver.info_3->configfile); - init_unistr( &info->configfile, temp ); - } else - init_unistr( &info->configfile, "" ); - - TALLOC_FREE(temp); - if (strlen(driver.info_3->helpfile)) { - temp = talloc_asprintf(ctx, - "\\\\%s%s", - cservername, - driver.info_3->helpfile); - init_unistr( &info->helpfile, temp ); - } else - init_unistr( &info->helpfile, "" ); - - TALLOC_FREE(temp); - init_unistr( &info->monitorname, driver.info_3->monitorname ); - init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype ); - - info->dependentfiles = NULL; - init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername ); - - info->previousdrivernames=NULL; - init_unistr_array(&info->previousdrivernames, &nullstr, servername); - - info->driver_date=0; - - info->padding=0; - info->driver_version_low=0; - info->driver_version_high=0; - - init_unistr( &info->mfgname, ""); - init_unistr( &info->oem_url, ""); - init_unistr( &info->hardware_id, ""); - init_unistr( &info->provider, ""); + return status; } /******************************************************************** @@ -5490,8 +4996,12 @@ static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_IN * fill a printer_info_6 struct ********************************************************************/ -static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, - const char *servername, fstring architecture, uint32 version) +static WERROR construct_printer_driver_info_6(TALLOC_CTX *mem_ctx, + struct spoolss_DriverInfo6 *r, + int snum, + const char *servername, + const char *architecture, + uint32_t version) { NT_PRINTER_INFO_LEVEL *printer = NULL; NT_PRINTER_DRIVER_INFO_LEVEL driver; @@ -5531,246 +5041,104 @@ static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, } } - fill_printer_driver_info_6(info, driver, servername); + status = fill_printer_driver_info6(mem_ctx, r, &driver, servername); free_a_printer(&printer,2); free_a_printer_driver(driver, 3); - return WERR_OK; -} - -/**************************************************************************** -****************************************************************************/ - -static void free_printer_driver_info_3(DRIVER_INFO_3 *info) -{ - SAFE_FREE(info->dependentfiles); -} - -/**************************************************************************** -****************************************************************************/ - -static void free_printer_driver_info_6(DRIVER_INFO_6 *info) -{ - SAFE_FREE(info->dependentfiles); -} - -/**************************************************************************** -****************************************************************************/ - -static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) -{ - DRIVER_INFO_1 *info=NULL; - WERROR result; - - if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL) - return WERR_NOMEM; - - result = construct_printer_driver_info_1(info, snum, servername, architecture, version); - if (!W_ERROR_IS_OK(result)) - goto out; - - /* check the required size. */ - *needed += spoolss_size_printer_driver_info_1(info); - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; - } - - /* fill the buffer with the structures */ - smb_io_printer_driver_info_1("", buffer, info, 0); - -out: - /* clear memory */ - SAFE_FREE(info); - - return result; -} - -/**************************************************************************** -****************************************************************************/ - -static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) -{ - DRIVER_INFO_2 *info=NULL; - WERROR result; - - if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL) - return WERR_NOMEM; - - result = construct_printer_driver_info_2(info, snum, servername, architecture, version); - if (!W_ERROR_IS_OK(result)) - goto out; - - /* check the required size. */ - *needed += spoolss_size_printer_driver_info_2(info); - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; - } - - /* fill the buffer with the structures */ - smb_io_printer_driver_info_2("", buffer, info, 0); - -out: - /* clear memory */ - SAFE_FREE(info); - - return result; -} - -/**************************************************************************** -****************************************************************************/ - -static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) -{ - DRIVER_INFO_3 info; - WERROR result; - - ZERO_STRUCT(info); - - result = construct_printer_driver_info_3(&info, snum, servername, architecture, version); - if (!W_ERROR_IS_OK(result)) - goto out; - - /* check the required size. */ - *needed += spoolss_size_printer_driver_info_3(&info); - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; - } - - /* fill the buffer with the structures */ - smb_io_printer_driver_info_3("", buffer, &info, 0); - -out: - free_printer_driver_info_3(&info); - - return result; + return status; } -/**************************************************************************** -****************************************************************************/ +/**************************************************************** + _spoolss_GetPrinterDriver2 +****************************************************************/ -static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) +WERROR _spoolss_GetPrinterDriver2(pipes_struct *p, + struct spoolss_GetPrinterDriver2 *r) { - DRIVER_INFO_6 info; - WERROR result; - - ZERO_STRUCT(info); - - result = construct_printer_driver_info_6(&info, snum, servername, architecture, version); - if (!W_ERROR_IS_OK(result)) - goto out; - - /* check the required size. */ - *needed += spoolss_size_printer_driver_info_6(&info); - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; - } - - /* fill the buffer with the structures */ - smb_io_printer_driver_info_6("", buffer, &info, 0); - -out: - free_printer_driver_info_6(&info); - - return result; -} - -/**************************************************************************** -****************************************************************************/ - -WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u) -{ - POLICY_HND *handle = &q_u->handle; - UNISTR2 *uni_arch = &q_u->architecture; - uint32 level = q_u->level; - uint32 clientmajorversion = q_u->clientmajorversion; - RPC_BUFFER *buffer = NULL; - uint32 offered = q_u->offered; - uint32 *needed = &r_u->needed; - uint32 *servermajorversion = &r_u->servermajorversion; - uint32 *serverminorversion = &r_u->serverminorversion; Printer_entry *printer; + WERROR result; - fstring servername; - fstring architecture; + const char *servername; int snum; /* that's an [in out] buffer */ - if (!q_u->buffer && (offered!=0)) { - return WERR_INVALID_PARAM; - } - - if (offered > MAX_RPC_DATA_SIZE) { + if (!r->in.buffer && (r->in.offered != 0)) { return WERR_INVALID_PARAM; } - rpcbuf_move(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; - - DEBUG(4,("_spoolss_getprinterdriver2\n")); + DEBUG(4,("_spoolss_GetPrinterDriver2\n")); - if ( !(printer = find_printer_index_by_hnd( p, handle )) ) { - DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n")); + if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) { + DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n")); return WERR_INVALID_PRINTER_NAME; } - *needed = 0; - *servermajorversion = 0; - *serverminorversion = 0; + *r->out.needed = 0; + *r->out.server_major_version = 0; + *r->out.server_minor_version = 0; - fstrcpy(servername, get_server_name( printer )); - unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)); + servername = get_server_name(printer); - if (!get_printer_snum(p, handle, &snum, NULL)) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { return WERR_BADFID; + } - switch (level) { + switch (r->in.level) { case 1: - return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed); + result = construct_printer_driver_info_1(p->mem_ctx, + &r->out.info->info1, + snum, + servername, + r->in.architecture, + r->in.client_major_version); + break; case 2: - return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed); + result = construct_printer_driver_info_2(p->mem_ctx, + &r->out.info->info2, + snum, + servername, + r->in.architecture, + r->in.client_major_version); + break; case 3: - return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed); + result = construct_printer_driver_info_3(p->mem_ctx, + &r->out.info->info3, + snum, + servername, + r->in.architecture, + r->in.client_major_version); + break; case 6: - return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed); + result = construct_printer_driver_info_6(p->mem_ctx, + &r->out.info->info6, + snum, + servername, + r->in.architecture, + r->in.client_major_version); + break; + default: #if 0 /* JERRY */ case 101: /* apparently this call is the equivalent of EnumPrinterDataEx() for the DsDriver key */ break; #endif + result = WERR_UNKNOWN_LEVEL; + break; } - return WERR_UNKNOWN_LEVEL; + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(r->out.info); + return result; + } + + *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo, NULL, + r->out.info, r->in.level); + r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); + + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); } @@ -5781,9 +5149,7 @@ WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_ WERROR _spoolss_StartPagePrinter(pipes_struct *p, struct spoolss_StartPagePrinter *r) { - POLICY_HND *handle = r->in.handle; - - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); if (!Printer) { DEBUG(3,("_spoolss_StartPagePrinter: " @@ -5802,18 +5168,17 @@ WERROR _spoolss_StartPagePrinter(pipes_struct *p, WERROR _spoolss_EndPagePrinter(pipes_struct *p, struct spoolss_EndPagePrinter *r) { - POLICY_HND *handle = r->in.handle; int snum; - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); if (!Printer) { DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n", - OUR_HANDLE(handle))); + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } - if (!get_printer_snum(p, handle, &snum, NULL)) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) return WERR_BADFID; Printer->page_started=False; @@ -5829,15 +5194,15 @@ WERROR _spoolss_EndPagePrinter(pipes_struct *p, WERROR _spoolss_StartDocPrinter(pipes_struct *p, struct spoolss_StartDocPrinter *r) { - POLICY_HND *handle = r->in.handle; uint32_t *jobid = r->out.job_id; struct spoolss_DocumentInfo1 *info_1; int snum; - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); if (!Printer) { DEBUG(2,("_spoolss_StartDocPrinter: " - "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle))); + "Invalid handle (%s:%u:%u)\n", + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } @@ -5863,12 +5228,12 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p, } /* get the share number of the printer */ - if (!get_printer_snum(p, handle, &snum, NULL)) { + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { return WERR_BADFID; } Printer->jobid = print_job_start(p->server_info, snum, - CONST_DISCARD(char *,info_1->document_name), + info_1->document_name, Printer->nt_devmode); /* An error occured in print_job_start() so return an appropriate @@ -5891,9 +5256,7 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p, WERROR _spoolss_EndDocPrinter(pipes_struct *p, struct spoolss_EndDocPrinter *r) { - POLICY_HND *handle = r->in.handle; - - return _spoolss_enddocprinter_internal(p, handle); + return _spoolss_enddocprinter_internal(p, r->in.handle); } /**************************************************************** @@ -5903,21 +5266,20 @@ WERROR _spoolss_EndDocPrinter(pipes_struct *p, WERROR _spoolss_WritePrinter(pipes_struct *p, struct spoolss_WritePrinter *r) { - POLICY_HND *handle = r->in.handle; uint32 buffer_size = r->in._data_size; uint8 *buffer = r->in.data.data; uint32 *buffer_written = &r->in._data_size; int snum; - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); if (!Printer) { DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n", - OUR_HANDLE(handle))); + OUR_HANDLE(r->in.handle))); *r->out.num_written = r->in._data_size; return WERR_BADFID; } - if (!get_printer_snum(p, handle, &snum, NULL)) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) return WERR_BADFID; (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer, @@ -5941,7 +5303,7 @@ WERROR _spoolss_WritePrinter(pipes_struct *p, * ********************************************************************/ -static WERROR control_printer(POLICY_HND *handle, uint32 command, +static WERROR control_printer(struct policy_handle *handle, uint32_t command, pipes_struct *p) { int snum; @@ -5949,7 +5311,8 @@ static WERROR control_printer(POLICY_HND *handle, uint32 command, Printer_entry *Printer = find_printer_index_by_hnd(p, handle); if (!Printer) { - DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle))); + DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", + OUR_HANDLE(handle))); return WERR_BADFID; } @@ -5990,18 +5353,17 @@ static WERROR control_printer(POLICY_HND *handle, uint32 command, WERROR _spoolss_AbortPrinter(pipes_struct *p, struct spoolss_AbortPrinter *r) { - POLICY_HND *handle = r->in.handle; - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); int snum; WERROR errcode = WERR_OK; if (!Printer) { DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n", - OUR_HANDLE(handle))); + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } - if (!get_printer_snum(p, handle, &snum, NULL)) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) return WERR_BADFID; print_job_delete(p->server_info, snum, Printer->jobid, &errcode ); @@ -6014,7 +5376,7 @@ WERROR _spoolss_AbortPrinter(pipes_struct *p, * when updating a printer description ********************************************************************/ -static WERROR update_printer_sec(POLICY_HND *handle, +static WERROR update_printer_sec(struct policy_handle *handle, pipes_struct *p, SEC_DESC_BUF *secdesc_ctr) { SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL; @@ -6300,7 +5662,7 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV * when updating a printer description. ********************************************************************/ -static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, +static WERROR update_printer(pipes_struct *p, struct policy_handle *handle, struct spoolss_SetPrinterInfoCtr *info_ctr, struct spoolss_DeviceMode *devmode) { @@ -6339,7 +5701,7 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, * just read from the tdb in the pointer 'printer'. */ - if (!convert_printer_info_new(info_ctr, printer)) { + if (!convert_printer_info(info_ctr, printer)) { result = WERR_NOMEM; goto done; } @@ -6349,9 +5711,8 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, convert it and link it*/ DEBUGADD(8,("update_printer: Converting the devicemode struct\n")); - if (!convert_devicemode_new(printer->info_2->printername, - devmode, - &printer->info_2->devmode)) { + if (!convert_devicemode(printer->info_2->printername, devmode, + &printer->info_2->devmode)) { result = WERR_NOMEM; goto done; } @@ -6494,7 +5855,8 @@ done: /**************************************************************************** ****************************************************************************/ -static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle, +static WERROR publish_or_unpublish_printer(pipes_struct *p, + struct policy_handle *handle, struct spoolss_SetPrinterInfo7 *info7) { #ifdef HAVE_ADS @@ -6530,36 +5892,35 @@ static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle, WERROR _spoolss_SetPrinter(pipes_struct *p, struct spoolss_SetPrinter *r) { - POLICY_HND *handle = r->in.handle; WERROR result; - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); if (!Printer) { DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n", - OUR_HANDLE(handle))); + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } /* check the level */ switch (r->in.info_ctr->level) { case 0: - return control_printer(handle, r->in.command, p); + return control_printer(r->in.handle, r->in.command, p); case 2: - result = update_printer(p, handle, + result = update_printer(p, r->in.handle, r->in.info_ctr, r->in.devmode_ctr->devmode); if (!W_ERROR_IS_OK(result)) return result; if (r->in.secdesc_ctr->sd) - result = update_printer_sec(handle, p, + result = update_printer_sec(r->in.handle, p, r->in.secdesc_ctr); return result; case 3: - return update_printer_sec(handle, p, + return update_printer_sec(r->in.handle, p, r->in.secdesc_ctr); case 7: - return publish_or_unpublish_printer(p, handle, + return publish_or_unpublish_printer(p, r->in.handle, r->in.info_ctr->info.info7); default: return WERR_UNKNOWN_LEVEL; @@ -6573,12 +5934,11 @@ WERROR _spoolss_SetPrinter(pipes_struct *p, WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p, struct spoolss_FindClosePrinterNotify *r) { - POLICY_HND *handle = r->in.handle; - Printer_entry *Printer= find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); if (!Printer) { DEBUG(2,("_spoolss_FindClosePrinterNotify: " - "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle))); + "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle))); return WERR_BADFID; } @@ -6588,7 +5948,7 @@ WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p, if ( Printer->printer_type == SPLHND_SERVER) snum = -1; else if ( (Printer->printer_type == SPLHND_PRINTER) && - !get_printer_snum(p, handle, &snum, NULL) ) + !get_printer_snum(p, r->in.handle, &snum, NULL) ) return WERR_BADFID; srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd); @@ -6626,251 +5986,276 @@ WERROR _spoolss_AddJob(pipes_struct *p, } /**************************************************************************** +fill_job_info1 ****************************************************************************/ -static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue, - int position, int snum, - const NT_PRINTER_INFO_LEVEL *ntprinter) +static WERROR fill_job_info1(TALLOC_CTX *mem_ctx, + struct spoolss_JobInfo1 *r, + const print_queue_struct *queue, + int position, int snum, + const NT_PRINTER_INFO_LEVEL *ntprinter) { struct tm *t; - t=gmtime(&queue->time); + t = gmtime(&queue->time); - job_info->jobid=queue->job; - init_unistr(&job_info->printername, lp_servicename(snum)); - init_unistr(&job_info->machinename, ntprinter->info_2->servername); - init_unistr(&job_info->username, queue->fs_user); - init_unistr(&job_info->document, queue->fs_file); - init_unistr(&job_info->datatype, "RAW"); - init_unistr(&job_info->text_status, ""); - job_info->status=nt_printj_status(queue->status); - job_info->priority=queue->priority; - job_info->position=position; - job_info->totalpages=queue->page_count; - job_info->pagesprinted=0; + r->job_id = queue->job; - make_systemtime(&job_info->submitted, t); + r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum)); + W_ERROR_HAVE_NO_MEMORY(r->printer_name); + r->server_name = talloc_strdup(mem_ctx, ntprinter->info_2->servername); + W_ERROR_HAVE_NO_MEMORY(r->server_name); + r->user_name = talloc_strdup(mem_ctx, queue->fs_user); + W_ERROR_HAVE_NO_MEMORY(r->user_name); + r->document_name = talloc_strdup(mem_ctx, queue->fs_file); + W_ERROR_HAVE_NO_MEMORY(r->document_name); + r->data_type = talloc_strdup(mem_ctx, "RAW"); + W_ERROR_HAVE_NO_MEMORY(r->data_type); + r->text_status = talloc_strdup(mem_ctx, ""); + W_ERROR_HAVE_NO_MEMORY(r->text_status); + + r->status = nt_printj_status(queue->status); + r->priority = queue->priority; + r->position = position; + r->total_pages = queue->page_count; + r->pages_printed = 0; /* ??? */ + + init_systemtime(&r->submitted, t); + + return WERR_OK; } /**************************************************************************** +fill_job_info2 ****************************************************************************/ -static bool fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue, - int position, int snum, - const NT_PRINTER_INFO_LEVEL *ntprinter, - DEVICEMODE *devmode) +static WERROR fill_job_info2(TALLOC_CTX *mem_ctx, + struct spoolss_JobInfo2 *r, + const print_queue_struct *queue, + int position, int snum, + const NT_PRINTER_INFO_LEVEL *ntprinter, + struct spoolss_DeviceMode *devmode) { struct tm *t; - t=gmtime(&queue->time); - - job_info->jobid=queue->job; - - init_unistr(&job_info->printername, ntprinter->info_2->printername); - - init_unistr(&job_info->machinename, ntprinter->info_2->servername); - init_unistr(&job_info->username, queue->fs_user); - init_unistr(&job_info->document, queue->fs_file); - init_unistr(&job_info->notifyname, queue->fs_user); - init_unistr(&job_info->datatype, "RAW"); - init_unistr(&job_info->printprocessor, "winprint"); - init_unistr(&job_info->parameters, ""); - init_unistr(&job_info->drivername, ntprinter->info_2->drivername); - init_unistr(&job_info->text_status, ""); + t = gmtime(&queue->time); + + r->job_id = queue->job; + + r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum)); + W_ERROR_HAVE_NO_MEMORY(r->printer_name); + r->server_name = talloc_strdup(mem_ctx, ntprinter->info_2->servername); + W_ERROR_HAVE_NO_MEMORY(r->server_name); + r->user_name = talloc_strdup(mem_ctx, queue->fs_user); + W_ERROR_HAVE_NO_MEMORY(r->user_name); + r->document_name = talloc_strdup(mem_ctx, queue->fs_file); + W_ERROR_HAVE_NO_MEMORY(r->document_name); + r->notify_name = talloc_strdup(mem_ctx, queue->fs_user); + W_ERROR_HAVE_NO_MEMORY(r->notify_name); + r->data_type = talloc_strdup(mem_ctx, "RAW"); + W_ERROR_HAVE_NO_MEMORY(r->data_type); + r->print_processor = talloc_strdup(mem_ctx, "winprint"); + W_ERROR_HAVE_NO_MEMORY(r->print_processor); + r->parameters = talloc_strdup(mem_ctx, ""); + W_ERROR_HAVE_NO_MEMORY(r->parameters); + r->driver_name = talloc_strdup(mem_ctx, ntprinter->info_2->drivername); + W_ERROR_HAVE_NO_MEMORY(r->driver_name); + + r->devmode = devmode; + + r->text_status = talloc_strdup(mem_ctx, ""); + W_ERROR_HAVE_NO_MEMORY(r->text_status); + + r->secdesc = NULL; + + r->status = nt_printj_status(queue->status); + r->priority = queue->priority; + r->position = position; + r->start_time = 0; + r->until_time = 0; + r->total_pages = queue->page_count; + r->size = queue->size; + init_systemtime(&r->submitted, t); + r->time = 0; + r->pages_printed = 0; /* ??? */ -/* and here the security descriptor */ - - job_info->status=nt_printj_status(queue->status); - job_info->priority=queue->priority; - job_info->position=position; - job_info->starttime=0; - job_info->untiltime=0; - job_info->totalpages=queue->page_count; - job_info->size=queue->size; - make_systemtime(&(job_info->submitted), t); - job_info->timeelapsed=0; - job_info->pagesprinted=0; - - job_info->devmode = devmode; - - return (True); + return WERR_OK; } /**************************************************************************** Enumjobs at level 1. ****************************************************************************/ -static WERROR enumjobs_level1(const print_queue_struct *queue, int snum, +static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx, + const print_queue_struct *queue, + uint32_t num_queues, int snum, const NT_PRINTER_INFO_LEVEL *ntprinter, - RPC_BUFFER *buffer, uint32 offered, - uint32 *needed, uint32 *returned) + union spoolss_JobInfo **info_p, + uint32_t *count) { - JOB_INFO_1 *info; + union spoolss_JobInfo *info; int i; WERROR result = WERR_OK; - info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned); - if (info==NULL) { - *returned=0; - return WERR_NOMEM; - } + info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues); + W_ERROR_HAVE_NO_MEMORY(info); - for (i=0; i<*returned; i++) - fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter ); + *count = num_queues; - /* check the required size. */ - for (i=0; i<*returned; i++) - (*needed) += spoolss_size_job_info_1(&info[i]); - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; + for (i=0; i<*count; i++) { + result = fill_job_info1(info, + &info[i].info1, + &queue[i], + i, + snum, + ntprinter); + if (!W_ERROR_IS_OK(result)) { + goto out; + } } - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; + out: + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(info); + *count = 0; + return result; } - /* fill the buffer with the structures */ - for (i=0; i<*returned; i++) - smb_io_job_info_1("", buffer, &info[i], 0); - -out: - /* clear memory */ - SAFE_FREE(info); - - if ( !W_ERROR_IS_OK(result) ) - *returned = 0; + *info_p = info; - return result; + return WERR_OK; } /**************************************************************************** Enumjobs at level 2. ****************************************************************************/ -static WERROR enumjobs_level2(const print_queue_struct *queue, int snum, +static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx, + const print_queue_struct *queue, + uint32_t num_queues, int snum, const NT_PRINTER_INFO_LEVEL *ntprinter, - RPC_BUFFER *buffer, uint32 offered, - uint32 *needed, uint32 *returned) + union spoolss_JobInfo **info_p, + uint32_t *count) { - JOB_INFO_2 *info = NULL; + union spoolss_JobInfo *info; int i; WERROR result = WERR_OK; - DEVICEMODE *devmode = NULL; - if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) { - *returned=0; - return WERR_NOMEM; - } + info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues); + W_ERROR_HAVE_NO_MEMORY(info); - /* this should not be a failure condition if the devmode is NULL */ + *count = num_queues; - devmode = construct_dev_mode(lp_const_servicename(snum)); + for (i=0; i<*count; i++) { - for (i=0; i<*returned; i++) - fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode); + struct spoolss_DeviceMode *devmode; - /* check the required size. */ - for (i=0; i<*returned; i++) - (*needed) += spoolss_size_job_info_2(&info[i]); + devmode = construct_dev_mode(info, lp_const_servicename(snum)); + if (!devmode) { + result = WERR_NOMEM; + goto out; + } - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; + result = fill_job_info2(info, + &info[i].info2, + &queue[i], + i, + snum, + ntprinter, + devmode); + if (!W_ERROR_IS_OK(result)) { + goto out; + } } - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; + out: + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(info); + *count = 0; + return result; } - /* fill the buffer with the structures */ - for (i=0; i<*returned; i++) - smb_io_job_info_2("", buffer, &info[i], 0); - -out: - free_devmode(devmode); - SAFE_FREE(info); - - if ( !W_ERROR_IS_OK(result) ) - *returned = 0; - - return result; + *info_p = info; + return WERR_OK; } -/**************************************************************************** - Enumjobs. -****************************************************************************/ +/**************************************************************** + _spoolss_EnumJobs +****************************************************************/ -WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u) +WERROR _spoolss_EnumJobs(pipes_struct *p, + struct spoolss_EnumJobs *r) { - POLICY_HND *handle = &q_u->handle; - uint32 level = q_u->level; - RPC_BUFFER *buffer = NULL; - uint32 offered = q_u->offered; - uint32 *needed = &r_u->needed; - uint32 *returned = &r_u->returned; - WERROR wret; + WERROR result; NT_PRINTER_INFO_LEVEL *ntprinter = NULL; int snum; print_status_struct prt_status; - print_queue_struct *queue=NULL; + print_queue_struct *queue = NULL; + uint32_t count; /* that's an [in out] buffer */ - if (!q_u->buffer && (offered!=0)) { - return WERR_INVALID_PARAM; - } - - if (offered > MAX_RPC_DATA_SIZE) { + if (!r->in.buffer && (r->in.offered != 0)) { return WERR_INVALID_PARAM; } - rpcbuf_move(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + DEBUG(4,("_spoolss_EnumJobs\n")); - DEBUG(4,("_spoolss_enumjobs\n")); - - *needed=0; - *returned=0; + *r->out.needed = 0; + *r->out.count = 0; + *r->out.info = NULL; /* lookup the printer snum and tdb entry */ - if (!get_printer_snum(p, handle, &snum, NULL)) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { return WERR_BADFID; + } - wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum)); - if ( !W_ERROR_IS_OK(wret) ) - return wret; + result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum)); + if (!W_ERROR_IS_OK(result)) { + return result; + } - *returned = print_queue_status(snum, &queue, &prt_status); - DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message)); + count = print_queue_status(snum, &queue, &prt_status); + DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", + count, prt_status.status, prt_status.message)); - if (*returned == 0) { + if (count == 0) { SAFE_FREE(queue); free_a_printer(&ntprinter, 2); return WERR_OK; } - switch (level) { + switch (r->in.level) { case 1: - wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned); + result = enumjobs_level1(p->mem_ctx, queue, count, snum, + ntprinter, r->out.info, r->out.count); break; case 2: - wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned); + result = enumjobs_level2(p->mem_ctx, queue, count, snum, + ntprinter, r->out.info, r->out.count); break; default: - *returned=0; - wret = WERR_UNKNOWN_LEVEL; + result = WERR_UNKNOWN_LEVEL; break; } SAFE_FREE(queue); - free_a_printer( &ntprinter, 2 ); - return wret; + free_a_printer(&ntprinter, 2); + + if (!W_ERROR_IS_OK(result)) { + return result; + } + + *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx, + spoolss_EnumJobs, NULL, + *r->out.info, r->in.level, + *r->out.count); + *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL); + *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0); + + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); } /**************************************************************** @@ -6890,14 +6275,13 @@ WERROR _spoolss_ScheduleJob(pipes_struct *p, WERROR _spoolss_SetJob(pipes_struct *p, struct spoolss_SetJob *r) { - POLICY_HND *handle = r->in.handle; uint32 jobid = r->in.job_id; uint32 command = r->in.command; int snum; WERROR errcode = WERR_BADFUNC; - if (!get_printer_snum(p, handle, &snum, NULL)) { + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { return WERR_BADFID; } @@ -6934,463 +6318,479 @@ WERROR _spoolss_SetJob(pipes_struct *p, Enumerates all printer drivers at level 1. ****************************************************************************/ -static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumprinterdrivers_level1(TALLOC_CTX *mem_ctx, + const char *servername, + const char *architecture, + union spoolss_DriverInfo **info_p, + uint32_t *count) { int i; int ndrivers; - uint32 version; + uint32_t version; fstring *list = NULL; NT_PRINTER_DRIVER_INFO_LEVEL driver; - DRIVER_INFO_1 *driver_info_1=NULL; + union spoolss_DriverInfo *info = NULL; WERROR result = WERR_OK; - *returned=0; + *count = 0; for (version=0; version<DRIVER_MAX_VERSION; version++) { - list=NULL; - ndrivers=get_ntdrivers(&list, architecture, version); - DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version)); + list = NULL; + ndrivers = get_ntdrivers(&list, architecture, version); + DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", + ndrivers, architecture, version)); - if(ndrivers == -1) { - SAFE_FREE(driver_info_1); - return WERR_NOMEM; + if (ndrivers == -1) { + result = WERR_NOMEM; + goto out; } - if(ndrivers != 0) { - if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) { - DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n")); - SAFE_FREE(list); - return WERR_NOMEM; + if (ndrivers != 0) { + info = TALLOC_REALLOC_ARRAY(mem_ctx, info, + union spoolss_DriverInfo, + *count + ndrivers); + if (!info) { + DEBUG(0,("enumprinterdrivers_level1: " + "failed to enlarge driver info buffer!\n")); + result = WERR_NOMEM; + goto out; } } for (i=0; i<ndrivers; i++) { - WERROR status; DEBUGADD(5,("\tdriver: [%s]\n", list[i])); ZERO_STRUCT(driver); - status = get_a_printer_driver(&driver, 3, list[i], + result = get_a_printer_driver(&driver, 3, list[i], architecture, version); - if (!W_ERROR_IS_OK(status)) { - SAFE_FREE(list); - SAFE_FREE(driver_info_1); - return status; + if (!W_ERROR_IS_OK(result)) { + goto out; + } + result = fill_printer_driver_info1(info, &info[*count+i].info1, + &driver, servername, + architecture); + if (!W_ERROR_IS_OK(result)) { + free_a_printer_driver(driver, 3); + goto out; } - fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture ); free_a_printer_driver(driver, 3); } - *returned+=ndrivers; + *count += ndrivers; SAFE_FREE(list); } - /* check the required size. */ - for (i=0; i<*returned; i++) { - DEBUGADD(6,("adding driver [%d]'s size\n",i)); - *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]); - } - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; - } + out: + SAFE_FREE(list); - /* fill the buffer with the driver structures */ - for (i=0; i<*returned; i++) { - DEBUGADD(6,("adding driver [%d] to buffer\n",i)); - smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0); + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(info); + *count = 0; + return result; } -out: - SAFE_FREE(driver_info_1); - - if ( !W_ERROR_IS_OK(result) ) - *returned = 0; + *info_p = info; - return result; + return WERR_OK; } /**************************************************************************** Enumerates all printer drivers at level 2. ****************************************************************************/ -static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumprinterdrivers_level2(TALLOC_CTX *mem_ctx, + const char *servername, + const char *architecture, + union spoolss_DriverInfo **info_p, + uint32_t *count) { int i; int ndrivers; - uint32 version; + uint32_t version; fstring *list = NULL; NT_PRINTER_DRIVER_INFO_LEVEL driver; - DRIVER_INFO_2 *driver_info_2=NULL; + union spoolss_DriverInfo *info = NULL; WERROR result = WERR_OK; - *returned=0; + *count = 0; for (version=0; version<DRIVER_MAX_VERSION; version++) { - list=NULL; - ndrivers=get_ntdrivers(&list, architecture, version); - DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version)); + list = NULL; + ndrivers = get_ntdrivers(&list, architecture, version); + DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", + ndrivers, architecture, version)); - if(ndrivers == -1) { - SAFE_FREE(driver_info_2); - return WERR_NOMEM; + if (ndrivers == -1) { + result = WERR_NOMEM; + goto out; } - if(ndrivers != 0) { - if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) { - DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n")); - SAFE_FREE(list); - return WERR_NOMEM; + if (ndrivers != 0) { + info = TALLOC_REALLOC_ARRAY(mem_ctx, info, + union spoolss_DriverInfo, + *count + ndrivers); + if (!info) { + DEBUG(0,("enumprinterdrivers_level2: " + "failed to enlarge driver info buffer!\n")); + result = WERR_NOMEM; + goto out; } } for (i=0; i<ndrivers; i++) { - WERROR status; - DEBUGADD(5,("\tdriver: [%s]\n", list[i])); ZERO_STRUCT(driver); - status = get_a_printer_driver(&driver, 3, list[i], + result = get_a_printer_driver(&driver, 3, list[i], architecture, version); - if (!W_ERROR_IS_OK(status)) { - SAFE_FREE(list); - SAFE_FREE(driver_info_2); - return status; + if (!W_ERROR_IS_OK(result)) { + goto out; + } + result = fill_printer_driver_info2(info, &info[*count+i].info2, + &driver, servername); + if (!W_ERROR_IS_OK(result)) { + free_a_printer_driver(driver, 3); + goto out; } - fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername); free_a_printer_driver(driver, 3); } - *returned+=ndrivers; + *count += ndrivers; SAFE_FREE(list); } - /* check the required size. */ - for (i=0; i<*returned; i++) { - DEBUGADD(6,("adding driver [%d]'s size\n",i)); - *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i])); - } - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; - } + out: + SAFE_FREE(list); - /* fill the buffer with the form structures */ - for (i=0; i<*returned; i++) { - DEBUGADD(6,("adding driver [%d] to buffer\n",i)); - smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0); + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(info); + *count = 0; + return result; } -out: - SAFE_FREE(driver_info_2); - - if ( !W_ERROR_IS_OK(result) ) - *returned = 0; + *info_p = info; - return result; + return WERR_OK; } /**************************************************************************** Enumerates all printer drivers at level 3. ****************************************************************************/ -static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumprinterdrivers_level3(TALLOC_CTX *mem_ctx, + const char *servername, + const char *architecture, + union spoolss_DriverInfo **info_p, + uint32_t *count) { int i; int ndrivers; - uint32 version; + uint32_t version; fstring *list = NULL; - DRIVER_INFO_3 *driver_info_3=NULL; + union spoolss_DriverInfo *info = NULL; NT_PRINTER_DRIVER_INFO_LEVEL driver; WERROR result = WERR_OK; - *returned=0; + *count = 0; for (version=0; version<DRIVER_MAX_VERSION; version++) { - list=NULL; - ndrivers=get_ntdrivers(&list, architecture, version); - DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version)); + list = NULL; + ndrivers = get_ntdrivers(&list, architecture, version); + DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", + ndrivers, architecture, version)); - if(ndrivers == -1) { - SAFE_FREE(driver_info_3); - return WERR_NOMEM; + if (ndrivers == -1) { + result = WERR_NOMEM; + goto out; } - if(ndrivers != 0) { - if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) { - DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n")); - SAFE_FREE(list); - return WERR_NOMEM; + if (ndrivers != 0) { + info = TALLOC_REALLOC_ARRAY(mem_ctx, info, + union spoolss_DriverInfo, + *count + ndrivers); + if (!info) { + DEBUG(0,("enumprinterdrivers_level3: " + "failed to enlarge driver info buffer!\n")); + result = WERR_NOMEM; + goto out; } } for (i=0; i<ndrivers; i++) { - WERROR status; - DEBUGADD(5,("\tdriver: [%s]\n", list[i])); ZERO_STRUCT(driver); - status = get_a_printer_driver(&driver, 3, list[i], + result = get_a_printer_driver(&driver, 3, list[i], architecture, version); - if (!W_ERROR_IS_OK(status)) { - SAFE_FREE(list); - SAFE_FREE(driver_info_3); - return status; + if (!W_ERROR_IS_OK(result)) { + goto out; + } + result = fill_printer_driver_info3(info, &info[*count+i].info3, + &driver, servername); + if (!W_ERROR_IS_OK(result)) { + free_a_printer_driver(driver, 3); + goto out; } - fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername); + free_a_printer_driver(driver, 3); } - *returned+=ndrivers; + *count += ndrivers; SAFE_FREE(list); } - /* check the required size. */ - for (i=0; i<*returned; i++) { - DEBUGADD(6,("adding driver [%d]'s size\n",i)); - *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]); - } - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; - } - - /* fill the buffer with the driver structures */ - for (i=0; i<*returned; i++) { - DEBUGADD(6,("adding driver [%d] to buffer\n",i)); - smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0); - } + out: + SAFE_FREE(list); -out: - for (i=0; i<*returned; i++) { - SAFE_FREE(driver_info_3[i].dependentfiles); + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(info); + *count = 0; + return result; } - SAFE_FREE(driver_info_3); - - if ( !W_ERROR_IS_OK(result) ) - *returned = 0; + *info_p = info; - return result; + return WERR_OK; } -/**************************************************************************** - Enumerates all printer drivers. -****************************************************************************/ +/**************************************************************** + _spoolss_EnumPrinterDrivers +****************************************************************/ -WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u) +WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p, + struct spoolss_EnumPrinterDrivers *r) { - uint32 level = q_u->level; - RPC_BUFFER *buffer = NULL; - uint32 offered = q_u->offered; - uint32 *needed = &r_u->needed; - uint32 *returned = &r_u->returned; const char *cservername; - fstring servername; - fstring architecture; + WERROR result; /* that's an [in out] buffer */ - if (!q_u->buffer && (offered!=0)) { - return WERR_INVALID_PARAM; - } - - if (offered > MAX_RPC_DATA_SIZE) { + if (!r->in.buffer && (r->in.offered != 0)) { return WERR_INVALID_PARAM; } - rpcbuf_move(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; - - DEBUG(4,("_spoolss_enumprinterdrivers\n")); + DEBUG(4,("_spoolss_EnumPrinterDrivers\n")); - *needed = 0; - *returned = 0; - - unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture)); - unistr2_to_ascii(servername, &q_u->name, sizeof(servername)); + *r->out.needed = 0; + *r->out.count = 0; + *r->out.info = NULL; - cservername = canon_servername(servername); + cservername = canon_servername(r->in.server); - if (!is_myname_or_ipaddr(cservername)) + if (!is_myname_or_ipaddr(cservername)) { return WERR_UNKNOWN_PRINTER_DRIVER; + } - switch (level) { + switch (r->in.level) { case 1: - return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned); + result = enumprinterdrivers_level1(p->mem_ctx, cservername, + r->in.environment, + r->out.info, r->out.count); + break; case 2: - return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned); + result = enumprinterdrivers_level2(p->mem_ctx, cservername, + r->in.environment, + r->out.info, r->out.count); + break; case 3: - return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned); + result = enumprinterdrivers_level3(p->mem_ctx, cservername, + r->in.environment, + r->out.info, r->out.count); + break; default: return WERR_UNKNOWN_LEVEL; } -} -/**************************************************************************** -****************************************************************************/ + if (!W_ERROR_IS_OK(result)) { + return result; + } -static void fill_form_1(FORM_1 *form, nt_forms_struct *list) -{ - form->flag=list->flag; - init_unistr(&form->name, list->name); - form->width=list->width; - form->length=list->length; - form->left=list->left; - form->top=list->top; - form->right=list->right; - form->bottom=list->bottom; + *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx, + spoolss_EnumPrinterDrivers, NULL, + *r->out.info, r->in.level, + *r->out.count); + *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL); + *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0); + + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); } /**************************************************************************** ****************************************************************************/ static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx, - struct spoolss_FormInfo1 *form, - nt_forms_struct *list) + struct spoolss_FormInfo1 *r, + const nt_forms_struct *form) { - form->form_name = talloc_strdup(mem_ctx, list->name); - W_ERROR_HAVE_NO_MEMORY(form->form_name); + r->form_name = talloc_strdup(mem_ctx, form->name); + W_ERROR_HAVE_NO_MEMORY(r->form_name); - form->flags = list->flag; - form->size.width = list->width; - form->size.height = list->length; - form->area.left = list->left; - form->area.top = list->top; - form->area.right = list->right; - form->area.bottom = list->bottom; + r->flags = form->flag; + r->size.width = form->width; + r->size.height = form->length; + r->area.left = form->left; + r->area.top = form->top; + r->area.right = form->right; + r->area.bottom = form->bottom; return WERR_OK; } -/**************************************************************************** -****************************************************************************/ +/**************************************************************** + spoolss_enumforms_level1 +****************************************************************/ -WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u) +static WERROR spoolss_enumforms_level1(TALLOC_CTX *mem_ctx, + const nt_forms_struct *builtin_forms, + uint32_t num_builtin_forms, + const nt_forms_struct *user_forms, + uint32_t num_user_forms, + union spoolss_FormInfo **info_p, + uint32_t *count) { - uint32 level = q_u->level; - RPC_BUFFER *buffer = NULL; - uint32 offered = q_u->offered; - uint32 *needed = &r_u->needed; - uint32 *numofforms = &r_u->numofforms; - uint32 numbuiltinforms; - - nt_forms_struct *list=NULL; - nt_forms_struct *builtinlist=NULL; - FORM_1 *forms_1; - int buffer_size=0; + union spoolss_FormInfo *info; + WERROR result = WERR_OK; int i; - /* that's an [in out] buffer */ + *count = num_builtin_forms + num_user_forms; - if (!q_u->buffer && (offered!=0) ) { - return WERR_INVALID_PARAM; + info = TALLOC_ARRAY(mem_ctx, union spoolss_FormInfo, *count); + W_ERROR_HAVE_NO_MEMORY(info); + + /* construct the list of form structures */ + for (i=0; i<num_builtin_forms; i++) { + DEBUGADD(6,("Filling form number [%d]\n",i)); + result = fill_form_info_1(info, &info[i].info1, + &builtin_forms[i]); + if (!W_ERROR_IS_OK(result)) { + goto out; + } } - if (offered > MAX_RPC_DATA_SIZE) { - return WERR_INVALID_PARAM; + for (; i<num_user_forms; i++) { + DEBUGADD(6,("Filling form number [%d]\n",i)); + result = fill_form_info_1(info, &info[i].info1, + &user_forms[i-num_builtin_forms]); + if (!W_ERROR_IS_OK(result)) { + goto out; + } } - rpcbuf_move(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + out: + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(info); + *count = 0; + return result; + } - DEBUG(4,("_spoolss_enumforms\n")); - DEBUGADD(5,("Offered buffer size [%d]\n", offered)); - DEBUGADD(5,("Info level [%d]\n", level)); + *info_p = info; - numbuiltinforms = get_builtin_ntforms(&builtinlist); - DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms)); - *numofforms = get_ntforms(&list); - DEBUGADD(5,("Number of user forms [%d]\n", *numofforms)); - *numofforms += numbuiltinforms; + return WERR_OK; +} - if (*numofforms == 0) { - SAFE_FREE(builtinlist); - SAFE_FREE(list); +/**************************************************************** + _spoolss_EnumForms +****************************************************************/ + +WERROR _spoolss_EnumForms(pipes_struct *p, + struct spoolss_EnumForms *r) +{ + WERROR result; + nt_forms_struct *user_forms = NULL; + nt_forms_struct *builtin_forms = NULL; + uint32_t num_user_forms; + uint32_t num_builtin_forms; + + *r->out.count = 0; + *r->out.needed = 0; + *r->out.info = NULL; + + /* that's an [in out] buffer */ + + if (!r->in.buffer && (r->in.offered != 0) ) { + return WERR_INVALID_PARAM; + } + + DEBUG(4,("_spoolss_EnumForms\n")); + DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered)); + DEBUGADD(5,("Info level [%d]\n", r->in.level)); + + num_builtin_forms = get_builtin_ntforms(&builtin_forms); + DEBUGADD(5,("Number of builtin forms [%d]\n", num_builtin_forms)); + num_user_forms = get_ntforms(&user_forms); + DEBUGADD(5,("Number of user forms [%d]\n", num_user_forms)); + + if (num_user_forms + num_builtin_forms == 0) { + SAFE_FREE(builtin_forms); + SAFE_FREE(user_forms); return WERR_NO_MORE_ITEMS; } - switch (level) { + switch (r->in.level) { case 1: - if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) { - SAFE_FREE(builtinlist); - SAFE_FREE(list); - *numofforms=0; - return WERR_NOMEM; - } + result = spoolss_enumforms_level1(p->mem_ctx, + builtin_forms, + num_builtin_forms, + user_forms, + num_user_forms, + r->out.info, + r->out.count); + break; + default: + result = WERR_UNKNOWN_LEVEL; + break; + } - /* construct the list of form structures */ - for (i=0; i<numbuiltinforms; i++) { - DEBUGADD(6,("Filling form number [%d]\n",i)); - fill_form_1(&forms_1[i], &builtinlist[i]); - } + SAFE_FREE(user_forms); + SAFE_FREE(builtin_forms); - SAFE_FREE(builtinlist); + if (!W_ERROR_IS_OK(result)) { + return result; + } - for (; i<*numofforms; i++) { - DEBUGADD(6,("Filling form number [%d]\n",i)); - fill_form_1(&forms_1[i], &list[i-numbuiltinforms]); - } + *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx, + spoolss_EnumForms, NULL, + *r->out.info, r->in.level, + *r->out.count); + *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL); + *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0); - SAFE_FREE(list); + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); +} - /* check the required size. */ - for (i=0; i<numbuiltinforms; i++) { - DEBUGADD(6,("adding form [%d]'s size\n",i)); - buffer_size += spoolss_size_form_1(&forms_1[i]); - } - for (; i<*numofforms; i++) { - DEBUGADD(6,("adding form [%d]'s size\n",i)); - buffer_size += spoolss_size_form_1(&forms_1[i]); - } +/**************************************************************** +****************************************************************/ - *needed=buffer_size; +static WERROR find_form_byname(const char *name, + nt_forms_struct *form) +{ + nt_forms_struct *list = NULL; + int num_forms = 0, i = 0; - if (*needed > offered) { - SAFE_FREE(forms_1); - *numofforms=0; - return WERR_INSUFFICIENT_BUFFER; - } + if (get_a_builtin_ntform_by_string(name, form)) { + return WERR_OK; + } - if (!rpcbuf_alloc_size(buffer, buffer_size)){ - SAFE_FREE(forms_1); - *numofforms=0; - return WERR_NOMEM; - } + num_forms = get_ntforms(&list); + DEBUGADD(5,("Number of forms [%d]\n", num_forms)); - /* fill the buffer with the form structures */ - for (i=0; i<numbuiltinforms; i++) { - DEBUGADD(6,("adding form [%d] to buffer\n",i)); - smb_io_form_1("", buffer, &forms_1[i], 0); - } - for (; i<*numofforms; i++) { - DEBUGADD(6,("adding form [%d] to buffer\n",i)); - smb_io_form_1("", buffer, &forms_1[i], 0); - } + if (num_forms == 0) { + return WERR_BADFID; + } - SAFE_FREE(forms_1); + /* Check if the requested name is in the list of form structures */ + for (i = 0; i < num_forms; i++) { - return WERR_OK; + DEBUG(4,("checking form %s (want %s)\n", list[i].name, name)); - default: - SAFE_FREE(list); - SAFE_FREE(builtinlist); - return WERR_UNKNOWN_LEVEL; + if (strequal(name, list[i].name)) { + DEBUGADD(6,("Found form %s number [%d]\n", name, i)); + *form = list[i]; + SAFE_FREE(list); + return WERR_OK; + } } + + SAFE_FREE(list); + + return WERR_BADFID; } /**************************************************************** @@ -7400,94 +6800,60 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF WERROR _spoolss_GetForm(pipes_struct *p, struct spoolss_GetForm *r) { - uint32 level = r->in.level; - uint32 offered = r->in.offered; - uint32 *needed = r->out.needed; - - nt_forms_struct *list=NULL; - nt_forms_struct builtin_form; - bool foundBuiltin; - union spoolss_FormInfo info; - struct spoolss_FormInfo1 form_1; - int numofforms=0, i=0; + WERROR result; + nt_forms_struct form; /* that's an [in out] buffer */ - if (!r->in.buffer && (offered!=0)) { + if (!r->in.buffer && (r->in.offered != 0)) { return WERR_INVALID_PARAM; } DEBUG(4,("_spoolss_GetForm\n")); - DEBUGADD(5,("Offered buffer size [%d]\n", offered)); - DEBUGADD(5,("Info level [%d]\n", level)); - - foundBuiltin = get_a_builtin_ntform_by_string(r->in.form_name, &builtin_form); - if (!foundBuiltin) { - numofforms = get_ntforms(&list); - DEBUGADD(5,("Number of forms [%d]\n", numofforms)); + DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered)); + DEBUGADD(5,("Info level [%d]\n", r->in.level)); - if (numofforms == 0) - return WERR_BADFID; + result = find_form_byname(r->in.form_name, &form); + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(r->out.info); + return result; } - ZERO_STRUCT(form_1); - - switch (level) { + switch (r->in.level) { case 1: - if (foundBuiltin) { - fill_form_info_1(p->mem_ctx, &form_1, &builtin_form); - } else { - - /* Check if the requested name is in the list of form structures */ - for (i=0; i<numofforms; i++) { - - DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n", - list[i].name, r->in.form_name)); - - if (strequal(r->in.form_name, list[i].name)) { - DEBUGADD(6,("Found form %s number [%d]\n", - r->in.form_name, i)); - fill_form_info_1(p->mem_ctx, &form_1, &list[i]); - break; - } - } - - SAFE_FREE(list); - if (i == numofforms) { - return WERR_BADFID; - } - } - /* check the required size. */ - - info.info1 = form_1; - - *needed = ndr_size_spoolss_FormInfo(&info, 1, NULL, 0); - - if (*needed > offered) { - r->out.info = NULL; - return WERR_INSUFFICIENT_BUFFER; - } + result = fill_form_info_1(p->mem_ctx, + &r->out.info->info1, + &form); + break; - r->out.info->info1 = form_1; + default: + result = WERR_UNKNOWN_LEVEL; + break; + } - /* fill the buffer with the form structures */ - DEBUGADD(6,("adding form %s [%d] to buffer\n", - r->in.form_name, i)); + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(r->out.info); + return result; + } - return WERR_OK; + *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo, NULL, + r->out.info, r->in.level); + r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); - default: - SAFE_FREE(list); - return WERR_UNKNOWN_LEVEL; - } + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); } /**************************************************************************** ****************************************************************************/ -static void fill_port_1(PORT_INFO_1 *port, const char *name) +static WERROR fill_port_1(TALLOC_CTX *mem_ctx, + struct spoolss_PortInfo1 *r, + const char *name) { - init_unistr(&port->port_name, name); + r->port_name = talloc_strdup(mem_ctx, name); + W_ERROR_HAVE_NO_MEMORY(r->port_name); + + return WERR_OK; } /**************************************************************************** @@ -7495,13 +6861,23 @@ static void fill_port_1(PORT_INFO_1 *port, const char *name) somehow. ****************************************************************************/ -static void fill_port_2(PORT_INFO_2 *port, const char *name) +static WERROR fill_port_2(TALLOC_CTX *mem_ctx, + struct spoolss_PortInfo2 *r, + const char *name) { - init_unistr(&port->port_name, name); - init_unistr(&port->monitor_name, "Local Monitor"); - init_unistr(&port->description, SPL_LOCAL_PORT ); - port->port_type=PORT_TYPE_WRITE; - port->reserved=0x0; + r->port_name = talloc_strdup(mem_ctx, name); + W_ERROR_HAVE_NO_MEMORY(r->port_name); + + r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor"); + W_ERROR_HAVE_NO_MEMORY(r->monitor_name); + + r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT); + W_ERROR_HAVE_NO_MEMORY(r->description); + + r->port_type = SPOOLSS_PORT_TYPE_WRITE; + r->reserved = 0; + + return WERR_OK; } @@ -7569,9 +6945,11 @@ WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines ) enumports level 1. ****************************************************************************/ -static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumports_level_1(TALLOC_CTX *mem_ctx, + union spoolss_PortInfo **info_p, + uint32_t *count) { - PORT_INFO_1 *ports=NULL; + union spoolss_PortInfo *info = NULL; int i=0; WERROR result = WERR_OK; char **qlines = NULL; @@ -7579,161 +6957,140 @@ static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *need result = enumports_hook(talloc_tos(), &numlines, &qlines ); if (!W_ERROR_IS_OK(result)) { - TALLOC_FREE(qlines); - return result; + goto out; } - if(numlines) { - if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) { - DEBUG(10,("Returning WERR_NOMEM [%s]\n", - win_errstr(WERR_NOMEM))); - TALLOC_FREE(qlines); - return WERR_NOMEM; + if (numlines) { + info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines); + if (!info) { + DEBUG(10,("Returning WERR_NOMEM\n")); + result = WERR_NOMEM; + goto out; } for (i=0; i<numlines; i++) { DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i])); - fill_port_1(&ports[i], qlines[i]); + result = fill_port_1(info, &info[i].info1, qlines[i]); + if (!W_ERROR_IS_OK(result)) { + goto out; + } } } TALLOC_FREE(qlines); - *returned = numlines; - - /* check the required size. */ - for (i=0; i<*returned; i++) { - DEBUGADD(6,("adding port [%d]'s size\n", i)); - *needed += spoolss_size_port_info_1(&ports[i]); - } - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; - } - - /* fill the buffer with the ports structures */ - for (i=0; i<*returned; i++) { - DEBUGADD(6,("adding port [%d] to buffer\n", i)); - smb_io_port_1("", buffer, &ports[i], 0); - } - out: - SAFE_FREE(ports); + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(info); + TALLOC_FREE(qlines); + *count = 0; + *info_p = NULL; + return result; + } - if ( !W_ERROR_IS_OK(result) ) - *returned = 0; + *info_p = info; + *count = numlines; - return result; + return WERR_OK; } /**************************************************************************** enumports level 2. ****************************************************************************/ -static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumports_level_2(TALLOC_CTX *mem_ctx, + union spoolss_PortInfo **info_p, + uint32_t *count) { - PORT_INFO_2 *ports=NULL; + union spoolss_PortInfo *info = NULL; int i=0; WERROR result = WERR_OK; char **qlines = NULL; int numlines = 0; result = enumports_hook(talloc_tos(), &numlines, &qlines ); - if ( !W_ERROR_IS_OK(result)) { - TALLOC_FREE(qlines); - return result; + if (!W_ERROR_IS_OK(result)) { + goto out; } - if(numlines) { - if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) { - TALLOC_FREE(qlines); - return WERR_NOMEM; + if (numlines) { + info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines); + if (!info) { + DEBUG(10,("Returning WERR_NOMEM\n")); + result = WERR_NOMEM; + goto out; } for (i=0; i<numlines; i++) { DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i])); - fill_port_2(&(ports[i]), qlines[i]); + result = fill_port_2(info, &info[i].info2, qlines[i]); + if (!W_ERROR_IS_OK(result)) { + goto out; + } } } - TALLOC_FREE(qlines); - *returned = numlines; - - /* check the required size. */ - for (i=0; i<*returned; i++) { - DEBUGADD(6,("adding port [%d]'s size\n", i)); - *needed += spoolss_size_port_info_2(&ports[i]); - } - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; - } - - /* fill the buffer with the ports structures */ - for (i=0; i<*returned; i++) { - DEBUGADD(6,("adding port [%d] to buffer\n", i)); - smb_io_port_2("", buffer, &ports[i], 0); - } - out: - SAFE_FREE(ports); + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(info); + TALLOC_FREE(qlines); + *count = 0; + *info_p = NULL; + return result; + } - if ( !W_ERROR_IS_OK(result) ) - *returned = 0; + *info_p = info; + *count = numlines; - return result; + return WERR_OK; } -/**************************************************************************** - enumports. -****************************************************************************/ +/**************************************************************** + _spoolss_EnumPorts +****************************************************************/ -WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u) +WERROR _spoolss_EnumPorts(pipes_struct *p, + struct spoolss_EnumPorts *r) { - uint32 level = q_u->level; - RPC_BUFFER *buffer = NULL; - uint32 offered = q_u->offered; - uint32 *needed = &r_u->needed; - uint32 *returned = &r_u->returned; + WERROR result; /* that's an [in out] buffer */ - if (!q_u->buffer && (offered!=0)) { - return WERR_INVALID_PARAM; - } - - if (offered > MAX_RPC_DATA_SIZE) { + if (!r->in.buffer && (r->in.offered != 0)) { return WERR_INVALID_PARAM; } - rpcbuf_move(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + DEBUG(4,("_spoolss_EnumPorts\n")); - DEBUG(4,("_spoolss_enumports\n")); - - *returned=0; - *needed=0; + *r->out.count = 0; + *r->out.needed = 0; + *r->out.info = NULL; - switch (level) { + switch (r->in.level) { case 1: - return enumports_level_1(buffer, offered, needed, returned); + result = enumports_level_1(p->mem_ctx, r->out.info, + r->out.count); + break; case 2: - return enumports_level_2(buffer, offered, needed, returned); + result = enumports_level_2(p->mem_ctx, r->out.info, + r->out.count); + break; default: return WERR_UNKNOWN_LEVEL; } + + if (!W_ERROR_IS_OK(result)) { + return result; + } + + *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx, + spoolss_EnumPorts, NULL, + *r->out.info, r->in.level, + *r->out.count); + *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL); + *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0); + + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); } /**************************************************************************** @@ -7745,7 +7102,7 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p, struct spoolss_DeviceMode *devmode, struct security_descriptor *sec_desc, struct spoolss_UserLevelCtr *user_ctr, - POLICY_HND *handle) + struct policy_handle *handle) { NT_PRINTER_INFO_LEVEL *printer = NULL; fstring name; @@ -7758,7 +7115,7 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p, } /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/ - if (!convert_printer_info_new(info_ctr, printer)) { + if (!convert_printer_info(info_ctr, printer)) { free_a_printer(&printer, 2); return WERR_NOMEM; } @@ -7831,10 +7188,10 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p, */ DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n")); - if (!convert_devicemode_new(printer->info_2->printername, - devmode, - &printer->info_2->devmode)) + if (!convert_devicemode(printer->info_2->printername, devmode, + &printer->info_2->devmode)) { return WERR_NOMEM; + } } /* write the ASCII on disk */ @@ -8138,9 +7495,7 @@ static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx, static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx, const char *servername, const char *environment, - struct spoolss_DriverDirectoryInfo1 *r, - uint32_t offered, - uint32_t *needed) + struct spoolss_DriverDirectoryInfo1 *r) { WERROR werr; char *path = NULL; @@ -8158,13 +7513,6 @@ static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx, r->directory_name = path; - *needed += ndr_size_spoolss_DriverDirectoryInfo1(r, NULL, 0); - - if (*needed > offered) { - talloc_free(path); - return WERR_INSUFFICIENT_BUFFER; - } - return WERR_OK; } @@ -8193,39 +7541,28 @@ WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p, werror = getprinterdriverdir_level_1(p->mem_ctx, r->in.server, r->in.environment, - &r->out.info->info1, - r->in.offered, - r->out.needed); + &r->out.info->info1); if (!W_ERROR_IS_OK(werror)) { TALLOC_FREE(r->out.info); + return werror; } - return werror; + *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo, NULL, + r->out.info, r->in.level); + r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); + + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); } -/**************************************************************************** -****************************************************************************/ +/**************************************************************** + _spoolss_EnumPrinterData +****************************************************************/ -WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u) +WERROR _spoolss_EnumPrinterData(pipes_struct *p, + struct spoolss_EnumPrinterData *r) { - POLICY_HND *handle = &q_u->handle; - uint32 idx = q_u->index; - uint32 in_value_len = q_u->valuesize; - uint32 in_data_len = q_u->datasize; - uint32 *out_max_value_len = &r_u->valuesize; - uint16 **out_value = &r_u->value; - uint32 *out_value_len = &r_u->realvaluesize; - uint32 *out_type = &r_u->type; - uint32 *out_max_data_len = &r_u->datasize; - uint8 **data_out = &r_u->data; - uint32 *out_data_len = &r_u->realdatasize; - NT_PRINTER_INFO_LEVEL *printer = NULL; - - uint32 biggest_valuesize; - uint32 biggest_datasize; - uint32 data_len; - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); int snum; WERROR result; REGISTRY_VALUE *val = NULL; @@ -8233,25 +7570,26 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S int i, key_index, num_values; int name_length; - *out_type = 0; + *r->out.value_needed = 0; + *r->out.type = REG_NONE; + *r->out.data_needed = 0; - *out_max_data_len = 0; - *data_out = NULL; - *out_data_len = 0; - - DEBUG(5,("spoolss_enumprinterdata\n")); + DEBUG(5,("_spoolss_EnumPrinterData\n")); if (!Printer) { - DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); + DEBUG(2,("_spoolss_EnumPrinterData: Invalid handle (%s:%u:%u).\n", + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } - if (!get_printer_snum(p,handle, &snum, NULL)) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { return WERR_BADFID; + } result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); - if (!W_ERROR_IS_OK(result)) + if (!W_ERROR_IS_OK(result)) { return result; + } p_data = printer->info_2->data; key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY ); @@ -8264,12 +7602,12 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S * cf: MSDN EnumPrinterData remark section */ - if ( !in_value_len && !in_data_len && (key_index != -1) ) - { - DEBUGADD(6,("Activating NT mega-hack to find sizes\n")); + if (!r->in.value_offered && !r->in.data_offered && (key_index != -1)) { + + uint32_t biggest_valuesize = 0; + uint32_t biggest_datasize = 0; - biggest_valuesize = 0; - biggest_datasize = 0; + DEBUGADD(6,("Activating NT mega-hack to find sizes\n")); num_values = regval_ctr_numvals( p_data->keys[key_index].values ); @@ -8291,10 +7629,11 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S /* the value is an UNICODE string but real_value_size is the length in bytes including the trailing 0 */ - *out_value_len = 2 * (1+biggest_valuesize); - *out_data_len = biggest_datasize; + *r->out.value_needed = 2 * (1 + biggest_valuesize); + *r->out.data_needed = biggest_datasize; - DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len)); + DEBUG(6,("final values: [%d], [%d]\n", + *r->out.value_needed, *r->out.data_needed)); goto done; } @@ -8304,46 +7643,34 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S * that's the number of bytes not the number of unicode chars */ - if ( key_index != -1 ) - val = regval_ctr_specific_value( p_data->keys[key_index].values, idx ); + if (key_index != -1) { + val = regval_ctr_specific_value(p_data->keys[key_index].values, + r->in.enum_index); + } - if ( !val ) - { + if (!val) { /* out_value should default to "" or else NT4 has problems unmarshalling the response */ - *out_max_value_len=(in_value_len/sizeof(uint16)); - - if (in_value_len) { - if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL) - { + if (r->in.value_offered) { + *r->out.value_needed = 1; + r->out.value_name = talloc_strdup(r, ""); + if (!r->out.value_name) { result = WERR_NOMEM; goto done; } - *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0); } else { - *out_value=NULL; - *out_value_len = 0; + r->out.value_name = NULL; + *r->out.value_needed = 0; } /* the data is counted in bytes */ - *out_max_data_len = in_data_len; - *out_data_len = in_data_len; - - /* only allocate when given a non-zero data_len */ - - if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) ) - { - result = WERR_NOMEM; - goto done; - } + *r->out.data_needed = r->in.data_offered; result = WERR_NO_MORE_ITEMS; - } - else - { + } else { /* * the value is: * - counted in bytes in the request @@ -8354,36 +7681,29 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S */ /* name */ - *out_max_value_len=(in_value_len/sizeof(uint16)); - if (in_value_len) { - if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL ) - { + if (r->in.value_offered) { + r->out.value_name = talloc_strdup(r, regval_name(val)); + if (!r->out.value_name) { result = WERR_NOMEM; goto done; } - - *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0); + *r->out.value_needed = strlen_m(regval_name(val)); } else { - *out_value = NULL; - *out_value_len = 0; + r->out.value_name = NULL; + *r->out.value_needed = 0; } /* type */ - *out_type = regval_type( val ); + *r->out.type = regval_type(val); /* data - counted in bytes */ - *out_max_data_len = in_data_len; - if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) - { - result = WERR_NOMEM; - goto done; + if (r->out.data && regval_size(val)) { + memcpy(r->out.data, regval_data_p(val), regval_size(val)); } - data_len = regval_size(val); - if ( *data_out && data_len ) - memcpy( *data_out, regval_data_p(val), data_len ); - *out_data_len = data_len; + + *r->out.data_needed = regval_size(val); } done: @@ -8391,37 +7711,36 @@ done: return result; } -/**************************************************************************** -****************************************************************************/ +/**************************************************************** + _spoolss_SetPrinterData +****************************************************************/ -WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u) +WERROR _spoolss_SetPrinterData(pipes_struct *p, + struct spoolss_SetPrinterData *r) { - POLICY_HND *handle = &q_u->handle; - UNISTR2 *value = &q_u->value; - uint32 type = q_u->type; - uint8 *data = q_u->data; - uint32 real_len = q_u->real_len; - - NT_PRINTER_INFO_LEVEL *printer = NULL; - int snum=0; - WERROR status = WERR_OK; - Printer_entry *Printer=find_printer_index_by_hnd(p, handle); - fstring valuename; + NT_PRINTER_INFO_LEVEL *printer = NULL; + int snum=0; + WERROR result = WERR_OK; + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); + DATA_BLOB blob; - DEBUG(5,("spoolss_setprinterdata\n")); + DEBUG(5,("_spoolss_SetPrinterData\n")); if (!Printer) { - DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); + DEBUG(2,("_spoolss_SetPrinterData: Invalid handle (%s:%u:%u).\n", + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } - if ( Printer->printer_type == SPLHND_SERVER ) { - DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n")); + if (Printer->printer_type == SPLHND_SERVER) { + DEBUG(10,("_spoolss_SetPrinterData: " + "Not implemented for server handles yet\n")); return WERR_INVALID_PARAM; } - if (!get_printer_snum(p,handle, &snum, NULL)) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { return WERR_BADFID; + } /* * Access check : NT returns "access denied" if you make a @@ -8431,43 +7750,49 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP * when connecting to a printer --jerry */ - if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) - { - DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n")); - status = WERR_ACCESS_DENIED; + if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { + DEBUG(3,("_spoolss_SetPrinterData: " + "change denied by handle access permissions\n")); + result = WERR_ACCESS_DENIED; goto done; } - status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); - if (!W_ERROR_IS_OK(status)) - return status; + result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); + if (!W_ERROR_IS_OK(result)) { + return result; + } - unistr2_to_ascii(valuename, value, sizeof(valuename)); + result = push_spoolss_PrinterData(p->mem_ctx, &blob, + r->in.type, &r->in.data); + if (!W_ERROR_IS_OK(result)) { + goto done; + } /* * When client side code sets a magic printer data key, detect it and save * the current printer data and the magic key's data (its the DEVMODE) for * future printer/driver initializations. */ - if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY)) - { + if ((r->in.type == REG_BINARY) && strequal(r->in.value_name, PHANTOM_DEVMODE_KEY)) { /* Set devmode and printer initialization info */ - status = save_driver_init( printer, 2, data, real_len ); + result = save_driver_init(printer, 2, blob.data, blob.length); - srv_spoolss_reset_printerdata( printer->info_2->drivername ); + srv_spoolss_reset_printerdata(printer->info_2->drivername); + + goto done; } - else - { - status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename, - type, data, real_len ); - if ( W_ERROR_IS_OK(status) ) - status = mod_a_printer(printer, 2); + + result = set_printer_dataex(printer, SPOOL_PRINTERDATA_KEY, + r->in.value_name, r->in.type, + blob.data, blob.length); + if (W_ERROR_IS_OK(result)) { + result = mod_a_printer(printer, 2); } done: free_a_printer(&printer, 2); - return status; + return result; } /**************************************************************** @@ -8477,8 +7802,7 @@ done: WERROR _spoolss_ResetPrinter(pipes_struct *p, struct spoolss_ResetPrinter *r) { - POLICY_HND *handle = r->in.handle; - Printer_entry *Printer=find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); int snum; DEBUG(5,("_spoolss_ResetPrinter\n")); @@ -8491,11 +7815,11 @@ WERROR _spoolss_ResetPrinter(pipes_struct *p, if (!Printer) { DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n", - OUR_HANDLE(handle))); + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } - if (!get_printer_snum(p,handle, &snum, NULL)) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) return WERR_BADFID; @@ -8510,21 +7834,20 @@ WERROR _spoolss_ResetPrinter(pipes_struct *p, WERROR _spoolss_DeletePrinterData(pipes_struct *p, struct spoolss_DeletePrinterData *r) { - POLICY_HND *handle = r->in.handle; NT_PRINTER_INFO_LEVEL *printer = NULL; int snum=0; WERROR status = WERR_OK; - Printer_entry *Printer=find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); DEBUG(5,("_spoolss_DeletePrinterData\n")); if (!Printer) { DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n", - OUR_HANDLE(handle))); + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } - if (!get_printer_snum(p, handle, &snum, NULL)) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) return WERR_BADFID; if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { @@ -8560,7 +7883,6 @@ WERROR _spoolss_DeletePrinterData(pipes_struct *p, WERROR _spoolss_AddForm(pipes_struct *p, struct spoolss_AddForm *r) { - POLICY_HND *handle = r->in.handle; struct spoolss_AddFormInfo1 *form = r->in.info.info1; nt_forms_struct tmpForm; int snum; @@ -8569,13 +7891,13 @@ WERROR _spoolss_AddForm(pipes_struct *p, int count=0; nt_forms_struct *list=NULL; - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); DEBUG(5,("_spoolss_AddForm\n")); if (!Printer) { DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n", - OUR_HANDLE(handle))); + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } @@ -8584,7 +7906,7 @@ WERROR _spoolss_AddForm(pipes_struct *p, if ( Printer->printer_type == SPLHND_PRINTER ) { - if (!get_printer_snum(p,handle, &snum, NULL)) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) return WERR_BADFID; status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); @@ -8636,12 +7958,11 @@ done: WERROR _spoolss_DeleteForm(pipes_struct *p, struct spoolss_DeleteForm *r) { - POLICY_HND *handle = r->in.handle; const char *form_name = r->in.form_name; nt_forms_struct tmpForm; int count=0; nt_forms_struct *list=NULL; - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); int snum; WERROR status = WERR_OK; NT_PRINTER_INFO_LEVEL *printer = NULL; @@ -8650,7 +7971,7 @@ WERROR _spoolss_DeleteForm(pipes_struct *p, if (!Printer) { DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n", - OUR_HANDLE(handle))); + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } @@ -8658,7 +7979,7 @@ WERROR _spoolss_DeleteForm(pipes_struct *p, if ( Printer->printer_type == SPLHND_PRINTER ) { - if (!get_printer_snum(p,handle, &snum, NULL)) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) return WERR_BADFID; status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); @@ -8706,7 +8027,6 @@ done: WERROR _spoolss_SetForm(pipes_struct *p, struct spoolss_SetForm *r) { - POLICY_HND *handle = r->in.handle; struct spoolss_AddFormInfo1 *form = r->in.info.info1; nt_forms_struct tmpForm; int snum; @@ -8715,13 +8035,13 @@ WERROR _spoolss_SetForm(pipes_struct *p, int count=0; nt_forms_struct *list=NULL; - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); DEBUG(5,("_spoolss_SetForm\n")); if (!Printer) { DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n", - OUR_HANDLE(handle))); + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } @@ -8729,7 +8049,7 @@ WERROR _spoolss_SetForm(pipes_struct *p, if ( Printer->printer_type == SPLHND_PRINTER ) { - if (!get_printer_snum(p,handle, &snum, NULL)) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) return WERR_BADFID; status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); @@ -8770,69 +8090,68 @@ done: } /**************************************************************************** - enumprintprocessors level 1. + fill_print_processor1 ****************************************************************************/ -static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx, + struct spoolss_PrintProcessorInfo1 *r, + const char *print_processor_name) { - PRINTPROCESSOR_1 *info_1=NULL; - WERROR result = WERR_OK; + r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name); + W_ERROR_HAVE_NO_MEMORY(r->print_processor_name); - if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL) - return WERR_NOMEM; + return WERR_OK; +} - (*returned) = 0x1; +/**************************************************************************** + enumprintprocessors level 1. +****************************************************************************/ - init_unistr(&info_1->name, "winprint"); +static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx, + union spoolss_PrintProcessorInfo **info_p, + uint32_t *count) +{ + union spoolss_PrintProcessorInfo *info; + WERROR result; - *needed += spoolss_size_printprocessor_info_1(info_1); + info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1); + W_ERROR_HAVE_NO_MEMORY(info); - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } + *count = 1; - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; + result = fill_print_processor1(info, &info[0].info1, "winprint"); + if (!W_ERROR_IS_OK(result)) { goto out; } - smb_io_printprocessor_info_1("", buffer, info_1, 0); - -out: - SAFE_FREE(info_1); + out: + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(info); + *count = 0; + return result; + } - if ( !W_ERROR_IS_OK(result) ) - *returned = 0; + *info_p = info; - return result; + return WERR_OK; } -/**************************************************************************** -****************************************************************************/ +/**************************************************************** + _spoolss_EnumPrintProcessors +****************************************************************/ -WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u) +WERROR _spoolss_EnumPrintProcessors(pipes_struct *p, + struct spoolss_EnumPrintProcessors *r) { - uint32 level = q_u->level; - RPC_BUFFER *buffer = NULL; - uint32 offered = q_u->offered; - uint32 *needed = &r_u->needed; - uint32 *returned = &r_u->returned; + WERROR result; /* that's an [in out] buffer */ - if (!q_u->buffer && (offered!=0)) { - return WERR_INVALID_PARAM; - } - - if (offered > MAX_RPC_DATA_SIZE) { + if (!r->in.buffer && (r->in.offered != 0)) { return WERR_INVALID_PARAM; } - rpcbuf_move(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; - - DEBUG(5,("spoolss_enumprintprocessors\n")); + DEBUG(5,("_spoolss_EnumPrintProcessors\n")); /* * Enumerate the print processors ... @@ -8841,213 +8160,254 @@ WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS * and I can use my nice printer checker. */ - *returned=0; - *needed=0; + *r->out.count = 0; + *r->out.needed = 0; + *r->out.info = NULL; - switch (level) { + switch (r->in.level) { case 1: - return enumprintprocessors_level_1(buffer, offered, needed, returned); + result = enumprintprocessors_level_1(p->mem_ctx, r->out.info, + r->out.count); + break; default: return WERR_UNKNOWN_LEVEL; } + + if (!W_ERROR_IS_OK(result)) { + return result; + } + + *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx, + spoolss_EnumPrintProcessors, NULL, + *r->out.info, r->in.level, + *r->out.count); + *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL); + *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0); + + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); } /**************************************************************************** - enumprintprocdatatypes level 1. + fill_printprocdatatype1 ****************************************************************************/ -static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx, + struct spoolss_PrintProcDataTypesInfo1 *r, + const char *name_array) { - PRINTPROCDATATYPE_1 *info_1=NULL; - WERROR result = WERR_OK; + r->name_array = talloc_strdup(mem_ctx, name_array); + W_ERROR_HAVE_NO_MEMORY(r->name_array); - if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL) - return WERR_NOMEM; + return WERR_OK; +} + +/**************************************************************************** + enumprintprocdatatypes level 1. +****************************************************************************/ - (*returned) = 0x1; +static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx, + union spoolss_PrintProcDataTypesInfo **info_p, + uint32_t *count) +{ + WERROR result; + union spoolss_PrintProcDataTypesInfo *info; - init_unistr(&info_1->name, "RAW"); + info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1); + W_ERROR_HAVE_NO_MEMORY(info); - *needed += spoolss_size_printprocdatatype_info_1(info_1); + *count = 1; - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; + result = fill_printprocdatatype1(info, &info[0].info1, "RAW"); + if (!W_ERROR_IS_OK(result)) { goto out; } - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; + out: + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(info); + *count = 0; + return result; } - smb_io_printprocdatatype_info_1("", buffer, info_1, 0); + *info_p = info; -out: - SAFE_FREE(info_1); - - if ( !W_ERROR_IS_OK(result) ) - *returned = 0; - - return result; + return WERR_OK; } -/**************************************************************************** -****************************************************************************/ +/**************************************************************** + _spoolss_EnumPrintProcDataTypes +****************************************************************/ -WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u) +WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p, + struct spoolss_EnumPrintProcDataTypes *r) { - uint32 level = q_u->level; - RPC_BUFFER *buffer = NULL; - uint32 offered = q_u->offered; - uint32 *needed = &r_u->needed; - uint32 *returned = &r_u->returned; + WERROR result; /* that's an [in out] buffer */ - if (!q_u->buffer && (offered!=0)) { - return WERR_INVALID_PARAM; - } - - if (offered > MAX_RPC_DATA_SIZE) { + if (!r->in.buffer && (r->in.offered != 0)) { return WERR_INVALID_PARAM; } - rpcbuf_move(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; - - DEBUG(5,("_spoolss_enumprintprocdatatypes\n")); + DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n")); - *returned=0; - *needed=0; + *r->out.count = 0; + *r->out.needed = 0; + *r->out.info = NULL; - switch (level) { + switch (r->in.level) { case 1: - return enumprintprocdatatypes_level_1(buffer, offered, needed, returned); + result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info, + r->out.count); + break; default: return WERR_UNKNOWN_LEVEL; } + + *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx, + spoolss_EnumPrintProcDataTypes, NULL, + *r->out.info, r->in.level, + *r->out.count); + *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL); + *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0); + + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); } /**************************************************************************** - enumprintmonitors level 1. + fill_monitor_1 ****************************************************************************/ -static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx, + struct spoolss_MonitorInfo1 *r, + const char *monitor_name) { - PRINTMONITOR_1 *info_1; - WERROR result = WERR_OK; - int i; + r->monitor_name = talloc_strdup(mem_ctx, monitor_name); + W_ERROR_HAVE_NO_MEMORY(r->monitor_name); - if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL) - return WERR_NOMEM; + return WERR_OK; +} - *returned = 2; +/**************************************************************************** + fill_monitor_2 +****************************************************************************/ - init_unistr(&(info_1[0].name), SPL_LOCAL_PORT ); - init_unistr(&(info_1[1].name), SPL_TCPIP_PORT ); +static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx, + struct spoolss_MonitorInfo2 *r, + const char *monitor_name, + const char *environment, + const char *dll_name) +{ + r->monitor_name = talloc_strdup(mem_ctx, monitor_name); + W_ERROR_HAVE_NO_MEMORY(r->monitor_name); + r->environment = talloc_strdup(mem_ctx, environment); + W_ERROR_HAVE_NO_MEMORY(r->environment); + r->dll_name = talloc_strdup(mem_ctx, dll_name); + W_ERROR_HAVE_NO_MEMORY(r->dll_name); - for ( i=0; i<*returned; i++ ) { - *needed += spoolss_size_printmonitor_info_1(&info_1[i]); - } + return WERR_OK; +} - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } +/**************************************************************************** + enumprintmonitors level 1. +****************************************************************************/ - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; +static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx, + union spoolss_MonitorInfo **info_p, + uint32_t *count) +{ + union spoolss_MonitorInfo *info; + WERROR result = WERR_OK; + + info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2); + W_ERROR_HAVE_NO_MEMORY(info); + + *count = 2; + + result = fill_monitor_1(info, &info[0].info1, + SPL_LOCAL_PORT); + if (!W_ERROR_IS_OK(result)) { goto out; } - for ( i=0; i<*returned; i++ ) { - smb_io_printmonitor_info_1("", buffer, &info_1[i], 0); + result = fill_monitor_1(info, &info[1].info1, + SPL_TCPIP_PORT); + if (!W_ERROR_IS_OK(result)) { + goto out; } out: - SAFE_FREE(info_1); + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(info); + *count = 0; + return result; + } - if ( !W_ERROR_IS_OK(result) ) - *returned = 0; + *info_p = info; - return result; + return WERR_OK; } /**************************************************************************** enumprintmonitors level 2. ****************************************************************************/ -static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx, + union spoolss_MonitorInfo **info_p, + uint32_t *count) { - PRINTMONITOR_2 *info_2; + union spoolss_MonitorInfo *info; WERROR result = WERR_OK; - int i; - - if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL) - return WERR_NOMEM; - - *returned = 2; - init_unistr( &(info_2[0].name), SPL_LOCAL_PORT ); - init_unistr( &(info_2[0].environment), "Windows NT X86" ); - init_unistr( &(info_2[0].dll_name), "localmon.dll" ); + info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2); + W_ERROR_HAVE_NO_MEMORY(info); - init_unistr( &(info_2[1].name), SPL_TCPIP_PORT ); - init_unistr( &(info_2[1].environment), "Windows NT X86" ); - init_unistr( &(info_2[1].dll_name), "tcpmon.dll" ); + *count = 2; - for ( i=0; i<*returned; i++ ) { - *needed += spoolss_size_printmonitor_info_2(&info_2[i]); - } - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; + result = fill_monitor_2(info, &info[0].info2, + SPL_LOCAL_PORT, + "Windows NT X86", /* FIXME */ + "localmon.dll"); + if (!W_ERROR_IS_OK(result)) { goto out; } - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; + result = fill_monitor_2(info, &info[1].info2, + SPL_TCPIP_PORT, + "Windows NT X86", /* FIXME */ + "tcpmon.dll"); + if (!W_ERROR_IS_OK(result)) { goto out; } - for ( i=0; i<*returned; i++ ) { - smb_io_printmonitor_info_2("", buffer, &info_2[i], 0); - } - out: - SAFE_FREE(info_2); + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(info); + *count = 0; + return result; + } - if ( !W_ERROR_IS_OK(result) ) - *returned = 0; + *info_p = info; - return result; + return WERR_OK; } -/**************************************************************************** -****************************************************************************/ +/**************************************************************** + _spoolss_EnumMonitors +****************************************************************/ -WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u) +WERROR _spoolss_EnumMonitors(pipes_struct *p, + struct spoolss_EnumMonitors *r) { - uint32 level = q_u->level; - RPC_BUFFER *buffer = NULL; - uint32 offered = q_u->offered; - uint32 *needed = &r_u->needed; - uint32 *returned = &r_u->returned; + WERROR result; /* that's an [in out] buffer */ - if (!q_u->buffer && (offered!=0)) { - return WERR_INVALID_PARAM; - } - - if (offered > MAX_RPC_DATA_SIZE) { + if (!r->in.buffer && (r->in.offered != 0)) { return WERR_INVALID_PARAM; } - rpcbuf_move(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; - - DEBUG(5,("spoolss_enumprintmonitors\n")); + DEBUG(5,("_spoolss_EnumMonitors\n")); /* * Enumerate the print monitors ... @@ -9056,102 +8416,95 @@ WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_ * and I can use my nice printer checker. */ - *returned=0; - *needed=0; + *r->out.count = 0; + *r->out.needed = 0; + *r->out.info = NULL; - switch (level) { + switch (r->in.level) { case 1: - return enumprintmonitors_level_1(buffer, offered, needed, returned); + result = enumprintmonitors_level_1(p->mem_ctx, r->out.info, + r->out.count); + break; case 2: - return enumprintmonitors_level_2(buffer, offered, needed, returned); + result = enumprintmonitors_level_2(p->mem_ctx, r->out.info, + r->out.count); + break; default: return WERR_UNKNOWN_LEVEL; } + + if (!W_ERROR_IS_OK(result)) { + return result; + } + + *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx, + spoolss_EnumMonitors, NULL, + *r->out.info, r->in.level, + *r->out.count); + *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL); + *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0); + + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); } /**************************************************************************** ****************************************************************************/ -static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, - NT_PRINTER_INFO_LEVEL *ntprinter, - uint32 jobid, RPC_BUFFER *buffer, uint32 offered, - uint32 *needed) +static WERROR getjob_level_1(TALLOC_CTX *mem_ctx, + const print_queue_struct *queue, + int count, int snum, + const NT_PRINTER_INFO_LEVEL *ntprinter, + uint32_t jobid, + struct spoolss_JobInfo1 *r) { - int i=0; - bool found=False; - JOB_INFO_1 *info_1=NULL; - WERROR result = WERR_OK; - - info_1=SMB_MALLOC_P(JOB_INFO_1); + int i = 0; + bool found = false; - if (info_1 == NULL) { - return WERR_NOMEM; - } - - for (i=0; i<count && found==False; i++) { - if ((*queue)[i].job==(int)jobid) - found=True; + for (i=0; i<count && found == false; i++) { + if (queue[i].job == (int)jobid) { + found = true; + } } - if (found==False) { - SAFE_FREE(info_1); + if (found == false) { /* NT treats not found as bad param... yet another bad choice */ return WERR_INVALID_PARAM; } - fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter ); - - *needed += spoolss_size_job_info_1(info_1); - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto out; - } - - smb_io_job_info_1("", buffer, info_1, 0); - -out: - SAFE_FREE(info_1); - - return result; + return fill_job_info1(mem_ctx, + r, + &queue[i-1], + i, + snum, + ntprinter); } /**************************************************************************** ****************************************************************************/ -static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, - NT_PRINTER_INFO_LEVEL *ntprinter, - uint32 jobid, RPC_BUFFER *buffer, uint32 offered, - uint32 *needed) -{ - int i = 0; - bool found = False; - JOB_INFO_2 *info_2; - WERROR result; - DEVICEMODE *devmode = NULL; - NT_DEVICEMODE *nt_devmode = NULL; - - if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) ) - return WERR_NOMEM; - - ZERO_STRUCTP(info_2); +static WERROR getjob_level_2(TALLOC_CTX *mem_ctx, + const print_queue_struct *queue, + int count, int snum, + const NT_PRINTER_INFO_LEVEL *ntprinter, + uint32_t jobid, + struct spoolss_JobInfo2 *r) +{ + int i = 0; + bool found = false; + struct spoolss_DeviceMode *devmode; + NT_DEVICEMODE *nt_devmode; + WERROR result; - for ( i=0; i<count && found==False; i++ ) - { - if ((*queue)[i].job == (int)jobid) - found = True; + for (i=0; i<count && found == false; i++) { + if (queue[i].job == (int)jobid) { + found = true; + } } - if ( !found ) { + if (found == false) { /* NT treats not found as bad param... yet another bad choice */ - result = WERR_INVALID_PARAM; - goto done; + return WERR_INVALID_PARAM; } /* @@ -9160,54 +8513,36 @@ static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, * a failure condition */ - if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) ) - devmode = construct_dev_mode(lp_const_servicename(snum)); - else { - if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) { - ZERO_STRUCTP( devmode ); - convert_nt_devicemode( devmode, nt_devmode ); + nt_devmode = print_job_devmode(lp_const_servicename(snum), jobid); + if (nt_devmode) { + devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode); + W_ERROR_HAVE_NO_MEMORY(devmode); + result = convert_nt_devicemode(devmode, devmode, nt_devmode); + if (!W_ERROR_IS_OK(result)) { + return result; } + } else { + devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum)); + W_ERROR_HAVE_NO_MEMORY(devmode); } - fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode); - - *needed += spoolss_size_job_info_2(info_2); - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto done; - } - - if (!rpcbuf_alloc_size(buffer, *needed)) { - result = WERR_NOMEM; - goto done; - } - - smb_io_job_info_2("", buffer, info_2, 0); - - result = WERR_OK; - - done: - /* Cleanup allocated memory */ - - free_job_info_2(info_2); /* Also frees devmode */ - SAFE_FREE(info_2); - - return result; + return fill_job_info2(mem_ctx, + r, + &queue[i-1], + i, + snum, + ntprinter, + devmode); } -/**************************************************************************** -****************************************************************************/ +/**************************************************************** + _spoolss_GetJob +****************************************************************/ -WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u) +WERROR _spoolss_GetJob(pipes_struct *p, + struct spoolss_GetJob *r) { - POLICY_HND *handle = &q_u->handle; - uint32 jobid = q_u->jobid; - uint32 level = q_u->level; - RPC_BUFFER *buffer = NULL; - uint32 offered = q_u->offered; - uint32 *needed = &r_u->needed; - WERROR wstatus = WERR_OK; + WERROR result = WERR_OK; NT_PRINTER_INFO_LEVEL *ntprinter = NULL; int snum; int count; @@ -9216,51 +8551,57 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_ /* that's an [in out] buffer */ - if (!q_u->buffer && (offered!=0)) { - return WERR_INVALID_PARAM; - } - - if (offered > MAX_RPC_DATA_SIZE) { + if (!r->in.buffer && (r->in.offered != 0)) { return WERR_INVALID_PARAM; } - rpcbuf_move(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; - - DEBUG(5,("spoolss_getjob\n")); + DEBUG(5,("_spoolss_GetJob\n")); - *needed = 0; + *r->out.needed = 0; - if (!get_printer_snum(p, handle, &snum, NULL)) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { return WERR_BADFID; + } - wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum)); - if ( !W_ERROR_IS_OK(wstatus) ) - return wstatus; + result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum)); + if (!W_ERROR_IS_OK(result)) { + return result; + } count = print_queue_status(snum, &queue, &prt_status); DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n", count, prt_status.status, prt_status.message)); - switch ( level ) { + switch (r->in.level) { case 1: - wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid, - buffer, offered, needed); - break; + result = getjob_level_1(p->mem_ctx, + queue, count, snum, ntprinter, + r->in.job_id, &r->out.info->info1); + break; case 2: - wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid, - buffer, offered, needed); - break; + result = getjob_level_2(p->mem_ctx, + queue, count, snum, ntprinter, + r->in.job_id, &r->out.info->info2); + break; default: - wstatus = WERR_UNKNOWN_LEVEL; - break; + result = WERR_UNKNOWN_LEVEL; + break; } SAFE_FREE(queue); - free_a_printer( &ntprinter, 2 ); + free_a_printer(&ntprinter, 2); + + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(r->out.info); + return result; + } + + *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, NULL, + r->out.info, r->in.level); + r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); - return wstatus; + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); } /**************************************************************** @@ -9273,31 +8614,27 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_ WERROR _spoolss_GetPrinterDataEx(pipes_struct *p, struct spoolss_GetPrinterDataEx *r) { - POLICY_HND *handle = r->in.handle; - uint8 *data = NULL; - const char *keyname = r->in.key_name; - const char *valuename = r->in.value_name; - - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); + REGISTRY_VALUE *val = NULL; NT_PRINTER_INFO_LEVEL *printer = NULL; int snum = 0; - WERROR status = WERR_OK; + WERROR result = WERR_OK; DEBUG(4,("_spoolss_GetPrinterDataEx\n")); DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n", - keyname, valuename)); + r->in.key_name, r->in.value_name)); /* in case of problem, return some default values */ *r->out.needed = 0; - *r->out.type = 0; + *r->out.type = REG_NONE; if (!Printer) { - DEBUG(2,("_spoolss_GetPrinterDataEx: " - "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); - status = WERR_BADFID; + DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n", + OUR_HANDLE(r->in.handle))); + result = WERR_BADFID; goto done; } @@ -9306,50 +8643,58 @@ WERROR _spoolss_GetPrinterDataEx(pipes_struct *p, if (Printer->printer_type == SPLHND_SERVER) { DEBUG(10,("_spoolss_GetPrinterDataEx: " "Not implemented for server handles yet\n")); - status = WERR_INVALID_PARAM; + result = WERR_INVALID_PARAM; goto done; } - if ( !get_printer_snum(p,handle, &snum, NULL) ) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { return WERR_BADFID; + } - status = get_a_printer(Printer, &printer, 2, lp_servicename(snum)); - if ( !W_ERROR_IS_OK(status) ) + result = get_a_printer(Printer, &printer, 2, lp_servicename(snum)); + if (!W_ERROR_IS_OK(result)) { goto done; + } /* check to see if the keyname is valid */ - if ( !strlen(keyname) ) { - status = WERR_INVALID_PARAM; + if (!strlen(r->in.key_name)) { + result = WERR_INVALID_PARAM; goto done; } - if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) { + if (lookup_printerkey(printer->info_2->data, r->in.key_name) == -1) { DEBUG(4,("_spoolss_GetPrinterDataEx: " - "Invalid keyname [%s]\n", keyname )); - free_a_printer( &printer, 2 ); - status = WERR_BADFILE; + "Invalid keyname [%s]\n", r->in.key_name )); + result = WERR_BADFILE; goto done; } /* When given a new keyname, we should just create it */ - status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename, - r->out.type, &data, r->out.needed, - r->in.offered ); + val = get_printer_data(printer->info_2, + r->in.key_name, r->in.value_name); + if (!val) { + result = WERR_BADFILE; + goto done; + } + + *r->out.needed = regval_size(val); if (*r->out.needed > r->in.offered) { - status = WERR_MORE_DATA; + result = WERR_MORE_DATA; + goto done; } - if (W_ERROR_IS_OK(status)) { - memcpy(r->out.buffer, data, r->in.offered); - } + *r->out.type = regval_type(val); -done: - if ( printer ) - free_a_printer( &printer, 2 ); + memcpy(r->out.buffer, regval_data_p(val), regval_size(val)); - return status; + done: + if (printer) { + free_a_printer(&printer, 2); + } + + return result; } /**************************************************************** @@ -9359,11 +8704,10 @@ done: WERROR _spoolss_SetPrinterDataEx(pipes_struct *p, struct spoolss_SetPrinterDataEx *r) { - POLICY_HND *handle = r->in.handle; NT_PRINTER_INFO_LEVEL *printer = NULL; int snum = 0; - WERROR status = WERR_OK; - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + WERROR result = WERR_OK; + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); char *oid_string; DEBUG(4,("_spoolss_SetPrinterDataEx\n")); @@ -9372,19 +8716,20 @@ WERROR _spoolss_SetPrinterDataEx(pipes_struct *p, SetPrinterData if key is "PrinterDriverData" */ if (!Printer) { - DEBUG(2,("_spoolss_SetPrinterDataEx: " - "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); + DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n", + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } - if ( Printer->printer_type == SPLHND_SERVER ) { + if (Printer->printer_type == SPLHND_SERVER) { DEBUG(10,("_spoolss_SetPrinterDataEx: " "Not implemented for server handles yet\n")); return WERR_INVALID_PARAM; } - if ( !get_printer_snum(p,handle, &snum, NULL) ) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { return WERR_BADFID; + } /* * Access check : NT returns "access denied" if you make a @@ -9394,38 +8739,38 @@ WERROR _spoolss_SetPrinterDataEx(pipes_struct *p, * when connecting to a printer --jerry */ - if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) - { + if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { DEBUG(3, ("_spoolss_SetPrinterDataEx: " "change denied by handle access permissions\n")); return WERR_ACCESS_DENIED; } - status = get_a_printer(Printer, &printer, 2, lp_servicename(snum)); - if (!W_ERROR_IS_OK(status)) - return status; + result = get_a_printer(Printer, &printer, 2, lp_servicename(snum)); + if (!W_ERROR_IS_OK(result)) { + return result; + } /* check for OID in valuename */ - if ( (oid_string = strchr( r->in.value_name, ',' )) != NULL ) - { + oid_string = strchr(r->in.value_name, ','); + if (oid_string) { *oid_string = '\0'; oid_string++; } /* save the registry data */ - status = set_printer_dataex( printer, r->in.key_name, r->in.value_name, - r->in.type, r->in.buffer, r->in.offered ); + result = set_printer_dataex(printer, r->in.key_name, r->in.value_name, + r->in.type, r->in.buffer, r->in.offered); - if ( W_ERROR_IS_OK(status) ) - { + if (W_ERROR_IS_OK(result)) { /* save the OID if one was specified */ - if ( oid_string ) { + if (oid_string) { char *str = talloc_asprintf(p->mem_ctx, "%s\\%s", r->in.key_name, SPOOL_OID_KEY); if (!str) { - return WERR_NOMEM; + result = WERR_NOMEM; + goto done; } /* @@ -9435,17 +8780,18 @@ WERROR _spoolss_SetPrinterDataEx(pipes_struct *p, * this is right. --jerry */ - set_printer_dataex( printer, str, r->in.value_name, - REG_SZ, (uint8 *)oid_string, - strlen(oid_string)+1 ); + set_printer_dataex(printer, str, r->in.value_name, + REG_SZ, (uint8_t *)oid_string, + strlen(oid_string)+1); } - status = mod_a_printer(printer, 2); + result = mod_a_printer(printer, 2); } + done: free_a_printer(&printer, 2); - return status; + return result; } /**************************************************************** @@ -9455,21 +8801,21 @@ WERROR _spoolss_SetPrinterDataEx(pipes_struct *p, WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p, struct spoolss_DeletePrinterDataEx *r) { - POLICY_HND *handle = r->in.handle; NT_PRINTER_INFO_LEVEL *printer = NULL; int snum=0; WERROR status = WERR_OK; - Printer_entry *Printer=find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); DEBUG(5,("_spoolss_DeletePrinterDataEx\n")); if (!Printer) { DEBUG(2,("_spoolss_DeletePrinterDataEx: " - "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); + "Invalid handle (%s:%u:%u).\n", + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } - if (!get_printer_snum(p, handle, &snum, NULL)) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) return WERR_BADFID; if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { @@ -9496,76 +8842,88 @@ WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p, return status; } -/******************************************************************** - * spoolss_enumprinterkey - ********************************************************************/ - +/**************************************************************** + _spoolss_EnumPrinterKey +****************************************************************/ -WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u) +WERROR _spoolss_EnumPrinterKey(pipes_struct *p, + struct spoolss_EnumPrinterKey *r) { - fstring key; fstring *keynames = NULL; - uint16 *enumkeys = NULL; int num_keys; - int printerkey_len; - POLICY_HND *handle = &q_u->handle; - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); NT_PRINTER_DATA *data; NT_PRINTER_INFO_LEVEL *printer = NULL; int snum = 0; - WERROR status = WERR_BADFILE; + WERROR result = WERR_BADFILE; + int i; + const char **array = NULL; - DEBUG(4,("_spoolss_enumprinterkey\n")); + DEBUG(4,("_spoolss_EnumPrinterKey\n")); if (!Printer) { - DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); + DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n", + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } - if ( !get_printer_snum(p,handle, &snum, NULL) ) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { return WERR_BADFID; + } - status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); - if (!W_ERROR_IS_OK(status)) - return status; + result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); + if (!W_ERROR_IS_OK(result)) { + return result; + } /* get the list of subkey names */ - unistr2_to_ascii(key, &q_u->key, sizeof(key)); data = printer->info_2->data; - num_keys = get_printer_subkeys( data, key, &keynames ); - - if ( num_keys == -1 ) { - status = WERR_BADFILE; + num_keys = get_printer_subkeys(data, r->in.key_name, &keynames); + if (num_keys == -1) { + result = WERR_BADFILE; goto done; } - printerkey_len = init_unistr_array( &enumkeys, keynames, NULL ); - - r_u->needed = printerkey_len*2; + *r->out.needed = 4; - if ( q_u->size < r_u->needed ) { - status = WERR_MORE_DATA; + array = talloc_zero_array(r->out.key_buffer, const char *, num_keys + 1); + if (!array) { + result = WERR_NOMEM; goto done; } - if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) { - status = WERR_NOMEM; + for (i=0; i < num_keys; i++) { + array[i] = talloc_strdup(array, keynames[i]); + if (!array[i]) { + result = WERR_NOMEM; + goto done; + } + + *r->out.needed += strlen_m_term(keynames[i]) * 2; + } + + if (r->in.offered < *r->out.needed) { + result = WERR_MORE_DATA; goto done; } - status = WERR_OK; + result = WERR_OK; - if ( q_u->size < r_u->needed ) - status = WERR_MORE_DATA; + *r->out.key_buffer = array; -done: - free_a_printer( &printer, 2 ); - SAFE_FREE( keynames ); + done: + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(array); + ZERO_STRUCTP(r->out.key_buffer); + } + + free_a_printer(&printer, 2); + SAFE_FREE(keynames); - return status; + return result; } /**************************************************************** @@ -9575,8 +8933,7 @@ done: WERROR _spoolss_DeletePrinterKey(pipes_struct *p, struct spoolss_DeletePrinterKey *r) { - POLICY_HND *handle = r->in.handle; - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); NT_PRINTER_INFO_LEVEL *printer = NULL; int snum=0; WERROR status; @@ -9585,7 +8942,7 @@ WERROR _spoolss_DeletePrinterKey(pipes_struct *p, if (!Printer) { DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n", - OUR_HANDLE(handle))); + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } @@ -9594,7 +8951,7 @@ WERROR _spoolss_DeletePrinterKey(pipes_struct *p, if ( !r->in.key_name ) return WERR_INVALID_PARAM; - if (!get_printer_snum(p, handle, &snum, NULL)) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) return WERR_BADFID; if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { @@ -9619,35 +8976,64 @@ WERROR _spoolss_DeletePrinterKey(pipes_struct *p, return status; } +/**************************************************************** +****************************************************************/ -/******************************************************************** - * spoolss_enumprinterdataex - ********************************************************************/ +static WERROR registry_value_to_printer_enum_value(TALLOC_CTX *mem_ctx, + REGISTRY_VALUE *v, + struct spoolss_PrinterEnumValues *r) +{ + WERROR result; + + r->data = TALLOC_ZERO_P(mem_ctx, union spoolss_PrinterData); + W_ERROR_HAVE_NO_MEMORY(r->data); + + r->value_name = talloc_strdup(mem_ctx, regval_name(v)); + W_ERROR_HAVE_NO_MEMORY(r->value_name); + + r->type = regval_type(v); + r->data_length = regval_size(v); + + if (r->data_length) { + DATA_BLOB blob = data_blob_const(regval_data_p(v), + regval_size(v)); + result = pull_spoolss_PrinterData(mem_ctx, &blob, + r->data, + r->type); + if (!W_ERROR_IS_OK(result)) { + return result; + } + } + + return WERR_OK; +} -WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u) +/**************************************************************** + _spoolss_EnumPrinterDataEx +****************************************************************/ + +WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p, + struct spoolss_EnumPrinterDataEx *r) { - POLICY_HND *handle = &q_u->handle; - uint32 in_size = q_u->size; - uint32 num_entries, - needed; + uint32_t count = 0; NT_PRINTER_INFO_LEVEL *printer = NULL; - PRINTER_ENUM_VALUES *enum_values = NULL; + struct spoolss_PrinterEnumValues *info = NULL; NT_PRINTER_DATA *p_data; - fstring key; - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); int snum; WERROR result; int key_index; int i; - REGISTRY_VALUE *val; - char *value_name; - uint32 data_len; + DEBUG(4,("_spoolss_EnumPrinterDataEx\n")); - DEBUG(4,("_spoolss_enumprinterdataex\n")); + *r->out.count = 0; + *r->out.needed = 0; + *r->out.info = NULL; if (!Printer) { - DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle))); + DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n", + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } @@ -9658,51 +9044,50 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_ * --jerry */ - unistr2_to_ascii(key, &q_u->key, sizeof(key)); - if ( !strlen(key) ) { + if (!strlen(r->in.key_name)) { result = WERR_INVALID_PARAM; goto done; } /* get the printer off of disk */ - if (!get_printer_snum(p,handle, &snum, NULL)) + if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { return WERR_BADFID; + } ZERO_STRUCT(printer); result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); - if (!W_ERROR_IS_OK(result)) + if (!W_ERROR_IS_OK(result)) { return result; + } /* now look for a match on the key name */ p_data = printer->info_2->data; - unistr2_to_ascii(key, &q_u->key, sizeof(key)); - if ( (key_index = lookup_printerkey( p_data, key)) == -1 ) - { - DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key)); + key_index = lookup_printerkey(p_data, r->in.key_name); + if (key_index == -1) { + DEBUG(10,("_spoolss_EnumPrinterDataEx: Unknown keyname [%s]\n", + r->in.key_name)); result = WERR_INVALID_PARAM; goto done; } - result = WERR_OK; - needed = 0; - /* allocate the memory for the array of pointers -- if necessary */ - num_entries = regval_ctr_numvals( p_data->keys[key_index].values ); - if ( num_entries ) - { - if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL ) - { - DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n", - (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES))); - result = WERR_NOMEM; - goto done; - } + count = regval_ctr_numvals(p_data->keys[key_index].values); + if (!count) { + result = WERR_OK; /* ??? */ + goto done; + } - memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) ); + info = TALLOC_ZERO_ARRAY(p->mem_ctx, + struct spoolss_PrinterEnumValues, + count); + if (!info) { + DEBUG(0,("_spoolss_EnumPrinterDataEx: talloc() failed\n")); + result = WERR_NOMEM; + goto done; } /* @@ -9710,37 +9095,25 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_ * back to the client */ - for ( i=0; i<num_entries; i++ ) - { - /* lookup the registry value */ + for (i=0; i < count; i++) { - val = regval_ctr_specific_value( p_data->keys[key_index].values, i ); - DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) )); + REGISTRY_VALUE *val; - /* copy the data */ + /* lookup the registry value */ - value_name = regval_name( val ); - init_unistr( &enum_values[i].valuename, value_name ); - enum_values[i].value_len = (strlen(value_name)+1) * 2; - enum_values[i].type = regval_type( val ); + val = regval_ctr_specific_value(p_data->keys[key_index].values, i); - data_len = regval_size( val ); - if ( data_len ) { - if ( !(enum_values[i].data = (uint8 *)TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) ) - { - DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n", - data_len )); - result = WERR_NOMEM; - goto done; - } - } - enum_values[i].data_len = data_len; + DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val))); - /* keep track of the size of the array in bytes */ + /* copy the data */ - needed += spoolss_size_printer_enum_values(&enum_values[i]); + result = registry_value_to_printer_enum_value(info, val, &info[i]); + if (!W_ERROR_IS_OK(result)) { + goto done; + } } +#if 0 /* FIXME - gd */ /* housekeeping information in the reply */ /* Fix from Martin Zielinski <mz@seh.de> - ensure @@ -9751,32 +9124,28 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_ if (needed % 4) { needed += 4-(needed % 4); } +#endif + *r->out.count = count; + *r->out.info = info; - r_u->needed = needed; - r_u->returned = num_entries; + done: - if (needed > in_size) { - result = WERR_MORE_DATA; - goto done; + if (printer) { + free_a_printer(&printer, 2); } - /* copy data into the reply */ - - /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the - response buffer size is != the offered buffer size - - r_u->ctr.size = r_u->needed; - */ - r_u->ctr.size = in_size; - - r_u->ctr.size_of_array = r_u->returned; - r_u->ctr.values = enum_values; + if (!W_ERROR_IS_OK(result)) { + return result; + } -done: - if ( printer ) - free_a_printer(&printer, 2); + *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx, + spoolss_EnumPrinterDataEx, NULL, + *r->out.info, + *r->out.count); + *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL); + *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count); - return result; + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA); } /**************************************************************************** @@ -9785,9 +9154,7 @@ done: static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx, const char *servername, const char *environment, - struct spoolss_PrintProcessorDirectoryInfo1 *r, - uint32_t offered, - uint32_t *needed) + struct spoolss_PrintProcessorDirectoryInfo1 *r) { WERROR werr; char *path = NULL; @@ -9805,13 +9172,6 @@ static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx, r->directory_name = path; - *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(r, NULL, 0); - - if (*needed > offered) { - talloc_free(path); - return WERR_INSUFFICIENT_BUFFER; - } - return WERR_OK; } @@ -9840,14 +9200,17 @@ WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p, result = getprintprocessordirectory_level_1(p->mem_ctx, r->in.server, r->in.environment, - &r->out.info->info1, - r->in.offered, - r->out.needed); + &r->out.info->info1); if (!W_ERROR_IS_OK(result)) { TALLOC_FREE(r->out.info); + return result; } - return result; + *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo, NULL, + r->out.info, r->in.level); + r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); + + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); } /******************************************************************* @@ -10103,7 +9466,7 @@ WERROR _spoolss_XcvData(pipes_struct *p, struct spoolss_XcvData *r) { Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); - DATA_BLOB out_data; + DATA_BLOB out_data = data_blob_null; WERROR werror; if (!Printer) { @@ -10181,39 +9544,6 @@ WERROR _spoolss_AddPrintProcessor(pipes_struct *p, } /**************************************************************** - _spoolss_EnumPrinters -****************************************************************/ - -WERROR _spoolss_EnumPrinters(pipes_struct *p, - struct spoolss_EnumPrinters *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** - _spoolss_GetJob -****************************************************************/ - -WERROR _spoolss_GetJob(pipes_struct *p, - struct spoolss_GetJob *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** - _spoolss_EnumJobs -****************************************************************/ - -WERROR _spoolss_EnumJobs(pipes_struct *p, - struct spoolss_EnumJobs *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** _spoolss_AddPrinter ****************************************************************/ @@ -10225,28 +9555,6 @@ WERROR _spoolss_AddPrinter(pipes_struct *p, } /**************************************************************** - _spoolss_GetPrinter -****************************************************************/ - -WERROR _spoolss_GetPrinter(pipes_struct *p, - struct spoolss_GetPrinter *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** - _spoolss_EnumPrinterDrivers -****************************************************************/ - -WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p, - struct spoolss_EnumPrinterDrivers *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** _spoolss_GetPrinterDriver ****************************************************************/ @@ -10258,17 +9566,6 @@ WERROR _spoolss_GetPrinterDriver(pipes_struct *p, } /**************************************************************** - _spoolss_EnumPrintProcessors -****************************************************************/ - -WERROR _spoolss_EnumPrintProcessors(pipes_struct *p, - struct spoolss_EnumPrintProcessors *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** _spoolss_ReadPrinter ****************************************************************/ @@ -10280,28 +9577,6 @@ WERROR _spoolss_ReadPrinter(pipes_struct *p, } /**************************************************************** - _spoolss_GetPrinterData -****************************************************************/ - -WERROR _spoolss_GetPrinterData(pipes_struct *p, - struct spoolss_GetPrinterData *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** - _spoolss_SetPrinterData -****************************************************************/ - -WERROR _spoolss_SetPrinterData(pipes_struct *p, - struct spoolss_SetPrinterData *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** _spoolss_WaitForPrinterChange ****************************************************************/ @@ -10313,39 +9588,6 @@ WERROR _spoolss_WaitForPrinterChange(pipes_struct *p, } /**************************************************************** - _spoolss_EnumForms -****************************************************************/ - -WERROR _spoolss_EnumForms(pipes_struct *p, - struct spoolss_EnumForms *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** - _spoolss_EnumPorts -****************************************************************/ - -WERROR _spoolss_EnumPorts(pipes_struct *p, - struct spoolss_EnumPorts *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** - _spoolss_EnumMonitors -****************************************************************/ - -WERROR _spoolss_EnumMonitors(pipes_struct *p, - struct spoolss_EnumMonitors *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** _spoolss_AddPort ****************************************************************/ @@ -10500,28 +9742,6 @@ WERROR _spoolss_DeletePrintProvidor(pipes_struct *p, } /**************************************************************** - _spoolss_EnumPrintProcDataTypes -****************************************************************/ - -WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p, - struct spoolss_EnumPrintProcDataTypes *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** - _spoolss_GetPrinterDriver2 -****************************************************************/ - -WERROR _spoolss_GetPrinterDriver2(pipes_struct *p, - struct spoolss_GetPrinterDriver2 *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** _spoolss_FindFirstPrinterChangeNotification ****************************************************************/ @@ -10665,17 +9885,6 @@ WERROR _spoolss_47(pipes_struct *p, } /**************************************************************** - _spoolss_EnumPrinterData -****************************************************************/ - -WERROR _spoolss_EnumPrinterData(pipes_struct *p, - struct spoolss_EnumPrinterData *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** _spoolss_4a ****************************************************************/ @@ -10709,28 +9918,6 @@ WERROR _spoolss_4c(pipes_struct *p, } /**************************************************************** - _spoolss_EnumPrinterDataEx -****************************************************************/ - -WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p, - struct spoolss_EnumPrinterDataEx *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** - _spoolss_EnumPrinterKey -****************************************************************/ - -WERROR _spoolss_EnumPrinterKey(pipes_struct *p, - struct spoolss_EnumPrinterKey *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** _spoolss_53 ****************************************************************/ diff --git a/source3/rpc_server/srv_svcctl_nt.c b/source3/rpc_server/srv_svcctl_nt.c index b90a189f7e..3ca85aa755 100644 --- a/source3/rpc_server/srv_svcctl_nt.c +++ b/source3/rpc_server/srv_svcctl_nt.c @@ -170,7 +170,7 @@ static SEC_DESC* construct_scm_sd( TALLOC_CTX *ctx ) Find a registry key handle and return a SERVICE_INFO *****************************************************************/ -static SERVICE_INFO *find_service_info_by_hnd(pipes_struct *p, POLICY_HND *hnd) +static SERVICE_INFO *find_service_info_by_hnd(pipes_struct *p, struct policy_handle *hnd) { SERVICE_INFO *service_info = NULL; @@ -185,7 +185,7 @@ static SERVICE_INFO *find_service_info_by_hnd(pipes_struct *p, POLICY_HND *hnd) /****************************************************************** *****************************************************************/ -static WERROR create_open_service_handle( pipes_struct *p, POLICY_HND *handle, uint32 type, +static WERROR create_open_service_handle( pipes_struct *p, struct policy_handle *handle, uint32 type, const char *service, uint32 access_granted ) { SERVICE_INFO *info = NULL; diff --git a/source3/rpc_server/srv_winreg_nt.c b/source3/rpc_server/srv_winreg_nt.c index 8092601202..3de9f0e623 100644 --- a/source3/rpc_server/srv_winreg_nt.c +++ b/source3/rpc_server/srv_winreg_nt.c @@ -30,7 +30,7 @@ *****************************************************************/ static struct registry_key *find_regkey_by_hnd(pipes_struct *p, - POLICY_HND *hnd) + struct policy_handle *hnd) { struct registry_key *regkey = NULL; @@ -50,7 +50,7 @@ static struct registry_key *find_regkey_by_hnd(pipes_struct *p, HK[LM|U]\<key>\<key>\... *******************************************************************/ -static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd, +static WERROR open_registry_key( pipes_struct *p, struct policy_handle *hnd, struct registry_key *parent, const char *subkeyname, uint32 access_desired ) @@ -83,7 +83,7 @@ static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd, Note that P should be valid & hnd should already have space *******************************************************************/ -static bool close_registry_key(pipes_struct *p, POLICY_HND *hnd) +static bool close_registry_key(pipes_struct *p, struct policy_handle *hnd) { struct registry_key *regkey = find_regkey_by_hnd(p, hnd); diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index 6424f1b3af..722a0a3832 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -29,7 +29,7 @@ static NTSTATUS name_to_sid(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, DOM_SID *sid, const char *name) { - POLICY_HND pol; + struct policy_handle pol; enum lsa_SidType *sid_types; NTSTATUS result; DOM_SID *sids; @@ -149,7 +149,7 @@ static NTSTATUS cmd_lsa_query_info_policy(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; union lsa_PolicyInformation *info = NULL; @@ -207,7 +207,7 @@ static NTSTATUS cmd_lsa_lookup_names(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_SID *sids; enum lsa_SidType *types; @@ -255,7 +255,7 @@ static NTSTATUS cmd_lsa_lookup_names_level(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_SID *sids; enum lsa_SidType *types; @@ -305,7 +305,7 @@ static NTSTATUS cmd_lsa_lookup_names_level(struct rpc_pipe_client *cli, static NTSTATUS cmd_lsa_lookup_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_SID *sids; char **domains; @@ -374,7 +374,7 @@ static NTSTATUS cmd_lsa_enum_trust_dom(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct lsa_DomainList domain_list; @@ -439,7 +439,7 @@ static NTSTATUS cmd_lsa_enum_privilege(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct lsa_PrivArray priv_array; @@ -496,7 +496,7 @@ static NTSTATUS cmd_lsa_get_dispname(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint16 lang_id=0; @@ -544,7 +544,7 @@ static NTSTATUS cmd_lsa_enum_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 enum_context=0; @@ -600,8 +600,8 @@ static NTSTATUS cmd_lsa_create_account(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND dom_pol; - POLICY_HND user_pol; + struct policy_handle dom_pol; + struct policy_handle user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 des_access = 0x000f000f; @@ -647,8 +647,8 @@ static NTSTATUS cmd_lsa_enum_privsaccounts(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND dom_pol; - POLICY_HND user_pol; + struct policy_handle dom_pol; + struct policy_handle user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 access_desired = 0x000f000f; DOM_SID sid; @@ -710,7 +710,7 @@ static NTSTATUS cmd_lsa_enum_acct_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND dom_pol; + struct policy_handle dom_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_SID sid; struct lsa_RightSet rights; @@ -760,7 +760,7 @@ static NTSTATUS cmd_lsa_add_acct_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND dom_pol; + struct policy_handle dom_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct lsa_RightSet rights; DOM_SID sid; @@ -813,7 +813,7 @@ static NTSTATUS cmd_lsa_remove_acct_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND dom_pol; + struct policy_handle dom_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct lsa_RightSet rights; DOM_SID sid; @@ -868,7 +868,7 @@ static NTSTATUS cmd_lsa_lookup_priv_value(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct lsa_LUID luid; struct lsa_String name; @@ -910,7 +910,7 @@ static NTSTATUS cmd_lsa_query_secobj(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; SEC_DESC_BUF *sdb; uint32 sec_info = DACL_SECURITY_INFORMATION; @@ -996,7 +996,7 @@ static NTSTATUS cmd_lsa_query_trustdominfobysid(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_SID dom_sid; uint32 access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED; @@ -1045,7 +1045,7 @@ static NTSTATUS cmd_lsa_query_trustdominfobyname(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED; union lsa_TrustedDomainInfo *info = NULL; @@ -1093,7 +1093,7 @@ static NTSTATUS cmd_lsa_query_trustdominfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol, trustdom_pol; + struct policy_handle pol, trustdom_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED; union lsa_TrustedDomainInfo *info = NULL; @@ -1152,7 +1152,7 @@ static NTSTATUS cmd_lsa_get_username(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; const char *servername = cli->desthost; struct lsa_String *account_name = NULL; @@ -1194,7 +1194,7 @@ static NTSTATUS cmd_lsa_add_priv(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND dom_pol, user_pol; + struct policy_handle dom_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct lsa_PrivilegeSet privs; struct lsa_LUIDAttribute *set = NULL; @@ -1278,7 +1278,7 @@ static NTSTATUS cmd_lsa_del_priv(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND dom_pol, user_pol; + struct policy_handle dom_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct lsa_PrivilegeSet privs; struct lsa_LUIDAttribute *set = NULL; diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index 936c2081f3..428984db13 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -299,7 +299,7 @@ static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol, user_pol; + struct policy_handle connect_pol, domain_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 info_level = 21; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; @@ -487,7 +487,7 @@ static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol, group_pol; + struct policy_handle connect_pol, domain_pol, group_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; enum samr_GroupInfoEnum info_level = GROUPINFOALL; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; @@ -555,7 +555,7 @@ static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, + struct policy_handle connect_pol, domain_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; @@ -624,7 +624,7 @@ static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_SID *sids; size_t num_sids; @@ -709,7 +709,7 @@ static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol, group_pol; + struct policy_handle connect_pol, domain_pol, group_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 group_rid; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; @@ -783,7 +783,7 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 start_idx, size, num_dom_users, i; struct samr_SamArray *dom_users = NULL; @@ -862,7 +862,7 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 start_idx, size, num_dom_groups, i; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; @@ -935,7 +935,7 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 start_idx, size, num_als_groups, i; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; @@ -1008,7 +1008,7 @@ static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol; + struct policy_handle connect_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 start_idx, size, num_entries, i; uint32 access_mask = SEC_FLAG_MAXIMUM_ALLOWED; @@ -1071,7 +1071,7 @@ static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol, alias_pol; + struct policy_handle connect_pol, domain_pol, alias_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 alias_rid, i; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; @@ -1144,7 +1144,7 @@ static NTSTATUS cmd_samr_query_aliasinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol, alias_pol; + struct policy_handle connect_pol, domain_pol, alias_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32_t alias_rid; uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; @@ -1239,7 +1239,7 @@ static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol, alias_pol; + struct policy_handle connect_pol, domain_pol, alias_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 alias_rid; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; @@ -1320,7 +1320,7 @@ static NTSTATUS cmd_samr_query_dispinfo_internal(struct rpc_pipe_client *cli, int argc, const char **argv, uint32_t opcode) { - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries = 0, i; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; @@ -1512,7 +1512,7 @@ static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 switch_level = 2; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; @@ -1615,7 +1615,7 @@ static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol, user_pol; + struct policy_handle connect_pol, domain_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct lsa_String acct_name; uint32 acb_info; @@ -1693,7 +1693,7 @@ static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol, group_pol; + struct policy_handle connect_pol, domain_pol, group_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct lsa_String grp_name; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; @@ -1759,7 +1759,7 @@ static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol, alias_pol; + struct policy_handle connect_pol, domain_pol, alias_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct lsa_String alias_name; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; @@ -1827,7 +1827,7 @@ static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli, int argc, const char **argv) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; uint32 num_names; struct samr_Ids rids, name_types; int i; @@ -1902,7 +1902,7 @@ static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli, int argc, const char **argv) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; uint32_t num_rids, *rids; struct lsa_Strings names; struct samr_Ids types; @@ -1977,7 +1977,7 @@ static NTSTATUS cmd_samr_delete_dom_group(struct rpc_pipe_client *cli, int argc, const char **argv) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - POLICY_HND connect_pol, domain_pol, group_pol; + struct policy_handle connect_pol, domain_pol, group_pol; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; if ((argc < 2) || (argc > 3)) { @@ -2058,7 +2058,7 @@ static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli, int argc, const char **argv) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - POLICY_HND connect_pol, domain_pol, user_pol; + struct policy_handle connect_pol, domain_pol, user_pol; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; if ((argc < 2) || (argc > 3)) { @@ -2140,7 +2140,7 @@ static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol, user_pol, *pol; + struct policy_handle connect_pol, domain_pol, user_pol, *pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 sec_info = DACL_SECURITY_INFORMATION; uint32 user_rid = 0; @@ -2230,7 +2230,7 @@ static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli, int argc, const char **argv) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - POLICY_HND connect_pol, domain_pol, user_pol; + struct policy_handle connect_pol, domain_pol, user_pol; struct samr_PwInfo info; uint32_t rid; @@ -2316,7 +2316,7 @@ static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; fstring sid_string; @@ -2369,7 +2369,7 @@ static NTSTATUS cmd_samr_chgpasswd(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol, user_pol; + struct policy_handle connect_pol, domain_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; const char *user, *oldpass, *newpass; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; @@ -2461,7 +2461,7 @@ static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; const char *user, *oldpass, *newpass; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; @@ -2518,7 +2518,7 @@ static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; const char *user, *oldpass, *newpass; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; @@ -2604,7 +2604,7 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, int argc, const char **argv, int opcode) { - POLICY_HND connect_pol, domain_pol, user_pol; + struct policy_handle connect_pol, domain_pol, user_pol; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; const char *user, *param; uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS; diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index c68cf00530..cd04462426 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -6,6 +6,7 @@ Copyright (C) Tim Potter 2000 Copyright (C) Andrew Tridgell 1992-1999 Copyright (C) Luke Kenneth Casson Leighton 1996-1999 + Copyright (C) Guenther Deschner 2009 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 @@ -104,7 +105,7 @@ static WERROR cmd_spoolss_open_printer_ex(struct rpc_pipe_client *cli, int argc, const char **argv) { WERROR werror; - POLICY_HND hnd; + struct policy_handle hnd; if (argc != 2) { printf("Usage: %s <printername>\n", argv[0]); @@ -137,57 +138,45 @@ static WERROR cmd_spoolss_open_printer_ex(struct rpc_pipe_client *cli, /**************************************************************************** ****************************************************************************/ -static void display_print_info_0(PRINTER_INFO_0 *i0) +static void display_print_info0(struct spoolss_PrinterInfo0 *r) { - fstring name = ""; - fstring servername = ""; - - if (!i0) + if (!r) return; - rpcstr_pull(name, i0->printername.buffer, sizeof(name), -1, STR_TERMINATE); - - rpcstr_pull(servername, i0->servername.buffer, sizeof(servername), -1,STR_TERMINATE); - - printf("\tprintername:[%s]\n", name); - printf("\tservername:[%s]\n", servername); - printf("\tcjobs:[0x%x]\n", i0->cjobs); - printf("\ttotal_jobs:[0x%x]\n", i0->total_jobs); - - printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i0->year, i0->month, - i0->day, i0->dayofweek); - printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i0->hour, i0->minute, - i0->second, i0->milliseconds); - - printf("\tglobal_counter:[0x%x]\n", i0->global_counter); - printf("\ttotal_pages:[0x%x]\n", i0->total_pages); - - printf("\tmajorversion:[0x%x]\n", i0->major_version); - printf("\tbuildversion:[0x%x]\n", i0->build_version); - - printf("\tunknown7:[0x%x]\n", i0->unknown7); - printf("\tunknown8:[0x%x]\n", i0->unknown8); - printf("\tunknown9:[0x%x]\n", i0->unknown9); - printf("\tsession_counter:[0x%x]\n", i0->session_counter); - printf("\tunknown11:[0x%x]\n", i0->unknown11); - printf("\tprinter_errors:[0x%x]\n", i0->printer_errors); - printf("\tunknown13:[0x%x]\n", i0->unknown13); - printf("\tunknown14:[0x%x]\n", i0->unknown14); - printf("\tunknown15:[0x%x]\n", i0->unknown15); - printf("\tunknown16:[0x%x]\n", i0->unknown16); - printf("\tchange_id:[0x%x]\n", i0->change_id); - printf("\tunknown18:[0x%x]\n", i0->unknown18); - printf("\tstatus:[0x%x]\n", i0->status); - printf("\tunknown20:[0x%x]\n", i0->unknown20); - printf("\tc_setprinter:[0x%x]\n", i0->c_setprinter); - printf("\tunknown22:[0x%x]\n", i0->unknown22); - printf("\tunknown23:[0x%x]\n", i0->unknown23); - printf("\tunknown24:[0x%x]\n", i0->unknown24); - printf("\tunknown25:[0x%x]\n", i0->unknown25); - printf("\tunknown26:[0x%x]\n", i0->unknown26); - printf("\tunknown27:[0x%x]\n", i0->unknown27); - printf("\tunknown28:[0x%x]\n", i0->unknown28); - printf("\tunknown29:[0x%x]\n", i0->unknown29); + printf("\tprintername:[%s]\n", r->printername); + printf("\tservername:[%s]\n", r->servername); + printf("\tcjobs:[0x%x]\n", r->cjobs); + printf("\ttotal_jobs:[0x%x]\n", r->total_jobs); + printf("\ttotal_bytes:[0x%x]\n", r->total_bytes); + printf("\t:date: [%d]-[%d]-[%d] (%d)\n", r->time.year, r->time.month, + r->time.day, r->time.day_of_week); + printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", r->time.hour, r->time.minute, + r->time.second, r->time.millisecond); + + printf("\tglobal_counter:[0x%x]\n", r->global_counter); + printf("\ttotal_pages:[0x%x]\n", r->total_pages); + + printf("\tversion:[0x%x]\n", r->version); + printf("\tfree_build:[0x%x]\n", r->free_build); + printf("\tspooling:[0x%x]\n", r->spooling); + printf("\tmax_spooling:[0x%x]\n", r->max_spooling); + printf("\tsession_counter:[0x%x]\n", r->session_counter); + printf("\tnum_error_out_of_paper:[0x%x]\n", r->num_error_out_of_paper); + printf("\tnum_error_not_ready:[0x%x]\n", r->num_error_not_ready); + printf("\tjob_error:[0x%x]\n", r->job_error); + printf("\tnumber_of_processors:[0x%x]\n", r->number_of_processors); + printf("\tprocessor_type:[0x%x]\n", r->processor_type); + printf("\thigh_part_total_bytes:[0x%x]\n", r->high_part_total_bytes); + printf("\tchange_id:[0x%x]\n", r->change_id); + printf("\tlast_error: %s\n", win_errstr(r->last_error)); + printf("\tstatus:[0x%x]\n", r->status); + printf("\tenumerate_network_printers:[0x%x]\n", r->enumerate_network_printers); + printf("\tc_setprinter:[0x%x]\n", r->c_setprinter); + printf("\tprocessor_architecture:[0x%x]\n", r->processor_architecture); + printf("\tprocessor_level:[0x%x]\n", r->processor_level); + printf("\tref_ic:[0x%x]\n", r->ref_ic); + printf("\treserved2:[0x%x]\n", r->reserved2); + printf("\treserved3:[0x%x]\n", r->reserved3); printf("\n"); } @@ -195,22 +184,12 @@ static void display_print_info_0(PRINTER_INFO_0 *i0) /**************************************************************************** ****************************************************************************/ -static void display_print_info_1(PRINTER_INFO_1 *i1) +static void display_print_info1(struct spoolss_PrinterInfo1 *r) { - fstring desc = ""; - fstring name = ""; - fstring comm = ""; - - rpcstr_pull(desc, i1->description.buffer, sizeof(desc), -1, - STR_TERMINATE); - - rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE); - rpcstr_pull(comm, i1->comment.buffer, sizeof(comm), -1, STR_TERMINATE); - - printf("\tflags:[0x%x]\n", i1->flags); - printf("\tname:[%s]\n", name); - printf("\tdescription:[%s]\n", desc); - printf("\tcomment:[%s]\n", comm); + printf("\tflags:[0x%x]\n", r->flags); + printf("\tname:[%s]\n", r->name); + printf("\tdescription:[%s]\n", r->description); + printf("\tcomment:[%s]\n", r->comment); printf("\n"); } @@ -218,54 +197,30 @@ static void display_print_info_1(PRINTER_INFO_1 *i1) /**************************************************************************** ****************************************************************************/ -static void display_print_info_2(PRINTER_INFO_2 *i2) +static void display_print_info2(struct spoolss_PrinterInfo2 *r) { - fstring servername = ""; - fstring printername = ""; - fstring sharename = ""; - fstring portname = ""; - fstring drivername = ""; - fstring comment = ""; - fstring location = ""; - fstring sepfile = ""; - fstring printprocessor = ""; - fstring datatype = ""; - fstring parameters = ""; - - rpcstr_pull(servername, i2->servername.buffer,sizeof(servername), -1, STR_TERMINATE); - rpcstr_pull(printername, i2->printername.buffer,sizeof(printername), -1, STR_TERMINATE); - rpcstr_pull(sharename, i2->sharename.buffer,sizeof(sharename), -1, STR_TERMINATE); - rpcstr_pull(portname, i2->portname.buffer,sizeof(portname), -1, STR_TERMINATE); - rpcstr_pull(drivername, i2->drivername.buffer,sizeof(drivername), -1, STR_TERMINATE); - rpcstr_pull(comment, i2->comment.buffer,sizeof(comment), -1, STR_TERMINATE); - rpcstr_pull(location, i2->location.buffer,sizeof(location), -1, STR_TERMINATE); - rpcstr_pull(sepfile, i2->sepfile.buffer,sizeof(sepfile), -1, STR_TERMINATE); - rpcstr_pull(printprocessor, i2->printprocessor.buffer,sizeof(printprocessor), -1, STR_TERMINATE); - rpcstr_pull(datatype, i2->datatype.buffer,sizeof(datatype), -1, STR_TERMINATE); - rpcstr_pull(parameters, i2->parameters.buffer,sizeof(parameters), -1, STR_TERMINATE); - - printf("\tservername:[%s]\n", servername); - printf("\tprintername:[%s]\n", printername); - printf("\tsharename:[%s]\n", sharename); - printf("\tportname:[%s]\n", portname); - printf("\tdrivername:[%s]\n", drivername); - printf("\tcomment:[%s]\n", comment); - printf("\tlocation:[%s]\n", location); - printf("\tsepfile:[%s]\n", sepfile); - printf("\tprintprocessor:[%s]\n", printprocessor); - printf("\tdatatype:[%s]\n", datatype); - printf("\tparameters:[%s]\n", parameters); - printf("\tattributes:[0x%x]\n", i2->attributes); - printf("\tpriority:[0x%x]\n", i2->priority); - printf("\tdefaultpriority:[0x%x]\n", i2->defaultpriority); - printf("\tstarttime:[0x%x]\n", i2->starttime); - printf("\tuntiltime:[0x%x]\n", i2->untiltime); - printf("\tstatus:[0x%x]\n", i2->status); - printf("\tcjobs:[0x%x]\n", i2->cjobs); - printf("\taverageppm:[0x%x]\n", i2->averageppm); - - if (i2->secdesc) - display_sec_desc(i2->secdesc); + printf("\tservername:[%s]\n", r->servername); + printf("\tprintername:[%s]\n", r->printername); + printf("\tsharename:[%s]\n", r->sharename); + printf("\tportname:[%s]\n", r->portname); + printf("\tdrivername:[%s]\n", r->drivername); + printf("\tcomment:[%s]\n", r->comment); + printf("\tlocation:[%s]\n", r->location); + printf("\tsepfile:[%s]\n", r->sepfile); + printf("\tprintprocessor:[%s]\n", r->printprocessor); + printf("\tdatatype:[%s]\n", r->datatype); + printf("\tparameters:[%s]\n", r->parameters); + printf("\tattributes:[0x%x]\n", r->attributes); + printf("\tpriority:[0x%x]\n", r->priority); + printf("\tdefaultpriority:[0x%x]\n", r->defaultpriority); + printf("\tstarttime:[0x%x]\n", r->starttime); + printf("\tuntiltime:[0x%x]\n", r->untiltime); + printf("\tstatus:[0x%x]\n", r->status); + printf("\tcjobs:[0x%x]\n", r->cjobs); + printf("\taverageppm:[0x%x]\n", r->averageppm); + + if (r->secdesc) + display_sec_desc(r->secdesc); printf("\n"); } @@ -273,9 +228,9 @@ static void display_print_info_2(PRINTER_INFO_2 *i2) /**************************************************************************** ****************************************************************************/ -static void display_print_info_3(PRINTER_INFO_3 *i3) +static void display_print_info3(struct spoolss_PrinterInfo3 *r) { - display_sec_desc(i3->secdesc); + display_sec_desc(r->secdesc); printf("\n"); } @@ -294,64 +249,65 @@ static void display_print_info7(struct spoolss_PrinterInfo7 *r) ****************************************************************************/ static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - int argc, const char **argv) + TALLOC_CTX *mem_ctx, + int argc, const char **argv) { WERROR result; - uint32 info_level = 1; - PRINTER_INFO_CTR ctr; - uint32 i = 0, num_printers; - fstring name; + uint32_t level = 1; + union spoolss_PrinterInfo *info; + uint32_t i, count; + const char *name; - if (argc > 3) - { + if (argc > 3) { printf("Usage: %s [level] [name]\n", argv[0]); return WERR_OK; } - if (argc >= 2) - info_level = atoi(argv[1]); - - if (argc == 3) - fstrcpy(name, argv[2]); - else { - slprintf(name, sizeof(name)-1, "\\\\%s", cli->desthost); - strupper_m(name); + if (argc >= 2) { + level = atoi(argv[1]); } - ZERO_STRUCT(ctr); - - result = rpccli_spoolss_enum_printers(cli, mem_ctx, name, PRINTER_ENUM_LOCAL, - info_level, &num_printers, &ctr); + if (argc == 3) { + name = argv[2]; + } else { + name = cli->srv_name_slash; + } + result = rpccli_spoolss_enumprinters(cli, mem_ctx, + PRINTER_ENUM_LOCAL, + name, + level, + 0, + &count, + &info); if (W_ERROR_IS_OK(result)) { - if (!num_printers) { + if (!count) { printf ("No printers returned.\n"); goto done; } - for (i = 0; i < num_printers; i++) { - switch(info_level) { + for (i = 0; i < count; i++) { + switch (level) { case 0: - display_print_info_0(&ctr.printers_0[i]); + display_print_info0(&info[i].info0); break; case 1: - display_print_info_1(&ctr.printers_1[i]); + display_print_info1(&info[i].info1); break; case 2: - display_print_info_2(&ctr.printers_2[i]); + display_print_info2(&info[i].info2); break; case 3: - display_print_info_3(&ctr.printers_3[i]); + display_print_info3(&info[i].info3); break; default: - printf("unknown info level %d\n", info_level); + printf("unknown info level %d\n", level); goto done; } } } - done: + done: return result; } @@ -359,55 +315,45 @@ static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli, /**************************************************************************** ****************************************************************************/ -static void display_port_info_1(PORT_INFO_1 *i1) +static void display_port_info_1(struct spoolss_PortInfo1 *r) { - fstring buffer; - - rpcstr_pull(buffer, i1->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE); - printf("\tPort Name:\t[%s]\n", buffer); + printf("\tPort Name:\t[%s]\n", r->port_name); } /**************************************************************************** ****************************************************************************/ -static void display_port_info_2(PORT_INFO_2 *i2) +static void display_port_info_2(struct spoolss_PortInfo2 *r) { - fstring buffer; - - rpcstr_pull(buffer, i2->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE); - printf("\tPort Name:\t[%s]\n", buffer); - rpcstr_pull(buffer, i2->monitor_name.buffer, sizeof(buffer), -1, STR_TERMINATE); - - printf("\tMonitor Name:\t[%s]\n", buffer); - rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), -1, STR_TERMINATE); - - printf("\tDescription:\t[%s]\n", buffer); + printf("\tPort Name:\t[%s]\n", r->port_name); + printf("\tMonitor Name:\t[%s]\n", r->monitor_name); + printf("\tDescription:\t[%s]\n", r->description); printf("\tPort Type:\t" ); - if ( i2->port_type ) { + if (r->port_type) { int comma = 0; /* hack */ printf( "[" ); - if ( i2->port_type & PORT_TYPE_READ ) { + if (r->port_type & SPOOLSS_PORT_TYPE_READ) { printf( "Read" ); comma = 1; } - if ( i2->port_type & PORT_TYPE_WRITE ) { + if (r->port_type & SPOOLSS_PORT_TYPE_WRITE) { printf( "%sWrite", comma ? ", " : "" ); comma = 1; } /* These two have slightly different interpretations on 95/98/ME but I'm disregarding that for now */ - if ( i2->port_type & PORT_TYPE_REDIRECTED ) { + if (r->port_type & SPOOLSS_PORT_TYPE_REDIRECTED) { printf( "%sRedirected", comma ? ", " : "" ); comma = 1; } - if ( i2->port_type & PORT_TYPE_NET_ATTACHED ) { + if (r->port_type & SPOOLSS_PORT_TYPE_NET_ATTACHED) { printf( "%sNet-Attached", comma ? ", " : "" ); } printf( "]\n" ); } else { printf( "[Unset]\n" ); } - printf("\tReserved:\t[%d]\n", i2->reserved); + printf("\tReserved:\t[%d]\n", r->reserved); printf("\n"); } @@ -419,37 +365,40 @@ static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli, const char **argv) { WERROR result; - uint32 info_level = 1; - PORT_INFO_CTR ctr; - uint32 returned; + uint32_t level = 1; + uint32_t count; + union spoolss_PortInfo *info; if (argc > 2) { printf("Usage: %s [level]\n", argv[0]); return WERR_OK; } - if (argc == 2) - info_level = atoi(argv[1]); + if (argc == 2) { + level = atoi(argv[1]); + } /* Enumerate ports */ - ZERO_STRUCT(ctr); - - result = rpccli_spoolss_enum_ports(cli, mem_ctx, info_level, &returned, &ctr); - + result = rpccli_spoolss_enumports(cli, mem_ctx, + cli->srv_name_slash, + level, + 0, + &count, + &info); if (W_ERROR_IS_OK(result)) { int i; - for (i = 0; i < returned; i++) { - switch (info_level) { + for (i = 0; i < count; i++) { + switch (level) { case 1: - display_port_info_1(&ctr.port.info_1[i]); + display_port_info_1(&info[i].info1); break; case 2: - display_port_info_2(&ctr.port.info_2[i]); + display_port_info_2(&info[i].info2); break; default: - printf("unknown info level %d\n", info_level); + printf("unknown info level %d\n", level); break; } } @@ -465,7 +414,7 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; WERROR result; NTSTATUS status; uint32 info_level = 2; @@ -511,6 +460,8 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, /* Modify the comment. */ info.info2.comment = comment; + info.info2.secdesc = NULL; + info.info2.devmode = NULL; info_ctr.level = 2; info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2; @@ -539,7 +490,7 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; WERROR result; NTSTATUS status; uint32 info_level = 2; @@ -615,9 +566,9 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; WERROR result; - uint32 info_level = 1; + uint32_t level = 1; const char *printername; union spoolss_PrinterInfo info; @@ -628,7 +579,7 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, /* Open a printer handle */ if (argc == 3) { - info_level = atoi(argv[2]); + level = atoi(argv[2]); } RPCCLIENT_PRINTERNAME(printername, cli, argv[1]); @@ -639,45 +590,46 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, printername, SEC_FLAG_MAXIMUM_ALLOWED, &pol); - if (!W_ERROR_IS_OK(result)) + if (!W_ERROR_IS_OK(result)) { goto done; + } /* Get printer info */ result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, - info_level, + level, 0, &info); - if (!W_ERROR_IS_OK(result)) + if (!W_ERROR_IS_OK(result)) { goto done; + } /* Display printer info */ - switch (info_level) { -#if 0 /* FIXME GD */ + switch (level) { case 0: - display_print_info_0(ctr.printers_0); + display_print_info0(&info.info0); break; case 1: - display_print_info_1(ctr.printers_1); + display_print_info1(&info.info1); break; case 2: - display_print_info_2(ctr.printers_2); + display_print_info2(&info.info2); break; case 3: - display_print_info_3(ctr.printers_3); + display_print_info3(&info.info3); break; -#endif case 7: display_print_info7(&info.info7); break; default: - printf("unknown info level %d\n", info_level); + printf("unknown info level %d\n", level); break; } done: - if (is_valid_policy_hnd(&pol)) + if (is_valid_policy_hnd(&pol)) { rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); + } return result; } @@ -731,6 +683,7 @@ static void display_reg_value(REGISTRY_VALUE value) break; } + printf("%s: REG_MULTI_SZ: \n", value.valuename); for (i=0; i<num_values; i++) { d_printf("%s\n", values[i]); } @@ -746,15 +699,64 @@ static void display_reg_value(REGISTRY_VALUE value) /**************************************************************************** ****************************************************************************/ +static void display_printer_data(const char *v, + enum winreg_Type type, + union spoolss_PrinterData *r) +{ + int i; + + switch (type) { + case REG_DWORD: + printf("%s: REG_DWORD: 0x%08x\n", v, r->value); + break; + case REG_SZ: + printf("%s: REG_SZ: %s\n", v, r->string); + break; + case REG_BINARY: { + char *hex = hex_encode_talloc(NULL, + r->binary.data, r->binary.length); + size_t len; + printf("%s: REG_BINARY:", v); + len = strlen(hex); + for (i=0; i<len; i++) { + if (hex[i] == '\0') { + break; + } + if (i%40 == 0) { + putchar('\n'); + } + putchar(hex[i]); + } + TALLOC_FREE(hex); + putchar('\n'); + break; + } + case REG_MULTI_SZ: + printf("%s: REG_MULTI_SZ: ", v); + for (i=0; r->string_array[i] != NULL; i++) { + printf("%s ", r->string_array[i]); + } + printf("\n"); + break; + default: + printf("%s: unknown type 0x%02x:\n", v, type); + break; + } +} + +/**************************************************************************** +****************************************************************************/ + static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; WERROR result; fstring printername; const char *valuename; - REGISTRY_VALUE value; + enum winreg_Type type; + union spoolss_PrinterData data; if (argc != 3) { printf("Usage: %s <printername> <valuename>\n", argv[0]); @@ -782,16 +784,18 @@ static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli, /* Get printer info */ - result = rpccli_spoolss_getprinterdata(cli, mem_ctx, &pol, valuename, &value); - + result = rpccli_spoolss_getprinterdata(cli, mem_ctx, + &pol, + valuename, + 0, + &type, + &data); if (!W_ERROR_IS_OK(result)) goto done; /* Display printer data */ - fstrcpy(value.valuename, valuename); - display_reg_value(value); - + display_printer_data(valuename, type, &data); done: if (is_valid_policy_hnd(&pol)) @@ -807,14 +811,14 @@ static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; WERROR result; NTSTATUS status; fstring printername; const char *valuename, *keyname; REGISTRY_VALUE value; - uint32_t type; + enum winreg_Type type; uint8_t *buffer = NULL; uint32_t offered = 0; uint32_t needed; @@ -901,116 +905,6 @@ static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli, /**************************************************************************** ****************************************************************************/ -static void display_print_driver_1(DRIVER_INFO_1 *i1) -{ - fstring name; - if (i1 == NULL) - return; - - rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE); - - printf ("Printer Driver Info 1:\n"); - printf ("\tDriver Name: [%s]\n\n", name); - - return; -} - -/**************************************************************************** -****************************************************************************/ - -static void display_print_driver_2(DRIVER_INFO_2 *i1) -{ - fstring name; - fstring architecture; - fstring driverpath; - fstring datafile; - fstring configfile; - if (i1 == NULL) - return; - - rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE); - rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE); - rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE); - rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE); - rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE); - - printf ("Printer Driver Info 2:\n"); - printf ("\tVersion: [%x]\n", i1->version); - printf ("\tDriver Name: [%s]\n", name); - printf ("\tArchitecture: [%s]\n", architecture); - printf ("\tDriver Path: [%s]\n", driverpath); - printf ("\tDatafile: [%s]\n", datafile); - printf ("\tConfigfile: [%s]\n\n", configfile); - - return; -} - -/**************************************************************************** -****************************************************************************/ - -static void display_print_driver_3(DRIVER_INFO_3 *i1) -{ - fstring name = ""; - fstring architecture = ""; - fstring driverpath = ""; - fstring datafile = ""; - fstring configfile = ""; - fstring helpfile = ""; - fstring dependentfiles = ""; - fstring monitorname = ""; - fstring defaultdatatype = ""; - - int length=0; - bool valid = True; - - if (i1 == NULL) - return; - - rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE); - rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE); - rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE); - rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE); - rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE); - rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE); - rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), -1, STR_TERMINATE); - rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), -1, STR_TERMINATE); - - printf ("Printer Driver Info 3:\n"); - printf ("\tVersion: [%x]\n", i1->version); - printf ("\tDriver Name: [%s]\n",name); - printf ("\tArchitecture: [%s]\n", architecture); - printf ("\tDriver Path: [%s]\n", driverpath); - printf ("\tDatafile: [%s]\n", datafile); - printf ("\tConfigfile: [%s]\n", configfile); - printf ("\tHelpfile: [%s]\n\n", helpfile); - - while (valid) - { - rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE); - - length+=strlen(dependentfiles)+1; - - if (strlen(dependentfiles) > 0) - { - printf ("\tDependentfiles: [%s]\n", dependentfiles); - } - else - { - valid = False; - } - } - - printf ("\n"); - - printf ("\tMonitorname: [%s]\n", monitorname); - printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype); - - return; -} - -/**************************************************************************** -****************************************************************************/ - static void display_print_driver1(struct spoolss_DriverInfo1 *r) { if (!r) { @@ -1074,21 +968,20 @@ static void display_print_driver3(struct spoolss_DriverInfo3 *r) ****************************************************************************/ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - int argc, const char **argv) + TALLOC_CTX *mem_ctx, + int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; WERROR werror; - uint32 info_level = 3; + uint32_t level = 3; const char *printername; - uint32 i; - bool success = False; + uint32_t i; + bool success = false; union spoolss_DriverInfo info; uint32_t server_major_version; uint32_t server_minor_version; - if ((argc == 1) || (argc > 3)) - { + if ((argc == 1) || (argc > 3)) { printf("Usage: %s <printername> [level]\n", argv[0]); return WERR_OK; } @@ -1097,8 +990,9 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, RPCCLIENT_PRINTERNAME(printername, cli, argv[1]); - if (argc == 3) - info_level = atoi(argv[2]); + if (argc == 3) { + level = atoi(argv[2]); + } /* Open a printer handle */ @@ -1118,23 +1012,24 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, werror = rpccli_spoolss_getprinterdriver2(cli, mem_ctx, &pol, archi_table[i].long_archi, - info_level, + level, 0, /* offered */ archi_table[i].version, 2, &info, &server_major_version, &server_minor_version); - if (!W_ERROR_IS_OK(werror)) + if (!W_ERROR_IS_OK(werror)) { continue; + } /* need at least one success */ - success = True; + success = true; - printf ("\n[%s]\n", archi_table[i].long_archi); + printf("\n[%s]\n", archi_table[i].long_archi); - switch (info_level) { + switch (level) { case 1: display_print_driver1(&info.info1); break; @@ -1145,18 +1040,20 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, display_print_driver3(&info.info3); break; default: - printf("unknown info level %d\n", info_level); + printf("unknown info level %d\n", level); break; } } /* Cleanup */ - if (is_valid_policy_hnd(&pol)) + if (is_valid_policy_hnd(&pol)) { rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); + } - if ( success ) + if (success) { werror = WERR_OK; + } return werror; } @@ -1169,68 +1066,73 @@ static WERROR cmd_spoolss_enum_drivers(struct rpc_pipe_client *cli, int argc, const char **argv) { WERROR werror = WERR_OK; - uint32 info_level = 1; - PRINTER_DRIVER_CTR ctr; - uint32 i, j, - returned; + uint32_t level = 1; + union spoolss_DriverInfo *info; + uint32_t i, j, count; if (argc > 2) { printf("Usage: enumdrivers [level]\n"); return WERR_OK; } - if (argc == 2) - info_level = atoi(argv[1]); + if (argc == 2) { + level = atoi(argv[1]); + } /* loop through and print driver info level for each architecture */ for (i=0; archi_table[i].long_archi!=NULL; i++) { /* check to see if we already asked for this architecture string */ - if ( i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi) ) + if (i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi)) { continue; + } - werror = rpccli_spoolss_enumprinterdrivers( - cli, mem_ctx, info_level, - archi_table[i].long_archi, &returned, &ctr); + werror = rpccli_spoolss_enumprinterdrivers(cli, mem_ctx, + cli->srv_name_slash, + archi_table[i].long_archi, + level, + 0, + &count, + &info); if (W_ERROR_V(werror) == W_ERROR_V(WERR_INVALID_ENVIRONMENT)) { - printf ("Server does not support environment [%s]\n", + printf("Server does not support environment [%s]\n", archi_table[i].long_archi); werror = WERR_OK; continue; } - if (returned == 0) + if (count == 0) { continue; + } if (!W_ERROR_IS_OK(werror)) { - printf ("Error getting driver for environment [%s] - %d\n", + printf("Error getting driver for environment [%s] - %d\n", archi_table[i].long_archi, W_ERROR_V(werror)); continue; } - printf ("\n[%s]\n", archi_table[i].long_archi); - switch (info_level) - { + printf("\n[%s]\n", archi_table[i].long_archi); + switch (level) { case 1: - for (j=0; j < returned; j++) { - display_print_driver_1 (&ctr.info1[j]); + for (j=0; j < count; j++) { + display_print_driver1(&info[j].info1); } break; case 2: - for (j=0; j < returned; j++) { - display_print_driver_2 (&ctr.info2[j]); + for (j=0; j < count; j++) { + display_print_driver2(&info[j].info2); } break; case 3: - for (j=0; j < returned; j++) { - display_print_driver_3 (&ctr.info3[j]); + for (j=0; j < count; j++) { + display_print_driver3(&info[j].info3); } break; default: - printf("unknown info level %d\n", info_level); + printf("unknown info level %d\n", level); return WERR_UNKNOWN_LEVEL; } } @@ -1562,7 +1464,7 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; WERROR result; NTSTATUS status; uint32 level = 2; @@ -1608,6 +1510,9 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, /* Set the printer driver */ info.info2.drivername = argv[2]; + info.info2.devmode = NULL; + info.info2.secdesc = NULL; + info_ctr.level = 2; info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2; @@ -1808,7 +1713,7 @@ static WERROR cmd_spoolss_getprintprocdir(struct rpc_pipe_client *cli, static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND handle; + struct policy_handle handle; WERROR werror; NTSTATUS status; const char *printername; @@ -1843,7 +1748,7 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c switch (level) { case 1: - info1.flags = FORM_USER; + info1.flags = SPOOLSS_FORM_USER; info1.form_name = argv[2]; info1.size.width = 100; info1.size.height = 100; @@ -1856,7 +1761,7 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c break; case 2: - info2.flags = FORM_USER; + info2.flags = SPOOLSS_FORM_USER; info2.form_name = argv[2]; info2.size.width = 100; info2.size.height = 100; @@ -1898,7 +1803,7 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND handle; + struct policy_handle handle; WERROR werror; NTSTATUS status; const char *printername; @@ -1925,7 +1830,7 @@ static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c /* Dummy up some values for the form data */ - info1.flags = FORM_PRINTER; + info1.flags = SPOOLSS_FORM_PRINTER; info1.size.width = 100; info1.size.height = 100; info1.area.left = 0; @@ -1958,11 +1863,11 @@ static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c static const char *get_form_flag(int form_flag) { switch (form_flag) { - case FORM_USER: + case SPOOLSS_FORM_USER: return "FORM_USER"; - case FORM_BUILTIN: + case SPOOLSS_FORM_BUILTIN: return "FORM_BUILTIN"; - case FORM_PRINTER: + case SPOOLSS_FORM_PRINTER: return "FORM_PRINTER"; default: return "unknown"; @@ -1972,27 +1877,6 @@ static const char *get_form_flag(int form_flag) /**************************************************************************** ****************************************************************************/ -static void display_form(FORM_1 *form) -{ - fstring form_name = ""; - - if (form->name.buffer) - rpcstr_pull(form_name, form->name.buffer, - sizeof(form_name), -1, STR_TERMINATE); - - printf("%s\n" \ - "\tflag: %s (%d)\n" \ - "\twidth: %d, length: %d\n" \ - "\tleft: %d, right: %d, top: %d, bottom: %d\n\n", - form_name, get_form_flag(form->flag), form->flag, - form->width, form->length, - form->left, form->right, - form->top, form->bottom); -} - -/**************************************************************************** -****************************************************************************/ - static void display_form_info1(struct spoolss_FormInfo1 *r) { printf("%s\n" \ @@ -2033,7 +1917,7 @@ static void display_form_info2(struct spoolss_FormInfo2 *r) static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND handle; + struct policy_handle handle; WERROR werror; NTSTATUS status; const char *printername; @@ -2117,7 +2001,7 @@ static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND handle; + struct policy_handle handle; WERROR werror; NTSTATUS status; const char *printername; @@ -2164,16 +2048,16 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - POLICY_HND handle; + struct policy_handle handle; WERROR werror; const char *printername; uint32 num_forms, level = 1, i; - FORM_1 *forms; + union spoolss_FormInfo *forms; /* Parse the command arguments */ - if (argc != 2) { - printf ("Usage: %s <printer>\n", argv[0]); + if (argc < 2 || argc > 4) { + printf ("Usage: %s <printer> [level]\n", argv[0]); return WERR_OK; } @@ -2188,9 +2072,18 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(werror)) goto done; + if (argc == 3) { + level = atoi(argv[2]); + } + /* Enumerate forms */ - werror = rpccli_spoolss_enumforms(cli, mem_ctx, &handle, level, &num_forms, &forms); + werror = rpccli_spoolss_enumforms(cli, mem_ctx, + &handle, + level, + 0, + &num_forms, + &forms); if (!W_ERROR_IS_OK(werror)) goto done; @@ -2198,9 +2091,14 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli, /* Display output */ for (i = 0; i < num_forms; i++) { - - display_form(&forms[i]); - + switch (level) { + case 1: + display_form_info1(&forms[i].info1); + break; + case 2: + display_form_info2(&forms[i].info2); + break; + } } done: @@ -2218,11 +2116,12 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, int argc, const char **argv) { WERROR result; + NTSTATUS status; const char *printername; - POLICY_HND pol; + struct policy_handle pol; union spoolss_PrinterInfo info; - REGISTRY_VALUE value; - TALLOC_CTX *tmp_ctx = talloc_stackframe(); + enum winreg_Type type; + union spoolss_PrinterData data; /* parse the command arguments */ if (argc < 5) { @@ -2235,25 +2134,25 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, RPCCLIENT_PRINTERNAME(printername, cli, argv[1]); - value.type = REG_NONE; + type = REG_NONE; if (strequal(argv[2], "string")) { - value.type = REG_SZ; + type = REG_SZ; } if (strequal(argv[2], "binary")) { - value.type = REG_BINARY; + type = REG_BINARY; } if (strequal(argv[2], "dword")) { - value.type = REG_DWORD; + type = REG_DWORD; } if (strequal(argv[2], "multistring")) { - value.type = REG_MULTI_SZ; + type = REG_MULTI_SZ; } - if (value.type == REG_NONE) { + if (type == REG_NONE) { printf("Unknown data type: %s\n", argv[2]); result = WERR_INVALID_PARAM; goto done; @@ -2265,92 +2164,73 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, printername, SEC_FLAG_MAXIMUM_ALLOWED, &pol); - if (!W_ERROR_IS_OK(result)) + if (!W_ERROR_IS_OK(result)) { goto done; + } result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, 0, &info); - if (!W_ERROR_IS_OK(result)) + if (!W_ERROR_IS_OK(result)) { goto done; + } - printf("%s\n", current_timestring(tmp_ctx, True)); + printf("%s\n", current_timestring(mem_ctx, true)); printf("\tchange_id (before set)\t:[0x%x]\n", info.info0.change_id); /* Set the printer data */ - fstrcpy(value.valuename, argv[3]); - - switch (value.type) { - case REG_SZ: { - UNISTR2 data; - init_unistr2(&data, argv[4], UNI_STR_TERMINATE); - value.size = data.uni_str_len * 2; - if (value.size) { - value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, data.buffer, - value.size); - } else { - value.data_p = NULL; - } + switch (type) { + case REG_SZ: + data.string = talloc_strdup(mem_ctx, argv[4]); + W_ERROR_HAVE_NO_MEMORY(data.string); break; - } - case REG_DWORD: { - uint32 data = strtoul(argv[4], NULL, 10); - value.size = sizeof(data); - if (sizeof(data)) { - value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, &data, - sizeof(data)); - } else { - value.data_p = NULL; - } + case REG_DWORD: + data.value = strtoul(argv[4], NULL, 10); break; - } - case REG_BINARY: { - DATA_BLOB data = strhex_to_data_blob(mem_ctx, argv[4]); - value.data_p = data.data; - value.size = data.length; + case REG_BINARY: + data.binary = strhex_to_data_blob(mem_ctx, argv[4]); break; - } case REG_MULTI_SZ: { - int i; - size_t len = 0; - char *p; + int i, num_strings; + const char **strings = NULL; for (i=4; i<argc; i++) { if (strcmp(argv[i], "NULL") == 0) { argv[i] = ""; } - len += strlen(argv[i])+1; + if (!add_string_to_array(mem_ctx, argv[i], + &strings, + &num_strings)) { + result = WERR_NOMEM; + goto done; + } } - - value.size = len*2; - value.data_p = TALLOC_ARRAY(mem_ctx, unsigned char, value.size); - if (value.data_p == NULL) { + data.string_array = talloc_zero_array(mem_ctx, const char *, num_strings + 1); + if (!data.string_array) { result = WERR_NOMEM; goto done; } - - p = (char *)value.data_p; - len = value.size; - for (i=4; i<argc; i++) { - size_t l = (strlen(argv[i])+1)*2; - rpcstr_push(p, argv[i], len, STR_TERMINATE); - p += l; - len -= l; + for (i=0; i < num_strings; i++) { + data.string_array[i] = strings[i]; } - SMB_ASSERT(len == 0); break; - } + } default: printf("Unknown data type: %s\n", argv[2]); result = WERR_INVALID_PARAM; goto done; } - result = rpccli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value); - + status = rpccli_spoolss_SetPrinterData(cli, mem_ctx, + &pol, + argv[3], /* value_name */ + type, + data, + 0, /* autocalculated size */ + &result); if (!W_ERROR_IS_OK(result)) { printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]); goto done; @@ -2362,17 +2242,18 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, 0, 0, &info); - if (!W_ERROR_IS_OK(result)) + if (!W_ERROR_IS_OK(result)) { goto done; + } - printf("%s\n", current_timestring(tmp_ctx, True)); + printf("%s\n", current_timestring(mem_ctx, true)); printf("\tchange_id (after set)\t:[0x%x]\n", info.info0.change_id); done: /* cleanup */ - TALLOC_FREE(tmp_ctx); - if (is_valid_policy_hnd(&pol)) + if (is_valid_policy_hnd(&pol)) { rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); + } return result; } @@ -2380,48 +2261,6 @@ done: /**************************************************************************** ****************************************************************************/ -static void display_job_info_1(JOB_INFO_1 *job) -{ - fstring username = "", document = "", text_status = ""; - - rpcstr_pull(username, job->username.buffer, - sizeof(username), -1, STR_TERMINATE); - - rpcstr_pull(document, job->document.buffer, - sizeof(document), -1, STR_TERMINATE); - - rpcstr_pull(text_status, job->text_status.buffer, - sizeof(text_status), -1, STR_TERMINATE); - - printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job->position, job->jobid, - username, document, text_status, job->pagesprinted, - job->totalpages); -} - -/**************************************************************************** -****************************************************************************/ - -static void display_job_info_2(JOB_INFO_2 *job) -{ - fstring username = "", document = "", text_status = ""; - - rpcstr_pull(username, job->username.buffer, - sizeof(username), -1, STR_TERMINATE); - - rpcstr_pull(document, job->document.buffer, - sizeof(document), -1, STR_TERMINATE); - - rpcstr_pull(text_status, job->text_status.buffer, - sizeof(text_status), -1, STR_TERMINATE); - - printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job->position, job->jobid, - username, document, text_status, job->pagesprinted, - job->totalpages, job->size); -} - -/**************************************************************************** -****************************************************************************/ - static void display_job_info1(struct spoolss_JobInfo1 *r) { printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r->position, r->job_id, @@ -2468,18 +2307,19 @@ static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli, const char **argv) { WERROR result; - uint32 level = 1, num_jobs, i; + uint32_t level = 1, count, i; const char *printername; - POLICY_HND hnd; - JOB_INFO_CTR ctr; + struct policy_handle hnd; + union spoolss_JobInfo *info; if (argc < 2 || argc > 3) { printf("Usage: %s printername [level]\n", argv[0]); return WERR_OK; } - if (argc == 3) + if (argc == 3) { level = atoi(argv[2]); + } /* Open printer handle */ @@ -2494,19 +2334,25 @@ static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli, /* Enumerate ports */ - result = rpccli_spoolss_enumjobs(cli, mem_ctx, &hnd, level, 0, 1000, - &num_jobs, &ctr); - - if (!W_ERROR_IS_OK(result)) + result = rpccli_spoolss_enumjobs(cli, mem_ctx, + &hnd, + 0, /* firstjob */ + 1000, /* numjobs */ + level, + 0, + &count, + &info); + if (!W_ERROR_IS_OK(result)) { goto done; + } - for (i = 0; i < num_jobs; i++) { - switch(level) { + for (i = 0; i < count; i++) { + switch (level) { case 1: - display_job_info_1(&ctr.job.job_info_1[i]); + display_job_info1(&info[i].info1); break; case 2: - display_job_info_2(&ctr.job.job_info_2[i]); + display_job_info2(&info[i].info2); break; default: d_printf("unknown info level %d\n", level); @@ -2515,8 +2361,9 @@ static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli, } done: - if (is_valid_policy_hnd(&hnd)) + if (is_valid_policy_hnd(&hnd)) { rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL); + } return result; } @@ -2601,14 +2448,22 @@ done: /**************************************************************************** ****************************************************************************/ -static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, int argc, - const char **argv) +static WERROR cmd_spoolss_enum_data(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) { WERROR result; - uint32 i=0, val_needed, data_needed; + NTSTATUS status; + uint32_t i = 0; const char *printername; - POLICY_HND hnd; + struct policy_handle hnd; + uint32_t value_offered = 0; + const char *value_name = NULL; + uint32_t value_needed; + enum winreg_Type type; + uint8_t *data = NULL; + uint32_t data_offered = 0; + uint32_t data_needed; if (argc != 2) { printf("Usage: %s printername\n", argv[0]); @@ -2623,28 +2478,60 @@ static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli, printername, SEC_FLAG_MAXIMUM_ALLOWED, &hnd); - if (!W_ERROR_IS_OK(result)) + if (!W_ERROR_IS_OK(result)) { goto done; + } /* Enumerate data */ - result = rpccli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0, - &val_needed, &data_needed, - NULL); - while (W_ERROR_IS_OK(result)) { - REGISTRY_VALUE value; - result = rpccli_spoolss_enumprinterdata( - cli, mem_ctx, &hnd, i++, val_needed, - data_needed, 0, 0, &value); - if (W_ERROR_IS_OK(result)) - display_reg_value(value); - } - if (W_ERROR_V(result) == ERRnomoreitems) + status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx, + &hnd, + i, + value_name, + value_offered, + &value_needed, + &type, + data, + data_offered, + &data_needed, + &result); + + data_offered = data_needed; + value_offered = value_needed; + data = talloc_zero_array(mem_ctx, uint8_t, data_needed); + value_name = talloc_zero_array(mem_ctx, char, value_needed); + + while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) { + + status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx, + &hnd, + i++, + value_name, + value_offered, + &value_needed, + &type, + data, + data_offered, + &data_needed, + &result); + if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) { + REGISTRY_VALUE v; + fstrcpy(v.valuename, value_name); + v.type = type; + v.size = data_offered; + v.data_p = data; + display_reg_value(v); + } + } + + if (W_ERROR_V(result) == ERRnomoreitems) { result = W_ERROR(ERRsuccess); + } done: - if (is_valid_policy_hnd(&hnd)) + if (is_valid_policy_hnd(&hnd)) { rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL); + } return result; } @@ -2659,17 +2546,15 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli, WERROR result; uint32 i; const char *printername; - const char *keyname = NULL; - POLICY_HND hnd; - REGVAL_CTR *ctr = NULL; + struct policy_handle hnd; + uint32_t count; + struct spoolss_PrinterEnumValues *info; if (argc != 3) { printf("Usage: %s printername <keyname>\n", argv[0]); return WERR_OK; } - keyname = argv[2]; - /* Open printer handle */ RPCCLIENT_PRINTERNAME(printername, cli, argv[1]); @@ -2678,28 +2563,32 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli, printername, SEC_FLAG_MAXIMUM_ALLOWED, &hnd); - if (!W_ERROR_IS_OK(result)) + if (!W_ERROR_IS_OK(result)) { goto done; + } /* Enumerate subkeys */ - if ( !(ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) ) - return WERR_NOMEM; - - result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &hnd, keyname, ctr); - - if (!W_ERROR_IS_OK(result)) + result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, + &hnd, + argv[2], + 0, + &count, + &info); + if (!W_ERROR_IS_OK(result)) { goto done; - - for (i=0; i < ctr->num_values; i++) { - display_reg_value(*(ctr->values[i])); } - TALLOC_FREE( ctr ); + for (i=0; i < count; i++) { + display_printer_data(info[i].value_name, + info[i].type, + info[i].data); + } -done: - if (is_valid_policy_hnd(&hnd)) + done: + if (is_valid_policy_hnd(&hnd)) { rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL); + } return result; } @@ -2707,25 +2596,27 @@ done: /**************************************************************************** ****************************************************************************/ -static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, int argc, - const char **argv) +static WERROR cmd_spoolss_enum_printerkey(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) { WERROR result; const char *printername; const char *keyname = NULL; - POLICY_HND hnd; - uint16 *keylist = NULL, *curkey; + struct policy_handle hnd; + const char **key_buffer = NULL; + int i; if (argc < 2 || argc > 3) { printf("Usage: %s printername [keyname]\n", argv[0]); return WERR_OK; } - if (argc == 3) + if (argc == 3) { keyname = argv[2]; - else + } else { keyname = ""; + } /* Open printer handle */ @@ -2735,34 +2626,31 @@ static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli, printername, SEC_FLAG_MAXIMUM_ALLOWED, &hnd); - if (!W_ERROR_IS_OK(result)) + if (!W_ERROR_IS_OK(result)) { goto done; + } /* Enumerate subkeys */ - result = rpccli_spoolss_enumprinterkey(cli, mem_ctx, &hnd, keyname, &keylist, NULL); + result = rpccli_spoolss_enumprinterkey(cli, mem_ctx, + &hnd, + keyname, + &key_buffer, + 0); - if (!W_ERROR_IS_OK(result)) + if (!W_ERROR_IS_OK(result)) { goto done; - - curkey = keylist; - while (*curkey != 0) { - char *subkey = NULL; - rpcstr_pull_talloc(mem_ctx, &subkey, curkey, -1, - STR_TERMINATE); - if (!subkey) { - break; - } - printf("%s\n", subkey); - curkey += strlen(subkey) + 1; } -done: + for (i=0; key_buffer && key_buffer[i]; i++) { + printf("%s\n", key_buffer[i]); + } - SAFE_FREE(keylist); + done: - if (is_valid_policy_hnd(&hnd)) + if (is_valid_policy_hnd(&hnd)) { rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL); + } return result; } @@ -2776,7 +2664,7 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli, { const char *printername; const char *clientname; - POLICY_HND hnd; + struct policy_handle hnd; WERROR result; NTSTATUS status; struct spoolss_NotifyOption option; @@ -2813,21 +2701,21 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli, option.types[0].type = PRINTER_NOTIFY_TYPE; option.types[0].count = 1; - option.types[0].fields = talloc_array(mem_ctx, enum spoolss_Field, 1); + option.types[0].fields = talloc_array(mem_ctx, union spoolss_Field, 1); if (option.types[0].fields == NULL) { result = WERR_NOMEM; goto done; } - option.types[0].fields[0] = PRINTER_NOTIFY_SERVER_NAME; + option.types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME; option.types[1].type = JOB_NOTIFY_TYPE; option.types[1].count = 1; - option.types[1].fields = talloc_array(mem_ctx, enum spoolss_Field, 1); + option.types[1].fields = talloc_array(mem_ctx, union spoolss_Field, 1); if (option.types[1].fields == NULL) { result = WERR_NOMEM; goto done; } - option.types[1].fields[0] = JOB_NOTIFY_PRINTER_NAME; + option.types[1].fields[0].field = JOB_NOTIFY_FIELD_PRINTER_NAME; clientname = talloc_asprintf(mem_ctx, "\\\\%s", global_myname()); if (!clientname) { @@ -2860,8 +2748,8 @@ done: /**************************************************************************** ****************************************************************************/ -static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, - struct rpc_pipe_client *cli2, POLICY_HND *hnd2 ) +static bool compare_printer( struct rpc_pipe_client *cli1, struct policy_handle *hnd1, + struct rpc_pipe_client *cli2, struct policy_handle *hnd2 ) { union spoolss_PrinterInfo info1, info2; WERROR werror; @@ -2901,8 +2789,8 @@ static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, /**************************************************************************** ****************************************************************************/ -static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, - struct rpc_pipe_client *cli2, POLICY_HND *hnd2 ) +static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy_handle *hnd1, + struct rpc_pipe_client *cli2, struct policy_handle *hnd2 ) { union spoolss_PrinterInfo info1, info2; WERROR werror; @@ -2976,7 +2864,7 @@ static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli, char *printername_path = NULL; struct cli_state *cli_server2 = NULL; struct rpc_pipe_client *cli2 = NULL; - POLICY_HND hPrinter1, hPrinter2; + struct policy_handle hPrinter1, hPrinter2; NTSTATUS nt_status; WERROR werror; @@ -3001,7 +2889,7 @@ static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli, if ( !NT_STATUS_IS_OK(nt_status) ) return WERR_GENERAL_FAILURE; - nt_status = cli_rpc_pipe_open_noauth(cli_server2, &syntax_spoolss, + nt_status = cli_rpc_pipe_open_noauth(cli_server2, &ndr_table_spoolss.syntax_id, &cli2); if (!NT_STATUS_IS_OK(nt_status)) { printf("failed to open spoolss pipe on server %s (%s)\n", @@ -3059,41 +2947,214 @@ done: return WERR_OK; } +static void display_proc_info1(struct spoolss_PrintProcessorInfo1 *r) +{ + printf("print_processor_name: %s\n", r->print_processor_name); +} + +static WERROR cmd_spoolss_enum_procs(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + WERROR werror; + const char *environment = SPOOLSS_ARCHITECTURE_NT_X86; + uint32_t num_procs, level = 1, i; + union spoolss_PrintProcessorInfo *procs; + + /* Parse the command arguments */ + + if (argc < 1 || argc > 4) { + printf ("Usage: %s [environment] [level]\n", argv[0]); + return WERR_OK; + } + + if (argc >= 2) { + environment = argv[1]; + } + + if (argc == 3) { + level = atoi(argv[2]); + } + + /* Enumerate Print Processors */ + + werror = rpccli_spoolss_enumprintprocessors(cli, mem_ctx, + cli->srv_name_slash, + environment, + level, + 0, + &num_procs, + &procs); + if (!W_ERROR_IS_OK(werror)) + goto done; + + /* Display output */ + + for (i = 0; i < num_procs; i++) { + switch (level) { + case 1: + display_proc_info1(&procs[i].info1); + break; + } + } + + done: + return werror; +} + +static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1 *r) +{ + printf("name_array: %s\n", r->name_array); +} + +static WERROR cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + WERROR werror; + const char *print_processor_name = "winprint"; + uint32_t num_procs, level = 1, i; + union spoolss_PrintProcDataTypesInfo *procs; + + /* Parse the command arguments */ + + if (argc < 1 || argc > 4) { + printf ("Usage: %s [environment] [level]\n", argv[0]); + return WERR_OK; + } + + if (argc >= 2) { + print_processor_name = argv[1]; + } + + if (argc == 3) { + level = atoi(argv[2]); + } + + /* Enumerate Print Processor Data Types */ + + werror = rpccli_spoolss_enumprintprocessordatatypes(cli, mem_ctx, + cli->srv_name_slash, + print_processor_name, + level, + 0, + &num_procs, + &procs); + if (!W_ERROR_IS_OK(werror)) + goto done; + + /* Display output */ + + for (i = 0; i < num_procs; i++) { + switch (level) { + case 1: + display_proc_data_types_info1(&procs[i].info1); + break; + } + } + + done: + return werror; +} + +static void display_monitor1(const struct spoolss_MonitorInfo1 *r) +{ + printf("monitor_name: %s\n", r->monitor_name); +} + +static void display_monitor2(const struct spoolss_MonitorInfo2 *r) +{ + printf("monitor_name: %s\n", r->monitor_name); + printf("environment: %s\n", r->environment); + printf("dll_name: %s\n", r->dll_name); +} + +static WERROR cmd_spoolss_enum_monitors(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + WERROR werror; + uint32_t count, level = 1, i; + union spoolss_MonitorInfo *info; + + /* Parse the command arguments */ + + if (argc > 2) { + printf("Usage: %s [level]\n", argv[0]); + return WERR_OK; + } + + if (argc == 2) { + level = atoi(argv[1]); + } + + /* Enumerate Print Monitors */ + + werror = rpccli_spoolss_enummonitors(cli, mem_ctx, + cli->srv_name_slash, + level, + 0, + &count, + &info); + if (!W_ERROR_IS_OK(werror)) { + goto done; + } + + /* Display output */ + + for (i = 0; i < count; i++) { + switch (level) { + case 1: + display_monitor1(&info[i].info1); + break; + case 2: + display_monitor2(&info[i].info2); + break; + } + } + + done: + return werror; +} + /* List of commands exported by this module */ struct cmd_set spoolss_commands[] = { { "SPOOLSS" }, - { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, &syntax_spoolss, NULL, "Add a print driver", "" }, - { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, &syntax_spoolss, NULL, "Add a printer", "" }, - { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, &syntax_spoolss, NULL, "Delete a printer driver", "" }, - { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, &syntax_spoolss, NULL, "Delete a printer driver with files", "" }, - { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, &syntax_spoolss, NULL, "Enumerate printer data", "" }, - { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, &syntax_spoolss, NULL, "Enumerate printer data for a key", "" }, - { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, &syntax_spoolss, NULL, "Enumerate printer keys", "" }, - { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, &syntax_spoolss, NULL, "Enumerate print jobs", "" }, - { "getjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_get_job, &syntax_spoolss, NULL, "Get print job", "" }, - { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, &syntax_spoolss, NULL, "Enumerate printer ports", "" }, - { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, &syntax_spoolss, NULL, "Enumerate installed printer drivers", "" }, - { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, &syntax_spoolss, NULL, "Enumerate printers", "" }, - { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, &syntax_spoolss, NULL, "Get print driver data", "" }, - { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, &syntax_spoolss, NULL, "Get printer driver data with keyname", ""}, - { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, &syntax_spoolss, NULL, "Get print driver information", "" }, - { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, &syntax_spoolss, NULL, "Get print driver upload directory", "" }, - { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, &syntax_spoolss, NULL, "Get printer info", "" }, - { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, &syntax_spoolss, NULL, "Open printer handle", "" }, - { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, &syntax_spoolss, NULL, "Set printer driver", "" }, - { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, &syntax_spoolss, NULL, "Get print processor directory", "" }, - { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, &syntax_spoolss, NULL, "Add form", "" }, - { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, &syntax_spoolss, NULL, "Set form", "" }, - { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, &syntax_spoolss, NULL, "Get form", "" }, - { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, &syntax_spoolss, NULL, "Delete form", "" }, - { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, &syntax_spoolss, NULL, "Enumerate forms", "" }, - { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, &syntax_spoolss, NULL, "Set printer comment", "" }, - { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, &syntax_spoolss, NULL, "Set printername", "" }, - { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, &syntax_spoolss, NULL, "Set REG_SZ printer data", "" }, - { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, &syntax_spoolss, NULL, "Rffpcnex test", "" }, - { "printercmp", RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp, &syntax_spoolss, NULL, "Printer comparison test", "" }, + { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, &ndr_table_spoolss.syntax_id, NULL, "Add a print driver", "" }, + { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, &ndr_table_spoolss.syntax_id, NULL, "Add a printer", "" }, + { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver", "" }, + { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver with files", "" }, + { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data", "" }, + { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data for a key", "" }, + { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer keys", "" }, + { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate print jobs", "" }, + { "getjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_get_job, &ndr_table_spoolss.syntax_id, NULL, "Get print job", "" }, + { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer ports", "" }, + { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, &ndr_table_spoolss.syntax_id, NULL, "Enumerate installed printer drivers", "" }, + { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printers", "" }, + { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, &ndr_table_spoolss.syntax_id, NULL, "Get print driver data", "" }, + { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, &ndr_table_spoolss.syntax_id, NULL, "Get printer driver data with keyname", ""}, + { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, &ndr_table_spoolss.syntax_id, NULL, "Get print driver information", "" }, + { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, &ndr_table_spoolss.syntax_id, NULL, "Get print driver upload directory", "" }, + { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, &ndr_table_spoolss.syntax_id, NULL, "Get printer info", "" }, + { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, &ndr_table_spoolss.syntax_id, NULL, "Open printer handle", "" }, + { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, &ndr_table_spoolss.syntax_id, NULL, "Set printer driver", "" }, + { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, &ndr_table_spoolss.syntax_id, NULL, "Get print processor directory", "" }, + { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, &ndr_table_spoolss.syntax_id, NULL, "Add form", "" }, + { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, &ndr_table_spoolss.syntax_id, NULL, "Set form", "" }, + { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, &ndr_table_spoolss.syntax_id, NULL, "Get form", "" }, + { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, &ndr_table_spoolss.syntax_id, NULL, "Delete form", "" }, + { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, &ndr_table_spoolss.syntax_id, NULL, "Enumerate forms", "" }, + { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, &ndr_table_spoolss.syntax_id, NULL, "Set printer comment", "" }, + { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, &ndr_table_spoolss.syntax_id, NULL, "Set printername", "" }, + { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, &ndr_table_spoolss.syntax_id, NULL, "Set REG_SZ printer data", "" }, + { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, &ndr_table_spoolss.syntax_id, NULL, "Rffpcnex test", "" }, + { "printercmp", RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp, &ndr_table_spoolss.syntax_id, NULL, "Printer comparison test", "" }, + { "enumprocs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_procs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processors", "" }, + { "enumprocdatatypes", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_proc_data_types, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processor Data Types", "" }, + { "enummonitors", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_monitors, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Monitors", "" }, { NULL } }; diff --git a/source3/rpcclient/cmd_test.c b/source3/rpcclient/cmd_test.c index 0f1d4221ca..b7be038539 100644 --- a/source3/rpcclient/cmd_test.c +++ b/source3/rpcclient/cmd_test.c @@ -26,7 +26,7 @@ static NTSTATUS cmd_testme(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, { struct rpc_pipe_client *lsa_pipe = NULL, *samr_pipe = NULL; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - POLICY_HND pol; + struct policy_handle pol; d_printf("testme\n"); diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 9a02c129b5..a202dcc5f3 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -133,7 +133,7 @@ static char *next_command (char **cmdstr) static void fetch_machine_sid(struct cli_state *cli) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_OK; static bool got_domain_sid; TALLOC_CTX *mem_ctx; @@ -868,12 +868,7 @@ out_free: goto done; } - if (!get_cmdline_auth_info_got_pass(rpcclient_auth_info)) { - char *pass = getpass("Password:"); - if (pass) { - set_cmdline_auth_info_password(rpcclient_auth_info, pass); - } - } + set_cmdline_auth_info_getpass(rpcclient_auth_info); if ((server[0] == '/' && server[1] == '/') || (server[0] == '\\' && server[1] == '\\')) { diff --git a/source3/samba4.m4 b/source3/samba4.m4 index d11d3be2d5..b5c7c74689 100644 --- a/source3/samba4.m4 +++ b/source3/samba4.m4 @@ -67,14 +67,16 @@ AC_CONFIG_FILES(../source4/param/samba-hostconfig.pc) AC_CONFIG_FILES(../source4/librpc/dcerpc_samr.pc) AC_CONFIG_FILES(../source4/librpc/dcerpc_atsvc.pc) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBTALLOC, talloc >= 1.2.0, +m4_include(../source4/min_versions.m4) + +SMB_EXT_LIB_FROM_PKGCONFIG(LIBTALLOC, talloc >= $TALLOC_MIN_VERSION, [], [ SMB_INCLUDE_MK(../lib/talloc/config.mk) ] ) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= 1.1.3, +SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= $TDB_MIN_VERSION, [], [ m4_include(../lib/tdb/libtdb.m4) @@ -84,13 +86,13 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= 1.1.3, SMB_INCLUDE_MK(../lib/tdb/python.mk) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent = 0.9.3, +SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent = $TEVENT_REQUIRED_VERSION, [],[m4_include(../lib/tevent/samba.m4)] ) SMB_INCLUDE_MK(../lib/tevent/python.mk) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb = 0.9.3, +SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb = $LDB_REQUIRED_VERSION, [ SMB_INCLUDE_MK(lib/ldb/ldb_ildap/config.mk) SMB_INCLUDE_MK(lib/ldb/tools/config.mk) @@ -152,6 +154,14 @@ fi dnl Samba 4 files AC_SUBST(LD) AC_LIBREPLACE_SHLD_FLAGS +dnl Remove -L/usr/lib/? from LDFLAGS and LIBS +LIB_REMOVE_USR_LIB(LDFLAGS) +LIB_REMOVE_USR_LIB(LIBS) +LIB_REMOVE_USR_LIB(KRB5_LIBS) + +dnl Remove -I/usr/include/? from CFLAGS and CPPFLAGS +CFLAGS_REMOVE_USR_INCLUDE(CFLAGS) +CFLAGS_REMOVE_USR_INCLUDE(CPPFLAGS) SMB_WRITE_MAKEVARS(samba4-config.mk, [prefix exec_prefix CPPFLAGS LDSHFLAGS POPT_OBJ CFLAGS TALLOC_OBJ POPT_LIBS srcdir builddir]) oldbuilddir="$builddir" diff --git a/source3/samba4.mk b/source3/samba4.mk index 10e3f76bbf..7e7690aadf 100644 --- a/source3/samba4.mk +++ b/source3/samba4.mk @@ -89,7 +89,7 @@ socketwrappersrcdir := $(samba4srcdir)/../lib/socket_wrapper nsswrappersrcdir := $(samba4srcdir)/../lib/nss_wrapper libstreamsrcdir := $(samba4srcdir)/lib/stream libutilsrcdir := $(samba4srcdir)/../lib/util -libtdrsrcdir := $(samba4srcdir)/lib/tdr +libtdrsrcdir := ../lib/tdr libcryptosrcdir := $(samba4srcdir)/../lib/crypto libtorturesrcdir := ../lib/torture libcompressionsrcdir := $(samba4srcdir)/../lib/compression diff --git a/source3/script/installmo.sh b/source3/script/installmo.sh index 9c4ab1eefe..5ca3371d80 100644 --- a/source3/script/installmo.sh +++ b/source3/script/installmo.sh @@ -35,7 +35,7 @@ for dir in $SRCDIR/locale/*; do if test "$mode" = 'install'; then echo "Installing $f as $FNAME" touch "$FNAME" - $MSGFMT "$f" -f -o "$FNAME" + $MSGFMT -f -o "$FNAME" "$f" if test ! -f "$FNAME"; then echo "Cannot install $FNAME. Does $USER have privileges?" exit 1 diff --git a/source3/script/mkversion.sh b/source3/script/mkversion.sh index a55aafcd0c..ce9d2af4c0 100755 --- a/source3/script/mkversion.sh +++ b/source3/script/mkversion.sh @@ -112,6 +112,7 @@ if test -n "${SAMBA_VERSION_VENDOR_SUFFIX}";then SAMBA_VERSION_STRING="${SAMBA_VERSION_STRING}-${SAMBA_VERSION_VENDOR_SUFFIX}" if test -n "${SAMBA_VERSION_VENDOR_PATCH}";then echo "#define SAMBA_VERSION_VENDOR_PATCH ${SAMBA_VERSION_VENDOR_PATCH}" >> $OUTPUT_FILE + echo "#define SAMBA_VERSION_VENDOR_PATCH_STRING \"${SAMBA_VERSION_VENDOR_PATCH}\"" >> $OUTPUT_FILE SAMBA_VERSION_STRING="${SAMBA_VERSION_STRING}-${SAMBA_VERSION_VENDOR_PATCH}" fi fi @@ -130,7 +131,7 @@ cat >>$OUTPUT_FILE<<CEOF #else /* SAMBA_VERSION_VENDOR_FUNCTION */ # ifdef SAMBA_VERSION_VENDOR_SUFFIX # ifdef SAMBA_VERSION_VENDOR_PATCH -# define SAMBA_VERSION_STRING SAMBA_VERSION_OFFICIAL_STRING "-" SAMBA_VERSION_VENDOR_SUFFIX "-" SAMBA_VERSION_VENDOR_PATCH +# define SAMBA_VERSION_STRING SAMBA_VERSION_OFFICIAL_STRING "-" SAMBA_VERSION_VENDOR_SUFFIX "-" SAMBA_VERSION_VENDOR_PATCH_STRING # else /* SAMBA_VERSION_VENDOR_PATCH */ # define SAMBA_VERSION_STRING SAMBA_VERSION_OFFICIAL_STRING "-" SAMBA_VERSION_VENDOR_SUFFIX # endif /* SAMBA_VERSION_VENDOR_SUFFIX */ diff --git a/source3/script/tests/selftest.sh b/source3/script/tests/selftest.sh index 94621841f5..a430d01a0e 100755 --- a/source3/script/tests/selftest.sh +++ b/source3/script/tests/selftest.sh @@ -104,13 +104,14 @@ SAMBA4SHAREDDIR="$SAMBA4BINDIR/shared" export SAMBA4SHAREDDIR export SMBTORTURE4 -if test x"$LD_LIBRARY_PATH" != x""; then - LD_LIBRARY_PATH="$BINDIR:$SAMBA4SHAREDDIR:$LD_LIBRARY_PATH" -else - LD_LIBRARY_PATH="$BINDIR:$SAMBA4SHAREDDIR" +if [ -z "$LIB_PATH_VAR" ] ; then + echo "Warning: LIB_PATH_VAR not set. Using best guess LD_LIBRARY_PATH." >&2 + LIB_PATH_VAR=LD_LIBRARY_PATH + export LIB_PATH_VAR fi -echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -export LD_LIBRARY_PATH + +eval $LIB_PATH_VAR=$BINDIR:$SAMBA4SHAREDDIR:\$$LIB_PATH_VAR +export $LIB_PATH_VAR ## ## verify that we were built with --enable-socket-wrapper diff --git a/source3/script/tests/test_smbtorture_s3.sh b/source3/script/tests/test_smbtorture_s3.sh index 842277b357..70c6d34c88 100755 --- a/source3/script/tests/test_smbtorture_s3.sh +++ b/source3/script/tests/test_smbtorture_s3.sh @@ -27,7 +27,7 @@ tests="$tests UNLINK BROWSE ATTR TRANS2 TORTURE " tests="$tests OPLOCK1 OPLOCK2 OPLOCK3" tests="$tests DIR DIR1 TCON TCONDEV RW1 RW2 RW3" tests="$tests OPEN XCOPY RENAME DELETE PROPERTIES W2K" -tests="$tests TCON2 IOCTL CHKPATH FDSESS LOCAL-SUBSTITUTE" +tests="$tests TCON2 IOCTL CHKPATH FDSESS LOCAL-SUBSTITUTE CHAIN1" skipped1="RANDOMIPC NEGNOWAIT NBENCH ERRMAPEXTRACT TRANS2SCAN NTTRANSSCAN" skipped2="DENY1 DENY2 OPENATTR CASETABLE EATEST" diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c index 6b19e098e5..cfa4b430eb 100644 --- a/source3/smbd/aio.c +++ b/source3/smbd/aio.c @@ -347,7 +347,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex) /* If errno is ECANCELED then don't return anything to the * client. */ if (errno == ECANCELED) { - srv_cancel_sign_response(aio_ex->req->mid); + srv_cancel_sign_response(aio_ex->req->mid, false); return 0; } @@ -441,7 +441,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) /* If errno is ECANCELED then don't return anything to the * client. */ if (errno == ECANCELED) { - srv_cancel_sign_response(aio_ex->req->mid); + srv_cancel_sign_response(aio_ex->req->mid, false); return 0; } @@ -534,7 +534,7 @@ void smbd_aio_complete_mid(unsigned int mid) if (!aio_ex) { DEBUG(3,("smbd_aio_complete_mid: Can't find record to " "match mid %u.\n", mid)); - srv_cancel_sign_response(mid); + srv_cancel_sign_response(mid, false); return; } @@ -544,7 +544,7 @@ void smbd_aio_complete_mid(unsigned int mid) * ignore. */ DEBUG( 3,( "smbd_aio_complete_mid: file closed whilst " "aio outstanding (mid[%u]).\n", mid)); - srv_cancel_sign_response(mid); + srv_cancel_sign_response(mid, false); return; } diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index 4b467b0312..a52f2d2e96 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -140,6 +140,7 @@ find_again: return NULL; } conn->cnum = i; + conn->force_group_gid = (gid_t)-1; bitmap_set(bmap, i); diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c index fe7ba1cc46..abffcd2f4f 100644 --- a/source3/smbd/file_access.c +++ b/source3/smbd/file_access.c @@ -34,6 +34,11 @@ bool can_access_file_acl(struct connection_struct *conn, uint32_t access_granted; struct security_descriptor *secdesc = NULL; + if (conn->server_info->utok.uid == 0 || conn->admin_user) { + /* I'm sorry sir, I didn't know you were root... */ + return true; + } + status = SMB_VFS_GET_NT_ACL(conn, fname, (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index d18b5debe0..f20c851297 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -211,14 +211,14 @@ struct dcerpc_cmd_state { size_t max_read; }; -static void api_dcerpc_cmd_write_done(struct async_req *subreq); -static void api_dcerpc_cmd_read_done(struct async_req *subreq); +static void api_dcerpc_cmd_write_done(struct tevent_req *subreq); +static void api_dcerpc_cmd_read_done(struct tevent_req *subreq); static void api_dcerpc_cmd(connection_struct *conn, struct smb_request *req, files_struct *fsp, uint8_t *data, size_t length, size_t max_read) { - struct async_req *subreq; + struct tevent_req *subreq; struct dcerpc_cmd_state *state; if (!fsp_is_np(fsp)) { @@ -254,14 +254,14 @@ static void api_dcerpc_cmd(connection_struct *conn, struct smb_request *req, reply_nterror(req, NT_STATUS_NO_MEMORY); return; } - subreq->async.fn = api_dcerpc_cmd_write_done; - subreq->async.priv = talloc_move(conn, &req); + tevent_req_set_callback(subreq, api_dcerpc_cmd_write_done, + talloc_move(conn, &req)); } -static void api_dcerpc_cmd_write_done(struct async_req *subreq) +static void api_dcerpc_cmd_write_done(struct tevent_req *subreq) { - struct smb_request *req = talloc_get_type_abort( - subreq->async.priv, struct smb_request); + struct smb_request *req = tevent_req_callback_data( + subreq, struct smb_request); struct dcerpc_cmd_state *state = talloc_get_type_abort( req->async_priv, struct dcerpc_cmd_state); NTSTATUS status; @@ -290,9 +290,7 @@ static void api_dcerpc_cmd_write_done(struct async_req *subreq) reply_nterror(req, NT_STATUS_NO_MEMORY); goto send; } - - subreq->async.fn = api_dcerpc_cmd_read_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, api_dcerpc_cmd_read_done, req); return; send: @@ -305,10 +303,10 @@ static void api_dcerpc_cmd_write_done(struct async_req *subreq) TALLOC_FREE(req); } -static void api_dcerpc_cmd_read_done(struct async_req *subreq) +static void api_dcerpc_cmd_read_done(struct tevent_req *subreq) { - struct smb_request *req = talloc_get_type_abort( - subreq->async.priv, struct smb_request); + struct smb_request *req = tevent_req_callback_data( + subreq, struct smb_request); struct dcerpc_cmd_state *state = talloc_get_type_abort( req->async_priv, struct dcerpc_cmd_state); NTSTATUS status; diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 86a46505a2..9c7fb1914e 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1131,7 +1131,7 @@ void reply_ntcancel(struct smb_request *req) START_PROFILE(SMBntcancel); remove_pending_change_notify_requests_by_mid(req->mid); remove_pending_lock_requests_by_mid(req->mid); - srv_cancel_sign_response(req->mid); + srv_cancel_sign_response(req->mid, true); DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", req->mid)); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 569c260319..d529b009d5 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -76,6 +76,15 @@ static NTSTATUS check_open_rights(struct connection_struct *conn, *access_granted = 0; + if (conn->server_info->utok.uid == 0 || conn->admin_user) { + /* I'm sorry sir, I didn't know you were root... */ + *access_granted = access_mask; + if (access_mask & SEC_FLAG_MAXIMUM_ALLOWED) { + *access_granted |= FILE_GENERIC_ALL; + } + return NT_STATUS_OK; + } + status = SMB_VFS_GET_NT_ACL(conn, fname, (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | @@ -445,8 +454,26 @@ static NTSTATUS open_file(files_struct *fsp, &access_granted); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + /* + * On NT_STATUS_ACCESS_DENIED, access_granted + * contains the denied bits. + */ + + if ((access_mask & FILE_WRITE_ATTRIBUTES) && + (access_granted & FILE_WRITE_ATTRIBUTES) && + (lp_map_readonly(SNUM(conn)) || + lp_map_archive(SNUM(conn)) || + lp_map_hidden(SNUM(conn)) || + lp_map_system(SNUM(conn)))) { + access_granted &= ~FILE_WRITE_ATTRIBUTES; + + DEBUG(10,("open_file: overrode FILE_WRITE_ATTRIBUTES " + "on file %s\n", + path )); + } + if ((access_mask & DELETE_ACCESS) && - (access_granted == DELETE_ACCESS) && + (access_granted & DELETE_ACCESS) && can_delete_file_in_directory(conn, path)) { /* Were we trying to do a stat open * for delete and didn't get DELETE @@ -456,10 +483,14 @@ static NTSTATUS open_file(files_struct *fsp, * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx * for details. */ - DEBUG(10,("open_file: overrode ACCESS_DENIED " + access_granted &= ~DELETE_ACCESS; + + DEBUG(10,("open_file: overrode DELETE_ACCESS " "on file %s\n", path )); - } else { + } + + if (access_granted != 0) { DEBUG(10, ("open_file: Access denied on " "file %s\n", path)); @@ -2377,6 +2408,14 @@ static NTSTATUS open_directory(connection_struct *conn, return status; } + /* We need to support SeSecurityPrivilege for this. */ + if (access_mask & SEC_RIGHT_SYSTEM_SECURITY) { + DEBUG(10, ("open_directory: open on %s " + "failed - SEC_RIGHT_SYSTEM_SECURITY denied.\n", + fname)); + return NT_STATUS_PRIVILEGE_NOT_HELD; + } + switch( create_disposition ) { case FILE_OPEN: @@ -2710,7 +2749,7 @@ struct case_semantics_state *set_posix_case_semantics(TALLOC_CTX *mem_ctx, * If that works, delete them all by setting the delete on close and close. */ -static NTSTATUS open_streams_for_delete(connection_struct *conn, +NTSTATUS open_streams_for_delete(connection_struct *conn, const char *fname) { struct stream_struct *stream_info; @@ -2768,13 +2807,15 @@ static NTSTATUS open_streams_for_delete(connection_struct *conn, goto fail; } - status = create_file_unixpath - (conn, /* conn */ + status = SMB_VFS_CREATE_FILE( + conn, /* conn */ NULL, /* req */ + 0, /* root_dir_fid */ streamname, /* fname */ + 0, /* create_file_flags */ DELETE_ACCESS, /* access_mask */ - FILE_SHARE_READ | FILE_SHARE_WRITE - | FILE_SHARE_DELETE, /* share_access */ + (FILE_SHARE_READ | /* share_access */ + FILE_SHARE_WRITE | FILE_SHARE_DELETE), FILE_OPEN, /* create_disposition*/ NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* create_options */ FILE_ATTRIBUTE_NORMAL, /* file_attributes */ @@ -2920,6 +2961,20 @@ static NTSTATUS create_file_unixpath(connection_struct *conn, status = NT_STATUS_PRIVILEGE_NOT_HELD; goto fail; } +#else + /* We need to support SeSecurityPrivilege for this. */ + if (access_mask & SEC_RIGHT_SYSTEM_SECURITY) { + status = NT_STATUS_PRIVILEGE_NOT_HELD; + goto fail; + } + /* Don't allow a SACL set from an NTtrans create until we + * support SeSecurityPrivilege. */ + if (!VALID_STAT(sbuf) && + lp_nt_acl_support(SNUM(conn)) && + sd && (sd->sacl != NULL)) { + status = NT_STATUS_PRIVILEGE_NOT_HELD; + goto fail; + } #endif if ((conn->fs_capabilities & FILE_NAMED_STREAMS) diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 6fd4031f3d..2686cf41d9 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -148,14 +148,14 @@ struct pipe_write_state { size_t numtowrite; }; -static void pipe_write_done(struct async_req *subreq); +static void pipe_write_done(struct tevent_req *subreq); void reply_pipe_write(struct smb_request *req) { files_struct *fsp = file_fsp(req, SVAL(req->vwv+0, 0)); const uint8_t *data; struct pipe_write_state *state; - struct async_req *subreq; + struct tevent_req *subreq; if (!fsp_is_np(fsp)) { reply_doserror(req, ERRDOS, ERRbadfid); @@ -188,14 +188,14 @@ void reply_pipe_write(struct smb_request *req) reply_nterror(req, NT_STATUS_NO_MEMORY); return; } - subreq->async.fn = pipe_write_done; - subreq->async.priv = talloc_move(req->conn, &req); + tevent_req_set_callback(subreq, pipe_write_done, + talloc_move(req->conn, &req)); } -static void pipe_write_done(struct async_req *subreq) +static void pipe_write_done(struct tevent_req *subreq) { - struct smb_request *req = talloc_get_type_abort( - subreq->async.priv, struct smb_request); + struct smb_request *req = tevent_req_callback_data( + subreq, struct smb_request); struct pipe_write_state *state = talloc_get_type_abort( req->async_priv, struct pipe_write_state); NTSTATUS status; @@ -235,7 +235,7 @@ struct pipe_write_andx_state { size_t numtowrite; }; -static void pipe_write_andx_done(struct async_req *subreq); +static void pipe_write_andx_done(struct tevent_req *subreq); void reply_pipe_write_and_X(struct smb_request *req) { @@ -243,7 +243,7 @@ void reply_pipe_write_and_X(struct smb_request *req) int smb_doff = SVAL(req->vwv+11, 0); uint8_t *data; struct pipe_write_andx_state *state; - struct async_req *subreq; + struct tevent_req *subreq; if (!fsp_is_np(fsp)) { reply_doserror(req, ERRDOS, ERRbadfid); @@ -297,14 +297,14 @@ void reply_pipe_write_and_X(struct smb_request *req) reply_nterror(req, NT_STATUS_NO_MEMORY); return; } - subreq->async.fn = pipe_write_andx_done; - subreq->async.priv = talloc_move(req->conn, &req); + tevent_req_set_callback(subreq, pipe_write_andx_done, + talloc_move(req->conn, &req)); } -static void pipe_write_andx_done(struct async_req *subreq) +static void pipe_write_andx_done(struct tevent_req *subreq) { - struct smb_request *req = talloc_get_type_abort( - subreq->async.priv, struct smb_request); + struct smb_request *req = tevent_req_callback_data( + subreq, struct smb_request); struct pipe_write_andx_state *state = talloc_get_type_abort( req->async_priv, struct pipe_write_andx_state); NTSTATUS status; @@ -340,14 +340,14 @@ struct pipe_read_andx_state { int smb_maxcnt; }; -static void pipe_read_andx_done(struct async_req *subreq); +static void pipe_read_andx_done(struct tevent_req *subreq); void reply_pipe_read_and_X(struct smb_request *req) { files_struct *fsp = file_fsp(req, SVAL(req->vwv+0, 0)); uint8_t *data; struct pipe_read_andx_state *state; - struct async_req *subreq; + struct tevent_req *subreq; /* we don't use the offset given to use for pipe reads. This is deliberate, instead we always return the next lump of @@ -392,14 +392,14 @@ void reply_pipe_read_and_X(struct smb_request *req) reply_nterror(req, NT_STATUS_NO_MEMORY); return; } - subreq->async.fn = pipe_read_andx_done; - subreq->async.priv = talloc_move(req->conn, &req); + tevent_req_set_callback(subreq, pipe_read_andx_done, + talloc_move(req->conn, &req)); } -static void pipe_read_andx_done(struct async_req *subreq) +static void pipe_read_andx_done(struct tevent_req *subreq) { - struct smb_request *req = talloc_get_type_abort( - subreq->async.priv, struct smb_request); + struct smb_request *req = tevent_req_callback_data( + subreq, struct smb_request); struct pipe_read_andx_state *state = talloc_get_type_abort( req->async_priv, struct pipe_read_andx_state); NTSTATUS status; diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 22e4c1aad7..8b560bd8ca 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -72,11 +72,16 @@ static NTSTATUS check_path_syntax_internal(char *path, } } - if (!stream_started && *s == ':') { + if (!posix_path && !stream_started && *s == ':') { if (*p_last_component_contains_wcard) { return NT_STATUS_OBJECT_NAME_INVALID; } - /* stream names allow more characters than file names */ + /* Stream names allow more characters than file names. + We're overloading posix_path here to allow a wider + range of characters. If stream_started is true this + is still a Windows path even if posix_path is true. + JRA. + */ stream_started = true; start_of_name_component = false; posix_path = true; @@ -2859,6 +2864,7 @@ void reply_readbraw(struct smb_request *req) size_t nread = 0; SMB_OFF_T startpos; files_struct *fsp; + struct lock_struct lock; SMB_STRUCT_STAT st; SMB_OFF_T size = 0; @@ -2959,10 +2965,11 @@ void reply_readbraw(struct smb_request *req) /* ensure we don't overrun the packet size */ maxcount = MIN(65535,maxcount); - if (is_locked(fsp,(uint32)req->smbpid, - (uint64_t)maxcount, - (uint64_t)startpos, - READ_LOCK)) { + init_strict_lock_struct(fsp, (uint32)req->smbpid, + (uint64_t)startpos, (uint64_t)maxcount, READ_LOCK, + &lock); + + if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { reply_readbraw_error(); END_PROFILE(SMBreadbraw); return; @@ -2993,7 +3000,11 @@ void reply_readbraw(struct smb_request *req) send_file_readbraw(conn, req, fsp, startpos, nread, mincount); DEBUG(5,("reply_readbraw finished\n")); + + SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); + END_PROFILE(SMBreadbraw); + return; } #undef DBGC_CLASS @@ -3121,6 +3132,7 @@ void reply_read(struct smb_request *req) SMB_OFF_T startpos; int outsize = 0; files_struct *fsp; + struct lock_struct lock; START_PROFILE(SMBread); @@ -3162,8 +3174,11 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n", data = smb_buf(req->outbuf) + 3; - if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtoread, - (uint64_t)startpos, READ_LOCK)) { + init_strict_lock_struct(fsp, (uint32)req->smbpid, + (uint64_t)startpos, (uint64_t)numtoread, READ_LOCK, + &lock); + + if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { reply_doserror(req, ERRDOS,ERRlock); END_PROFILE(SMBread); return; @@ -3174,8 +3189,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n", if (nread < 0) { reply_unixerror(req, ERRDOS,ERRnoaccess); - END_PROFILE(SMBread); - return; + goto strict_unlock; } srv_set_message((char *)req->outbuf, 5, nread+3, False); @@ -3188,6 +3202,9 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n", DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n", fsp->fnum, (int)numtoread, (int)nread ) ); +strict_unlock: + SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); + END_PROFILE(SMBread); return; } @@ -3387,6 +3404,7 @@ void reply_read_and_X(struct smb_request *req) files_struct *fsp; SMB_OFF_T startpos; size_t smb_maxcnt; + struct lock_struct lock; bool big_readX = False; #if 0 size_t smb_mincnt = SVAL(req->vwv+6, 0); @@ -3474,8 +3492,11 @@ void reply_read_and_X(struct smb_request *req) } - if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)smb_maxcnt, - (uint64_t)startpos, READ_LOCK)) { + init_strict_lock_struct(fsp, (uint32)req->smbpid, + (uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK, + &lock); + + if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { END_PROFILE(SMBreadX); reply_doserror(req, ERRDOS, ERRlock); return; @@ -3483,12 +3504,14 @@ void reply_read_and_X(struct smb_request *req) if (!big_readX && schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) { - END_PROFILE(SMBreadX); - return; + goto strict_unlock; } send_file_readX(conn, req, fsp, startpos, smb_maxcnt); +strict_unlock: + SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); + END_PROFILE(SMBreadX); return; } @@ -3523,6 +3546,7 @@ void reply_writebraw(struct smb_request *req) char *data=NULL; bool write_through; files_struct *fsp; + struct lock_struct lock; NTSTATUS status; START_PROFILE(SMBwritebraw); @@ -3584,8 +3608,11 @@ void reply_writebraw(struct smb_request *req) return; } - if (is_locked(fsp,(uint32)req->smbpid,(uint64_t)tcount, - (uint64_t)startpos, WRITE_LOCK)) { + init_strict_lock_struct(fsp, (uint32)req->smbpid, + (uint64_t)startpos, (uint64_t)tcount, WRITE_LOCK, + &lock); + + if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { reply_doserror(req, ERRDOS, ERRlock); error_to_writebrawerr(req); END_PROFILE(SMBwritebraw); @@ -3604,8 +3631,7 @@ void reply_writebraw(struct smb_request *req) if (nwritten < (ssize_t)numtowrite) { reply_unixerror(req, ERRHRD, ERRdiskfull); error_to_writebrawerr(req); - END_PROFILE(SMBwritebraw); - return; + goto strict_unlock; } total_written = nwritten; @@ -3615,8 +3641,7 @@ void reply_writebraw(struct smb_request *req) if (!buf) { reply_doserror(req, ERRDOS, ERRnomem); error_to_writebrawerr(req); - END_PROFILE(SMBwritebraw); - return; + goto strict_unlock; } /* Return a SMBwritebraw message to the redirector to tell @@ -3674,8 +3699,7 @@ void reply_writebraw(struct smb_request *req) TALLOC_FREE(buf); reply_unixerror(req, ERRHRD, ERRdiskfull); error_to_writebrawerr(req); - END_PROFILE(SMBwritebraw); - return; + goto strict_unlock; } if (nwritten < (ssize_t)numtowrite) { @@ -3697,8 +3721,7 @@ void reply_writebraw(struct smb_request *req) fsp->fsp_name, nt_errstr(status) )); reply_nterror(req, status); error_to_writebrawerr(req); - END_PROFILE(SMBwritebraw); - return; + goto strict_unlock; } DEBUG(3,("reply_writebraw: secondart write fnum=%d start=%.0f num=%d " @@ -3706,6 +3729,8 @@ void reply_writebraw(struct smb_request *req) fsp->fnum, (double)startpos, (int)numtowrite, (int)total_written)); + SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); + /* We won't return a status if write through is not selected - this * follows what WfWg does */ END_PROFILE(SMBwritebraw); @@ -3726,6 +3751,12 @@ void reply_writebraw(struct smb_request *req) TALLOC_FREE(req->outbuf); } return; + +strict_unlock: + SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); + + END_PROFILE(SMBwritebraw); + return; } #undef DBGC_CLASS @@ -3744,6 +3775,7 @@ void reply_writeunlock(struct smb_request *req) const char *data; NTSTATUS status = NT_STATUS_OK; files_struct *fsp; + struct lock_struct lock; START_PROFILE(SMBwriteunlock); @@ -3770,12 +3802,16 @@ void reply_writeunlock(struct smb_request *req) startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0); data = (const char *)req->buf + 3; - if (numtowrite - && is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite, - (uint64_t)startpos, WRITE_LOCK)) { - reply_doserror(req, ERRDOS, ERRlock); - END_PROFILE(SMBwriteunlock); - return; + if (numtowrite) { + init_strict_lock_struct(fsp, (uint32)req->smbpid, + (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK, + &lock); + + if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { + reply_doserror(req, ERRDOS, ERRlock); + END_PROFILE(SMBwriteunlock); + return; + } } /* The special X/Open SMB protocol handling of @@ -3792,14 +3828,12 @@ void reply_writeunlock(struct smb_request *req) DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n", fsp->fsp_name, nt_errstr(status) )); reply_nterror(req, status); - END_PROFILE(SMBwriteunlock); - return; + goto strict_unlock; } if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) { reply_unixerror(req, ERRHRD, ERRdiskfull); - END_PROFILE(SMBwriteunlock); - return; + goto strict_unlock; } if (numtowrite) { @@ -3812,8 +3846,7 @@ void reply_writeunlock(struct smb_request *req) if (NT_STATUS_V(status)) { reply_nterror(req, status); - END_PROFILE(SMBwriteunlock); - return; + goto strict_unlock; } } @@ -3824,6 +3857,11 @@ void reply_writeunlock(struct smb_request *req) DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten)); +strict_unlock: + if (numtowrite) { + SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); + } + END_PROFILE(SMBwriteunlock); return; } @@ -3843,6 +3881,7 @@ void reply_write(struct smb_request *req) SMB_OFF_T startpos; const char *data; files_struct *fsp; + struct lock_struct lock; NTSTATUS status; START_PROFILE(SMBwrite); @@ -3877,8 +3916,11 @@ void reply_write(struct smb_request *req) startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0); data = (const char *)req->buf + 3; - if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite, - (uint64_t)startpos, WRITE_LOCK)) { + init_strict_lock_struct(fsp, (uint32)req->smbpid, + (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK, + &lock); + + if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { reply_doserror(req, ERRDOS, ERRlock); END_PROFILE(SMBwrite); return; @@ -3897,14 +3939,12 @@ void reply_write(struct smb_request *req) nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos); if (nwritten < 0) { reply_nterror(req, NT_STATUS_DISK_FULL); - END_PROFILE(SMBwrite); - return; + goto strict_unlock; } nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos); if (nwritten < 0) { reply_nterror(req, NT_STATUS_DISK_FULL); - END_PROFILE(SMBwrite); - return; + goto strict_unlock; } trigger_write_time_update_immediate(fsp); } else { @@ -3916,14 +3956,12 @@ void reply_write(struct smb_request *req) DEBUG(5,("reply_write: sync_file for %s returned %s\n", fsp->fsp_name, nt_errstr(status) )); reply_nterror(req, status); - END_PROFILE(SMBwrite); - return; + goto strict_unlock; } if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { reply_unixerror(req, ERRHRD, ERRdiskfull); - END_PROFILE(SMBwrite); - return; + goto strict_unlock; } reply_outbuf(req, 1, 0); @@ -3937,6 +3975,9 @@ void reply_write(struct smb_request *req) DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten)); +strict_unlock: + SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); + END_PROFILE(SMBwrite); return; } @@ -4034,6 +4075,7 @@ void reply_write_and_X(struct smb_request *req) { connection_struct *conn = req->conn; files_struct *fsp; + struct lock_struct lock; SMB_OFF_T startpos; size_t numtowrite; bool write_through; @@ -4136,9 +4178,11 @@ void reply_write_and_X(struct smb_request *req) #endif /* LARGE_SMB_OFF_T */ } - if (is_locked(fsp,(uint32)req->smbpid, - (uint64_t)numtowrite, - (uint64_t)startpos, WRITE_LOCK)) { + init_strict_lock_struct(fsp, (uint32)req->smbpid, + (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK, + &lock); + + if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { reply_doserror(req, ERRDOS, ERRlock); END_PROFILE(SMBwriteX); return; @@ -4156,8 +4200,7 @@ void reply_write_and_X(struct smb_request *req) if ((req->unread_bytes == 0) && schedule_aio_write_and_X(conn, req, fsp, data, startpos, numtowrite)) { - END_PROFILE(SMBwriteX); - return; + goto strict_unlock; } nwritten = write_file(req,fsp,data,startpos,numtowrite); @@ -4165,8 +4208,7 @@ void reply_write_and_X(struct smb_request *req) if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { reply_unixerror(req, ERRHRD, ERRdiskfull); - END_PROFILE(SMBwriteX); - return; + goto strict_unlock; } reply_outbuf(req, 6, 0); @@ -4186,13 +4228,20 @@ void reply_write_and_X(struct smb_request *req) DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n", fsp->fsp_name, nt_errstr(status) )); reply_nterror(req, status); - END_PROFILE(SMBwriteX); - return; + goto strict_unlock; } + SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); + END_PROFILE(SMBwriteX); chain_reply(req); return; + +strict_unlock: + SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); + + END_PROFILE(SMBwriteX); + return; } /**************************************************************************** @@ -4432,6 +4481,7 @@ void reply_writeclose(struct smb_request *req) const char *data; struct timespec mtime; files_struct *fsp; + struct lock_struct lock; START_PROFILE(SMBwriteclose); @@ -4458,12 +4508,16 @@ void reply_writeclose(struct smb_request *req) mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+4)); data = (const char *)req->buf + 1; - if (numtowrite - && is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite, - (uint64_t)startpos, WRITE_LOCK)) { - reply_doserror(req, ERRDOS,ERRlock); - END_PROFILE(SMBwriteclose); - return; + if (numtowrite) { + init_strict_lock_struct(fsp, (uint32)req->smbpid, + (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK, + &lock); + + if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { + reply_doserror(req, ERRDOS,ERRlock); + END_PROFILE(SMBwriteclose); + return; + } } nwritten = write_file(req,fsp,data,startpos,numtowrite); @@ -4487,19 +4541,23 @@ void reply_writeclose(struct smb_request *req) if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { reply_doserror(req, ERRHRD, ERRdiskfull); - END_PROFILE(SMBwriteclose); - return; + goto strict_unlock; } if(!NT_STATUS_IS_OK(close_status)) { reply_nterror(req, close_status); - END_PROFILE(SMBwriteclose); - return; + goto strict_unlock; } reply_outbuf(req, 1, 0); SSVAL(req->outbuf,smb_vwv0,nwritten); + +strict_unlock: + if (numtowrite) { + SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); + } + END_PROFILE(SMBwriteclose); return; } diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 538e04938e..d27f98281b 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -654,52 +654,16 @@ static void smbd_parent_loop(struct smbd_parent_context *parent) { /* now accept incoming connections - forking a new process for each incoming connection */ - DEBUG(2,("waiting for a connection\n")); + DEBUG(2,("waiting for connections\n")); while (1) { - struct timeval now, idle_timeout; - fd_set r_fds, w_fds; - int maxfd = 0; - int num; + int ret; TALLOC_CTX *frame = talloc_stackframe(); - if (run_events(smbd_event_context(), 0, NULL, NULL)) { - TALLOC_FREE(frame); - continue; - } - - idle_timeout = timeval_zero(); - - FD_ZERO(&w_fds); - FD_ZERO(&r_fds); - GetTimeOfDay(&now); - - event_add_to_select_args(smbd_event_context(), &now, - &r_fds, &w_fds, &idle_timeout, - &maxfd); - - num = sys_select(maxfd+1,&r_fds,&w_fds,NULL, - timeval_is_zero(&idle_timeout) ? - NULL : &idle_timeout); - - /* check if we need to reload services */ - check_reload(time(NULL)); - - if (run_events(smbd_event_context(), num, &r_fds, &w_fds)) { - TALLOC_FREE(frame); - continue; + ret = tevent_loop_once(smbd_event_context()); + if (ret != 0) { + exit_server_cleanly("tevent_loop_once() error"); } - /* socket error */ - if (num < 0) - exit_server_cleanly("socket error"); - - /* If the idle timeout fired and we don't have any connected - * users, exit gracefully. We should be running under a process - * controller that will restart us if necessry. - */ - if (num == 0 && count_all_current_connections() == 0) { - exit_server_cleanly("idle timeout"); - } TALLOC_FREE(frame); } /* end while 1 */ diff --git a/source3/smbd/service.c b/source3/smbd/service.c index dcdd69f997..eb16a2601e 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -833,6 +833,14 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, *pstatus = status; return NULL; } + + /* + * We need to cache this gid, to use within + * change_to_user() separately from the conn->server_info + * struct. We only use conn->server_info directly if + * "force_user" was set. + */ + conn->force_group_gid = conn->server_info->utok.gid; } conn->vuid = (vuser != NULL) ? vuser->vuid : UID_FIELD_INVALID; diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 4f059bdb59..f8c55b1b8f 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -254,6 +254,8 @@ bool change_to_user(connection_struct *conn, uint16 vuid) if((group_c = *lp_force_group(snum))) { + SMB_ASSERT(conn->force_group_gid != (gid_t)-1); + if(group_c == '+') { /* @@ -266,15 +268,18 @@ bool change_to_user(connection_struct *conn, uint16 vuid) int i; for (i = 0; i < num_groups; i++) { if (group_list[i] - == conn->server_info->utok.gid) { - gid = conn->server_info->utok.gid; + == conn->force_group_gid) { + conn->server_info->utok.gid = + conn->force_group_gid; + gid = conn->force_group_gid; gid_to_sid(&conn->server_info->ptok ->user_sids[1], gid); break; } } } else { - gid = conn->server_info->utok.gid; + conn->server_info->utok.gid = conn->force_group_gid; + gid = conn->force_group_gid; gid_to_sid(&conn->server_info->ptok->user_sids[1], gid); } diff --git a/source3/torture/torture.c b/source3/torture/torture.c index db89b05603..6029eb0727 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -333,6 +333,7 @@ bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid) uint16 old_vuid = cli->vuid; fstring old_user_name; size_t passlen = strlen(password); + NTSTATUS status; bool ret; fstrcpy(old_user_name, cli->user_name); @@ -343,7 +344,10 @@ bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid) workgroup)); *new_vuid = cli->vuid; cli->vuid = old_vuid; - fstrcpy(cli->user_name, old_user_name); + status = cli_set_username(cli, old_user_name); + if (!NT_STATUS_IS_OK(status)) { + return false; + } return ret; } @@ -4150,6 +4154,119 @@ static bool run_opentest(int dummy) return correct; } +/* + Test POSIX open /mkdir calls. + */ +static bool run_simple_posix_open_test(int dummy) +{ + static struct cli_state *cli1; + const char *fname = "\\posix:file"; + const char *dname = "\\posix:dir"; + uint16 major, minor; + uint32 caplow, caphigh; + int fnum1 = -1; + bool correct = false; + + printf("Starting simple POSIX open test\n"); + + if (!torture_open_connection(&cli1, 0)) { + return false; + } + + cli_sockopt(cli1, sockops); + + if (!SERVER_HAS_UNIX_CIFS(cli1)) { + printf("Server doesn't support UNIX CIFS extensions.\n"); + return false; + } + + if (!cli_unix_extensions_version(cli1, &major, + &minor, &caplow, &caphigh)) { + printf("Server didn't return UNIX CIFS extensions.\n"); + return false; + } + + if (!cli_set_unix_extensions_capabilities(cli1, + major, minor, caplow, caphigh)) { + printf("Server doesn't support setting UNIX CIFS extensions.\n"); + return false; + } + + cli_setatr(cli1, fname, 0, 0); + cli_posix_unlink(cli1, fname); + cli_setatr(cli1, dname, 0, 0); + cli_posix_rmdir(cli1, dname); + + /* Create a directory. */ + if (cli_posix_mkdir(cli1, dname, 0777) == -1) { + printf("Server doesn't support setting UNIX CIFS extensions.\n"); + goto out; + } + + fnum1 = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600); + if (fnum1 == -1) { + printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1)); + goto out; + } + + if (!cli_close(cli1, fnum1)) { + printf("close failed (%s)\n", cli_errstr(cli1)); + goto out; + } + + /* Now open the file again for read only. */ + fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0); + if (fnum1 == -1) { + printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1)); + goto out; + } + + /* Now unlink while open. */ + if (!cli_posix_unlink(cli1, fname)) { + printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1)); + goto out; + } + + if (!cli_close(cli1, fnum1)) { + printf("close(2) failed (%s)\n", cli_errstr(cli1)); + goto out; + } + + /* Ensure the file has gone. */ + fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0); + if (fnum1 != -1) { + printf("POSIX open of %s succeeded, should have been deleted.\n", fname); + goto out; + } + + if (!cli_posix_rmdir(cli1, dname)) { + printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1)); + goto out; + } + + printf("Simple POSIX open test passed\n"); + correct = true; + + out: + + if (fnum1 != -1) { + cli_close(cli1, fnum1); + fnum1 = -1; + } + + cli_setatr(cli1, fname, 0, 0); + cli_posix_unlink(cli1, fname); + cli_setatr(cli1, dname, 0, 0); + cli_posix_rmdir(cli1, dname); + + if (!torture_close_connection(cli1)) { + correct = false; + } + + return correct; +} + + static uint32 open_attrs_table[] = { FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, @@ -5496,11 +5613,11 @@ static bool run_local_memcache(int dummy) return ret; } -static void wbclient_done(struct async_req *req) +static void wbclient_done(struct tevent_req *req) { wbcErr wbc_err; struct winbindd_response *wb_resp; - int *i = (int *)req->async.priv; + int *i = (int *)tevent_req_callback_data_void(req); wbc_err = wb_trans_recv(req, req, &wb_resp); TALLOC_FREE(req); @@ -5537,14 +5654,13 @@ static bool run_local_wbclient(int dummy) goto fail; } for (j=0; j<5; j++) { - struct async_req *req; + struct tevent_req *req; req = wb_trans_send(ev, ev, wb_ctx[i], (j % 2) == 0, &wb_req); if (req == NULL) { goto fail; } - req->async.fn = wbclient_done; - req->async.priv = &i; + tevent_req_set_callback(req, wbclient_done, &i); } } @@ -5690,6 +5806,7 @@ static struct { {"RW2", run_readwritemulti, FLAG_MULTIPROC}, {"RW3", run_readwritelarge, 0}, {"OPEN", run_opentest, 0}, + {"POSIX", run_simple_posix_open_test, 0}, #if 1 {"OPENATTR", run_openattrtest, 0}, #endif diff --git a/source3/utils/net.c b/source3/utils/net.c index d483198a9e..7823a98219 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -272,7 +272,7 @@ static bool search_maxrid(struct pdb_search *search, const char *type, num_entries = pdb_search_entries(search, 0, 0xffffffff, &entries); for (i=0; i<num_entries; i++) *max_rid = MAX(*max_rid, entries[i].rid); - pdb_search_destroy(search); + TALLOC_FREE(search); return true; } @@ -280,13 +280,14 @@ static uint32 get_maxrid(void) { uint32 max_rid = 0; - if (!search_maxrid(pdb_search_users(0), "users", &max_rid)) + if (!search_maxrid(pdb_search_users(talloc_tos(), 0), "users", &max_rid)) return 0; - if (!search_maxrid(pdb_search_groups(), "groups", &max_rid)) + if (!search_maxrid(pdb_search_groups(talloc_tos()), "groups", &max_rid)) return 0; - if (!search_maxrid(pdb_search_aliases(get_global_sam_sid()), + if (!search_maxrid(pdb_search_aliases(talloc_tos(), + get_global_sam_sid()), "aliases", &max_rid)) return 0; diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 58bbb70ce6..2a66619438 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -1662,7 +1662,7 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char * SAFE_FREE(srv_cn_escaped); SAFE_FREE(printername_escaped); - nt_status = cli_rpc_pipe_open_noauth(cli, &syntax_spoolss, &pipe_hnd); + nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_spoolss.syntax_id, &pipe_hnd); if (!NT_STATUS_IS_OK(nt_status)) { d_fprintf(stderr, "Unable to open a connnection to the spoolss pipe on %s\n", servername); diff --git a/source3/utils/net_conf.c b/source3/utils/net_conf.c index 05b552c00d..38a2553e53 100644 --- a/source3/utils/net_conf.c +++ b/source3/utils/net_conf.c @@ -331,12 +331,6 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx, "would import the following configuration:\n\n"); } - werr = smbconf_transaction_start(conf_ctx); - if (!W_ERROR_IS_OK(werr)) { - d_printf("error starting transaction: %s\n", win_errstr(werr)); - goto done; - } - if (servicename != NULL) { struct smbconf_service *service = NULL; @@ -366,12 +360,45 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx, goto cancel; } } + + /* + * Wrap the importing of shares into a transaction, + * but only 100 at a time, in order to serve memory. + * The allocated memory accumulates across the actions + * within the transaction, and for me, some 1500 + * imported shares, the MAX_TALLOC_SIZE of 256 MB + * was exceeded. + */ + werr = smbconf_transaction_start(conf_ctx); + if (!W_ERROR_IS_OK(werr)) { + d_printf("error starting transaction: %s\n", + win_errstr(werr)); + goto done; + } + for (sidx = 0; sidx < num_shares; sidx++) { werr = import_process_service(c, conf_ctx, services[sidx]); if (!W_ERROR_IS_OK(werr)) { goto cancel; } + + if (sidx % 100) { + continue; + } + + werr = smbconf_transaction_commit(conf_ctx); + if (!W_ERROR_IS_OK(werr)) { + d_printf("error committing transaction: %s\n", + win_errstr(werr)); + goto done; + } + werr = smbconf_transaction_start(conf_ctx); + if (!W_ERROR_IS_OK(werr)) { + d_printf("error starting transaction: %s\n", + win_errstr(werr)); + goto done; + } } } diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index c54d479413..d83fb44aba 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -55,7 +55,7 @@ NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx, const char **domain_name) { struct rpc_pipe_client *lsa_pipe; - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_OK; union lsa_PolicyInformation *info = NULL; @@ -470,7 +470,7 @@ NTSTATUS rpc_info_internals(struct net_context *c, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; union samr_DomainInfo *info = NULL; fstring sid_str; @@ -989,10 +989,10 @@ static NTSTATUS rpc_sh_handle_user(struct net_context *c, TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, struct rpc_pipe_client *pipe_hnd, - POLICY_HND *user_hnd, + struct policy_handle *user_hnd, int argc, const char **argv)) { - POLICY_HND connect_pol, domain_pol, user_pol; + struct policy_handle connect_pol, domain_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_SID sid; uint32 rid; @@ -1073,7 +1073,7 @@ static NTSTATUS rpc_sh_user_show_internals(struct net_context *c, TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, struct rpc_pipe_client *pipe_hnd, - POLICY_HND *user_hnd, + struct policy_handle *user_hnd, int argc, const char **argv) { NTSTATUS result; @@ -1124,7 +1124,7 @@ static NTSTATUS rpc_sh_user_str_edit_internals(struct net_context *c, TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, struct rpc_pipe_client *pipe_hnd, - POLICY_HND *user_hnd, + struct policy_handle *user_hnd, int argc, const char **argv) { NTSTATUS result; @@ -1209,7 +1209,7 @@ static NTSTATUS rpc_sh_user_flag_edit_internals(struct net_context *c, TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, struct rpc_pipe_client *pipe_hnd, - POLICY_HND *user_hnd, + struct policy_handle *user_hnd, int argc, const char **argv) { NTSTATUS result; @@ -1386,7 +1386,7 @@ static NTSTATUS rpc_group_delete_internals(struct net_context *c, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol, group_pol, user_pol; + struct policy_handle connect_pol, domain_pol, group_pol, user_pol; bool group_is_primary = false; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32_t group_rid; @@ -1658,7 +1658,7 @@ static NTSTATUS get_sid_from_name(struct cli_state *cli, DOM_SID *sids = NULL; enum lsa_SidType *types = NULL; struct rpc_pipe_client *pipe_hnd; - POLICY_HND lsa_pol; + struct policy_handle lsa_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id, @@ -1710,10 +1710,10 @@ static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd, const DOM_SID *group_sid, const char *member) { - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; NTSTATUS result; uint32 group_rid; - POLICY_HND group_pol; + struct policy_handle group_pol; struct samr_Ids rids, rid_types; struct lsa_String lsa_acct_name; @@ -1784,10 +1784,10 @@ static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd, const DOM_SID *alias_sid, const char *member) { - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; NTSTATUS result; uint32 alias_rid; - POLICY_HND alias_pol; + struct policy_handle alias_pol; DOM_SID member_sid; enum lsa_SidType member_type; @@ -1918,10 +1918,10 @@ static NTSTATUS rpc_del_groupmem(struct net_context *c, const DOM_SID *group_sid, const char *member) { - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; NTSTATUS result; uint32 group_rid; - POLICY_HND group_pol; + struct policy_handle group_pol; struct samr_Ids rids, rid_types; struct lsa_String lsa_acct_name; @@ -1986,10 +1986,10 @@ static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd, const DOM_SID *alias_sid, const char *member) { - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; NTSTATUS result; uint32 alias_rid; - POLICY_HND alias_pol; + struct policy_handle alias_pol; DOM_SID member_sid; enum lsa_SidType member_type; @@ -2136,7 +2136,7 @@ static NTSTATUS rpc_group_list_internals(struct net_context *c, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0; struct samr_SamArray *groups = NULL; @@ -2259,7 +2259,7 @@ static NTSTATUS rpc_group_list_internals(struct net_context *c, if (c->opt_long_list_entries) { - POLICY_HND alias_pol; + struct policy_handle alias_pol; union samr_AliasInfo *info = NULL; if ((NT_STATUS_IS_OK(rpccli_samr_OpenAlias(pipe_hnd, mem_ctx, @@ -2318,7 +2318,7 @@ static NTSTATUS rpc_group_list_internals(struct net_context *c, if (c->opt_long_list_entries) { - POLICY_HND alias_pol; + struct policy_handle alias_pol; union samr_AliasInfo *info = NULL; if ((NT_STATUS_IS_OK(rpccli_samr_OpenAlias(pipe_hnd, mem_ctx, @@ -2362,11 +2362,11 @@ static NTSTATUS rpc_list_group_members(struct net_context *c, TALLOC_CTX *mem_ctx, const char *domain_name, const DOM_SID *domain_sid, - POLICY_HND *domain_pol, + struct policy_handle *domain_pol, uint32 rid) { NTSTATUS result; - POLICY_HND group_pol; + struct policy_handle group_pol; uint32 num_members, *group_rids; int i; struct samr_RidTypeArray *rids = NULL; @@ -2437,12 +2437,12 @@ static NTSTATUS rpc_list_group_members(struct net_context *c, static NTSTATUS rpc_list_alias_members(struct net_context *c, struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, + struct policy_handle *domain_pol, uint32 rid) { NTSTATUS result; struct rpc_pipe_client *lsa_pipe; - POLICY_HND alias_pol, lsa_pol; + struct policy_handle alias_pol, lsa_pol; uint32 num_members; DOM_SID *alias_sids; char **domains; @@ -2545,7 +2545,7 @@ static NTSTATUS rpc_group_members_internals(struct net_context *c, const char **argv) { NTSTATUS result; - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; struct samr_Ids rids, rid_types; struct lsa_String lsa_acct_name; @@ -3299,7 +3299,7 @@ static bool sync_files(struct copy_clistate *cp_clistate, const char *mask) DEBUG(3,("calling cli_list with mask: %s\n", mask)); - if ( !cli_resolve_path(talloc_tos(), "", cp_clistate->cli_share_src, + if ( !cli_resolve_path(talloc_tos(), "", NULL, cp_clistate->cli_share_src, mask, &targetcli, &targetpath ) ) { d_fprintf(stderr, "cli_resolve_path %s failed with error: %s\n", mask, cli_errstr(cp_clistate->cli_share_src)); @@ -3752,13 +3752,13 @@ static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias) static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - POLICY_HND *connect_pol, + struct policy_handle *connect_pol, const DOM_SID *domain_sid) { uint32 start_idx, max_entries, num_entries, i; struct samr_SamArray *groups = NULL; NTSTATUS result; - POLICY_HND domain_pol; + struct policy_handle domain_pol; /* Get domain policy handle */ @@ -3782,7 +3782,7 @@ static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd, &num_entries); for (i = 0; i < num_entries; i++) { - POLICY_HND alias_pol; + struct policy_handle alias_pol; struct full_alias alias; struct lsa_SidArray sid_array; int j; @@ -3847,7 +3847,7 @@ static NTSTATUS rpc_aliaslist_dump(struct net_context *c, { int i; NTSTATUS result; - POLICY_HND lsa_pol; + struct policy_handle lsa_pol; result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true, SEC_RIGHTS_MAXIMUM_ALLOWED, @@ -3912,7 +3912,7 @@ static NTSTATUS rpc_aliaslist_internals(struct net_context *c, const char **argv) { NTSTATUS result; - POLICY_HND connect_pol; + struct policy_handle connect_pol; result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, pipe_hnd->desthost, @@ -5149,7 +5149,7 @@ static NTSTATUS rpc_trustdom_add_internals(struct net_context *c, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol, user_pol; + struct policy_handle connect_pol, domain_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; char *acct_name; struct lsa_String lsa_acct_name; @@ -5306,7 +5306,7 @@ static NTSTATUS rpc_trustdom_del_internals(struct net_context *c, int argc, const char **argv) { - POLICY_HND connect_pol, domain_pol, user_pol; + struct policy_handle connect_pol, domain_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; char *acct_name; DOM_SID trust_acct_sid; @@ -5495,7 +5495,7 @@ static int rpc_trustdom_establish(struct net_context *c, int argc, struct cli_state *cli = NULL; struct sockaddr_storage server_ss; struct rpc_pipe_client *pipe_hnd = NULL; - POLICY_HND connect_hnd; + struct policy_handle connect_hnd; TALLOC_CTX *mem_ctx; NTSTATUS nt_status; DOM_SID *domain_sid; @@ -5731,7 +5731,7 @@ static void print_trusted_domain(DOM_SID *dom_sid, const char *trusted_dom_name) static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, + struct policy_handle *pol, DOM_SID dom_sid, const char *trusted_dom_name) { @@ -5797,7 +5797,7 @@ static int rpc_trustdom_vampire(struct net_context *c, int argc, NTSTATUS nt_status; const char *domain_name = NULL; DOM_SID *queried_dom_sid; - POLICY_HND connect_hnd; + struct policy_handle connect_hnd; union lsa_PolicyInformation *info = NULL; /* trusted domains listing variables */ @@ -5950,7 +5950,7 @@ static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv) DOM_SID *queried_dom_sid; fstring padding; int ascii_dom_name_len; - POLICY_HND connect_hnd; + struct policy_handle connect_hnd; union lsa_PolicyInformation *info = NULL; /* trusted domains listing variables */ @@ -5960,7 +5960,7 @@ static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv) fstring pdc_name; /* trusting domains listing variables */ - POLICY_HND domain_hnd; + struct policy_handle domain_hnd; struct samr_SamArray *trusts = NULL; if (c->display_usage) { @@ -6421,30 +6421,30 @@ static int rpc_printer_migrate_all(struct net_context *c, int argc, return -1; } - ret = run_rpc_command(c, NULL, &syntax_spoolss, 0, + ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_migrate_printers_internals, argc, argv); if (ret) return ret; - ret = run_rpc_command(c, NULL, &syntax_spoolss, 0, + ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_migrate_drivers_internals, argc, argv); if (ret) return ret; - ret = run_rpc_command(c, NULL, &syntax_spoolss, 0, + ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_migrate_forms_internals, argc, argv); if (ret) return ret; - ret = run_rpc_command(c, NULL, &syntax_spoolss, 0, + ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_migrate_settings_internals, argc, argv); if (ret) return ret; - return run_rpc_command(c, NULL, &syntax_spoolss, 0, + return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_migrate_security_internals, argc, argv); @@ -6475,7 +6475,7 @@ static int rpc_printer_migrate_drivers(struct net_context *c, int argc, return -1; } - return run_rpc_command(c, NULL, &syntax_spoolss, 0, + return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_migrate_drivers_internals, argc, argv); } @@ -6505,7 +6505,7 @@ static int rpc_printer_migrate_forms(struct net_context *c, int argc, return -1; } - return run_rpc_command(c, NULL, &syntax_spoolss, 0, + return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_migrate_forms_internals, argc, argv); } @@ -6535,7 +6535,7 @@ static int rpc_printer_migrate_printers(struct net_context *c, int argc, return -1; } - return run_rpc_command(c, NULL, &syntax_spoolss, 0, + return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_migrate_printers_internals, argc, argv); } @@ -6565,7 +6565,7 @@ static int rpc_printer_migrate_security(struct net_context *c, int argc, return -1; } - return run_rpc_command(c, NULL, &syntax_spoolss, 0, + return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_migrate_security_internals, argc, argv); } @@ -6595,7 +6595,7 @@ static int rpc_printer_migrate_settings(struct net_context *c, int argc, return -1; } - return run_rpc_command(c, NULL, &syntax_spoolss, 0, + return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_migrate_settings_internals, argc, argv); } @@ -6691,7 +6691,7 @@ static int rpc_printer_list(struct net_context *c, int argc, const char **argv) return 0; } - return run_rpc_command(c, NULL, &syntax_spoolss, 0, + return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_list_internals, argc, argv); } @@ -6716,7 +6716,7 @@ static int rpc_printer_driver_list(struct net_context *c, int argc, return 0; } - return run_rpc_command(c, NULL, &syntax_spoolss, 0, + return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_driver_list_internals, argc, argv); } @@ -6741,7 +6741,7 @@ static int rpc_printer_publish_publish(struct net_context *c, int argc, return 0; } - return run_rpc_command(c, NULL, &syntax_spoolss, 0, + return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_publish_publish_internals, argc, argv); } @@ -6765,7 +6765,7 @@ static int rpc_printer_publish_update(struct net_context *c, int argc, const cha return 0; } - return run_rpc_command(c, NULL, &syntax_spoolss, 0, + return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_publish_update_internals, argc, argv); } @@ -6790,7 +6790,7 @@ static int rpc_printer_publish_unpublish(struct net_context *c, int argc, return 0; } - return run_rpc_command(c, NULL, &syntax_spoolss, 0, + return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_publish_unpublish_internals, argc, argv); } @@ -6815,7 +6815,7 @@ static int rpc_printer_publish_list(struct net_context *c, int argc, return 0; } - return run_rpc_command(c, NULL, &syntax_spoolss, 0, + return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_publish_list_internals, argc, argv); } @@ -6880,7 +6880,7 @@ static int rpc_printer_publish(struct net_context *c, int argc, net_display_usage_from_functable(func); return 0; } - return run_rpc_command(c, NULL, &syntax_spoolss, 0, + return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_publish_list_internals, argc, argv); } @@ -6983,7 +6983,7 @@ int net_rpc_printer(struct net_context *c, int argc, const char **argv) net_display_usage_from_functable(func); return 0; } - return run_rpc_command(c, NULL, &syntax_spoolss, 0, + return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0, rpc_printer_list_internals, argc, argv); } diff --git a/source3/utils/net_rpc_audit.c b/source3/utils/net_rpc_audit.c index dc4c796c17..aa7fc7c394 100644 --- a/source3/utils/net_rpc_audit.c +++ b/source3/utils/net_rpc_audit.c @@ -70,7 +70,7 @@ static NTSTATUS rpc_audit_get_internal(struct net_context *c, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; union lsa_PolicyInformation *info = NULL; int i; @@ -138,7 +138,7 @@ static NTSTATUS rpc_audit_set_internal(struct net_context *c, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; union lsa_PolicyInformation *info = NULL; uint32_t audit_policy, audit_category; @@ -224,7 +224,7 @@ static NTSTATUS rpc_audit_enable_internal_ext(struct rpc_pipe_client *pipe_hnd, const char **argv, bool enable) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; union lsa_PolicyInformation *info = NULL; @@ -308,7 +308,7 @@ static NTSTATUS rpc_audit_list_internal(struct net_context *c, int argc, const char **argv) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; union lsa_PolicyInformation *info = NULL; int i; diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index 1c45d0c515..7f3515ce75 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -141,7 +141,7 @@ int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv) /* rpc variables */ - POLICY_HND lsa_pol, sam_pol, domain_pol, user_pol; + struct policy_handle lsa_pol, sam_pol, domain_pol, user_pol; DOM_SID *domain_sid; uint32 user_rid; diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index 8116764d9b..b25c897770 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -1,7 +1,7 @@ /* Samba Unix/Linux SMB client library Distributed SMB/CIFS Server Management Utility - Copyright (C) 2004 Guenther Deschner (gd@samba.org) + Copyright (C) 2004,2009 Guenther Deschner (gd@samba.org) 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 @@ -77,62 +77,6 @@ static void display_print_driver3(struct spoolss_DriverInfo3 *r) printf("\tDefaultdatatype: [%s]\n\n", r->default_datatype); } -static void display_print_driver_3(DRIVER_INFO_3 *i1) -{ - fstring name = ""; - fstring architecture = ""; - fstring driverpath = ""; - fstring datafile = ""; - fstring configfile = ""; - fstring helpfile = ""; - fstring dependentfiles = ""; - fstring monitorname = ""; - fstring defaultdatatype = ""; - - int length=0; - bool valid = true; - - if (i1 == NULL) - return; - - rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE); - rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE); - rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE); - rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE); - rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE); - rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE); - rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), -1, STR_TERMINATE); - rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), -1, STR_TERMINATE); - - d_printf ("Printer Driver Info 3:\n"); - d_printf ("\tVersion: [%x]\n", i1->version); - d_printf ("\tDriver Name: [%s]\n",name); - d_printf ("\tArchitecture: [%s]\n", architecture); - d_printf ("\tDriver Path: [%s]\n", driverpath); - d_printf ("\tDatafile: [%s]\n", datafile); - d_printf ("\tConfigfile: [%s]\n", configfile); - d_printf ("\tHelpfile: [%s]\n\n", helpfile); - - while (valid) { - rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE); - - length+=strlen(dependentfiles)+1; - - if (strlen(dependentfiles) > 0) { - d_printf ("\tDependentfiles: [%s]\n", dependentfiles); - } else { - valid = false; - } - } - - printf ("\n"); - - d_printf ("\tMonitorname: [%s]\n", monitorname); - d_printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype); - - return; -} - static void display_reg_value(const char *subkey, REGISTRY_VALUE value) { char *text; @@ -713,14 +657,19 @@ static bool net_spoolss_enum_printers(struct rpc_pipe_client *pipe_hnd, uint32 flags, uint32 level, uint32 *num_printers, - PRINTER_INFO_CTR *ctr) + union spoolss_PrinterInfo **info) { WERROR result; /* enum printers */ - result = rpccli_spoolss_enum_printers(pipe_hnd, mem_ctx, name, flags, - level, num_printers, ctr); + result = rpccli_spoolss_enumprinters(pipe_hnd, mem_ctx, + flags, + name, + level, + 0, + num_printers, + info); if (!W_ERROR_IS_OK(result)) { printf("cannot enum printers: %s\n", win_errstr(result)); return false; @@ -734,7 +683,7 @@ static bool net_spoolss_open_printer_ex(struct rpc_pipe_client *pipe_hnd, const char *printername, uint32 access_required, const char *username, - POLICY_HND *hnd) + struct policy_handle *hnd) { WERROR result; fstring printername2; @@ -773,7 +722,7 @@ static bool net_spoolss_open_printer_ex(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, + struct policy_handle *hnd, uint32 level, union spoolss_PrinterInfo *info) { @@ -795,7 +744,7 @@ static bool net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, + struct policy_handle *hnd, uint32 level, union spoolss_PrinterInfo *info) { @@ -866,14 +815,23 @@ static bool net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_setprinterdata(struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, - REGISTRY_VALUE *value) + TALLOC_CTX *mem_ctx, + struct policy_handle *hnd, + const char *value_name, + enum winreg_Type type, + union spoolss_PrinterData data) { WERROR result; + NTSTATUS status; /* setprinterdata call */ - result = rpccli_spoolss_setprinterdata(pipe_hnd, mem_ctx, hnd, value); + status = rpccli_spoolss_SetPrinterData(pipe_hnd, mem_ctx, + hnd, + value_name, + type, + data, + 0, /* autocalculated */ + &result); if (!W_ERROR_IS_OK(result)) { printf ("unable to set printerdata: %s\n", win_errstr(result)); @@ -886,14 +844,14 @@ static bool net_spoolss_setprinterdata(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_enumprinterkey(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, + struct policy_handle *hnd, const char *keyname, - uint16 **keylist) + const char ***keylist) { WERROR result; /* enumprinterkey call */ - result = rpccli_spoolss_enumprinterkey(pipe_hnd, mem_ctx, hnd, keyname, keylist, NULL); + result = rpccli_spoolss_enumprinterkey(pipe_hnd, mem_ctx, hnd, keyname, keylist, 0); if (!W_ERROR_IS_OK(result)) { printf("enumprinterkey failed: %s\n", win_errstr(result)); @@ -906,14 +864,20 @@ static bool net_spoolss_enumprinterkey(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_enumprinterdataex(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, uint32 offered, - POLICY_HND *hnd, + struct policy_handle *hnd, const char *keyname, - REGVAL_CTR *ctr) + uint32_t *count, + struct spoolss_PrinterEnumValues **info) { WERROR result; /* enumprinterdataex call */ - result = rpccli_spoolss_enumprinterdataex(pipe_hnd, mem_ctx, hnd, keyname, ctr); + result = rpccli_spoolss_enumprinterdataex(pipe_hnd, mem_ctx, + hnd, + keyname, + 0, /* offered */ + count, + info); if (!W_ERROR_IS_OK(result)) { printf("enumprinterdataex failed: %s\n", win_errstr(result)); @@ -926,8 +890,8 @@ static bool net_spoolss_enumprinterdataex(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_setprinterdataex(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, - char *keyname, + struct policy_handle *hnd, + const char *keyname, REGISTRY_VALUE *value) { WERROR result; @@ -953,16 +917,20 @@ static bool net_spoolss_setprinterdataex(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_enumforms(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, + struct policy_handle *hnd, int level, - uint32 *num_forms, - FORM_1 **forms) + uint32_t *num_forms, + union spoolss_FormInfo **forms) { WERROR result; /* enumforms call */ - result = rpccli_spoolss_enumforms(pipe_hnd, mem_ctx, hnd, level, num_forms, forms); - + result = rpccli_spoolss_enumforms(pipe_hnd, mem_ctx, + hnd, + level, + 0, + num_forms, + forms); if (!W_ERROR_IS_OK(result)) { printf("could not enum forms: %s\n", win_errstr(result)); return false; @@ -974,16 +942,19 @@ static bool net_spoolss_enumforms(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_enumprinterdrivers (struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, uint32 level, const char *env, - uint32 *num_drivers, - PRINTER_DRIVER_CTR *ctr) + uint32 *count, + union spoolss_DriverInfo **info) { WERROR result; /* enumprinterdrivers call */ - result = rpccli_spoolss_enumprinterdrivers( - pipe_hnd, mem_ctx, level, - env, num_drivers, ctr); - + result = rpccli_spoolss_enumprinterdrivers(pipe_hnd, mem_ctx, + pipe_hnd->srv_name_slash, + env, + level, + 0, + count, + info); if (!W_ERROR_IS_OK(result)) { printf("cannot enum drivers: %s\n", win_errstr(result)); return false; @@ -994,7 +965,7 @@ static bool net_spoolss_enumprinterdrivers (struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 level, + struct policy_handle *hnd, uint32 level, const char *env, int version, union spoolss_DriverInfo *info) { @@ -1078,26 +1049,21 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd, int argc, const char **argv, uint32 *num_printers, - PRINTER_INFO_CTR *ctr) + union spoolss_PrinterInfo **info_p) { - - POLICY_HND hnd; - union spoolss_PrinterInfo info; + struct policy_handle hnd; /* no arguments given, enumerate all printers */ if (argc == 0) { if (!net_spoolss_enum_printers(pipe_hnd, mem_ctx, NULL, PRINTER_ENUM_LOCAL|PRINTER_ENUM_SHARED, - level, num_printers, ctr)) + level, num_printers, info_p)) return false; goto out; } - /* FIXME GD */ - return false; - /* argument given, get a single printer by name */ if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, argv[0], MAXIMUM_ALLOWED_ACCESS, @@ -1105,7 +1071,7 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd, &hnd)) return false; - if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info)) { + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, *info_p)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL); return false; } @@ -1150,26 +1116,19 @@ NTSTATUS rpc_printer_list_internals(struct net_context *c, NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uint32 i, num_printers; uint32 level = 2; - char *printername, *sharename; - PRINTER_INFO_CTR ctr; + const char *printername, *sharename; + union spoolss_PrinterInfo *info; printf("listing printers\n"); - if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &ctr)) + if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info)) return nt_status; for (i = 0; i < num_printers; i++) { + /* do some initialization */ - rpcstr_pull_talloc(mem_ctx, - &printername, - ctr.printers_2[i].printername.buffer, - -1, - STR_TERMINATE); - rpcstr_pull_talloc(mem_ctx, - &sharename, - ctr.printers_2[i].sharename.buffer, - -1, - STR_TERMINATE); + printername = info[i].info2.printername; + sharename = info[i].info2.sharename; if (printername && sharename) { d_printf("printer %d: %s, shared as: %s\n", @@ -1209,11 +1168,9 @@ NTSTATUS rpc_printer_driver_list_internals(struct net_context *c, NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uint32 i; uint32 level = 3; - PRINTER_DRIVER_CTR drv_ctr_enum; + union spoolss_DriverInfo *info; int d; - ZERO_STRUCT(drv_ctr_enum); - printf("listing printer-drivers\n"); for (i=0; archi_table[i].long_archi!=NULL; i++) { @@ -1223,7 +1180,7 @@ NTSTATUS rpc_printer_driver_list_internals(struct net_context *c, /* enum remote drivers */ if (!net_spoolss_enumprinterdrivers(pipe_hnd, mem_ctx, level, archi_table[i].long_archi, - &num_drivers, &drv_ctr_enum)) { + &num_drivers, &info)) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -1240,7 +1197,7 @@ NTSTATUS rpc_printer_driver_list_internals(struct net_context *c, /* do something for all drivers for architecture */ for (d = 0; d < num_drivers; d++) { - display_print_driver_3(&(drv_ctr_enum.info3[d])); + display_print_driver3(&info[d].info3); } } @@ -1273,31 +1230,24 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uint32 i, num_printers; uint32 level = 7; - char *printername, *sharename; - PRINTER_INFO_CTR ctr; + const char *printername, *sharename; + union spoolss_PrinterInfo *info_enum; union spoolss_PrinterInfo info; struct spoolss_SetPrinterInfoCtr info_ctr; struct spoolss_DevmodeContainer devmode_ctr; struct sec_desc_buf secdesc_ctr; - POLICY_HND hnd; + struct policy_handle hnd; WERROR result; const char *action_str; - if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &ctr)) + if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum)) return nt_status; for (i = 0; i < num_printers; i++) { + /* do some initialization */ - rpcstr_pull_talloc(mem_ctx, - &printername, - ctr.printers_2[i].printername.buffer, - -1, - STR_TERMINATE); - rpcstr_pull_talloc(mem_ctx, - &sharename, - ctr.printers_2[i].sharename.buffer, - -1, - STR_TERMINATE); + printername = info_enum[i].info2.printername; + sharename = info_enum[i].info2.sharename; if (!printername || !sharename) { goto done; } @@ -1425,29 +1375,21 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uint32 i, num_printers; uint32 level = 7; - char *printername, *sharename; - PRINTER_INFO_CTR ctr, ctr_pub; + const char *printername, *sharename; + union spoolss_PrinterInfo *info_enum; union spoolss_PrinterInfo info; - POLICY_HND hnd; + struct policy_handle hnd; int state; - if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &ctr)) + if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum)) return nt_status; for (i = 0; i < num_printers; i++) { - ZERO_STRUCT(ctr_pub); /* do some initialization */ - rpcstr_pull_talloc(mem_ctx, - &printername, - ctr.printers_2[i].printername.buffer, - -1, - STR_TERMINATE); - rpcstr_pull_talloc(mem_ctx, - &sharename, - ctr.printers_2[i].sharename.buffer, - -1, - STR_TERMINATE); + printername = info_enum[i].info2.printername; + sharename = info_enum[i].info2.sharename; + if (!printername || !sharename) { goto done; } @@ -1526,26 +1468,24 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, uint32 i = 0; uint32 num_printers; uint32 level = 2; - char *printername, *sharename; + const char *printername, *sharename; struct rpc_pipe_client *pipe_hnd_dst = NULL; - POLICY_HND hnd_src, hnd_dst; - PRINTER_INFO_CTR ctr_src, ctr_enum; + struct policy_handle hnd_src, hnd_dst; + union spoolss_PrinterInfo *info_enum; struct cli_state *cli_dst = NULL; union spoolss_PrinterInfo info_src, info_dst; - ZERO_STRUCT(ctr_src); - DEBUG(3,("copying printer ACLs\n")); /* connect destination PI_SPOOLSS */ nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst, - &syntax_spoolss); + &ndr_table_spoolss.syntax_id); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; /* enum source printers */ - if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &ctr_enum)) { + if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info_enum)) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -1558,17 +1498,11 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, /* do something for all printers */ for (i = 0; i < num_printers; i++) { + /* do some initialization */ - rpcstr_pull_talloc(mem_ctx, - &printername, - ctr_enum.printers_2[i].printername.buffer, - -1, - STR_TERMINATE); - rpcstr_pull_talloc(mem_ctx, - &sharename, - ctr_enum.printers_2[i].sharename.buffer, - -1, - STR_TERMINATE); + printername = info_enum[i].info2.printername; + sharename = info_enum[i].info2.sharename; + if (!printername || !sharename) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; @@ -1680,27 +1614,25 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, uint32 i, f; uint32 num_printers; uint32 level = 1; - char *printername, *sharename; + const char *printername, *sharename; struct rpc_pipe_client *pipe_hnd_dst = NULL; - POLICY_HND hnd_src, hnd_dst; - PRINTER_INFO_CTR ctr_enum; + struct policy_handle hnd_src, hnd_dst; + union spoolss_PrinterInfo *info_enum; union spoolss_PrinterInfo info_dst; - uint32 num_forms; - FORM_1 *forms; + uint32_t num_forms; + union spoolss_FormInfo *forms; struct cli_state *cli_dst = NULL; - ZERO_STRUCT(ctr_enum); - DEBUG(3,("copying forms\n")); /* connect destination PI_SPOOLSS */ nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst, - &syntax_spoolss); + &ndr_table_spoolss.syntax_id); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; /* enum src printers */ - if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &ctr_enum)) { + if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum)) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -1713,17 +1645,11 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, /* do something for all printers */ for (i = 0; i < num_printers; i++) { + /* do some initialization */ - rpcstr_pull_talloc(mem_ctx, - &printername, - ctr_enum.printers_2[i].printername.buffer, - -1, - STR_TERMINATE); - rpcstr_pull_talloc(mem_ctx, - &sharename, - ctr_enum.printers_2[i].sharename.buffer, - -1, - STR_TERMINATE); + printername = info_enum[i].info2.printername; + sharename = info_enum[i].info2.sharename; + if (!printername || !sharename) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; @@ -1760,34 +1686,19 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, for (f = 0; f < num_forms; f++) { union spoolss_AddFormInfo info; - struct spoolss_AddFormInfo1 info1; - fstring form_name; NTSTATUS status; /* only migrate FORM_PRINTER types, according to jerry FORM_BUILTIN-types are hard-coded in samba */ - if (forms[f].flag != FORM_PRINTER) + if (forms[f].info1.flags != SPOOLSS_FORM_PRINTER) continue; - if (forms[f].name.buffer) - rpcstr_pull(form_name, forms[f].name.buffer, - sizeof(form_name), -1, STR_TERMINATE); - if (c->opt_verbose) d_printf("\tmigrating form # %d [%s] of type [%d]\n", - f, form_name, forms[f].flag); + f, forms[f].info1.form_name, + forms[f].info1.flags); - /* is there a more elegant way to do that ? */ - info1.flags = FORM_PRINTER; - info1.size.width = forms[f].width; - info1.size.height = forms[f].length; - info1.area.left = forms[f].left; - info1.area.top = forms[f].top; - info1.area.right = forms[f].right; - info1.area.bottom = forms[f].bottom; - info1.form_name = form_name; - - info.info1 = &info1; + info.info1 = (struct spoolss_AddFormInfo1 *)&forms[f].info1; /* FIXME: there might be something wrong with samba's builtin-forms */ @@ -1798,11 +1709,12 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, &result); if (!W_ERROR_IS_OK(result)) { d_printf("\tAddForm form %d: [%s] refused.\n", - f, form_name); + f, forms[f].info1.form_name); continue; } - DEBUGADD(1,("\tAddForm of [%s] succeeded\n", form_name)); + DEBUGADD(1,("\tAddForm of [%s] succeeded\n", + forms[f].info1.form_name)); } @@ -1862,26 +1774,23 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, uint32 i, p; uint32 num_printers; uint32 level = 3; - char *printername, *sharename; + const char *printername, *sharename; bool got_src_driver_share = false; bool got_dst_driver_share = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; - POLICY_HND hnd_src, hnd_dst; + struct policy_handle hnd_src, hnd_dst; union spoolss_DriverInfo drv_info_src; - PRINTER_INFO_CTR info_ctr_enum, info_ctr_dst; + union spoolss_PrinterInfo *info_enum; union spoolss_PrinterInfo info_dst; struct cli_state *cli_dst = NULL; struct cli_state *cli_share_src = NULL; struct cli_state *cli_share_dst = NULL; const char *drivername = NULL; - ZERO_STRUCT(info_ctr_enum); - ZERO_STRUCT(info_ctr_dst); - DEBUG(3,("copying printer-drivers\n")); nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst, - &syntax_spoolss); + &ndr_table_spoolss.syntax_id); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; @@ -1904,7 +1813,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, /* enum src printers */ - if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_ctr_enum)) { + if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum)) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -1918,17 +1827,11 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, /* do something for all printers */ for (p = 0; p < num_printers; p++) { + /* do some initialization */ - rpcstr_pull_talloc(mem_ctx, - &printername, - info_ctr_enum.printers_2[p].printername.buffer, - -1, - STR_TERMINATE); - rpcstr_pull_talloc(mem_ctx, - &sharename, - info_ctr_enum.printers_2[p].sharename.buffer, - -1, - STR_TERMINATE); + printername = info_enum[p].info2.printername; + sharename = info_enum[p].info2.sharename; + if (!printername || !sharename) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; @@ -2082,11 +1985,11 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uint32 i = 0, num_printers; uint32 level = 2; - PRINTER_INFO_CTR ctr_enum; union spoolss_PrinterInfo info_dst, info_src; + union spoolss_PrinterInfo *info_enum; struct cli_state *cli_dst = NULL; - POLICY_HND hnd_dst, hnd_src; - char *printername, *sharename; + struct policy_handle hnd_dst, hnd_src; + const char *printername, *sharename; struct rpc_pipe_client *pipe_hnd_dst = NULL; struct spoolss_SetPrinterInfoCtr info_ctr; @@ -2094,12 +1997,12 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, /* connect destination PI_SPOOLSS */ nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst, - &syntax_spoolss); + &ndr_table_spoolss.syntax_id); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; /* enum printers */ - if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &ctr_enum)) { + if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info_enum)) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -2112,17 +2015,11 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, /* do something for all printers */ for (i = 0; i < num_printers; i++) { + /* do some initialization */ - rpcstr_pull_talloc(mem_ctx, - &printername, - ctr_enum.printers_2[i].printername.buffer, - -1, - STR_TERMINATE); - rpcstr_pull_talloc(mem_ctx, - &sharename, - ctr_enum.printers_2[i].sharename.buffer, - -1, - STR_TERMINATE); + printername = info_enum[i].info2.printername; + sharename = info_enum[i].info2.sharename; + if (!printername || !sharename) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; @@ -2243,21 +2140,19 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, WERROR result; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uint32 i = 0, p = 0, j = 0; - uint32 num_printers, val_needed, data_needed; + uint32 num_printers; uint32 level = 2; - char *printername, *sharename; + const char *printername, *sharename; struct rpc_pipe_client *pipe_hnd_dst = NULL; - POLICY_HND hnd_src, hnd_dst; - PRINTER_INFO_CTR ctr_enum; - union spoolss_PrinterInfo info_dst_publish, info_dst; - REGVAL_CTR *reg_ctr; + struct policy_handle hnd_src, hnd_dst; + union spoolss_PrinterInfo *info_enum; + union spoolss_PrinterInfo info_dst_publish; + union spoolss_PrinterInfo info_dst; struct cli_state *cli_dst = NULL; char *devicename = NULL, *unc_name = NULL, *url = NULL; const char *longname; + const char **keylist = NULL; - uint16 *keylist = NULL, *curkey; - - ZERO_STRUCT(ctr_enum); /* FIXME GD */ ZERO_STRUCT(info_dst_publish); @@ -2265,12 +2160,12 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, /* connect destination PI_SPOOLSS */ nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst, - &syntax_spoolss); + &ndr_table_spoolss.syntax_id); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; /* enum src printers */ - if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &ctr_enum)) { + if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info_enum)) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -2291,17 +2186,17 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, /* do something for all printers */ for (i = 0; i < num_printers; i++) { + + uint32_t value_offered = 0, value_needed; + uint32_t data_offered = 0, data_needed; + enum winreg_Type type; + uint8_t *buffer = NULL; + const char *value_name = NULL; + /* do some initialization */ - rpcstr_pull_talloc(mem_ctx, - &printername, - ctr_enum.printers_2[i].printername.buffer, - -1, - STR_TERMINATE); - rpcstr_pull_talloc(mem_ctx, - &sharename, - ctr_enum.printers_2[i].sharename.buffer, - -1, - STR_TERMINATE); + printername = info_enum[i].info2.printername; + sharename = info_enum[i].info2.sharename; + if (!printername || !sharename) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; @@ -2329,20 +2224,19 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, level, &info_dst)) goto done; -#if 0 /* FIXME GD */ /* STEP 1: COPY DEVICE-MODE and other PRINTER_INFO_2-attributes */ - info_dst.info2 = &ctr_enum.printers_2[i]; + info_dst.info2 = info_enum[i].info2; /* why is the port always disconnected when the printer is correctly installed (incl. driver ???) */ info_dst.info2.portname = SAMBA_PRINTER_PORT_NAME; /* check if printer is published */ - if (ctr_enum.printers_2[i].attributes & PRINTER_ATTRIBUTE_PUBLISHED) { + if (info_enum[i].info2.attributes & PRINTER_ATTRIBUTE_PUBLISHED) { /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &info_dst_publish)) @@ -2356,13 +2250,10 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, DEBUG(3,("republished printer\n")); } - if (ctr_enum.printers_2[i].devmode != NULL) { + if (info_enum[i].info2.devmode != NULL) { /* copy devmode (info level 2) */ - info_dst.info2.devmode = (DEVICEMODE *) - TALLOC_MEMDUP(mem_ctx, - ctr_enum.printers_2[i].devmode, - sizeof(DEVICEMODE)); + info_dst.info2.devmode = info_enum[i].info2.devmode; /* do not copy security descriptor (we have another * command for that) */ @@ -2384,7 +2275,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, DEBUGADD(1,("\tSetPrinter of DEVICEMODE succeeded\n")); } -#endif + /* STEP 2: COPY REGISTRY VALUES */ /* please keep in mind that samba parse_spools gives horribly @@ -2394,32 +2285,69 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, */ /* enumerate data on src handle */ - result = rpccli_spoolss_enumprinterdata(pipe_hnd, mem_ctx, &hnd_src, p, 0, 0, - &val_needed, &data_needed, NULL); + nt_status = rpccli_spoolss_EnumPrinterData(pipe_hnd, mem_ctx, + &hnd_src, + p, + value_name, + value_offered, + &value_needed, + &type, + buffer, + data_offered, + &data_needed, + &result); + + data_offered = data_needed; + value_offered = value_needed; + buffer = talloc_zero_array(mem_ctx, uint8_t, data_needed); + value_name = talloc_zero_array(mem_ctx, char, value_needed); /* loop for all printerdata of "PrinterDriverData" */ - while (W_ERROR_IS_OK(result)) { - - REGISTRY_VALUE value; - - result = rpccli_spoolss_enumprinterdata( - pipe_hnd, mem_ctx, &hnd_src, p++, val_needed, - data_needed, 0, 0, &value); - + while (NT_STATUS_IS_OK(nt_status) && W_ERROR_IS_OK(result)) { + + nt_status = rpccli_spoolss_EnumPrinterData(pipe_hnd, mem_ctx, + &hnd_src, + p++, + value_name, + value_offered, + &value_needed, + &type, + buffer, + data_offered, + &data_needed, + &result); /* loop for all reg_keys */ - if (W_ERROR_IS_OK(result)) { + if (NT_STATUS_IS_OK(nt_status) && W_ERROR_IS_OK(result)) { + + REGISTRY_VALUE v; + DATA_BLOB blob; + union spoolss_PrinterData printer_data; /* display_value */ - if (c->opt_verbose) - display_reg_value(SPOOL_PRINTERDATA_KEY, value); + if (c->opt_verbose) { + fstrcpy(v.valuename, value_name); + v.type = type; + v.size = data_offered; + v.data_p = buffer; + display_reg_value(SPOOL_PRINTERDATA_KEY, v); + } + + result = pull_spoolss_PrinterData(mem_ctx, + &blob, + &printer_data, + type); + if (!W_ERROR_IS_OK(result)) { + goto done; + } /* set_value */ if (!net_spoolss_setprinterdata(pipe_hnd_dst, mem_ctx, - &hnd_dst, &value)) + &hnd_dst, value_name, + type, printer_data)) goto done; DEBUGADD(1,("\tSetPrinterData of [%s] succeeded\n", - value.valuename)); + v.valuename)); } } @@ -2443,30 +2371,20 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, if (keylist == NULL) continue; - curkey = keylist; - while (*curkey != 0) { - char *subkey; - rpcstr_pull_talloc(mem_ctx, - &subkey, - curkey, - -1, - STR_TERMINATE); - if (!subkey) { - return NT_STATUS_NO_MEMORY; - } - - curkey += strlen(subkey) + 1; + for (i=0; keylist && keylist[i] != NULL; i++) { - if ( !(reg_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) ) - return NT_STATUS_NO_MEMORY; + const char *subkey = keylist[i]; + uint32_t count; + struct spoolss_PrinterEnumValues *info; /* enumerate all src subkeys */ if (!net_spoolss_enumprinterdataex(pipe_hnd, mem_ctx, 0, &hnd_src, subkey, - reg_ctr)) + &count, &info)) { goto done; + } - for (j=0; j < reg_ctr->num_values; j++) { + for (j=0; j < count; j++) { REGISTRY_VALUE value; UNISTR2 data; @@ -2474,20 +2392,20 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, /* although samba replies with sane data in most cases we should try to avoid writing wrong registry data */ - if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_PORTNAME) || - strequal(reg_ctr->values[j]->valuename, SPOOL_REG_UNCNAME) || - strequal(reg_ctr->values[j]->valuename, SPOOL_REG_URL) || - strequal(reg_ctr->values[j]->valuename, SPOOL_REG_SHORTSERVERNAME) || - strequal(reg_ctr->values[j]->valuename, SPOOL_REG_SERVERNAME)) { + if (strequal(info[j].value_name, SPOOL_REG_PORTNAME) || + strequal(info[j].value_name, SPOOL_REG_UNCNAME) || + strequal(info[j].value_name, SPOOL_REG_URL) || + strequal(info[j].value_name, SPOOL_REG_SHORTSERVERNAME) || + strequal(info[j].value_name, SPOOL_REG_SERVERNAME)) { - if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_PORTNAME)) { + if (strequal(info[j].value_name, SPOOL_REG_PORTNAME)) { /* although windows uses a multi-sz, we use a sz */ init_unistr2(&data, SAMBA_PRINTER_PORT_NAME, UNI_STR_TERMINATE); fstrcpy(value.valuename, SPOOL_REG_PORTNAME); } - if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_UNCNAME)) { + if (strequal(info[j].value_name, SPOOL_REG_UNCNAME)) { if (asprintf(&unc_name, "\\\\%s\\%s", longname, sharename) < 0) { nt_status = NT_STATUS_NO_MEMORY; @@ -2497,7 +2415,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, fstrcpy(value.valuename, SPOOL_REG_UNCNAME); } - if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_URL)) { + if (strequal(info[j].value_name, SPOOL_REG_URL)) { continue; @@ -2512,13 +2430,13 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, #endif } - if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_SERVERNAME)) { + if (strequal(info[j].value_name, SPOOL_REG_SERVERNAME)) { init_unistr2(&data, longname, UNI_STR_TERMINATE); fstrcpy(value.valuename, SPOOL_REG_SERVERNAME); } - if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_SHORTSERVERNAME)) { + if (strequal(info[j].value_name, SPOOL_REG_SHORTSERVERNAME)) { init_unistr2(&data, global_myname(), UNI_STR_TERMINATE); fstrcpy(value.valuename, SPOOL_REG_SHORTSERVERNAME); @@ -2542,25 +2460,40 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, } else { - if (c->opt_verbose) - display_reg_value(subkey, *(reg_ctr->values[j])); + REGISTRY_VALUE v; + DATA_BLOB blob; + + result = push_spoolss_PrinterData(mem_ctx, &blob, + info[j].type, + info[j].data); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + fstrcpy(v.valuename, info[j].value_name); + v.type = info[j].type; + v.data_p = blob.data; + v.size = blob.length; + + if (c->opt_verbose) { + display_reg_value(subkey, v); + } /* here we have to set all subkeys on the dst server */ if (!net_spoolss_setprinterdataex(pipe_hnd_dst, mem_ctx, &hnd_dst, - subkey, reg_ctr->values[j])) + subkey, &v)) { goto done; + } } DEBUGADD(1,("\tSetPrinterDataEx of key [%s\\%s] succeeded\n", - subkey, reg_ctr->values[j]->valuename)); + subkey, info[j].value_name)); } - - TALLOC_FREE( reg_ctr ); } - SAFE_FREE(keylist); + TALLOC_FREE(keylist); /* close printer handles here */ if (is_valid_policy_hnd(&hnd_src)) { diff --git a/source3/utils/net_rpc_registry.c b/source3/utils/net_rpc_registry.c index 00c827928e..60274728f3 100644 --- a/source3/utils/net_rpc_registry.c +++ b/source3/utils/net_rpc_registry.c @@ -767,7 +767,7 @@ static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c, int argc, const char **argv ) { - POLICY_HND pol_hive, pol_key; + struct policy_handle pol_hive, pol_key; NTSTATUS status; uint32 num_subkeys = 0; uint32 num_values = 0; @@ -843,7 +843,7 @@ static NTSTATUS rpc_registry_save_internal(struct net_context *c, const char **argv ) { WERROR result = WERR_GENERAL_FAILURE; - POLICY_HND pol_hive, pol_key; + struct policy_handle pol_hive, pol_key; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; struct winreg_String filename; @@ -1139,7 +1139,7 @@ static NTSTATUS rpc_registry_getsd_internal(struct net_context *c, int argc, const char **argv) { - POLICY_HND pol_hive, pol_key; + struct policy_handle pol_hive, pol_key; NTSTATUS status; enum ndr_err_code ndr_err; struct KeySecurityData *sd = NULL; diff --git a/source3/utils/net_rpc_rights.c b/source3/utils/net_rpc_rights.c index ddcfff3685..10166b6d2b 100644 --- a/source3/utils/net_rpc_rights.c +++ b/source3/utils/net_rpc_rights.c @@ -28,7 +28,7 @@ static NTSTATUS sid_to_name(struct rpc_pipe_client *pipe_hnd, DOM_SID *sid, fstring name) { - POLICY_HND pol; + struct policy_handle pol; enum lsa_SidType *sid_types = NULL; NTSTATUS result; char **domains = NULL, **names = NULL; @@ -59,7 +59,7 @@ static NTSTATUS name_to_sid(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, DOM_SID *sid, const char *name) { - POLICY_HND pol; + struct policy_handle pol; enum lsa_SidType *sid_types; NTSTATUS result; DOM_SID *sids; @@ -90,7 +90,7 @@ static NTSTATUS name_to_sid(struct rpc_pipe_client *pipe_hnd, static NTSTATUS enum_privileges(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *ctx, - POLICY_HND *pol ) + struct policy_handle *pol ) { NTSTATUS result; uint32 enum_context = 0; @@ -148,7 +148,7 @@ static NTSTATUS enum_privileges(struct rpc_pipe_client *pipe_hnd, static NTSTATUS check_privilege_for_user(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *ctx, - POLICY_HND *pol, + struct policy_handle *pol, DOM_SID *sid, const char *right) { @@ -183,7 +183,7 @@ static NTSTATUS check_privilege_for_user(struct rpc_pipe_client *pipe_hnd, static NTSTATUS enum_privileges_for_user(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *ctx, - POLICY_HND *pol, + struct policy_handle *pol, DOM_SID *sid ) { NTSTATUS result; @@ -214,7 +214,7 @@ static NTSTATUS enum_privileges_for_user(struct rpc_pipe_client *pipe_hnd, static NTSTATUS enum_accounts_for_privilege(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *ctx, - POLICY_HND *pol, + struct policy_handle *pol, const char *privilege) { NTSTATUS result; @@ -265,7 +265,7 @@ static NTSTATUS enum_accounts_for_privilege(struct rpc_pipe_client *pipe_hnd, static NTSTATUS enum_privileges_for_accounts(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *ctx, - POLICY_HND *pol) + struct policy_handle *pol) { NTSTATUS result; uint32 enum_context=0; @@ -317,7 +317,7 @@ static NTSTATUS rpc_rights_list_internal(struct net_context *c, int argc, const char **argv ) { - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result; DOM_SID sid; fstring privname; @@ -436,7 +436,7 @@ static NTSTATUS rpc_rights_grant_internal(struct net_context *c, int argc, const char **argv ) { - POLICY_HND dom_pol; + struct policy_handle dom_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct lsa_RightSet rights; int i; @@ -506,7 +506,7 @@ static NTSTATUS rpc_rights_revoke_internal(struct net_context *c, int argc, const char **argv ) { - POLICY_HND dom_pol; + struct policy_handle dom_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct lsa_RightSet rights; DOM_SID sid; diff --git a/source3/utils/net_rpc_service.c b/source3/utils/net_rpc_service.c index 236414222c..bcb1a00dab 100644 --- a/source3/utils/net_rpc_service.c +++ b/source3/utils/net_rpc_service.c @@ -61,11 +61,11 @@ const char *svc_status_string( uint32 state ) static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - POLICY_HND *hSCM, + struct policy_handle *hSCM, const char *service, uint32 *state ) { - POLICY_HND hService; + struct policy_handle hService; struct SERVICE_STATUS service_status; WERROR result = WERR_GENERAL_FAILURE; NTSTATUS status; @@ -102,7 +102,7 @@ static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd, static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - POLICY_HND *hSCM, + struct policy_handle *hSCM, const char *service, uint32 watch_state, uint32 *final_state ) @@ -137,12 +137,12 @@ static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd, static WERROR control_service(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - POLICY_HND *hSCM, + struct policy_handle *hSCM, const char *service, uint32 control, uint32 watch_state ) { - POLICY_HND hService; + struct policy_handle hService; WERROR result = WERR_GENERAL_FAILURE; NTSTATUS status; struct SERVICE_STATUS service_status; @@ -199,7 +199,7 @@ static NTSTATUS rpc_service_list_internal(struct net_context *c, int argc, const char **argv ) { - POLICY_HND hSCM; + struct policy_handle hSCM; struct ENUM_SERVICE_STATUSW *services = NULL; WERROR result = WERR_GENERAL_FAILURE; NTSTATUS status; @@ -309,7 +309,7 @@ static NTSTATUS rpc_service_status_internal(struct net_context *c, int argc, const char **argv ) { - POLICY_HND hSCM, hService; + struct policy_handle hSCM, hService; WERROR result = WERR_GENERAL_FAILURE; NTSTATUS status; struct SERVICE_STATUS service_status; @@ -433,7 +433,7 @@ static NTSTATUS rpc_service_stop_internal(struct net_context *c, int argc, const char **argv ) { - POLICY_HND hSCM; + struct policy_handle hSCM; WERROR result = WERR_GENERAL_FAILURE; NTSTATUS status; fstring servicename; @@ -477,7 +477,7 @@ static NTSTATUS rpc_service_pause_internal(struct net_context *c, int argc, const char **argv ) { - POLICY_HND hSCM; + struct policy_handle hSCM; WERROR result = WERR_GENERAL_FAILURE; NTSTATUS status; fstring servicename; @@ -521,7 +521,7 @@ static NTSTATUS rpc_service_resume_internal(struct net_context *c, int argc, const char **argv ) { - POLICY_HND hSCM; + struct policy_handle hSCM; WERROR result = WERR_GENERAL_FAILURE; NTSTATUS status; fstring servicename; @@ -565,7 +565,7 @@ static NTSTATUS rpc_service_start_internal(struct net_context *c, int argc, const char **argv ) { - POLICY_HND hSCM, hService; + struct policy_handle hSCM, hService; WERROR result = WERR_GENERAL_FAILURE; NTSTATUS status; uint32 state = 0; diff --git a/source3/utils/net_rpc_sh_acct.c b/source3/utils/net_rpc_sh_acct.c index 977e1e2a0a..af0b426bbc 100644 --- a/source3/utils/net_rpc_sh_acct.c +++ b/source3/utils/net_rpc_sh_acct.c @@ -38,7 +38,7 @@ static NTSTATUS rpc_sh_acct_do(struct net_context *c, struct samr_DomInfo12 *i12, int argc, const char **argv)) { - POLICY_HND connect_pol, domain_pol; + struct policy_handle connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; union samr_DomainInfo *info1 = NULL; union samr_DomainInfo *info3 = NULL; diff --git a/source3/utils/net_sam.c b/source3/utils/net_sam.c index e8ebb60205..eea22c0dc2 100644 --- a/source3/utils/net_sam.c +++ b/source3/utils/net_sam.c @@ -1269,28 +1269,31 @@ static int net_sam_do_list(struct net_context *c, int argc, const char **argv, } } - pdb_search_destroy(search); + TALLOC_FREE(search); return 0; } static int net_sam_list_users(struct net_context *c, int argc, const char **argv) { - return net_sam_do_list(c, argc, argv, pdb_search_users(ACB_NORMAL), + return net_sam_do_list(c, argc, argv, + pdb_search_users(talloc_tos(), ACB_NORMAL), "users"); } static int net_sam_list_groups(struct net_context *c, int argc, const char **argv) { - return net_sam_do_list(c, argc, argv, pdb_search_groups(), "groups"); + return net_sam_do_list(c, argc, argv, pdb_search_groups(talloc_tos()), + "groups"); } static int net_sam_list_localgroups(struct net_context *c, int argc, const char **argv) { return net_sam_do_list(c, argc, argv, - pdb_search_aliases(get_global_sam_sid()), + pdb_search_aliases(talloc_tos(), + get_global_sam_sid()), "localgroups"); } @@ -1298,7 +1301,8 @@ static int net_sam_list_builtin(struct net_context *c, int argc, const char **argv) { return net_sam_do_list(c, argc, argv, - pdb_search_aliases(&global_sid_Builtin), + pdb_search_aliases(talloc_tos(), + &global_sid_Builtin), "builtin"); } @@ -1306,7 +1310,7 @@ static int net_sam_list_workstations(struct net_context *c, int argc, const char **argv) { return net_sam_do_list(c, argc, argv, - pdb_search_users(ACB_WSTRUST), + pdb_search_users(talloc_tos(), ACB_WSTRUST), "workstations"); } diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c index 7fbfdbab44..c6b6ee9e80 100644 --- a/source3/utils/net_util.c +++ b/source3/utils/net_util.c @@ -29,7 +29,7 @@ NTSTATUS net_rpc_lookup_name(struct net_context *c, enum lsa_SidType *ret_type) { struct rpc_pipe_client *lsa_pipe; - POLICY_HND pol; + struct policy_handle pol; NTSTATUS result = NT_STATUS_OK; const char **dom_names; DOM_SID *sids; diff --git a/source3/utils/netlookup.c b/source3/utils/netlookup.c index 14f2dddebc..dd0efa4142 100644 --- a/source3/utils/netlookup.c +++ b/source3/utils/netlookup.c @@ -31,7 +31,7 @@ struct con_struct { NTSTATUS err; struct cli_state *cli; struct rpc_pipe_client *lsapipe; - POLICY_HND pol; + struct policy_handle pol; }; static struct con_struct *cs; diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 50cbc43d6d..a5bc0c9bd4 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -67,7 +67,7 @@ static int export_database (struct pdb_methods *in, DEBUG(3, ("export_database: username=\"%s\"\n", username ? username : "(NULL)")); - u_search = pdb_search_init(PDB_USER_SEARCH); + u_search = pdb_search_init(talloc_tos(), PDB_USER_SEARCH); if (u_search == NULL) { DEBUG(0, ("pdb_search_init failed\n")); return 1; @@ -75,7 +75,7 @@ static int export_database (struct pdb_methods *in, if (!in->search_users(in, u_search, 0)) { DEBUG(0, ("Could not start searching users\n")); - pdb_search_destroy(u_search); + TALLOC_FREE(u_search); return 1; } @@ -116,7 +116,7 @@ static int export_database (struct pdb_methods *in, fprintf(stderr, "export_database: Memory allocation " "failure!\n"); TALLOC_FREE( user ); - pdb_search_destroy(u_search); + TALLOC_FREE(u_search); return 1; } @@ -139,7 +139,7 @@ static int export_database (struct pdb_methods *in, TALLOC_FREE( user ); } - pdb_search_destroy(u_search); + TALLOC_FREE(u_search); return 0; } @@ -352,7 +352,7 @@ static int print_users_list (struct pdb_methods *in, bool verbosity, bool smbpwd struct pdb_search *u_search; struct samr_displayentry userentry; - u_search = pdb_search_init(PDB_USER_SEARCH); + u_search = pdb_search_init(talloc_tos(), PDB_USER_SEARCH); if (u_search == NULL) { DEBUG(0, ("pdb_search_init failed\n")); return 1; @@ -360,7 +360,7 @@ static int print_users_list (struct pdb_methods *in, bool verbosity, bool smbpwd if (!in->search_users(in, u_search, 0)) { DEBUG(0, ("Could not start searching users\n")); - pdb_search_destroy(u_search); + TALLOC_FREE(u_search); return 1; } @@ -391,7 +391,7 @@ static int print_users_list (struct pdb_methods *in, bool verbosity, bool smbpwd print_sam_info (sam_pwent, verbosity, smbpwdstyle); TALLOC_FREE(sam_pwent); } - pdb_search_destroy(u_search); + TALLOC_FREE(u_search); return 0; } @@ -404,7 +404,7 @@ static int fix_users_list (struct pdb_methods *in) struct pdb_search *u_search; struct samr_displayentry userentry; - u_search = pdb_search_init(PDB_USER_SEARCH); + u_search = pdb_search_init(talloc_tos(), PDB_USER_SEARCH); if (u_search == NULL) { DEBUG(0, ("pdb_search_init failed\n")); return 1; @@ -412,7 +412,7 @@ static int fix_users_list (struct pdb_methods *in) if (!in->search_users(in, u_search, 0)) { DEBUG(0, ("Could not start searching users\n")); - pdb_search_destroy(u_search); + TALLOC_FREE(u_search); return 1; } @@ -444,7 +444,7 @@ static int fix_users_list (struct pdb_methods *in) } TALLOC_FREE(sam_pwent); } - pdb_search_destroy(u_search); + TALLOC_FREE(u_search); return 0; } diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c index c12778f8c7..85b7baad00 100644 --- a/source3/utils/smbcacls.c +++ b/source3/utils/smbcacls.c @@ -973,12 +973,7 @@ static struct cli_state *connect_one(struct user_auth_info *auth_info, return NULL; } - if (!get_cmdline_auth_info_got_pass(auth_info)) { - char *pass = getpass("Password: "); - if (pass) { - set_cmdline_auth_info_password(auth_info, pass); - } - } + set_cmdline_auth_info_getpass(auth_info); nt_status = cli_full_connection(&c, global_myname(), server, &ss, 0, diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index 6ea200bfec..fc7d0aa360 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -669,11 +669,11 @@ static bool do_printnotify(struct messaging_context *msg_ctx, } if (strcmp(argv[3], "comment") == 0) { - attribute = PRINTER_NOTIFY_COMMENT; + attribute = PRINTER_NOTIFY_FIELD_COMMENT; } else if (strcmp(argv[3], "port") == 0) { - attribute = PRINTER_NOTIFY_PORT_NAME; + attribute = PRINTER_NOTIFY_FIELD_PORT_NAME; } else if (strcmp(argv[3], "driver") == 0) { - attribute = PRINTER_NOTIFY_DRIVER_NAME; + attribute = PRINTER_NOTIFY_FIELD_DRIVER_NAME; } else { fprintf(stderr, "Invalid printer command '%s'\n", argv[3]); diff --git a/source3/utils/smbcquotas.c b/source3/utils/smbcquotas.c index a95394b125..78260acf76 100644 --- a/source3/utils/smbcquotas.c +++ b/source3/utils/smbcquotas.c @@ -35,7 +35,7 @@ enum exit_values {EXIT_OK, EXIT_FAILED, EXIT_PARSE_ERROR}; static struct cli_state *cli_ipc; static struct rpc_pipe_client *global_pipe_hnd; -static POLICY_HND pol; +static struct policy_handle pol; static bool got_policy_hnd; static struct user_auth_info *smbcquotas_auth_info; @@ -385,12 +385,7 @@ static struct cli_state *connect_one(const char *share) } - if (!get_cmdline_auth_info_got_pass(smbcquotas_auth_info)) { - char *pass = getpass("Password: "); - if (pass) { - set_cmdline_auth_info_password(smbcquotas_auth_info, pass); - } - } + set_cmdline_auth_info_getpass(smbcquotas_auth_info); nt_status = cli_full_connection(&c, global_myname(), server, &ss, 0, diff --git a/source3/utils/smbtree.c b/source3/utils/smbtree.c index 6c69300e85..02001f0abb 100644 --- a/source3/utils/smbtree.c +++ b/source3/utils/smbtree.c @@ -315,12 +315,7 @@ static bool print_tree(struct user_auth_info *user_info) return 1; } - if (!get_cmdline_auth_info_got_pass(auth_info)) { - char *pass = getpass("Password: "); - if (pass) { - set_cmdline_auth_info_password(auth_info, pass); - } - } + set_cmdline_auth_info_getpass(auth_info); /* Now do our stuff */ diff --git a/source3/winbindd/idmap_ad.c b/source3/winbindd/idmap_ad.c index b22e5af94a..5c29ba0b22 100644 --- a/source3/winbindd/idmap_ad.c +++ b/source3/winbindd/idmap_ad.c @@ -304,6 +304,11 @@ static NTSTATUS idmap_ad_unixids_to_sids(struct idmap_domain *dom, struct id_map char *u_filter = NULL; char *g_filter = NULL; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + /* Only do query if we are online */ if (idmap_is_offline()) { return NT_STATUS_FILE_IS_OFFLINE; @@ -516,6 +521,11 @@ static NTSTATUS idmap_ad_sids_to_unixids(struct idmap_domain *dom, struct id_map int i; char *sidstr; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + /* Only do query if we are online */ if (idmap_is_offline()) { return NT_STATUS_FILE_IS_OFFLINE; diff --git a/source3/winbindd/idmap_adex/idmap_adex.c b/source3/winbindd/idmap_adex/idmap_adex.c index 7e186ca8a1..e2fcda83d3 100644 --- a/source3/winbindd/idmap_adex/idmap_adex.c +++ b/source3/winbindd/idmap_adex/idmap_adex.c @@ -159,6 +159,11 @@ static NTSTATUS _idmap_adex_get_sid_from_id(struct NTSTATUS nt_status; struct likewise_cell *cell; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + nt_status = _idmap_adex_init(dom, NULL); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; @@ -207,6 +212,11 @@ static NTSTATUS _idmap_adex_get_id_from_sid(struct NTSTATUS nt_status; struct likewise_cell *cell; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + nt_status = _idmap_adex_init(dom, NULL); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; diff --git a/source3/winbindd/idmap_hash/idmap_hash.c b/source3/winbindd/idmap_hash/idmap_hash.c index 7dd94aede0..42830720f3 100644 --- a/source3/winbindd/idmap_hash/idmap_hash.c +++ b/source3/winbindd/idmap_hash/idmap_hash.c @@ -160,6 +160,11 @@ static NTSTATUS unixids_to_sids(struct idmap_domain *dom, NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + nt_status = be_init(dom, NULL); BAIL_ON_NTSTATUS_ERROR(nt_status); @@ -206,6 +211,11 @@ static NTSTATUS sids_to_unixids(struct idmap_domain *dom, NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + nt_status = be_init(dom, NULL); BAIL_ON_NTSTATUS_ERROR(nt_status); diff --git a/source3/winbindd/idmap_nss.c b/source3/winbindd/idmap_nss.c index 156fdc7cc9..f50e6172ba 100644 --- a/source3/winbindd/idmap_nss.c +++ b/source3/winbindd/idmap_nss.c @@ -44,6 +44,11 @@ static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_ma TALLOC_CTX *ctx; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + ctx = talloc_new(dom); if ( ! ctx) { DEBUG(0, ("Out of memory!\n")); @@ -130,6 +135,11 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma TALLOC_CTX *ctx; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + ctx = talloc_new(dom); if ( ! ctx) { DEBUG(0, ("Out of memory!\n")); diff --git a/source3/winbindd/idmap_rid.c b/source3/winbindd/idmap_rid.c index 9d1898708c..359bbfd411 100644 --- a/source3/winbindd/idmap_rid.c +++ b/source3/winbindd/idmap_rid.c @@ -171,6 +171,11 @@ static NTSTATUS idmap_rid_unixids_to_sids(struct idmap_domain *dom, struct id_ma NTSTATUS ret; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context); ctx = talloc_new(dom); @@ -205,6 +210,11 @@ static NTSTATUS idmap_rid_sids_to_unixids(struct idmap_domain *dom, struct id_ma NTSTATUS ret; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context); ctx = talloc_new(dom); diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c index 3a64979f33..22c17578e6 100644 --- a/source3/winbindd/idmap_tdb.c +++ b/source3/winbindd/idmap_tdb.c @@ -775,6 +775,11 @@ static NTSTATUS idmap_tdb_unixids_to_sids(struct idmap_domain *dom, struct id_ma NTSTATUS ret; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); for (i = 0; ids[i]; i++) { @@ -813,6 +818,11 @@ static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_ma NTSTATUS ret; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); for (i = 0; ids[i]; i++) { diff --git a/source3/winbindd/idmap_tdb2.c b/source3/winbindd/idmap_tdb2.c index fb90dd097e..b2723270eb 100644 --- a/source3/winbindd/idmap_tdb2.c +++ b/source3/winbindd/idmap_tdb2.c @@ -655,6 +655,11 @@ static NTSTATUS idmap_tdb2_unixids_to_sids(struct idmap_domain *dom, struct id_m NTSTATUS ret; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); for (i = 0; ids[i]; i++) { @@ -692,6 +697,11 @@ static NTSTATUS idmap_tdb2_sids_to_unixids(struct idmap_domain *dom, struct id_m NTSTATUS ret; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); for (i = 0; ids[i]; i++) { diff --git a/source3/winbindd/idmap_util.c b/source3/winbindd/idmap_util.c index 9abf425f3e..ad4a7ddd99 100644 --- a/source3/winbindd/idmap_util.c +++ b/source3/winbindd/idmap_util.c @@ -18,6 +18,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.*/ #include "includes.h" +#include "winbindd.h" +#include "winbindd_proto.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_IDMAP @@ -36,7 +38,8 @@ NTSTATUS idmap_uid_to_sid(const char *domname, DOM_SID *sid, uid_t uid) DEBUG(10,("idmap_uid_to_sid: uid = [%lu], domain = '%s'\n", (unsigned long)uid, domname?domname:"NULL")); - if (idmap_cache_find_uid2sid(uid, sid, &expired)) { + if (winbindd_use_idmap_cache() + && idmap_cache_find_uid2sid(uid, sid, &expired)) { DEBUG(10, ("idmap_cache_find_uid2sid found %d%s\n", uid, expired ? " (expired)": "")); if (expired && idmap_is_online()) { @@ -63,14 +66,18 @@ backend: } if (map.status != ID_MAPPED) { - struct dom_sid null_sid; - ZERO_STRUCT(null_sid); - idmap_cache_set_sid2uid(&null_sid, uid); + if (winbindd_use_idmap_cache()) { + struct dom_sid null_sid; + ZERO_STRUCT(null_sid); + idmap_cache_set_sid2uid(&null_sid, uid); + } DEBUG(10, ("uid [%lu] not mapped\n", (unsigned long)uid)); return NT_STATUS_NONE_MAPPED; } - idmap_cache_set_sid2uid(sid, uid); + if (winbindd_use_idmap_cache()) { + idmap_cache_set_sid2uid(sid, uid); + } return NT_STATUS_OK; } @@ -89,7 +96,8 @@ NTSTATUS idmap_gid_to_sid(const char *domname, DOM_SID *sid, gid_t gid) DEBUG(10,("idmap_gid_to_si: gid = [%lu], domain = '%s'\n", (unsigned long)gid, domname?domname:"NULL")); - if (idmap_cache_find_gid2sid(gid, sid, &expired)) { + if (winbindd_use_idmap_cache() + && idmap_cache_find_gid2sid(gid, sid, &expired)) { DEBUG(10, ("idmap_cache_find_gid2sid found %d%s\n", gid, expired ? " (expired)": "")); if (expired && idmap_is_online()) { @@ -116,14 +124,18 @@ backend: } if (map.status != ID_MAPPED) { - struct dom_sid null_sid; - ZERO_STRUCT(null_sid); - idmap_cache_set_sid2uid(&null_sid, gid); + if (winbindd_use_idmap_cache()) { + struct dom_sid null_sid; + ZERO_STRUCT(null_sid); + idmap_cache_set_sid2uid(&null_sid, gid); + } DEBUG(10, ("gid [%lu] not mapped\n", (unsigned long)gid)); return NT_STATUS_NONE_MAPPED; } - idmap_cache_set_sid2gid(sid, gid); + if (winbindd_use_idmap_cache()) { + idmap_cache_set_sid2gid(sid, gid); + } return NT_STATUS_OK; } @@ -142,7 +154,8 @@ NTSTATUS idmap_sid_to_uid(const char *dom_name, DOM_SID *sid, uid_t *uid) DEBUG(10,("idmap_sid_to_uid: sid = [%s], domain = '%s'\n", sid_string_dbg(sid), dom_name)); - if (idmap_cache_find_sid2uid(sid, uid, &expired)) { + if (winbindd_use_idmap_cache() + && idmap_cache_find_sid2uid(sid, uid, &expired)) { DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n", (int)(*uid), expired ? " (expired)": "")); if (expired && idmap_is_online()) { @@ -171,7 +184,9 @@ backend: map.status, map.xid.type, map.xid.id)); - idmap_cache_set_sid2uid(sid, -1); + if (winbindd_use_idmap_cache()) { + idmap_cache_set_sid2uid(sid, -1); + } return NT_STATUS_NONE_MAPPED; } goto done; @@ -182,7 +197,9 @@ backend: * We had the task to go to a specific domain which * could not answer our request. Fail. */ - idmap_cache_set_sid2uid(sid, -1); + if (winbindd_use_idmap_cache()) { + idmap_cache_set_sid2uid(sid, -1); + } return NT_STATUS_NONE_MAPPED; } @@ -191,13 +208,17 @@ backend: if (!NT_STATUS_IS_OK(ret)) { DEBUG(10, ("idmap_new_mapping failed: %s\n", nt_errstr(ret))); - idmap_cache_set_sid2uid(sid, -1); + if (winbindd_use_idmap_cache()) { + idmap_cache_set_sid2uid(sid, -1); + } return ret; } done: *uid = (uid_t)map.xid.id; - idmap_cache_set_sid2uid(sid, *uid); + if (winbindd_use_idmap_cache()) { + idmap_cache_set_sid2uid(sid, *uid); + } return NT_STATUS_OK; } @@ -215,7 +236,8 @@ NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid) DEBUG(10,("idmap_sid_to_gid: sid = [%s], domain = '%s'\n", sid_string_dbg(sid), domname)); - if (idmap_cache_find_sid2gid(sid, gid, &expired)) { + if (winbindd_use_idmap_cache() + && idmap_cache_find_sid2gid(sid, gid, &expired)) { DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n", (int)(*gid), expired ? " (expired)": "")); if (expired && idmap_is_online()) { @@ -243,7 +265,9 @@ backend: map.status, map.xid.type, map.xid.id)); - idmap_cache_set_sid2gid(sid, -1); + if (winbindd_use_idmap_cache()) { + idmap_cache_set_sid2gid(sid, -1); + } return NT_STATUS_NONE_MAPPED; } goto done; @@ -254,7 +278,9 @@ backend: * We had the task to go to a specific domain which * could not answer our request. Fail. */ - idmap_cache_set_sid2uid(sid, -1); + if (winbindd_use_idmap_cache()) { + idmap_cache_set_sid2uid(sid, -1); + } return NT_STATUS_NONE_MAPPED; } @@ -263,12 +289,16 @@ backend: if (!NT_STATUS_IS_OK(ret)) { DEBUG(10, ("idmap_new_mapping failed: %s\n", nt_errstr(ret))); - idmap_cache_set_sid2gid(sid, -1); + if (winbindd_use_idmap_cache()) { + idmap_cache_set_sid2gid(sid, -1); + } return ret; } done: *gid = map.xid.id; - idmap_cache_set_sid2gid(sid, *gid); + if (winbindd_use_idmap_cache()) { + idmap_cache_set_sid2gid(sid, *gid); + } return NT_STATUS_OK; } diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index dbe83152dd..66271068d2 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -28,7 +28,7 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND -bool opt_nocache = False; +static bool opt_nocache = False; static bool interactive = False; extern bool override_logfile; @@ -320,7 +320,7 @@ static bool winbindd_setup_sig_usr2_handler(void) se = tevent_add_signal(winbind_event_context(), winbind_event_context(), - SIGCHLD, 0, + SIGUSR2, 0, winbindd_sig_usr2_handler, NULL); if (!se) { @@ -927,6 +927,97 @@ static bool remove_idle_client(void) return False; } +struct winbindd_listen_state { + bool privileged; + int fd; + struct tevent_fd *fde; +}; + +static void winbindd_listen_fde_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, + void *private_data) +{ + struct winbindd_listen_state *s = talloc_get_type_abort(private_data, + struct winbindd_listen_state); + + while (winbindd_num_clients() > + WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) { + DEBUG(5,("winbindd: Exceeding %d client " + "connections, removing idle " + "connection.\n", + WINBINDD_MAX_SIMULTANEOUS_CLIENTS)); + if (!remove_idle_client()) { + DEBUG(0,("winbindd: Exceeding %d " + "client connections, no idle " + "connection found\n", + WINBINDD_MAX_SIMULTANEOUS_CLIENTS)); + break; + } + } + + /* new, non-privileged connection */ + new_connection(s->fd, s->privileged); +} + +static bool winbindd_setup_listeners(void) +{ + struct winbindd_listen_state *pub_state = NULL; + struct winbindd_listen_state *priv_state = NULL; + + pub_state = talloc(winbind_event_context(), + struct winbindd_listen_state); + if (!pub_state) { + goto failed; + } + + pub_state->privileged = false; + pub_state->fd = open_winbindd_socket(); + if (pub_state->fd == -1) { + goto failed; + } + + pub_state->fde = tevent_add_fd(winbind_event_context(), + pub_state, pub_state->fd, + TEVENT_FD_READ, + winbindd_listen_fde_handler, + pub_state); + if (!pub_state->fde) { + close(pub_state->fd); + goto failed; + } + tevent_fd_set_auto_close(pub_state->fde); + + priv_state = talloc(winbind_event_context(), + struct winbindd_listen_state); + if (!priv_state) { + goto failed; + } + + priv_state->privileged = true; + priv_state->fd = open_winbindd_priv_socket(); + if (priv_state->fd == -1) { + goto failed; + } + + priv_state->fde = tevent_add_fd(winbind_event_context(), + priv_state, priv_state->fd, + TEVENT_FD_READ, + winbindd_listen_fde_handler, + priv_state); + if (!priv_state->fde) { + close(priv_state->fd); + goto failed; + } + tevent_fd_set_auto_close(priv_state->fde); + + return true; +failed: + TALLOC_FREE(pub_state); + TALLOC_FREE(priv_state); + return false; +} + /* Process incoming clients on listen_sock. We use a tricky non-blocking, non-forking, non-threaded model which allows us to handle many simultaneous connections while remaining impervious to many denial of @@ -934,35 +1025,17 @@ static bool remove_idle_client(void) static void process_loop(void) { - struct winbindd_cli_state *state; struct winbindd_fd_event *ev; fd_set r_fds, w_fds; - int maxfd, listen_sock, listen_priv_sock, selret; + int maxfd = 0, selret; struct timeval timeout, ev_timeout; - /* Open Sockets here to get stuff going ASAP */ - listen_sock = open_winbindd_socket(); - listen_priv_sock = open_winbindd_priv_socket(); - - if (listen_sock == -1 || listen_priv_sock == -1) { - perror("open_winbind_socket"); - exit(1); - } - run_events(winbind_event_context(), 0, NULL, NULL); - /* refresh the trusted domain cache */ - - rescan_trusted_domains(); - /* Initialise fd lists for select() */ - maxfd = MAX(listen_sock, listen_priv_sock); - FD_ZERO(&r_fds); FD_ZERO(&w_fds); - FD_SET(listen_sock, &r_fds); - FD_SET(listen_priv_sock, &r_fds); timeout.tv_sec = WINBINDD_ESTABLISH_LOOP; timeout.tv_usec = 0; @@ -979,23 +1052,6 @@ static void process_loop(void) timeout = timeval_min(&timeout, &ev_timeout); } - /* Set up client readers and writers */ - - state = winbindd_client_list(); - - while (state) { - - struct winbindd_cli_state *next = state->next; - - /* Dispose of client connection if it is marked as - finished */ - - if (state->finished) - remove_client(state); - - state = next; - } - for (ev = fd_events; ev; ev = ev->next) { if (ev->flags & EVENT_FD_READ) { FD_SET(ev->fd, &r_fds); @@ -1043,43 +1099,7 @@ static void process_loop(void) ev = next; } - if (FD_ISSET(listen_sock, &r_fds)) { - while (winbindd_num_clients() > - WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) { - DEBUG(5,("winbindd: Exceeding %d client " - "connections, removing idle " - "connection.\n", - WINBINDD_MAX_SIMULTANEOUS_CLIENTS)); - if (!remove_idle_client()) { - DEBUG(0,("winbindd: Exceeding %d " - "client connections, no idle " - "connection found\n", - WINBINDD_MAX_SIMULTANEOUS_CLIENTS)); - break; - } - } - /* new, non-privileged connection */ - new_connection(listen_sock, False); - } - - if (FD_ISSET(listen_priv_sock, &r_fds)) { - while (winbindd_num_clients() > - WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) { - DEBUG(5,("winbindd: Exceeding %d client " - "connections, removing idle " - "connection.\n", - WINBINDD_MAX_SIMULTANEOUS_CLIENTS)); - if (!remove_idle_client()) { - DEBUG(0,("winbindd: Exceeding %d " - "client connections, no idle " - "connection found\n", - WINBINDD_MAX_SIMULTANEOUS_CLIENTS)); - break; - } - } - /* new, privileged connection */ - new_connection(listen_priv_sock, True); - } + return; no_fds_ready: @@ -1090,6 +1110,16 @@ static void process_loop(void) #endif } +bool winbindd_use_idmap_cache(void) +{ + return !opt_nocache; +} + +bool winbindd_use_cache(void) +{ + return !opt_nocache; +} + /* Main function */ int main(int argc, char **argv, char **envp) @@ -1356,12 +1386,39 @@ int main(int argc, char **argv, char **envp) smb_nscd_flush_user_cache(); smb_nscd_flush_group_cache(); - /* Loop waiting for requests */ + /* setup listen sockets */ + + if (!winbindd_setup_listeners()) { + DEBUG(0,("winbindd_setup_listeners() failed\n")); + exit(1); + } TALLOC_FREE(frame); + /* Loop waiting for requests */ while (1) { + struct winbindd_cli_state *state; + frame = talloc_stackframe(); + + /* refresh the trusted domain cache */ + + rescan_trusted_domains(); + + /* Dispose of client connection if it is marked as + finished */ + state = winbindd_client_list(); + while (state) { + struct winbindd_cli_state *next = state->next; + + if (state->finished) { + remove_client(state); + } + + state = next; + } + process_loop(); + TALLOC_FREE(frame); } diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h index 5ebbb72cf5..f3733dc131 100644 --- a/source3/winbindd/winbindd.h +++ b/source3/winbindd/winbindd.h @@ -119,10 +119,10 @@ struct winbindd_cm_conn { struct cli_state *cli; struct rpc_pipe_client *samr_pipe; - POLICY_HND sam_connect_handle, sam_domain_handle; + struct policy_handle sam_connect_handle, sam_domain_handle; struct rpc_pipe_client *lsa_pipe; - POLICY_HND lsa_policy; + struct policy_handle lsa_policy; struct rpc_pipe_client *netlogon_pipe; }; diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c index a508682e5e..a76faa7a25 100644 --- a/source3/winbindd/winbindd_ads.c +++ b/source3/winbindd/winbindd_ads.c @@ -978,7 +978,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, size_t num_members = 0; ads_control args; struct rpc_pipe_client *cli; - POLICY_HND lsa_policy; + struct policy_handle lsa_policy; DOM_SID *sid_mem_nocache = NULL; char **names_nocache = NULL; enum lsa_SidType *name_types_nocache = NULL; diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index 02d0b5bc4e..66166bf292 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -34,7 +34,6 @@ #define WINBINDD_CACHE_VERSION_KEYSTR "WINBINDD_CACHE_VERSION" extern struct winbindd_methods reconnect_methods; -extern bool opt_nocache; #ifdef HAVE_ADS extern struct winbindd_methods ads_methods; #endif @@ -632,7 +631,7 @@ static struct cache_entry *wcache_fetch(struct winbind_cache *cache, char *kstr; struct cache_entry *centry; - if (opt_nocache) { + if (!winbindd_use_cache()) { return NULL; } @@ -834,7 +833,7 @@ static void centry_end(struct cache_entry *centry, const char *format, ...) char *kstr; TDB_DATA key, data; - if (opt_nocache) { + if (!winbindd_use_cache()) { return; } @@ -2861,8 +2860,9 @@ void wcache_flush_cache(void) tdb_close(wcache->tdb); wcache->tdb = NULL; } - if (opt_nocache) + if (!winbindd_use_cache()) { return; + } /* when working offline we must not clear the cache on restart */ wcache->tdb = tdb_open_log(cache_path("winbindd_cache.tdb"), diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 35768fe7f2..ed0a33a5f2 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -821,8 +821,6 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, } } - cli_setup_signing_state(*cli, Undefined); - result = cli_negprot(*cli); if (!NT_STATUS_IS_OK(result)) { @@ -868,7 +866,10 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, result = ads_ntstatus(ads_status); if (NT_STATUS_IS_OK(result)) { /* Ensure creds are stored for NTLMSSP authenticated pipe access. */ - cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password); + result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } goto session_setup_done; } } @@ -893,7 +894,10 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, result = ads_ntstatus(ads_status); if (NT_STATUS_IS_OK(result)) { /* Ensure creds are stored for NTLMSSP authenticated pipe access. */ - cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password); + result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } goto session_setup_done; } } @@ -919,7 +923,10 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, ipc_password, strlen(ipc_password)+1, ipc_domain))) { /* Successful logon with given username. */ - cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password); + result = cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } goto session_setup_done; } else { DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n", @@ -937,7 +944,10 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0, NULL, 0, ""))) { DEBUG(5, ("Connected anonymously\n")); - cli_init_creds(*cli, "", "", ""); + result = cli_init_creds(*cli, "", "", ""); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } goto session_setup_done; } @@ -972,8 +982,11 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, *retry = False; /* set the domain if empty; needed for schannel connections */ - if ( !*(*cli)->domain ) { - fstrcpy( (*cli)->domain, domain->name ); + if ( !(*cli)->domain[0] ) { + result = cli_set_domain((*cli), domain->name); + if (!NT_STATUS_IS_OK(result)) { + return result; + } } result = NT_STATUS_OK; @@ -1759,8 +1772,8 @@ static void set_dc_type_and_flags_connect( struct winbindd_domain *domain ) NTSTATUS result; WERROR werr; TALLOC_CTX *mem_ctx = NULL; - struct rpc_pipe_client *cli; - POLICY_HND pol; + struct rpc_pipe_client *cli = NULL; + struct policy_handle pol; union dssetup_DsRoleInfo info; union lsa_PolicyInformation *lsa_info = NULL; @@ -1977,11 +1990,10 @@ static bool cm_get_schannel_dcinfo(struct winbindd_domain *domain, } NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - struct rpc_pipe_client **cli, POLICY_HND *sam_handle) + struct rpc_pipe_client **cli, struct policy_handle *sam_handle) { struct winbindd_cm_conn *conn; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - fstring conn_pwd; struct dcinfo *p_dcinfo; char *machine_password = NULL; char *machine_account = NULL; @@ -2006,10 +2018,9 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, * anonymous. */ - pwd_get_cleartext(&conn->cli->pwd, conn_pwd); if ((conn->cli->user_name[0] == '\0') || (conn->cli->domain[0] == '\0') || - (conn_pwd[0] == '\0')) + (conn->cli->password == NULL || conn->cli->password[0] == '\0')) { result = get_trust_creds(domain, &machine_password, &machine_account, NULL); @@ -2020,7 +2031,7 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, } domain_name = domain->name; } else { - machine_password = SMB_STRDUP(conn_pwd); + machine_password = SMB_STRDUP(conn->cli->password); machine_account = SMB_STRDUP(conn->cli->user_name); domain_name = conn->cli->domain; } @@ -2145,11 +2156,10 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, } NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - struct rpc_pipe_client **cli, POLICY_HND *lsa_policy) + struct rpc_pipe_client **cli, struct policy_handle *lsa_policy) { struct winbindd_cm_conn *conn; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - fstring conn_pwd; struct dcinfo *p_dcinfo; result = init_dc_connection(domain); @@ -2162,10 +2172,9 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, goto done; } - pwd_get_cleartext(&conn->cli->pwd, conn_pwd); if ((conn->cli->user_name[0] == '\0') || (conn->cli->domain[0] == '\0') || - (conn_pwd[0] == '\0')) { + (conn->cli->password == NULL || conn->cli->password[0] == '\0')) { DEBUG(10, ("cm_connect_lsa: No no user available for " "domain %s, trying schannel\n", conn->cli->domain)); goto schannel; @@ -2176,7 +2185,7 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, result = cli_rpc_pipe_open_spnego_ntlmssp (conn->cli, &ndr_table_lsarpc.syntax_id, PIPE_AUTH_LEVEL_PRIVACY, - conn->cli->domain, conn->cli->user_name, conn_pwd, + conn->cli->domain, conn->cli->user_name, conn->cli->password, &conn->lsa_pipe); if (!NT_STATUS_IS_OK(result)) { diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c index 043f26e578..6ad93adf4a 100644 --- a/source3/winbindd/winbindd_group.c +++ b/source3/winbindd/winbindd_group.c @@ -25,8 +25,6 @@ #include "includes.h" #include "winbindd.h" -extern bool opt_nocache; - #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 597d48aad0..15d1b7e2bf 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -1396,7 +1396,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, NT_STATUS_IS_OK(result) && (my_info3->base.acct_flags == 0)) { struct rpc_pipe_client *samr_pipe; - POLICY_HND samr_domain_handle, user_pol; + struct policy_handle samr_domain_handle, user_pol; union samr_UserInfo *info = NULL; NTSTATUS status_tmp; uint32 acct_flags; @@ -2066,7 +2066,7 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact { char *oldpass; char *newpass = NULL; - POLICY_HND dom_pol; + struct policy_handle dom_pol; struct rpc_pipe_client *cli; bool got_info = false; struct samr_DomInfo1 *info = NULL; @@ -2394,7 +2394,7 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai DATA_BLOB new_lm_password; DATA_BLOB old_lm_hash_enc; fstring domain,user; - POLICY_HND dom_pol; + struct policy_handle dom_pol; struct winbindd_domain *contact_domain = domainSt; struct rpc_pipe_client *cli; diff --git a/source3/winbindd/winbindd_passdb.c b/source3/winbindd/winbindd_passdb.c index d704ca0fd3..1a358b2b44 100644 --- a/source3/winbindd/winbindd_passdb.c +++ b/source3/winbindd/winbindd_passdb.c @@ -40,9 +40,9 @@ static NTSTATUS enum_groups_internal(struct winbindd_domain *domain, NTSTATUS result = NT_STATUS_UNSUCCESSFUL; if (sidtype == SID_NAME_ALIAS) { - search = pdb_search_aliases(&domain->sid); + search = pdb_search_aliases(talloc_tos(), &domain->sid); } else { - search = pdb_search_groups(); + search = pdb_search_groups(talloc_tos()); } if (search == NULL) goto done; @@ -68,7 +68,7 @@ static NTSTATUS enum_groups_internal(struct winbindd_domain *domain, result = NT_STATUS_OK; done: - pdb_search_destroy(search); + TALLOC_FREE(search); return result; } @@ -456,7 +456,7 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain, uint32 *num_entries, WINBIND_USERINFO **info) { - struct pdb_search *ps = pdb_search_users(ACB_NORMAL); + struct pdb_search *ps = pdb_search_users(talloc_tos(), ACB_NORMAL); struct samr_displayentry *entries = NULL; uint32 i; @@ -473,7 +473,7 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain, *info = TALLOC_ZERO_ARRAY(mem_ctx, WINBIND_USERINFO, *num_entries); if (!(*info)) { - pdb_search_destroy(ps); + TALLOC_FREE(ps); return NT_STATUS_NO_MEMORY; } @@ -498,7 +498,7 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain, DOMAIN_GROUP_RID_USERS); } - pdb_search_destroy(ps); + TALLOC_FREE(ps); return NT_STATUS_OK; } diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index c6e8803ce8..384395f896 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -65,6 +65,8 @@ void request_error(struct winbindd_cli_state *state); void request_ok(struct winbindd_cli_state *state); bool winbindd_setup_sig_term_handler(bool parent); bool winbindd_setup_sig_hup_handler(const char *lfile); +bool winbindd_use_idmap_cache(void); +bool winbindd_use_cache(void); int main(int argc, char **argv, char **envp); /* The following definitions come from winbindd/winbindd_ads.c */ @@ -206,9 +208,9 @@ void invalidate_cm_connection(struct winbindd_cm_conn *conn); void close_conns_after_fork(void); NTSTATUS init_dc_connection(struct winbindd_domain *domain); NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - struct rpc_pipe_client **cli, POLICY_HND *sam_handle); + struct rpc_pipe_client **cli, struct policy_handle *sam_handle); NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - struct rpc_pipe_client **cli, POLICY_HND *lsa_policy); + struct rpc_pipe_client **cli, struct policy_handle *lsa_policy); NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, struct rpc_pipe_client **cli); @@ -547,7 +549,6 @@ const char *get_winbind_pipe_dir(void) ; char *get_winbind_priv_pipe_dir(void) ; int open_winbindd_socket(void); int open_winbindd_priv_socket(void); -void close_winbindd_socket(void); struct winbindd_cli_state *winbindd_client_list(void); void winbindd_add_client(struct winbindd_cli_state *cli); void winbindd_remove_client(struct winbindd_cli_state *cli); diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c index 0070bde2cc..5edb0d98b0 100644 --- a/source3/winbindd/winbindd_rpc.c +++ b/source3/winbindd/winbindd_rpc.c @@ -38,7 +38,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, WINBIND_USERINFO **info) { NTSTATUS result; - POLICY_HND dom_pol; + struct policy_handle dom_pol; unsigned int i, start_idx; uint32 loop_count; struct rpc_pipe_client *cli; @@ -130,7 +130,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, uint32 *num_entries, struct acct_info **info) { - POLICY_HND dom_pol; + struct policy_handle dom_pol; NTSTATUS status; uint32 start = 0; struct rpc_pipe_client *cli; @@ -201,7 +201,7 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain, uint32 *num_entries, struct acct_info **info) { - POLICY_HND dom_pol; + struct policy_handle dom_pol; NTSTATUS result; struct rpc_pipe_client *cli; @@ -278,7 +278,7 @@ static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain, enum lsa_SidType *types = NULL; char *full_name = NULL; struct rpc_pipe_client *cli; - POLICY_HND lsa_policy; + struct policy_handle lsa_policy; NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL; char *mapped_name = NULL; @@ -343,7 +343,7 @@ static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain, enum lsa_SidType *types = NULL; NTSTATUS result; struct rpc_pipe_client *cli; - POLICY_HND lsa_policy; + struct policy_handle lsa_policy; NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL; char *mapped_name = NULL; @@ -396,7 +396,7 @@ static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain, char **domains; NTSTATUS result; struct rpc_pipe_client *cli; - POLICY_HND lsa_policy; + struct policy_handle lsa_policy; DOM_SID *sids; size_t i; char **ret_names; @@ -461,7 +461,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain, WINBIND_USERINFO *user_info) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - POLICY_HND dom_pol, user_pol; + struct policy_handle dom_pol, user_pol; union samr_UserInfo *info = NULL; uint32 user_rid; struct netr_SamInfo3 *user; @@ -564,7 +564,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, uint32 *num_groups, DOM_SID **user_grpsids) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - POLICY_HND dom_pol, user_pol; + struct policy_handle dom_pol, user_pol; uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; struct samr_RidWithAttributeArray *rid_array = NULL; unsigned int i; @@ -645,7 +645,7 @@ static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain, uint32 **alias_rids) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - POLICY_HND dom_pol; + struct policy_handle dom_pol; uint32 num_query_sids = 0; int i; struct rpc_pipe_client *cli; @@ -745,7 +745,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 i, total_names = 0; - POLICY_HND dom_pol, group_pol; + struct policy_handle dom_pol, group_pol; uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; uint32 *rid_mem = NULL; uint32 group_rid; @@ -857,14 +857,15 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, } for (r=0; r<tmp_names.count; r++) { - (*names)[i+r] = fill_domain_username_talloc(mem_ctx, - domain->name, - tmp_names.names[r].string, - true); - (*name_types)[i+r] = tmp_types.ids[r]; + if (tmp_types.ids[r] == SID_NAME_UNKNOWN) { + continue; + } + (*names)[total_names] = fill_domain_username_talloc( + mem_ctx, domain->name, + tmp_names.names[r].string, true); + (*name_types)[total_names] = tmp_types.ids[r]; + total_names += 1; } - - total_names += tmp_names.count; } *num_names = total_names; @@ -952,7 +953,7 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) TALLOC_CTX *mem_ctx; union samr_DomainInfo *info = NULL; NTSTATUS result; - POLICY_HND dom_pol; + struct policy_handle dom_pol; bool got_seq_num = False; struct rpc_pipe_client *cli; @@ -1053,7 +1054,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 enum_ctx = 0; struct rpc_pipe_client *cli; - POLICY_HND lsa_policy; + struct policy_handle lsa_policy; DEBUG(3,("rpc: trusted_domains\n")); @@ -1111,7 +1112,7 @@ static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain, { NTSTATUS result; struct rpc_pipe_client *cli; - POLICY_HND dom_pol; + struct policy_handle dom_pol; union samr_DomainInfo *info = NULL; DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name)); @@ -1152,7 +1153,7 @@ static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain, { NTSTATUS result; struct rpc_pipe_client *cli; - POLICY_HND dom_pol; + struct policy_handle dom_pol; union samr_DomainInfo *info = NULL; DEBUG(10,("rpc: fetch password policy for %s\n", domain->name)); diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 2d87015fec..a2c1c85e0b 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1316,24 +1316,6 @@ int open_winbindd_priv_socket(void) return _winbindd_priv_socket; } -/* Close the winbindd socket */ - -void close_winbindd_socket(void) -{ - if (_winbindd_socket != -1) { - DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n", - _winbindd_socket)); - close(_winbindd_socket); - _winbindd_socket = -1; - } - if (_winbindd_priv_socket != -1) { - DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n", - _winbindd_priv_socket)); - close(_winbindd_priv_socket); - _winbindd_priv_socket = -1; - } -} - /* * Client list accessor functions */ |