1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-24 02:04:21 +03:00

Added John Reilly's enumports/addprinter/delprinter scripting code plus the

fix for the Win9x printer drivers.
Changed command names to add "command" string on the end for some consistancy
with the other scripting commands.
Added '%P' option to tdbpack/unpack to store long comment string.
Made port name be "Samba Printer Port" if no enum port script given.
Fixed prs_uint32_pre code to cope with null args.
Jeremy.
(This used to be commit 902ada63799cf27924c72e24e7593a8c9fb5eba9)
This commit is contained in:
Jeremy Allison 2000-07-31 20:41:51 +00:00
parent 2759822674
commit 49fcb300de
10 changed files with 355 additions and 147 deletions

View File

@ -239,7 +239,7 @@ typedef struct nt_printer_info_level_2
fstring sharename;
fstring portname;
fstring drivername;
fstring comment;
pstring comment;
fstring location;
NT_DEVICEMODE *devmode;
fstring sepfile;

View File

@ -1302,6 +1302,9 @@ char *lp_configfile(void);
char *lp_smb_passwd_file(void);
char *lp_serverstring(void);
char *lp_printcapname(void);
char *lp_enumports_cmd(void);
char *lp_addprinter_cmd(void);
char *lp_deleteprinter_cmd(void);
char *lp_lockdir(void);
char *lp_utmpdir(void);
char *lp_rootdir(void);
@ -1530,6 +1533,7 @@ BOOL lp_snum_ok(int iService);
void lp_add_one_printer(char *name, char *comment);
BOOL lp_loaded(void);
void lp_killunused(BOOL (*snumused) (int));
void lp_killservice(int iServiceIn);
BOOL lp_load(char *pszFname, BOOL global_only, BOOL save_defaults,
BOOL add_ipc);
void lp_resetnumservices(void);
@ -1654,6 +1658,7 @@ BOOL trust_password_delete(char *domain);
/*The following definitions come from printing/load.c */
void add_all_printers(void);
void load_printers(void);
/*The following definitions come from printing/lpq_parse.c */

View File

