diff options
Diffstat (limited to 'source3')
49 files changed, 3306 insertions, 5590 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 56080841db..f69c39b6e4 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -456,7 +456,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) \ @@ -666,6 +666,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 @@ -2566,6 +2567,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/client/client.c b/source3/client/client.c index 67a2458a94..6491f39ed0 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -220,9 +220,7 @@ struct push_state { SMB_OFF_T nread; }; -static size_t push_source(uint8_t *inbuf, size_t n, - const uint8_t **outbuf, - void *priv) +static size_t push_source(uint8_t *buf, size_t n, void *priv) { struct push_state *state = (struct push_state *)priv; int result; @@ -231,7 +229,7 @@ static size_t push_source(uint8_t *inbuf, size_t n, return 0; } - result = readfile(inbuf, n, state->f); + result = readfile(buf, n, state->f); state->nread += result; return result; } @@ -1421,7 +1419,7 @@ static bool do_altname(const char *name) static int cmd_quit(void) { - cli_cm_shutdown(); + cli_shutdown(cli); exit(0); /* NOTREACHED */ return 0; @@ -1683,8 +1681,8 @@ static int do_put(const char *rname, const char *lname, bool reput) state.f = f; state.nread = 0; - status = cli_push(targetcli, fnum, 0, 0, io_bufsize, - false, push_source, &state); + status = cli_push(targetcli, fnum, 0, 0, io_bufsize, push_source, + &state); if (!NT_STATUS_IS_OK(status)) { d_fprintf(stderr, "cli_push returned %s\n", nt_errstr(status)); } @@ -1716,7 +1714,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); } @@ -3817,7 +3815,7 @@ static int cmd_logon(void) static int cmd_list_connect(void) { - cli_cm_display(); + cli_cm_display(cli); return 0; } @@ -4528,7 +4526,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; } } @@ -4539,7 +4537,7 @@ static int process(const char *base_directory) process_stdin(); } - cli_cm_shutdown(); + cli_shutdown(cli); return rc; } @@ -4570,7 +4568,7 @@ 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, max_protocol, 139, name_type); @@ -4583,7 +4581,7 @@ static int do_host_query(const char *query_host) list_servers(lp_workgroup()); - cli_cm_shutdown(); + cli_shutdown(cli); return(0); } @@ -4611,14 +4609,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); } @@ -4665,12 +4663,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(); + cli_shutdown(cli); return 0; } 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 6d9e198244..98f41d61e5 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -436,7 +436,7 @@ 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" 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" @@ -1196,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) @@ -6204,6 +6201,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) diff --git a/source3/include/client.h b/source3/include/client.h index 646d54aa05..320a90e66b 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -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/proto.h b/source3/include/proto.h index 794a006a68..f992f0686a 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2355,7 +2355,6 @@ 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, @@ -2365,8 +2364,7 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx, int max_protocol, int port, int name_type); -void cli_cm_shutdown(void); -void cli_cm_display(void); +void cli_cm_display(const struct cli_state *c); 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); @@ -2426,7 +2424,10 @@ 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); +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); @@ -2790,18 +2791,13 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct cli_state *cli, uint16_t fnum, uint16_t mode, off_t start_offset, size_t window_size, - bool caller_buffers, - size_t (*source)(uint8_t *inbuf, size_t n, - const uint8_t **outbuf, + size_t (*source)(uint8_t *buf, size_t n, void *priv), void *priv); NTSTATUS cli_push_recv(struct async_req *req); NTSTATUS cli_push(struct cli_state *cli, uint16_t fnum, uint16_t mode, off_t start_offset, size_t window_size, - bool caller_buffers, - size_t (*source)(uint8_t *inbuf, size_t n, - const uint8_t **outbuf, - void *priv), + size_t (*source)(uint8_t *buf, size_t n, void *priv), void *priv); /* The following definitions come from libsmb/clisecdesc.c */ @@ -3161,11 +3157,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); @@ -3416,11 +3407,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, @@ -4933,7 +4929,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, @@ -5513,17 +5509,31 @@ WERROR rpccli_spoolss_enummonitors(struct rpc_pipe_client *cli, uint32_t offered, uint32_t *count, union spoolss_MonitorInfo **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_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_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_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, POLICY_HND *hnd, const char *valuename, REGISTRY_VALUE *value); @@ -5831,66 +5841,7 @@ bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, 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_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); -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_printer_enum_values(PRINTER_ENUM_VALUES *p); -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 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 make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src); 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); @@ -5904,17 +5855,6 @@ bool make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_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); @@ -6117,17 +6057,13 @@ void construct_info_data(struct spoolss_Notify *info_data, enum spoolss_Field 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_new(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 enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines ); 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_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); diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index fdce63aba3..eb2fdd5309 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -311,274 +311,6 @@ typedef struct spool_r_getprinterdata } 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; @@ -606,116 +338,6 @@ typedef struct systemtime } 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 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; - /********************************************/ typedef struct spool_q_enumprinterdata @@ -772,37 +394,6 @@ typedef struct _form } 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; diff --git a/source3/include/smb.h b/source3/include/smb.h index a0140fe081..281a218256 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1759,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/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 b5e769f8c3..fd9b669710 100644 --- a/source3/include/wbc_async.h +++ b/source3/include/wbc_async.h @@ -61,7 +61,8 @@ wbcErr wb_resp_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct winbindd_response **presp); struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, int fd, + struct tevent_context *ev, + struct tevent_queue *queue, int fd, struct winbindd_response *wb_resp); wbcErr wb_resp_write_recv(struct tevent_req *req); diff --git a/source3/lib/events.c b/source3/lib/events.c index f875e0dc0c..8c56941829 100644 --- a/source3/lib/events.c +++ b/source3/lib/events.c @@ -145,7 +145,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,12 +181,12 @@ static int s3_event_loop_once(struct tevent_context *ev) return 0; } -static int s3_event_loop_wait(struct tevent_context *ev) +static int s3_event_loop_wait(struct tevent_context *ev, const char *location) { int ret = 0; while (ret == 0) { - ret = s3_event_loop_once(ev); + ret = s3_event_loop_once(ev, location); } return ret; diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c index 233255fed4..43ebed6c22 100644 --- a/source3/lib/netapi/cm.c +++ b/source3/lib/netapi/cm.c @@ -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/wb_reqtrans.c b/source3/lib/wb_reqtrans.c index 6ae1d1bb9b..e1c67491c0 100644 --- a/source3/lib/wb_reqtrans.c +++ b/source3/lib/wb_reqtrans.c @@ -372,7 +372,8 @@ struct resp_write_state { static void wb_resp_write_done(struct tevent_req *subreq); struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, int fd, + struct tevent_context *ev, + struct tevent_queue *queue, int fd, struct winbindd_response *wb_resp) { struct tevent_req *result, *subreq; @@ -394,7 +395,7 @@ struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, count = 2; } - subreq = writev_send(state, ev, NULL, fd, state->iov, count); + subreq = writev_send(state, ev, queue, fd, state->iov, count); if (subreq == NULL) { goto fail; } diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ec2932488e..43326e912c 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; } @@ -520,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 */ @@ -898,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)); @@ -936,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 @@ -2101,7 +2118,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 1153d8dc89..8544d5520e 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,12 +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; @@ -49,8 +43,6 @@ static struct cm_cred_struct { 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 +88,7 @@ NTSTATUS cli_cm_force_encryption(struct cli_state *c, return status; } - + /******************************************************************** Return a connection to a server. ********************************************************************/ @@ -301,52 +293,20 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, /**************************************************************************** ****************************************************************************/ -static void cli_cm_set_mntpoint(struct cli_state *c, 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) +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) { - 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, @@ -359,53 +319,62 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx, 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, 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; } } @@ -413,8 +382,7 @@ 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, @@ -427,50 +395,28 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx, 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 */ + if (c) { + return c; + } - c = cli_cm_find(server, share); - if (!c) { - c = cli_cm_connect(ctx, referring_cli, + return cli_cm_connect(ctx, referring_cli, server, share, show_hdr, force_encrypt, max_protocol, port, name_type); - } - - 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); - } - - connections = NULL; - return; } /**************************************************************************** ****************************************************************************/ -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 ); } } @@ -998,7 +944,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. */ diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2983f7771a..c1ba4e5c4f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -409,23 +409,68 @@ void cli_setup_bcc(struct cli_state *cli, void *p) } /**************************************************************************** + Initialize Domain, user or password. +****************************************************************************/ + +NTSTATUS cli_set_domain(struct cli_state *cli, const char *domain) +{ + TALLOC_FREE(cli->domain); + cli->domain = talloc_strdup(cli, domain ? domain : ""); + if (cli->domain == NULL) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +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; +} + +/**************************************************************************** Initialise credentials of a client structure. ****************************************************************************/ -void cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password) +NTSTATUS cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password) { - fstrcpy(cli->domain, domain); - fstrcpy(cli->user_name, username); - pwd_set_cleartext(&cli->pwd, password); - if (!*username) { - cli->pwd.null_pwd = true; + 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)); - DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain)); + 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). ****************************************************************************/ @@ -446,6 +491,10 @@ struct cli_state *cli_initialise_ex(int signing_state) return NULL; } + cli->dfs_mountpoint = talloc_strdup(cli, ""); + if (!cli->dfs_mountpoint) { + goto error; + } cli->port = 0; cli->fd = -1; cli->cnum = -1; @@ -521,7 +570,7 @@ struct cli_state *cli_initialise_ex(int signing_state) SAFE_FREE(cli->inbuf); SAFE_FREE(cli->outbuf); - SAFE_FREE(cli); + TALLOC_FREE(cli); return NULL; } @@ -550,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 7e7cf0d682..f2f447b4c9 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -930,11 +930,8 @@ struct cli_push_state { uint16_t mode; off_t start_offset; size_t window_size; - bool caller_buffers; - size_t (*source)(uint8_t *inbuf, size_t n, - const uint8_t **outbuf, - void *priv); + size_t (*source)(uint8_t *buf, size_t n, void *priv); void *priv; bool eof; @@ -966,21 +963,13 @@ static bool cli_push_write_setup(struct async_req *req, substate->req = req; substate->idx = idx; substate->ofs = state->next_offset; - if (state->caller_buffers) { - substate->buf = NULL; - } else { - substate->buf = talloc_array(substate, uint8_t, - state->chunk_size); - if (!substate->buf) { - talloc_free(substate); - return false; - } + substate->buf = talloc_array(substate, uint8_t, state->chunk_size); + if (!substate->buf) { + talloc_free(substate); + return false; } - - /* source function can overwrite substate->buf... */ substate->size = state->source(substate->buf, state->chunk_size, - (const uint8_t **)&substate->buf, state->priv); if (substate->size == 0) { state->eof = true; @@ -1013,9 +1002,7 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct cli_state *cli, uint16_t fnum, uint16_t mode, off_t start_offset, size_t window_size, - bool caller_buffers, - size_t (*source)(uint8_t *inbuf, size_t n, - const uint8_t **outbuf, + size_t (*source)(uint8_t *buf, size_t n, void *priv), void *priv) { @@ -1032,7 +1019,6 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev, state->fnum = fnum; state->start_offset = start_offset; state->mode = mode; - state->caller_buffers = caller_buffers; state->source = source; state->priv = priv; state->eof = false; @@ -1122,10 +1108,7 @@ NTSTATUS cli_push_recv(struct async_req *req) NTSTATUS cli_push(struct cli_state *cli, uint16_t fnum, uint16_t mode, off_t start_offset, size_t window_size, - bool caller_buffers, - size_t (*source)(uint8_t *inbuf, size_t n, - const uint8_t **outbuf, - void *priv), + size_t (*source)(uint8_t *buf, size_t n, void *priv), void *priv) { TALLOC_CTX *frame = talloc_stackframe(); @@ -1146,7 +1129,7 @@ NTSTATUS cli_push(struct cli_state *cli, uint16_t fnum, uint16_t mode, } req = cli_push_send(frame, ev, cli, fnum, mode, start_offset, - window_size, caller_buffers, source, priv); + window_size, source, priv); if (req == NULL) { goto nomem; } 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/locking/locking.c b/source3/locking/locking.c index e9a5f757e5..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. ****************************************************************************/ 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/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_onefs.c b/source3/modules/vfs_onefs.c index 2ec6e069c3..ad59c2b32d 100644 --- a/source3/modules/vfs_onefs.c +++ b/source3/modules/vfs_onefs.c @@ -289,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/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/printing.c b/source3/printing/printing.c index fc3667ea3a..71c634442b 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2407,7 +2407,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/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 24dbcb0193..ef10c123f3 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -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_spoolss.c b/source3/rpc_client/cli_spoolss.c index a83b0c53c6..76614c67eb 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -540,519 +540,174 @@ WERROR rpccli_spoolss_enummonitors(struct rpc_pipe_client *cli, return werror; } -/********************************************************************* - Decode various spoolss rpc's and info levels - ********************************************************************/ - -/********************************************************************** -**********************************************************************/ - -static bool decode_printer_info_0(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, PRINTER_INFO_0 **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); - - for (i=0; i<returned; i++) { - if (!smb_io_printer_info_0("", buffer, &inf[i], 0)) { - return False; - } - } - - *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; - } - - prs_set_offset(&buffer->prs,0); - - for (i=0; i<returned; i++) { - if (!smb_io_printer_info_1("", buffer, &inf[i], 0)) { - return False; - } - } - - *info=inf; - return True; -} - /********************************************************************** + convencience wrapper around rpccli_spoolss_EnumJobs **********************************************************************/ -static bool decode_printer_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, PRINTER_INFO_2 **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) { - 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); - - 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; - } - } - - *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; - } - - prs_set_offset(&buffer->prs,0); - - for (i=0; i<returned; i++) { - inf[i].secdesc = NULL; - if (!smb_io_printer_info_3("", buffer, &inf[i], 0)) { - return False; - } - } - - *info=inf; - return True; -} - -/********************************************************************** -**********************************************************************/ - -static bool decode_printer_driver_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, DRIVER_INFO_1 **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); - - for (i=0; i<returned; i++) { - if (!smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0)) { - return False; - } - } - - *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; - } - - 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_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_driver_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, DRIVER_INFO_3 **info) -{ - uint32 i; - DRIVER_INFO_3 *inf; + status = rpccli_spoolss_EnumJobs(cli, mem_ctx, + handle, + firstjob, + numjobs, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); - 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); + 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_3("", buffer, &(inf[i]), 0)) { - return False; - } + status = rpccli_spoolss_EnumJobs(cli, mem_ctx, + handle, + firstjob, + numjobs, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); } - *info=inf; - return True; + return werror; } /********************************************************************** + convencience wrapper around rpccli_spoolss_EnumPrinterDrivers **********************************************************************/ -static bool decode_jobs_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 num_jobs, JOB_INFO_1 **jobs) +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) { - 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); + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; - for (i = 0; i < num_jobs; i++) { - if (!smb_io_job_info_1("", 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_jobs_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 num_jobs, JOB_INFO_2 **jobs) -{ - uint32 i; + status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx, + server, + environment, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); - 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); + 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_2("", buffer, &((*jobs)[i]), 0)) { - return False; - } + status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx, + server, + environment, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); } - return True; + return werror; } /********************************************************************** + convencience wrapper around rpccli_spoolss_EnumPrinters **********************************************************************/ -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_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_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 ); + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; - 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 (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); } - 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; -} - -/********************************************************************** -**********************************************************************/ - -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 ); + status = rpccli_spoolss_EnumPrinters(cli, mem_ctx, + flags, + server, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); - 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_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; - - 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_EnumPrinters(cli, mem_ctx, + flags, + server, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); } - return out.status; + return 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_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; - } - - *returned = out.returned; - - return out.status; -} +/********************************************************************* + Decode various spoolss rpc's and info levels + ********************************************************************/ /********************************************************************** **********************************************************************/ diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 337121d70d..e499607a4d 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -347,15 +347,6 @@ bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, } /******************************************************************* - * 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) ********************************************************************/ @@ -365,1084 +356,6 @@ static uint32 size_of_uint32(uint32 *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 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; -} - -/******************************************************************* -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_printer_enum_values(PRINTER_ENUM_VALUES *p) @@ -1462,405 +375,6 @@ uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p) } /******************************************************************* - * 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; -} - -/******************************************************************* - * 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; -} - -/******************************************************************* make a BUFFER5 struct from a uint16* ******************************************************************/ @@ -2073,117 +587,6 @@ bool spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, } /******************************************************************* - 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, diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index 616eb1dbf0..da8220232b 100644 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -190,27 +190,7 @@ static bool api_spoolss_rfnpcnex(pipes_struct *p) 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; + return proxy_spoolss_call(p, NDR_SPOOLSS_ENUMPRINTERS); } /******************************************************************** @@ -221,27 +201,7 @@ static bool api_spoolss_enumprinters(pipes_struct *p) 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; + return proxy_spoolss_call(p, NDR_SPOOLSS_GETPRINTER); } /******************************************************************** @@ -252,27 +212,7 @@ static bool api_spoolss_getprinter(pipes_struct *p) 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; + return proxy_spoolss_call(p, NDR_SPOOLSS_GETPRINTERDRIVER2); } /******************************************************************** @@ -351,27 +291,7 @@ static bool api_spoolss_addjob(pipes_struct *p) 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; + return proxy_spoolss_call(p, NDR_SPOOLSS_ENUMJOBS); } /**************************************************************************** @@ -395,27 +315,7 @@ static bool api_spoolss_setjob(pipes_struct *p) 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; + return proxy_spoolss_call(p, NDR_SPOOLSS_ENUMPRINTERDRIVERS); } /**************************************************************************** @@ -589,27 +489,7 @@ static bool api_spoolss_enumprintmonitors(pipes_struct *p) 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; + return proxy_spoolss_call(p, NDR_SPOOLSS_GETJOB); } /******************************************************************** diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 0a4f5ae05c..950dc013b2 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -27,6 +27,16 @@ #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_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false) + + extern userdom_struct current_user_info; #undef DBGC_CLASS @@ -3914,149 +3924,81 @@ 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; + 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; - 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); - - return True; + return WERR_OK; } /**************************************************************************** @@ -4072,6 +4014,73 @@ static void free_dev_mode(DEVICEMODE *dev) SAFE_FREE(dev); } +/**************************************************************************** + Convert an NT_DEVICEMODE to a spoolss_DeviceMode structure. Both pointers + should be valid upon entry +****************************************************************************/ + +static WERROR convert_nt_devicemode_new(TALLOC_CTX *mem_ctx, + struct spoolss_DeviceMode *r, + const NT_DEVICEMODE *ntdevmode) +{ + if (!r || !ntdevmode) { + return WERR_INVALID_PARAM; + } + + 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) { + r->driverextra_data = data_blob_talloc(mem_ctx, + ntdevmode->nt_dev_private, + ntdevmode->driverextra); + W_ERROR_HAVE_NO_MEMORY(r->driverextra_data.data); + } + + return WERR_OK; +} + /**************************************************************************** Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers @@ -4120,6 +4129,48 @@ static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode } /**************************************************************************** + Create a spoolss_DeviceMode struct. Returns talloced memory. +****************************************************************************/ + +struct spoolss_DeviceMode *construct_dev_mode_new(TALLOC_CTX *mem_ctx, + const char *servicename) +{ + WERROR result; + NT_PRINTER_INFO_LEVEL *printer = NULL; + struct spoolss_DeviceMode *devmode = NULL; + + DEBUG(7,("construct_dev_mode_new\n")); + + DEBUGADD(8,("getting printer characteristics\n")); + + if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename))) + return NULL; + + if (!printer->info_2->devmode) { + DEBUG(5, ("BONG! There was no device mode!\n")); + goto done; + } + + devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode); + if (!devmode) { + DEBUG(2,("construct_dev_mode_new: talloc fail.\n")); + goto done; + } + + DEBUGADD(8,("loading DEVICEMODE\n")); + + result = convert_nt_devicemode_new(mem_ctx, devmode, printer->info_2->devmode); + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(devmode); + } + +done: + free_a_printer(&printer,2); + + return devmode; +} + +/**************************************************************************** Create a DEVMODE struct. Returns malloced memory. ****************************************************************************/ @@ -4161,298 +4212,336 @@ 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_new(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)++; + } - 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; } /******************************************************************** 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 + + if (!is_myname_or_ipaddr(s)) { return WERR_INVALID_NAME; + } + + return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count); } #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */ @@ -4523,9 +4612,12 @@ out: 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 +4629,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 +4646,96 @@ 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)); + struct spoolss_PrinterInfo2 info2; + NT_PRINTER_INFO_LEVEL *ntprinter = NULL; - memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2)); - - (*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_LOCAL) { + return enum_all_printers_info_1_local(mem_ctx, info, count); + } - if (flags & PRINTER_ENUM_NAME) - return enum_all_printers_info_1_name(name, buffer, offered, needed, returned); + if (flags & PRINTER_ENUM_NAME) { + return enum_all_printers_info_1_name(mem_ctx, name, 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); + if (flags & PRINTER_ENUM_REMOTE) { + return enum_all_printers_info_1_remote(mem_ctx, name, info, count); + } #endif - 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 +4744,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 +4773,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 +4818,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); - -out: - /* clear memory */ - - SAFE_FREE(printer); + *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); - 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); - /* fill the buffer with the structures */ - smb_io_printer_info_3("", buffer, printer, 0); + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(r->out.info); + return result; + } -out: - /* clear memory */ - free_printer_info_3(printer); + *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); - 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; - } - - /* 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; - } + r->driver_name = talloc_strdup(mem_ctx, driver->info_3->name); + W_ERROR_HAVE_NO_MEMORY(r->driver_name); - /* 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) -{ - PRINTER_INFO_7 *printer=NULL; - WERROR result = WERR_OK; +/******************************************************************** + * fill a spoolss_DriverInfo3 struct + ********************************************************************/ - if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL) - return WERR_NOMEM; +static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx, + struct spoolss_DriverInfo3 *r, + const NT_PRINTER_DRIVER_INFO_LEVEL *driver, + const char *servername) +{ + const char *cservername = canon_servername(servername); - if (!construct_printer_info_7(print_hnd, printer, snum)) { - result = WERR_NOMEM; - goto out; - } + r->version = driver->info_3->cversion; - /* 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; + 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); - 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->helpfile)) { + r->help_file = talloc_asprintf(mem_ctx, "\\\\%s%s", + cservername, driver->info_3->helpfile); + } else { + r->help_file = talloc_strdup(mem_ctx, ""); } - return WERR_UNKNOWN_LEVEL; -} + W_ERROR_HAVE_NO_MEMORY(r->config_file); -/******************************************************************** - * fill a DRIVER_INFO_1 struct - ********************************************************************/ + 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 +5199,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 +5211,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,11 +5233,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; + return result; } /******************************************************************** @@ -5285,72 +5318,12 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const c * 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); -} - -/******************************************************************** - * construct_printer_info_3 - * 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 +5370,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 +5382,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 +5427,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; -} - -/**************************************************************************** -****************************************************************************/ - -static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) -{ - 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; + return status; } -/**************************************************************************** -****************************************************************************/ +/**************************************************************** + _spoolss_GetPrinterDriver2 +****************************************************************/ -WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u) +WERROR _spoolss_GetPrinterDriver2(pipes_struct *p, + struct spoolss_GetPrinterDriver2 *r) { - 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); } @@ -5868,7 +5622,7 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p, } 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 @@ -6626,251 +6380,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); + + 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->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); - 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->status = nt_printj_status(queue->status); + r->priority = queue->priority; + r->position = position; + r->total_pages = queue->page_count; + r->pages_printed = 0; /* ??? */ - make_systemtime(&job_info->submitted, t); + 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; - } - - for (i=0; i<*returned; i++) - fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter ); + info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues); + W_ERROR_HAVE_NO_MEMORY(info); - /* check the required size. */ - for (i=0; i<*returned; i++) - (*needed) += spoolss_size_job_info_1(&info[i]); + *count = num_queues; - 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_new(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); } /**************************************************************** @@ -6934,330 +6713,369 @@ 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")); - - *needed = 0; - *returned = 0; + DEBUG(4,("_spoolss_EnumPrinterDrivers\n")); - 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; + } + + *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 +****************************************************************/ + +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) +{ + union spoolss_FormInfo *info; + WERROR result = WERR_OK; + int i; + + *count = num_builtin_forms + num_user_forms; + + 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; + } + } + + 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; + } + } + + out: + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(info); + *count = 0; + return result; + } + + *info_p = info; return WERR_OK; } @@ -7269,15 +7087,15 @@ static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx, WERROR _spoolss_EnumForms(pipes_struct *p, struct spoolss_EnumForms *r) { - nt_forms_struct *list=NULL; - nt_forms_struct *builtinlist=NULL; - union spoolss_FormInfo *info; - uint32_t count; - uint32_t numbuiltinforms; - size_t buffer_size = 0; - int i; + 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 */ @@ -7289,69 +7107,85 @@ WERROR _spoolss_EnumForms(pipes_struct *p, DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered)); DEBUGADD(5,("Info level [%d]\n", r->in.level)); - numbuiltinforms = get_builtin_ntforms(&builtinlist); - DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms)); - count = get_ntforms(&list); - DEBUGADD(5,("Number of user forms [%d]\n", count)); - count += numbuiltinforms; + 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 (count == 0) { - SAFE_FREE(builtinlist); - SAFE_FREE(list); + if (num_user_forms + num_builtin_forms == 0) { + SAFE_FREE(builtin_forms); + SAFE_FREE(user_forms); return WERR_NO_MORE_ITEMS; } - info = TALLOC_ARRAY(p->mem_ctx, union spoolss_FormInfo, count); - if (!info) { - SAFE_FREE(builtinlist); - SAFE_FREE(list); - return WERR_NOMEM; - } - switch (r->in.level) { case 1: - /* construct the list of form structures */ - for (i=0; i<numbuiltinforms; i++) { - DEBUGADD(6,("Filling form number [%d]\n",i)); - fill_form_info_1(info, &info[i].info1, &builtinlist[i]); - } - - SAFE_FREE(builtinlist); + 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; + } - for (; i<count; i++) { - DEBUGADD(6,("Filling form number [%d]\n",i)); - fill_form_info_1(info, &info[i].info1, &list[i-numbuiltinforms]); - } + SAFE_FREE(user_forms); + SAFE_FREE(builtin_forms); - SAFE_FREE(list); + if (!W_ERROR_IS_OK(result)) { + return result; + } - /* check the required size. */ - for (i=0; i<numbuiltinforms; i++) { - DEBUGADD(6,("adding form [%d]'s size\n",i)); - buffer_size += ndr_size_spoolss_FormInfo1(&info[i].info1, NULL, 0); - } - for (; i<count; i++) { - DEBUGADD(6,("adding form [%d]'s size\n",i)); - buffer_size += ndr_size_spoolss_FormInfo1(&info[i].info1, NULL, 0); - } + *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); - *r->out.needed = buffer_size; + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); +} - if (*r->out.needed > r->in.offered) { - TALLOC_FREE(info); - return WERR_INSUFFICIENT_BUFFER; - } +/**************************************************************** +****************************************************************/ - *r->out.count = count; - *r->out.info = info; +static WERROR find_form_byname(const char *name, + nt_forms_struct *form) +{ + nt_forms_struct *list = NULL; + int num_forms = 0, i = 0; + if (get_a_builtin_ntform_by_string(name, form)) { return WERR_OK; + } - default: - SAFE_FREE(list); - SAFE_FREE(builtinlist); - return WERR_UNKNOWN_LEVEL; + num_forms = get_ntforms(&list); + DEBUGADD(5,("Number of forms [%d]\n", num_forms)); + + if (num_forms == 0) { + return WERR_BADFID; } + + /* Check if the requested name is in the list of form structures */ + for (i = 0; i < num_forms; i++) { + + DEBUG(4,("checking form %s (want %s)\n", list[i].name, name)); + + 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; } /**************************************************************** @@ -7361,86 +7195,47 @@ WERROR _spoolss_EnumForms(pipes_struct *p, 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); } /**************************************************************************** @@ -7547,8 +7342,6 @@ WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines ) static WERROR enumports_level_1(TALLOC_CTX *mem_ctx, union spoolss_PortInfo **info_p, - uint32_t offered, - uint32_t *needed, uint32_t *count) { union spoolss_PortInfo *info = NULL; @@ -7580,17 +7373,6 @@ static WERROR enumports_level_1(TALLOC_CTX *mem_ctx, } TALLOC_FREE(qlines); - /* check the required size. */ - for (i=0; i<numlines; i++) { - DEBUGADD(6,("adding port [%d]'s size\n", i)); - *needed += ndr_size_spoolss_PortInfo1(&info[i].info1, NULL, 0); - } - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - out: if (!W_ERROR_IS_OK(result)) { TALLOC_FREE(info); @@ -7612,8 +7394,6 @@ out: static WERROR enumports_level_2(TALLOC_CTX *mem_ctx, union spoolss_PortInfo **info_p, - uint32_t offered, - uint32_t *needed, uint32_t *count) { union spoolss_PortInfo *info = NULL; @@ -7645,17 +7425,6 @@ static WERROR enumports_level_2(TALLOC_CTX *mem_ctx, } TALLOC_FREE(qlines); - /* check the required size. */ - for (i=0; i<numlines; i++) { - DEBUGADD(6,("adding port [%d]'s size\n", i)); - *needed += ndr_size_spoolss_PortInfo2(&info[i].info2, NULL, 0); - } - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - out: if (!W_ERROR_IS_OK(result)) { TALLOC_FREE(info); @@ -7678,6 +7447,8 @@ out: WERROR _spoolss_EnumPorts(pipes_struct *p, struct spoolss_EnumPorts *r) { + WERROR result; + /* that's an [in out] buffer */ if (!r->in.buffer && (r->in.offered != 0)) { @@ -7692,16 +7463,29 @@ WERROR _spoolss_EnumPorts(pipes_struct *p, switch (r->in.level) { case 1: - return enumports_level_1(p->mem_ctx, r->out.info, - r->in.offered, r->out.needed, - r->out.count); + result = enumports_level_1(p->mem_ctx, r->out.info, + r->out.count); + break; case 2: - return enumports_level_2(p->mem_ctx, r->out.info, - r->in.offered, r->out.needed, - r->out.count); + 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); } /**************************************************************************** @@ -8106,9 +7890,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; @@ -8126,13 +7908,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; } @@ -8161,14 +7936,17 @@ 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); } /**************************************************************************** @@ -8757,8 +8535,6 @@ static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx, static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx, union spoolss_PrintProcessorInfo **info_p, - uint32_t offered, - uint32_t *needed, uint32_t *count) { union spoolss_PrintProcessorInfo *info; @@ -8774,13 +8550,6 @@ static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx, goto out; } - *needed += ndr_size_spoolss_PrintProcessorInfo1(&info[0].info1, NULL, 0); - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - out: if (!W_ERROR_IS_OK(result)) { TALLOC_FREE(info); @@ -8800,6 +8569,8 @@ static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx, WERROR _spoolss_EnumPrintProcessors(pipes_struct *p, struct spoolss_EnumPrintProcessors *r) { + WERROR result; + /* that's an [in out] buffer */ if (!r->in.buffer && (r->in.offered != 0)) { @@ -8821,12 +8592,25 @@ WERROR _spoolss_EnumPrintProcessors(pipes_struct *p, switch (r->in.level) { case 1: - return enumprintprocessors_level_1(p->mem_ctx, r->out.info, - r->in.offered, r->out.needed, - r->out.count); + 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); } /**************************************************************************** @@ -8849,8 +8633,6 @@ static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx, static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx, union spoolss_PrintProcDataTypesInfo **info_p, - uint32_t offered, - uint32_t *needed, uint32_t *count) { WERROR result; @@ -8866,13 +8648,6 @@ static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx, goto out; } - *needed += ndr_size_spoolss_PrintProcDataTypesInfo1(&info[0].info1, NULL, 0); - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - out: if (!W_ERROR_IS_OK(result)) { TALLOC_FREE(info); @@ -8892,6 +8667,8 @@ static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx, WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p, struct spoolss_EnumPrintProcDataTypes *r) { + WERROR result; + /* that's an [in out] buffer */ if (!r->in.buffer && (r->in.offered != 0)) { @@ -8906,12 +8683,21 @@ WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p, switch (r->in.level) { case 1: - return enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info, - r->in.offered, r->out.needed, - r->out.count); + 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); } /**************************************************************************** @@ -8954,13 +8740,10 @@ static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx, static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx, union spoolss_MonitorInfo **info_p, - uint32_t offered, - uint32_t *needed, uint32_t *count) { union spoolss_MonitorInfo *info; WERROR result = WERR_OK; - int i; info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2); W_ERROR_HAVE_NO_MEMORY(info); @@ -8979,15 +8762,6 @@ static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx, goto out; } - for (i=0; i<*count; i++) { - *needed += ndr_size_spoolss_MonitorInfo1(&info[i].info1, NULL, 0); - } - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - out: if (!W_ERROR_IS_OK(result)) { TALLOC_FREE(info); @@ -9006,13 +8780,10 @@ out: static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx, union spoolss_MonitorInfo **info_p, - uint32_t offered, - uint32_t *needed, uint32_t *count) { union spoolss_MonitorInfo *info; WERROR result = WERR_OK; - int i; info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2); W_ERROR_HAVE_NO_MEMORY(info); @@ -9035,15 +8806,6 @@ static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx, goto out; } - for (i=0; i<*count; i++) { - *needed += ndr_size_spoolss_MonitorInfo2(&info[i].info2, NULL, 0); - } - - if (*needed > offered) { - result = WERR_INSUFFICIENT_BUFFER; - goto out; - } - out: if (!W_ERROR_IS_OK(result)) { TALLOC_FREE(info); @@ -9063,6 +8825,8 @@ out: WERROR _spoolss_EnumMonitors(pipes_struct *p, struct spoolss_EnumMonitors *r) { + WERROR result; + /* that's an [in out] buffer */ if (!r->in.buffer && (r->in.offered != 0)) { @@ -9084,101 +8848,89 @@ WERROR _spoolss_EnumMonitors(pipes_struct *p, switch (r->in.level) { case 1: - return enumprintmonitors_level_1(p->mem_ctx, r->out.info, - r->in.offered, r->out.needed, - r->out.count); + result = enumprintmonitors_level_1(p->mem_ctx, r->out.info, + r->out.count); + break; case 2: - return enumprintmonitors_level_2(p->mem_ctx, r->out.info, - r->in.offered, r->out.needed, - r->out.count); + 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); - - if (info_1 == NULL) { - return WERR_NOMEM; - } + int i = 0; + bool found = false; - 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; } /* @@ -9187,54 +8939,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_new(devmode, devmode, nt_devmode); + if (!W_ERROR_IS_OK(result)) { + return result; } + } else { + devmode = construct_dev_mode_new(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; @@ -9243,51 +8977,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); - return wstatus; + 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 SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); } /**************************************************************** @@ -9812,9 +9552,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; @@ -9832,13 +9570,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; } @@ -9867,14 +9598,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); } /******************************************************************* @@ -10208,39 +9942,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 ****************************************************************/ @@ -10252,28 +9953,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 ****************************************************************/ @@ -10483,17 +10162,6 @@ WERROR _spoolss_DeletePrintProvidor(pipes_struct *p, } /**************************************************************** - _spoolss_GetPrinterDriver2 -****************************************************************/ - -WERROR _spoolss_GetPrinterDriver2(pipes_struct *p, - struct spoolss_GetPrinterDriver2 *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** _spoolss_FindFirstPrinterChangeNotification ****************************************************************/ diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 6cbdf89583..33fff2e3b3 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -137,57 +137,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 +183,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 +196,30 @@ static void display_print_info_1(PRINTER_INFO_1 *i1) /**************************************************************************** ****************************************************************************/ -static void display_print_info_2(PRINTER_INFO_2 *i2) -{ - 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); +static void display_print_info2(struct spoolss_PrinterInfo2 *r) +{ + 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 +227,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 +248,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; } @@ -409,8 +364,8 @@ static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli, const char **argv) { WERROR result; - uint32 info_level = 1; - uint32 returned; + uint32_t level = 1; + uint32_t count; union spoolss_PortInfo *info; if (argc > 2) { @@ -418,22 +373,23 @@ static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli, return WERR_OK; } - if (argc == 2) - info_level = atoi(argv[1]); + if (argc == 2) { + level = atoi(argv[1]); + } /* Enumerate ports */ result = rpccli_spoolss_enumports(cli, mem_ctx, cli->srv_name_slash, - info_level, + level, 0, - &returned, + &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(&info[i].info1); break; @@ -441,7 +397,7 @@ static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli, 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; } } @@ -611,7 +567,7 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, { POLICY_HND pol; WERROR result; - uint32 info_level = 1; + uint32_t level = 1; const char *printername; union spoolss_PrinterInfo info; @@ -622,7 +578,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]); @@ -633,45 +589,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; } @@ -895,116 +852,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) { @@ -1068,21 +915,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; 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; } @@ -1091,8 +937,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 */ @@ -1112,23 +959,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; @@ -1139,18 +987,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; } @@ -1163,68 +1013,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; } } @@ -2370,48 +2225,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, @@ -2458,18 +2271,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; + 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 */ @@ -2484,19 +2298,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); @@ -2505,8 +2325,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; } diff --git a/source3/samba4.m4 b/source3/samba4.m4 index 3a8b05ff3c..cfb7c1c75e 100644 --- a/source3/samba4.m4 +++ b/source3/samba4.m4 @@ -84,7 +84,7 @@ 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 = 0.9.4, [],[m4_include(../lib/tevent/samba.m4)] ) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index c8cc2e64a3..d529b009d5 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -454,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 @@ -465,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)); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 22e4c1aad7..a743385f7f 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2859,6 +2859,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 +2960,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 +2995,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 +3127,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 +3169,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 +3184,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 +3197,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 +3399,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 +3487,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 +3499,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 +3541,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 +3603,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 +3626,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 +3636,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 +3694,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 +3716,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 +3724,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 +3746,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 +3770,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 +3797,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 +3823,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 +3841,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 +3852,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 +3876,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 +3911,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 +3934,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 +3951,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 +3970,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 +4070,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 +4173,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 +4195,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 +4203,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 +4223,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 +4476,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 +4503,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 +4536,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/torture/torture.c b/source3/torture/torture.c index a563557d5f..e2d1497b28 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, @@ -5004,9 +5121,7 @@ static bool run_chain1(int dummy) return True; } -static size_t null_source(uint8_t *inbuf, size_t n, - const uint8_t *outbuf, - void *priv) +static size_t null_source(uint8_t *buf, size_t n, void *priv) { size_t *to_pull = (size_t *)priv; size_t thistime = *to_pull; @@ -5016,7 +5131,7 @@ static size_t null_source(uint8_t *inbuf, size_t n, return 0; } - memset(inbuf, 0, thistime); + memset(buf, 0, thistime); *to_pull -= thistime; return thistime; } @@ -5059,7 +5174,7 @@ static bool run_windows_write(int dummy) } status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize, - false, null_source, &to_pull); + null_source, &to_pull); if (!NT_STATUS_IS_OK(status)) { printf("cli_push returned: %s\n", nt_errstr(status)); goto fail; @@ -5692,6 +5807,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_rpc_printer.c b/source3/utils/net_rpc_printer.c index 950ca72ed8..8a2ebfb01f 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -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; @@ -978,16 +927,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; @@ -1082,26 +1034,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; /* 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, @@ -1109,7 +1056,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; } @@ -1154,26 +1101,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", @@ -1213,11 +1153,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++) { @@ -1227,7 +1165,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; } @@ -1244,7 +1182,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); } } @@ -1277,8 +1215,8 @@ 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; @@ -1287,21 +1225,14 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ 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; } @@ -1429,29 +1360,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; 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; } @@ -1530,15 +1453,13 @@ 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; + 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 */ @@ -1549,7 +1470,7 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, /* 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; } @@ -1562,17 +1483,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; @@ -1684,17 +1599,15 @@ 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; + union spoolss_PrinterInfo *info_enum; union spoolss_PrinterInfo info_dst; 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 */ @@ -1704,7 +1617,7 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, 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; } @@ -1717,17 +1630,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; @@ -1852,22 +1759,19 @@ 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; 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, @@ -1894,7 +1798,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; } @@ -1908,17 +1812,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; @@ -2072,11 +1970,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; + const char *printername, *sharename; struct rpc_pipe_client *pipe_hnd_dst = NULL; struct spoolss_SetPrinterInfoCtr info_ctr; @@ -2089,7 +1987,7 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, 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; } @@ -2102,17 +2000,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; @@ -2235,11 +2127,12 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, uint32 i = 0, p = 0, j = 0; uint32 num_printers, val_needed, data_needed; 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; + union spoolss_PrinterInfo *info_enum; + union spoolss_PrinterInfo info_dst_publish; + union spoolss_PrinterInfo info_dst; REGVAL_CTR *reg_ctr; struct cli_state *cli_dst = NULL; char *devicename = NULL, *unc_name = NULL, *url = NULL; @@ -2247,7 +2140,6 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, uint16 *keylist = NULL, *curkey; - ZERO_STRUCT(ctr_enum); /* FIXME GD */ ZERO_STRUCT(info_dst_publish); @@ -2260,7 +2152,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, 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; } @@ -2281,17 +2173,11 @@ NTSTATUS rpc_printer_migrate_settings_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; @@ -2319,20 +2205,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)) @@ -2346,13 +2231,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) */ @@ -2374,7 +2256,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 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 e455d936e0..f5812f9e65 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; @@ -1090,6 +1090,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) 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 7a53f19ffd..e06e30e0a8 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -866,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; } } @@ -891,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; } } @@ -917,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", @@ -935,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; } @@ -970,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; @@ -1979,7 +1994,6 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, { 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; @@ -2004,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); @@ -2018,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; } @@ -2147,7 +2160,6 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, { struct winbindd_cm_conn *conn; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - fstring conn_pwd; struct dcinfo *p_dcinfo; result = init_dc_connection(domain); @@ -2160,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; @@ -2174,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_proto.h b/source3/winbindd/winbindd_proto.h index c6e8803ce8..4fc96e8a4b 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 */ |