summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in12
-rw-r--r--source3/include/ntdomain.h1
-rw-r--r--source3/include/proto.h132
-rw-r--r--source3/include/rpc_dce.h2
-rw-r--r--source3/include/rpc_misc.h7
-rw-r--r--source3/include/smb.h2
-rw-r--r--source3/param/loadparm.c19
-rw-r--r--source3/rpc_parse/parse_misc.c65
-rw-r--r--source3/rpc_parse/parse_prs.c14
-rw-r--r--source3/rpc_parse/parse_rpc.c31
-rw-r--r--source3/rpc_server/srv_pipe.c51
-rw-r--r--source3/smbd/nttrans.c1
-rw-r--r--source3/smbd/server.c1
13 files changed, 323 insertions, 15 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 00fbf9d578..356ded7504 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -41,6 +41,8 @@ NMBLOGFILE = $(VARDIR)/log.nmb
CONFIGFILE = $(LIBDIR)/smb.conf
LMHOSTSFILE = $(LIBDIR)/lmhosts
DRIVERFILE = $(LIBDIR)/printers.def
+FORMSFILE = $(LIBDIR)/ntforms.def
+NTDRIVERSDIR = $(LIBDIR)
PASSWD_PROGRAM = /bin/passwd
SMB_PASSWD_FILE = $(BASEDIR)/private/smbpasswd
SMB_PASSGRP_FILE = $(BASEDIR)/private/smbpassgrp
@@ -78,7 +80,7 @@ PASSWD_FLAGS = \
FLAGS1 = $(CFLAGS) -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/smbwrapper $(CPPFLAGS) -DSMBLOGFILE=\"$(SMBLOGFILE)\" -DNMBLOGFILE=\"$(NMBLOGFILE)\"
FLAGS2 = -DCONFIGFILE=\"$(CONFIGFILE)\" -DLMHOSTSFILE=\"$(LMHOSTSFILE)\"
FLAGS3 = -DSWATDIR=\"$(SWATDIR)\" -DSBINDIR=\"$(SBINDIR)\" -DLOCKDIR=\"$(LOCKDIR)\" -DSMBRUN=\"$(SMBRUN)\" -DCODEPAGEDIR=\"$(CODEPAGEDIR)\"
-FLAGS4 = -DDRIVERFILE=\"$(DRIVERFILE)\" -DBINDIR=\"$(BINDIR)\"
+FLAGS4 = -DDRIVERFILE=\"$(DRIVERFILE)\" -DBINDIR=\"$(BINDIR)\" -DFORMSFILE=\"$(FORMSFILE)\" -DNTDRIVERSDIR=\"$(NTDRIVERSDIR)\"
FLAGS5 = $(FLAGS1) $(FLAGS2) $(FLAGS3) $(FLAGS4) -DHAVE_INCLUDES_H
FLAGS = $(FLAGS5) $(PASSWD_FLAGS)
@@ -130,14 +132,16 @@ RPC_SERVER_OBJ = \
rpc_server/srv_svcctl.o \
rpc_server/srv_pipe.o \
rpc_server/srv_lookup.o \
- rpc_server/srv_wkssvc.o
+ rpc_server/srv_wkssvc.o \
+ rpc_server/srv_spoolss.o
RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_misc.o \
rpc_parse/parse_net.o rpc_parse/parse_prs.o \
rpc_parse/parse_reg.o rpc_parse/parse_rpc.o \
rpc_parse/parse_samr.o rpc_parse/parse_srv.o \
rpc_parse/parse_wks.o rpc_parse/parse_sec.o \
- rpc_parse/parse_svc.o rpc_parse/parse_at.o
+ rpc_parse/parse_svc.o rpc_parse/parse_at.o \
+ rpc_parse/parse_spoolss.o
RPC_CLIENT_OBJ = \
rpc_client/cli_login.o \
@@ -178,7 +182,7 @@ SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/$(QUOTAOBJS) smbd/reply.o smbd/ssl.o smbd/trans2.o smbd/uid.o \
smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o smbd/blocking.o \
smbd/process.o smbd/oplock.o smbd/service.o smbd/error.o smbd/vfs.o \
- smbd/vfs-wrap.o
+ smbd/vfs-wrap.o printing/nt_printing.o
PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/printing.o
diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
index c4eccfc466..cfd1cc37b3 100644
--- a/source3/include/ntdomain.h
+++ b/source3/include/ntdomain.h
@@ -43,6 +43,7 @@
#include "rpc_svcctl.h"
#include "rpc_wkssvc.h"
#include "rpc_atsvc.h"
+#include "rpc_spoolss.h"
/*
* A bunch of stuff that was put into smb.h
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 0fb5962094..e528505d43 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1201,6 +1201,8 @@ char *lp_nis_home_map_name(void);
char *lp_netbios_aliases(void);
char *lp_driverfile(void);
char *lp_panic_action(void);
+char *lp_nt_forms(void);
+char *lp_nt_drivers_file(void);
char *lp_ldap_server(void);
char *lp_ldap_suffix(void);
char *lp_ldap_bind_as(void);
@@ -1560,6 +1562,27 @@ struct passgrp_ops *file_initialise_password_grp(void);
struct passgrp_ops *unix_initialise_password_grp(void);
+/*The following definitions come from printing/nt_printing.c */
+
+int get_ntforms(nt_forms_struct **list);
+int get_ntdrivers(fstring **list, char *architecture);
+void get_short_archi(char *short_archi, char *long_archi);
+void dump_a_param(NT_PRINTER_PARAM *param);
+BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param);
+BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param);
+uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level);
+uint32 get_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level, fstring sharename);
+uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level);
+uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level);
+uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
+ fstring printername, fstring architecture);
+uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level);
+BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
+ fstring value, uint8 **data, uint32 *type, uint32 *len);
+BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
+ fstring value, uint8 **data, uint32 *type, uint32 *len);
+void init_devicemode(NT_DEVICEMODE *nt_devmode);
+
/*The following definitions come from printing/pcap.c */
BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname);
@@ -2008,6 +2031,10 @@ void make_buffer3_hex(BUFFER3 *str, char *buf);
void make_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len);
void smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth);
void smb_io_buffer4(char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth);
+void init_buffer5(BUFFER5 **str);
+void clear_buffer5(BUFFER5 **str);
+void make_buffer5(BUFFER5 *str, char *buf, int len);
+void smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth);
void make_buffer2(BUFFER2 *str, const char *buf, int len);
void smb_io_buffer2(char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth);
void make_buf_unistr2(UNISTR2 *str, uint32 *ptr, char *buf);
@@ -2144,6 +2171,7 @@ BOOL prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8);
BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16);
BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32);
BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len);
+BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len);
BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str);
BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str);
@@ -2646,6 +2674,103 @@ SEC_DESC_BUF *dup_sec_desc_buf(SEC_DESC_BUF *src);
void free_sec_desc_buf(SEC_DESC_BUF **ppsdb);
BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth);
+/*The following definitions come from rpc_parse/parse_spoolss.c */
+
+void make_systemtime(SYSTEMTIME *systime, struct tm *unixtime);
+void smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
+ prs_struct *ps, int depth);
+void spoolss_io_r_open_printer(char *desc, SPOOL_R_OPEN_PRINTER *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_open_printer(char *desc, SPOOL_Q_OPEN_PRINTER *q_u, prs_struct *ps, int depth);
+void spoolss_io_q_getprinterdata(char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_closeprinter(char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_closeprinter(char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_startdocprinter(char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_startdocprinter(char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_enddocprinter(char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_enddocprinter(char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_startpageprinter(char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_startpageprinter(char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_endpageprinter(char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_endpageprinter(char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_writeprinter(char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_writeprinter(char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u,
+ prs_struct *ps, int depth);
+void spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u,
+ prs_struct *ps, int depth);
+void spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u,
+ prs_struct *ps, int depth);
+void spoolss_io_r_rfnpcnex(char *desc,
+ SPOOL_R_RFNPCNEX *r_u,
+ prs_struct *ps, int depth);
+void spoolss_io_q_getprinterdriver2(char *desc,
+ SPOOL_Q_GETPRINTERDRIVER2 *q_u,
+ prs_struct *ps, int depth);
+void spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u,
+ prs_struct *ps, int depth);
+void spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u,
+ prs_struct *ps, int depth);
+void spoolss_io_r_enumprinters(char *desc,
+ SPOOL_R_ENUMPRINTERS *r_u,
+ prs_struct *ps, int depth);
+void spoolss_io_r_getprinter(char *desc,
+ SPOOL_R_GETPRINTER *r_u,
+ prs_struct *ps, int depth);
+void spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u,
+ prs_struct *ps, int depth);
+void spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_fcpn(char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_schedulejob(char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_setjob(char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_enumdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_enumprinterdrivers(char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth);
+void spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 **q_u, prs_struct *ps, int depth);
+void spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth);
+void spool_io_user_level_1(char *desc, SPOOL_USER_LEVEL_1 **q_u, prs_struct *ps, int depth);
+void spool_io_user_level(char *desc, SPOOL_USER_LEVEL *q_u, prs_struct *ps, int depth);
+void spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u, prs_struct *ps, int depth);
+void spool_io_printer_driver_info_level_3(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u,
+ prs_struct *ps, int depth);
+void uniarray_2_ascarray(BUFFER5 *buf5, char ***ar);
+void smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth);
+void spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth);
+void spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth);
+void uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
+ NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc);
+void uni_2_asc_printer_info_2(SPOOL_PRINTER_INFO_LEVEL_2 *uni,
+ NT_PRINTER_INFO_LEVEL_2 **asc);
+void convert_printer_info(SPOOL_PRINTER_INFO_LEVEL uni,
+ NT_PRINTER_INFO_LEVEL *printer,
+ uint32 level);
+void convert_printer_driver_info(SPOOL_PRINTER_DRIVER_INFO_LEVEL uni,
+ NT_PRINTER_DRIVER_INFO_LEVEL *printer,
+ uint32 level);
+void convert_devicemode(DEVICEMODE devmode, NT_DEVICEMODE *nt_devmode);
+void spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth);
+void spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth);
+void convert_specific_param(NT_PRINTER_PARAM **param, UNISTR2 value , uint32 type, uint8 *data, uint32 len);
+
/*The following definitions come from rpc_parse/parse_srv.c */
void make_srv_share_info1_str(SH_INFO_1_STR *sh1, char *net_name, char *remark);
@@ -2861,6 +2986,13 @@ BOOL api_reg_rpc(pipes_struct *p, prs_struct *data);
BOOL api_samr_rpc(pipes_struct *p, prs_struct *data);
+/*The following definitions come from rpc_server/srv_spoolss.c */
+
+void init_printer_hnd(void);
+uint32 size_of_notify_info_data(uint16 type, uint16 field);
+BOOL type_of_notify_info_data(uint16 type, uint16 field);
+BOOL api_spoolss_rpc(pipes_struct *p, prs_struct *data);
+
/*The following definitions come from rpc_server/srv_srvsvc.c */
BOOL api_srvsvc_rpc(pipes_struct *p, prs_struct *data);
diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h
index 70eb1b4e20..a324daac6a 100644
--- a/source3/include/rpc_dce.h
+++ b/source3/include/rpc_dce.h
@@ -36,6 +36,8 @@ enum RPC_PKT_TYPE
RPC_FAULT = 0x03,
RPC_BIND = 0x0B,
RPC_BINDACK = 0x0C,
+ RPC_ALTCONT = 0x0E,
+ RPC_ALTCONTRESP = 0x0F,
RPC_BINDRESP = 0x10 /* not the real name! this is undocumented! */
};
diff --git a/source3/include/rpc_misc.h b/source3/include/rpc_misc.h
index eb345770ff..2447e3307f 100644
--- a/source3/include/rpc_misc.h
+++ b/source3/include/rpc_misc.h
@@ -189,6 +189,13 @@ typedef struct buffer4_info
} BUFFER4;
+/* BUFFER5 */
+typedef struct buffer5_info
+{
+ uint32 buf_len;
+ uint16 *buffer; /* data */
+} BUFFER5;
+
/* UNISTR2 - unicode string size (in uint16 unicode chars) and buffer */
typedef struct unistr2_info
{
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 605218d51f..6d9bcb479b 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -360,6 +360,7 @@ typedef char fstring[FSTRING_LEN];
#define PIPE_LSASS "\\PIPE\\lsass"
#define PIPE_LSARPC "\\PIPE\\lsarpc"
#define PIPE_ATSVC "\\PIPE\\atsvc"
+#define PIPE_SPOOLSS "\\pipe\\spoolss"
/* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */
@@ -1877,6 +1878,7 @@ extern int unix_ERR_code;
__FILE__, __LINE__)), smb_panic("assert failed")))
#define SMB_ASSERT_ARRAY(a,n) SMB_ASSERT((sizeof(a)/sizeof((a)[0])) >= (n))
+#include "nt_printing.h"
#include "ntdomain.h"
/* A netbios name structure. */
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index b55a4f3d21..142ab4af32 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -153,6 +153,8 @@ typedef struct
char *szLdapPasswdFile;
#endif /* WITH_LDAP */
char *szPanicAction;
+ char *szNtForms;
+ char *szNtDriverFile;
int max_log_size;
int mangled_stack;
int max_xmit;
@@ -676,6 +678,8 @@ static struct parm_struct parm_table[] =
{"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0},
{"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, 0},
{"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_GLOBAL},
+ {"nt forms file", P_STRING, P_GLOBAL, &Globals.szNtForms, NULL, NULL, FLAG_GLOBAL},
+ {"nt printer driver",P_STRING, P_GLOBAL, &Globals.szNtDriverFile, NULL, NULL, FLAG_GLOBAL},
{"Filename Handling", P_SEP, P_SEPARATOR},
{"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0},
@@ -860,6 +864,8 @@ static void init_globals(void)
string_set(&Globals.szPasswdProgram, PASSWD_PROGRAM);
string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
string_set(&Globals.szDriverFile, DRIVERFILE);
+ string_set(&Globals.szNtForms, FORMSFILE);
+ string_set(&Globals.szNtDriverFile, NTDRIVERSDIR);
string_set(&Globals.szLockDir, LOCKDIR);
string_set(&Globals.szRootdir, "/");
string_set(&Globals.szSmbrun, SMBRUN);
@@ -1028,12 +1034,21 @@ static void init_locals(void)
{
case PRINT_BSD:
case PRINT_AIX:
- case PRINT_LPRNG:
case PRINT_PLP:
string_initial(&sDefault.szLpqcommand,"lpq -P%p");
string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
break;
+
+ case PRINT_LPRNG:
+ string_initial(&sDefault.szLpqcommand,"lpq -P%p");
+ string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
+ string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
+ string_initial(&sDefault.szQueuepausecommand, "lpc stop %p");
+ string_initial(&sDefault.szQueueresumecommand, "lpc start %p");
+ string_initial(&sDefault.szLppausecommand,"lpc hold %p %j");
+ string_initial(&sDefault.szLpresumecommand,"lpc release %p %j");
+ break;
case PRINT_SYSV:
case PRINT_HPUX:
@@ -1186,6 +1201,8 @@ static FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
FN_GLOBAL_STRING(lp_panic_action,&Globals.szPanicAction)
+FN_GLOBAL_STRING(lp_nt_forms,&Globals.szNtForms)
+FN_GLOBAL_STRING(lp_nt_drivers_file,&Globals.szNtDriverFile)
#ifdef WITH_LDAP
FN_GLOBAL_STRING(lp_ldap_server,&Globals.szLdapServer);
diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c
index a84469f8f9..4927886fc8 100644
--- a/source3/rpc_parse/parse_misc.c
+++ b/source3/rpc_parse/parse_misc.c
@@ -519,6 +519,71 @@ void smb_io_buffer4(char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, in
}
/*******************************************************************
+initialise a BUFFER5 structure.
+********************************************************************/
+void init_buffer5(BUFFER5 **str)
+{
+ BUFFER5 *buf5;
+
+ buf5=(BUFFER5 *)malloc( sizeof(BUFFER5) );
+
+ buf5->buf_len=0;
+ buf5->buffer=NULL;
+ *str=buf5;
+}
+
+/*******************************************************************
+clear a BUFFER5 structure.
+********************************************************************/
+void clear_buffer5(BUFFER5 **str)
+{
+ BUFFER5 *buf5;
+
+ buf5=*str;
+ if (buf5->buffer != NULL )
+ {
+ free(buf5->buffer);
+ }
+ free(buf5);
+ *str=NULL;
+}
+
+/*******************************************************************
+creates a BUFFER5 structure.
+********************************************************************/
+void make_buffer5(BUFFER5 *str, char *buf, int len)
+{
+
+ /* max buffer size (allocated size) */
+ str->buf_len = len;
+ str->buffer = (uint16 *)malloc( sizeof(uint16) * len );
+ ascii_to_unistr(str->buffer, buf, len);
+}
+
+/*******************************************************************
+reads or writes a BUFFER5 structure.
+the buf_len member tells you how large the buffer is.
+********************************************************************/
+void smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "smb_io_buffer4");
+ depth++;
+
+ if (buf5 == NULL) return;
+
+ prs_align(ps);
+ prs_uint32("buf_len", ps, depth, &(buf5->buf_len));
+
+ /* reading: alloc the buffer first */
+ if ( ps->io )
+ {
+ buf5->buffer=(uint16 *)malloc( sizeof(uint16)*buf5->buf_len );
+ }
+
+ prs_uint16s(True, "buffer ", ps, depth, buf5->buffer, buf5->buf_len);
+}
+
+/*******************************************************************
creates a BUFFER2 structure.
********************************************************************/
void make_buffer2(BUFFER2 *str, const char *buf, int len)
diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c
index 23a9d5bfdf..a231fb57cf 100644
--- a/source3/rpc_parse/parse_prs.c
+++ b/source3/rpc_parse/parse_prs.c
@@ -158,6 +158,20 @@ BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *dat
}
/******************************************************************
+ stream an array of uint16s. length is number of uint16s
+ ********************************************************************/
+BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len)
+{
+ char *q = mem_data(&(ps->data), ps->offset);
+ if (q == NULL) return False;
+
+ DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, data16s, len)
+ ps->offset += len * sizeof(uint16);
+
+ return True;
+}
+
+/******************************************************************
stream an array of uint32s. length is number of uint32s
********************************************************************/
BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len)
diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c
index 81e7ffa116..2f47f06e36 100644
--- a/source3/rpc_parse/parse_rpc.c
+++ b/source3/rpc_parse/parse_rpc.c
@@ -132,6 +132,16 @@ interface/version dce/rpc pipe identification
}, 0x01 \
} \
+#define SYNT_SPOOLSS_V1 \
+{ \
+ { \
+ 0x78, 0x56, 0x34, 0x12, \
+ 0x34, 0x12, 0xcd, 0xab, \
+ 0xef, 0x00, 0x01, 0x23, \
+ 0x45, 0x67, 0x89, 0xab \
+ }, 0x01 \
+} \
+
#define SYNT_NONE_V0 \
{ \
{ \
@@ -153,6 +163,7 @@ struct pipe_id_info pipe_names [] =
{ PIPE_WKSSVC , SYNT_WKSSVC_V1 , PIPE_NTSVCS , TRANS_SYNT_V2 },
{ PIPE_WINREG , SYNT_WINREG_V1 , PIPE_WINREG , TRANS_SYNT_V2 },
{ PIPE_ATSVC , SYNT_ATSVC_V1 , PIPE_ATSVC , TRANS_SYNT_V2 },
+ { PIPE_SPOOLSS , SYNT_SPOOLSS_V1 , PIPE_SPOOLSS , TRANS_SYNT_V2 },
{ NULL , SYNT_NONE_V0 , NULL , SYNT_NONE_V0 }
};
@@ -212,13 +223,22 @@ static void smb_io_rpc_iface(char *desc, RPC_IFACE *ifc, prs_struct *ps, int de
/*******************************************************************
creates an RPC_ADDR_STR structure.
+
+The name can be null (RPC Alter-Context)
********************************************************************/
static void make_rpc_addr_str(RPC_ADDR_STR *str, char *name)
{
- if (str == NULL || name == NULL) return;
-
- str->len = strlen(name) + 1;
- fstrcpy(str->str, name);
+ if (str == NULL ) return;
+ if (name == NULL)
+ {
+ str->len = 1;
+ fstrcpy(str->str, "");
+ }
+ else
+ {
+ str->len = strlen(name) + 1;
+ fstrcpy(str->str, name);
+ }
}
/*******************************************************************
@@ -349,6 +369,7 @@ static void smb_io_rpc_results(char *desc, RPC_RESULTS *res, prs_struct *ps, in
creates an RPC_HDR_BA structure.
lkclXXXX only one reason at the moment!
+jfm: nope two ! The pipe_addr can be NULL !
********************************************************************/
void make_rpc_hdr_ba(RPC_HDR_BA *rpc,
@@ -357,7 +378,7 @@ void make_rpc_hdr_ba(RPC_HDR_BA *rpc,
uint8 num_results, uint16 result, uint16 reason,
RPC_IFACE *transfer)
{
- if (rpc == NULL || transfer == NULL || pipe_addr == NULL) return;
+ if (rpc == NULL || transfer == NULL) return;
make_rpc_hdr_bba (&(rpc->bba ), max_tsize, max_rsize, assoc_gid);
make_rpc_addr_str(&(rpc->addr), pipe_addr);
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 54d26650e9..466d56b67a 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -360,6 +360,7 @@ static struct api_cmd api_fd_commands[] =
{ "svcctl", "ntsvcs", api_svcctl_rpc },
{ "NETLOGON", "lsass", api_netlog_rpc },
{ "winreg", "winreg", api_reg_rpc },
+ { "spoolss", "spoolss", api_spoolss_rpc },
{ NULL, NULL, NULL }
};
@@ -383,7 +384,7 @@ static BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *pd)
return api_pipe_ntlmssp(p, pd);
}
-static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd)
+static BOOL api_pipe_bind_and_alt_req(pipes_struct *p, prs_struct *pd, enum RPC_PKT_TYPE pkt_type)
{
uint16 assoc_gid;
fstring ack_pipe_name;
@@ -435,9 +436,29 @@ static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd)
}
}
- /* name has to be \PIPE\xxxxx */
- fstrcpy(ack_pipe_name, "\\PIPE\\");
- fstrcat(ack_pipe_name, p->pipe_srv_name);
+ switch (pkt_type)
+ {
+ case RPC_BINDACK:
+ {
+ /* name has to be \PIPE\xxxxx */
+ fstrcpy(ack_pipe_name, "\\PIPE\\");
+ fstrcat(ack_pipe_name, p->pipe_srv_name);
+ break;
+ }
+ case RPC_ALTCONTRESP:
+ {
+ /* secondary address CAN be NULL
+ * as the specs says it's ignored.
+ * It MUST NULL to have the spoolss working.
+ */
+ fstrcpy(ack_pipe_name, "");
+ break;
+ }
+ default:
+ {
+ return False;
+ }
+ }
DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
@@ -505,7 +526,7 @@ static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd)
/*** then do the header, now we know the length ***/
/***/
- make_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST,
+ make_rpc_hdr(&p->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST,
p->hdr.call_id,
p->rdata.offset + p->rverf.offset + p->rauth.offset + p->rntlm.offset + 0x10,
p->rauth.offset + p->rntlm.offset);
@@ -534,6 +555,21 @@ static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd)
return True;
}
+/*
+ * The RPC Alter-Context call is used only by the spoolss pipe
+ * simply because there is a bug (?) in the MS unmarshalling code
+ * or in the marshalling code. If it's in the later, then Samba
+ * have the same bug.
+ */
+static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd)
+{
+ return api_pipe_bind_and_alt_req(p, pd, RPC_BINDACK);
+}
+
+static BOOL api_pipe_alt_req(pipes_struct *p, prs_struct *pd)
+{
+ return api_pipe_bind_and_alt_req(p, pd, RPC_ALTCONTRESP);
+}
static BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *pd)
{
@@ -635,6 +671,11 @@ BOOL rpc_command(pipes_struct *p, prs_struct *pd)
reply = api_pipe_bind_req(p, pd);
break;
}
+ case RPC_ALTCONT:
+ {
+ reply = api_pipe_alt_req(p, pd);
+ break;
+ }
case RPC_REQUEST:
{
if (p->ntlmssp_auth && !p->ntlmssp_validated)
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 923de7a197..5c26c7f578 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -46,6 +46,7 @@ static char *known_nt_pipes[] = {
"\\lsass",
"\\lsarpc",
"\\winreg",
+ "\\spoolss",
NULL
};
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index dcc53cb8d0..339fab8398 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -450,6 +450,7 @@ static void init_structs(void)
file_init();
init_rpc_pipe_hnd(); /* for RPC pipes */
init_lsa_policy_hnd(); /* for LSA handles */
+ init_printer_hnd(); /* for SPOOLSS handles */
init_dptrs();
}