@ -104,6 +104,9 @@ static BOOL defaults_saved = False;
typedef struct
{
char *szPrintcapname;
char *szEnumPortsCommand;
char *szAddPrinterCommand;
char *szDeletePrinterCommand;
char *szLockDir;
char *szRootdir;
char *szDefaultService;
@ -793,6 +796,10 @@ static struct parm_struct parm_table[] = {
{"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
{"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
{"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, 0},
{"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, 0},
{"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, 0},
{"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
{"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0},
{"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, FLAG_PRINT},
@ -1317,6 +1324,9 @@ FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
#ifdef WITH_UTMP
FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
@ -3007,6 +3017,18 @@ void lp_killunused(BOOL (*snumused) (int))
}
/***************************************************************************
unload a service
***************************************************************************/
void lp_killservice(int iServiceIn)
{
if (VALID(iServiceIn))
{
iSERVICE(iServiceIn).valid = False;
free_service(pSERVICE(iServiceIn));
}
}
/***************************************************************************
save the curent values of all global and sDefault parameters into the
defaults union. This allows swat and testparm to show only the

View File

@ -25,7 +25,7 @@
/***************************************************************************
auto-load printer services
***************************************************************************/
static void add_all_printers(void)
void add_all_printers(void)
{
int printers = lp_servicenumber(PRINTERS_NAME);

View File

@ -387,7 +387,6 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
fstring architecture;
fstring clean_driver_name;
pstring new_dir;
pstring old_name;
pstring new_name;
@ -406,10 +405,6 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
get_short_archi(architecture, driver->environment);
/* clean up the driver's name */
fstrcpy(clean_driver_name, driver->name);
all_string_sub(clean_driver_name, "/", "#", 0);
/* connect to the print$ share under the same account as the user connected to the rpc pipe */
fstrcpy(user_name, uidtoname(user->uid));
DEBUG(10,("move_driver_to_download_area: uid %d -> user %s\n", (int)user->uid, user_name));
@ -447,18 +442,22 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
slprintf(new_dir, sizeof(new_dir), "%s\\%d", architecture, driver->cversion);
mkdir_internal(conn, inbuf, outbuf, new_dir);
slprintf(new_dir, sizeof(new_dir), "%s\\%d\\%s", architecture, driver->cversion, clean_driver_name);
mkdir_internal(conn, inbuf, outbuf, new_dir);
/* move all the files, one by one,
* from archi\filexxx.yyy to
* archi\version\driver name\filexxx.yyy
* archi\version\filexxx.yyy
*
* Note: drivers may list the same file name in several places. This
* causes problems on a second attempt to move the file. JRR
*
* Note: use the replace flag on rename_internals() call, otherwise it
* is very difficult to change previously installed drivers... the Windows
* GUI offers the user the choice to replace or keep exisitng driver. JRR
*/
DEBUG(5,("Moving file now !\n"));
slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->driverpath);
slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->driverpath);
if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False)) != 0) {
if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
old_name, new_name ));
close_cnum(conn, user->vuid);
@ -466,45 +465,61 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
return False;
}
if (!strequal(driver->datafile, driver->driverpath)) {
slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->datafile);
slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->datafile);
if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False)) != 0) {
if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
old_name, new_name ));
close_cnum(conn, user->vuid);
unbecome_root();
return False;
}
}
if (!strequal(driver->configfile, driver->driverpath) &&
!strequal(driver->configfile, driver->datafile)) {
slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->configfile);
slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->configfile);
if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False)) != 0) {
if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
old_name, new_name ));
close_cnum(conn, user->vuid);
unbecome_root();
return False;
}
}
if (!strequal(driver->helpfile, driver->driverpath) &&
!strequal(driver->helpfile, driver->datafile) &&
!strequal(driver->helpfile, driver->configfile)) {
slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->helpfile);
slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->helpfile);
if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False)) != 0) {
if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
old_name, new_name ));
close_cnum(conn, user->vuid);
unbecome_root();
return False;
}
}
if (driver->dependentfiles) {
for (i=0; *driver->dependentfiles[i]; i++) {
if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
!strequal(driver->dependentfiles[i], driver->datafile) &&
!strequal(driver->dependentfiles[i], driver->configfile) &&
!strequal(driver->dependentfiles[i], driver->helpfile)) {
slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->dependentfiles[i]);
slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->dependentfiles[i]);
/*
* We don't check the error returns here as several of these
* files may have already been moved in the list above...
*/
rename_internals(conn, inbuf, outbuf, old_name, new_name, False);
if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
old_name, new_name ));
close_cnum(conn, user->vuid);
unbecome_root();
return False;
}
}
}
}
@ -521,7 +536,6 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
int len, buflen;
fstring architecture;
pstring directory;
fstring clean_driver_name;
pstring temp_name;
pstring key;
char *buf;
@ -530,16 +544,12 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
get_short_archi(architecture, driver->environment);
/* The names are relative. We store them in the form: \print$\arch\version\printer-name\driver.xxx
/* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
* \\server is added in the rpc server layer.
* It does make sense to NOT store the server's name in the printer TDB.
*/
/* clean up the driver's name */
fstrcpy(clean_driver_name, driver->name);
all_string_sub(clean_driver_name, "/", "#", 0);
slprintf(directory, sizeof(directory), "\\print$\\%s\\%d\\%s\\", architecture, driver->cversion, clean_driver_name);
slprintf(directory, sizeof(directory), "\\print$\\%s\\%d\\", architecture, driver->cversion);
fstrcpy(temp_name, driver->driverpath);
@ -752,12 +762,16 @@ uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
DEBUGADD(10,("info3->configfile [%s]\n", info3->configfile));
/*pstrcat(line, info3->name); pstrcat(line, ":");*/
trim_string(info3->configfile, "\\print$\\WIN40\\0\\", 0);
pstrcat(line, info3->configfile);
pstrcat(line, ":");
trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
pstrcat(line, info3->datafile);
pstrcat(line, ":");
trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
pstrcat(line, info3->helpfile);
pstrcat(line, ":");
trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
pstrcat(line, info3->monitorname);
pstrcat(line, ":");
pstrcat(line, "RAW"); /*info3->defaultdatatype);*/
@ -766,6 +780,7 @@ uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
for (i=0; info3->dependentfiles &&
*info3->dependentfiles[i]; i++) {
if (i) pstrcat(line, ","); /* don't end in a "," */
trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
pstrcat(line, info3->dependentfiles[i]);
}
@ -969,7 +984,7 @@ static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
again:
len = 0;
len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffffffff",
len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
info->attributes,
info->priority,
info->default_priority,
@ -1367,7 +1382,7 @@ static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstrin
fstrcpy(info.printername, sharename);
fstrcpy(info.portname, sharename);
fstrcpy(info.drivername, lp_printerdriver(snum));
fstrcpy(info.comment, "");
pstrcpy(info.comment, "");
fstrcpy(info.printprocessor, "winprint");
fstrcpy(info.datatype, "RAW");
@ -1428,7 +1443,7 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
if (!dbuf.dptr) return 1;
#endif
len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffffffff",
len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
&info.attributes,
&info.priority,
&info.default_priority,

View File

@ -867,7 +867,7 @@ BOOL prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
BOOL prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset)
{
*offset = ps->data_offset;
if (UNMARSHALLING(ps)) {
if (UNMARSHALLING(ps) && (data32 != NULL)) {
/* reading. */
return prs_uint32(name, ps, depth, data32);
} else {

View File

@ -1778,7 +1778,7 @@ BOOL new_smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *i
{
uint32 sec_offset;
prs_struct *ps=&buffer->prs;
int i = 0;
uint32 dummy = 0;
prs_debug(ps, depth, desc, "new_smb_io_printer_info_2");
depth++;
@ -1814,7 +1814,7 @@ BOOL new_smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *i
return False;
#if 1 /* JFMTEST */
if (!prs_uint32_pre("secdesc_ptr ", ps, depth, &i, &sec_offset))
if (!prs_uint32_pre("secdesc_ptr ", ps, depth, &dummy, &sec_offset))
return False;
#else
if (!new_smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))

View File

@ -28,6 +28,10 @@
extern int DEBUGLEVEL;
extern pstring global_myname;
#ifndef SAMBA_PRINTER_PORT_NAME
#define SAMBA_PRINTER_PORT_NAME "Samba Printer Port"
#endif
#ifndef MAX_OPEN_PRINTER_EXS
#define MAX_OPEN_PRINTER_EXS 50
#endif
@ -217,6 +221,45 @@ static BOOL delete_printer_handle(POLICY_HND *hnd)
return False;
}
if (*lp_deleteprinter_cmd()) {
pid_t local_pid = sys_getpid();
char *cmd = lp_deleteprinter_cmd();
char *path;
pstring tmp_file;
pstring command;
int ret;
int i;
if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
else
path = tmpdir();
/* Printer->dev.handlename equals portname equals sharename */
slprintf(command, sizeof(command), "%s \"%s\"", cmd,
Printer->dev.handlename);
slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
unlink(tmp_file);
DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
ret = smbrun(command, tmp_file, False);
if (ret != 0) {
unlink(tmp_file);
return False;
}
DEBUGADD(10,("returned [%d]\n", ret));
DEBUGADD(10,("Unlinking output file [%s]\n", tmp_file));
unlink(tmp_file);
if ( ( i = lp_servicenumber( Printer->dev.handlename ) ) >= 0 ) {
lp_remove_service( i );
lp_killservice( i );
return True;
} else
return False;
}
return True;
}
@ -3204,7 +3247,7 @@ static uint32 update_printer(POLICY_HND *handle, uint32 level,
*/
if (!check_printer_ok(printer->info_2, snum)) {
result = ERROR_ACCESS_DENIED;
result = ERROR_INVALID_PARAMETER;
goto done;
}
@ -3914,46 +3957,71 @@ static void fill_port_2(PORT_INFO_2 *port, char *name)
****************************************************************************/
static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int n_services=lp_numservices();
int snum;
int i=0;
PORT_INFO_1 *ports=NULL;
int i=0;
for (snum=0; snum<n_services; snum++)
if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
(*returned)++;
if (*lp_enumports_cmd()) {
pid_t local_pid = sys_getpid();
char *cmd = lp_enumports_cmd();
char *path;
char **qlines;
pstring tmp_file;
pstring command;
int numlines;
int ret;
if((ports=(PORT_INFO_1 *)malloc( (*returned+1) * sizeof(PORT_INFO_1) )) == NULL)
return ERROR_NOT_ENOUGH_MEMORY;
for (snum=0; snum<n_services; snum++) {
if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
/*
* Ensure this port name is unique.
*/
int j;
if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
else
path = tmpdir();
DEBUG(10,("enumports_level_1: port name %s\n", PRINTERNAME(snum)));
slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
slprintf(command, sizeof(command), "%s \"%d\"", cmd, 1);
for(j = 0; j < i; j++) {
fstring port_name;
unistr_to_dos(port_name, (const char *)&ports[j].port_name.buffer[0], sizeof(port_name));
unlink(tmp_file);
DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
ret = smbrun(command, tmp_file, False);
DEBUG(10,("Returned [%d]\n", ret));
if (ret != 0) {
unlink(tmp_file);
// Is this the best error to return here?
return ERROR_ACCESS_DENIED;
}
if (strequal(port_name, PRINTERNAME(snum)))
break;
numlines = 0;
qlines = file_lines_load(tmp_file, &numlines);
DEBUGADD(10,("Lines returned = [%d]\n", numlines));
DEBUGADD(10,("Line[0] = [%s]\n", qlines[0]));
DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
unlink(tmp_file);
if(numlines) {
if((ports=(PORT_INFO_1 *)malloc( numlines * sizeof(PORT_INFO_1) )) == NULL) {
DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY));
file_lines_free(qlines);
return ERROR_NOT_ENOUGH_MEMORY;
}
if (j < i)
continue;
for (i=0; i<numlines; i++) {
DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
fill_port_1(&ports[i], qlines[i]);
}
DEBUGADD(6,("Filling port number [%d]\n", i));
fill_port_1(&ports[i], PRINTERNAME(snum));
i++;
file_lines_free(qlines);
}
}
*returned = i;
*returned = numlines;
} else {
*returned = 1; /* Sole Samba port returned. */
if((ports=(PORT_INFO_1 *)malloc( sizeof(PORT_INFO_1) )) == NULL)
return ERROR_NOT_ENOUGH_MEMORY;
DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME));
fill_port_1(&ports[0], SAMBA_PRINTER_PORT_NAME);
}
/* check the required size. */
for (i=0; i<*returned; i++) {
@ -3988,46 +4056,72 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int n_services=lp_numservices();
int snum;
int i=0;
PORT_INFO_2 *ports=NULL;
int i=0;
for (snum=0; snum<n_services; snum++)
if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
(*returned)++;
if (*lp_enumports_cmd()) {
pid_t local_pid = sys_getpid();
char *cmd = lp_enumports_cmd();
char *path;
char **qlines;
pstring tmp_file;
pstring command;
int numlines;
int ret;
if((ports=(PORT_INFO_2 *)malloc( (*returned+1) * sizeof(PORT_INFO_2) )) == NULL)
return ERROR_NOT_ENOUGH_MEMORY;
for (snum=0; snum<n_services; snum++) {
if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
/*
* Ensure this port name is unique.
*/
int j;
if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
else
path = tmpdir();
DEBUG(10,("enumports_level_2: port name %s\n", PRINTERNAME(snum)));
slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
slprintf(command, sizeof(command), "%s \"%d\"", cmd, 2);
for(j = 0; j < i; j++) {
fstring port_name;
unistr_to_dos(port_name, (const char *)&ports[j].port_name.buffer[0], sizeof(port_name));
unlink(tmp_file);
DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
ret = smbrun(command, tmp_file, False);
DEBUGADD(10,("returned [%d]\n", ret));
if (ret != 0) {
unlink(tmp_file);
// Is this the best error to return here?
return ERROR_ACCESS_DENIED;
}
if (strequal(port_name, PRINTERNAME(snum)))
break;
numlines = 0;
qlines = file_lines_load(tmp_file, &numlines);
DEBUGADD(10,("Lines returned = [%d]\n", numlines));
DEBUGADD(10,("Line[0] = [%s]\n", qlines[0]));
DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
unlink(tmp_file);
if(numlines) {
if((ports=(PORT_INFO_2 *)malloc( numlines * sizeof(PORT_INFO_2) )) == NULL) {
DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY));
file_lines_free(qlines);
return ERROR_NOT_ENOUGH_MEMORY;
}
if (j < i)
continue;
for (i=0; i<numlines; i++) {
DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
fill_port_2(&(ports[i]), qlines[i]);
}
DEBUGADD(6,("Filling port number [%d]\n", i));
fill_port_2(&ports[i], PRINTERNAME(snum));
i++;
file_lines_free(qlines);
}
}
*returned = i;
*returned = numlines;
} else {
*returned = 1;
if((ports=(PORT_INFO_2 *)malloc( sizeof(PORT_INFO_2) )) == NULL)
return ERROR_NOT_ENOUGH_MEMORY;
DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME));
fill_port_2(&ports[0], SAMBA_PRINTER_PORT_NAME);
}
/* check the required size. */
for (i=0; i<*returned; i++) {
@ -4081,6 +4175,68 @@ uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
}
}
/****************************************************************************
****************************************************************************/
static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
{
pid_t local_pid = sys_getpid();
char *cmd = lp_addprinter_cmd();
char *path;
char **qlines;
pstring tmp_file;
pstring command;
pstring driverlocation;
int numlines;
int ret;
if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
else
path = tmpdir();
/* build driver path... only 9X architecture is needed for legacy reasons */
slprintf(driverlocation, sizeof(driverlocation)-1, "\\\\%s\\print$\\WIN40\\0",
global_myname);
/* change \ to \\ for the shell */
all_string_sub(driverlocation,"\\","\\\\",sizeof(pstring));
slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
slprintf(command, sizeof(command), "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
cmd, printer->info_2->printername, printer->info_2->sharename,
printer->info_2->portname, printer->info_2->drivername,
printer->info_2->location, driverlocation);
unlink(tmp_file);
DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
ret = smbrun(command, tmp_file, False);
DEBUGADD(10,("returned [%d]\n", ret));
if ( ret != 0 ) {
unlink(tmp_file);
free_a_printer(&printer,2);
return False;
}
numlines = 0;
qlines = file_lines_load(tmp_file, &numlines);
DEBUGADD(10,("Lines returned = [%d]\n", numlines));
DEBUGADD(10,("Line[0] = [%s]\n", qlines[0]));
DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
unlink(tmp_file);
if(numlines) {
// Set the portname to what the script says the portname should be
strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
// Send SIGHUP to process group... is there a better way?
kill(0, SIGHUP);
add_all_printers();
}
file_lines_free(qlines);
return True;
}
/****************************************************************************
****************************************************************************/
static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
@ -4091,7 +4247,6 @@ static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
fstring name;
fstring share_name;
int snum;
if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
@ -4104,11 +4259,14 @@ static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
/* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
convert_printer_info(info, printer, 2);
unistr2_to_ascii(share_name, &info->info_2->sharename, sizeof(share_name)-1);
if (*lp_addprinter_cmd() )
if ( !add_printer_hook(printer) )
return ERROR_ACCESS_DENIED;
slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname, share_name);
slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname,
printer->info_2->sharename);
if ((snum = print_queue_snum(share_name)) == -1) {
if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
free_a_printer(&printer,2);
return ERROR_ACCESS_DENIED;
}
@ -4119,7 +4277,7 @@ static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
if (!check_printer_ok(printer->info_2, snum)) {
free_a_printer(&printer,2);
return ERROR_ACCESS_DENIED;
return ERROR_INVALID_PARAMETER;
}
/* write the ASCII on disk */
@ -4130,7 +4288,7 @@ static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
if (!open_printer_hnd(handle, name)) {
/* Handle open failed - remove addition. */
del_a_printer(share_name);
del_a_printer(printer->info_2->sharename);
free_a_printer(&printer,2);
return ERROR_ACCESS_DENIED;
}

View File

@ -495,11 +495,10 @@ static void fill_printq_info_52(connection_struct *conn, int snum, int uLevel,
print_status_struct* status)
{
int i;
BOOL ok = False;
BOOL ok;
pstring tok,driver,datafile,langmon,helpfile,datatype;
char *p;
char **lines;
char *line = NULL;
char **lines = NULL;
pstring gen_line;
/*
@ -512,23 +511,18 @@ static void fill_printq_info_52(connection_struct *conn, int snum, int uLevel,
p = gen_line;
DEBUG(10,("9x compatable driver line for [%s]: [%s]\n", lp_printerdriver(snum), gen_line));
} else {
/* didn't find driver in tdb either... oh well */
DEBUG(10,("9x driver not found in tdb\n"));
}
/* didn't find driver in tdb */
DEBUG(10,("snum: %d\nlp_printerdriver: [%s]\nlp_driverfile: [%s]\n",
snum, lp_printerdriver(snum), lp_driverfile(snum)));
lines = file_lines_load(lp_driverfile(snum),NULL);
if (!lines) {
DEBUG(3,("fill_printq_info: Can't open %s - %s\n",
lp_driverfile(snum),strerror(errno)));
DEBUG(3,("Can't open %s - %s\n", lp_driverfile(snum),strerror(errno)));
desc->errcode=NERR_notsupported;
return;
} else {
/* lookup the long printer driver name in the file
description */
/* lookup the long printer driver name in the file description */
for (i=0;lines[i] && !ok;i++) {
p = lines[i];
if (next_token(&p,tok,":",sizeof(tok)) &&
@ -537,16 +531,10 @@ static void fill_printq_info_52(connection_struct *conn, int snum, int uLevel,
ok = True;
}
}
}
if (!ok)
goto err;
if ((line = strdup(p)) == NULL)
goto err;
p = line;
file_lines_free(lines);
if (ok)
{
/* driver file name */
if (!next_token(&p,driver,":",sizeof(driver)))
goto err;
@ -588,9 +576,11 @@ static void fill_printq_info_52(connection_struct *conn, int snum, int uLevel,
PACKS(desc,"z",datatype); /* default data type */
PACKS(desc,"z",helpfile); /* helpfile name */
PACKS(desc,"z",driver); /* driver name */
DEBUG(3,("lp_printerdriver:%s:\n",lp_printerdriver(snum)));
DEBUG(3,("Driver:%s:\n",driver));
DEBUG(3,("Data File:%s:\n",datafile));
DEBUG(3,("Language Monitor:%s:\n",langmon));
DEBUG(3,("lp_driverlocation:%s:\n",lp_driverlocation(snum)));
DEBUG(3,("Data Type:%s:\n",datatype));
DEBUG(3,("Help File:%s:\n",helpfile));
PACKI(desc,"N",count); /* number of files to copy */
@ -607,15 +597,16 @@ static void fill_printq_info_52(connection_struct *conn, int snum, int uLevel,
DEBUG(3,("fill_printq_info on <%s> gave %d entries\n",
SERVICE(snum),count));
free(line);
desc->errcode=NERR_Success;
file_lines_free(lines);
return;
}
err:
DEBUG(3,("fill_printq_info: Can't supply driver files\n"));
desc->errcode=NERR_notsupported;
if (line)
free(line);
file_lines_free(lines);
}
@ -697,64 +688,67 @@ static void fill_printq_info(connection_struct *conn, int snum, int uLevel,
/* This function returns the number of files for a given driver */
static int get_printerdrivernumber(int snum)
{
int i=0,ok=0;
int i;
BOOL ok;
pstring tok;
char *p;
char **lines, *line;
char **lines = NULL;
pstring gen_line;
/*
* Check in the tdb *first* before checking the legacy
* files. This allows an NT upload to take precedence over
* the existing fileset. JRA.
*/
if ((ok = get_a_printer_driver_9x_compatible(gen_line, lp_printerdriver(snum))) == True ) {
p = gen_line;
DEBUG(10,("9x compatable driver line for [%s]: [%s]\n", lp_printerdriver(snum), gen_line));
} else {
/* didn't find driver in tdb */
DEBUG(10,("snum: %d\nlp_printerdriver: [%s]\nlp_driverfile: [%s]\n",
snum, lp_printerdriver(snum), lp_driverfile(snum)));
lines = file_lines_load(lp_driverfile(snum), NULL);
if (!lines) {
DEBUG(3,("get_printerdrivernumber: Can't open %s - %s\n",
lp_driverfile(snum),strerror(errno)));
DEBUG(3,("Can't open %s - %s\n", lp_driverfile(snum),strerror(errno)));
}
else
{
/* lookup the long printer driver name in the file
description */
/* lookup the long printer driver name in the file description */
for (i=0;lines[i] && !ok;i++) {
p = lines[i];
if (next_token(&p,tok,":",sizeof(tok)) &&
(strlen(lp_printerdriver(snum)) == strlen(tok)) &&
(!strncmp(tok,lp_printerdriver(snum),strlen(lp_printerdriver(snum)))))
ok=1;
ok = True;
}
}
if( !ok ) {
/* no printers.def, or driver not found, check the NT driver tdb */
if ((ok = get_a_printer_driver_9x_compatible(gen_line, lp_printerdriver(snum)))==True ) {
p = gen_line;
DEBUG(10,("9x compatable driver line for [%s]: [%s]\n",
lp_printerdriver(snum), gen_line));
} else {
/* didn't find driver in tdb either... oh well */
DEBUG(10,("9x driver not found in tdb\n"));
return (0);
}
}
line = strdup(p);
p = line;
file_lines_free(lines);
if (ok) {
if( ok ) {
/* skip 5 fields */
i = 5;
while (*p && i) {
if (*p++ == ':') i--;
}
if (!*p || i)
return(0);
goto err;
/* count the number of files */
while (next_token(&p,tok,",",sizeof(tok)))
i++;
}
free(line);
file_lines_free(lines);
return(i);
}
err:
DEBUG(3,("Can't determine number of printer driver files\n"));
file_lines_free(lines);
return (0);
}
static BOOL api_DosPrintQGetInfo(connection_struct *conn,

View File

@ -136,6 +136,14 @@ size_t tdb_pack(char *buf, int bufsize, char *fmt, ...)
SIVAL(buf, 0, d);
}
break;
case 'P':
s = va_arg(ap,char *);
w = strlen(s);
len = w + 1;
if (bufsize >= len) {
memcpy(buf, s, len);
}
break;
case 'f':
s = va_arg(ap,char *);
w = strlen(s);
@ -211,6 +219,12 @@ int tdb_unpack(char *buf, int bufsize, char *fmt, ...)
if (bufsize < len) goto no_space;
*p = (void *)IVAL(buf, 0);
break;
case 'P':
s = va_arg(ap,char *);
len = strlen(buf) + 1;
if (bufsize < len || len > sizeof(pstring)) goto no_space;
memcpy(s, buf, len);
break;
case 'f':
s = va_arg(ap,char *);
len = strlen(buf) + 1;