summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h3
-rw-r--r--source3/printing/nt_printing.c29
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c373
3 files changed, 173 insertions, 232 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 0904c4a0dc..52f2cca050 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -5149,7 +5149,8 @@ WERROR set_printer_dataex(NT_PRINTER_INFO_LEVEL *printer,
uint32_t type, uint8_t *data, int real_len);
struct spoolss_DeviceMode *construct_dev_mode(TALLOC_CTX *mem_ctx,
const char *servicename);
-bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer);
+bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
+ struct spoolss_SetPrinterInfo2 *info2);
/* The following definitions come from rpc_server/srv_srvsvc_nt.c */
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index c65da830fb..beb1e45755 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -25,6 +25,7 @@
#include "registry.h"
#include "registry/reg_objects.h"
#include "../librpc/gen_ndr/ndr_security.h"
+#include "rpc_server/srv_spoolss_util.h"
static TDB_CONTEXT *tdb_forms; /* used for forms files */
static TDB_CONTEXT *tdb_drivers; /* used for driver files */
@@ -5463,9 +5464,11 @@ void map_job_permissions(struct security_descriptor *sd)
bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
int access_type)
{
- struct sec_desc_buf *secdesc = NULL;
+ struct spoolss_security_descriptor *secdesc = NULL;
uint32 access_granted;
+ size_t sd_size;
NTSTATUS status;
+ WERROR result;
const char *pname;
TALLOC_CTX *mem_ctx = NULL;
SE_PRIV se_printop = SE_PRINT_OPERATOR;
@@ -5495,34 +5498,42 @@ bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
return False;
}
- if (!nt_printing_getsec(mem_ctx, pname, &secdesc)) {
+ result = winreg_get_printer_secdesc(mem_ctx,
+ server_info,
+ pname,
+ &secdesc);
+ if (!W_ERROR_IS_OK(result)) {
talloc_destroy(mem_ctx);
errno = ENOMEM;
return False;
}
if (access_type == JOB_ACCESS_ADMINISTER) {
- struct sec_desc_buf *parent_secdesc = secdesc;
+ struct spoolss_security_descriptor *parent_secdesc = secdesc;
/* Create a child security descriptor to check permissions
against. This is because print jobs are child objects
objects of a printer. */
-
- status = se_create_child_secdesc_buf(mem_ctx, &secdesc, parent_secdesc->sd, False);
-
+ status = se_create_child_secdesc(mem_ctx,
+ &secdesc,
+ &sd_size,
+ parent_secdesc,
+ parent_secdesc->owner_sid,
+ parent_secdesc->group_sid,
+ false);
if (!NT_STATUS_IS_OK(status)) {
talloc_destroy(mem_ctx);
errno = map_errno_from_nt_status(status);
return False;
}
- map_job_permissions(secdesc->sd);
+ map_job_permissions(secdesc);
} else {
- map_printer_permissions(secdesc->sd);
+ map_printer_permissions(secdesc);
}
/* Check access */
- status = se_access_check(secdesc->sd, server_info->ptok, access_type,
+ status = se_access_check(secdesc, server_info->ptok, access_type,
&access_granted);
DEBUG(4, ("access check was %s\n", NT_STATUS_IS_OK(status) ? "SUCCESS" : "FAILURE"));
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 3cb51d8cf0..2f41430c0e 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -5201,7 +5201,9 @@ WERROR _spoolss_AbortPrinter(pipes_struct *p,
static WERROR update_printer_sec(struct policy_handle *handle,
pipes_struct *p, struct sec_desc_buf *secdesc_ctr)
{
- struct sec_desc_buf *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
+ struct spoolss_security_descriptor *new_secdesc = NULL;
+ struct spoolss_security_descriptor *old_secdesc = NULL;
+ const char *printer;
WERROR result;
int snum;
@@ -5215,11 +5217,12 @@ static WERROR update_printer_sec(struct policy_handle *handle,
goto done;
}
- if (!secdesc_ctr) {
+ if (secdesc_ctr == NULL) {
DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
result = WERR_INVALID_PARAM;
goto done;
}
+ printer = lp_const_servicename(snum);
/* Check the user has permissions to change the security
descriptor. By experimentation with two NT machines, the user
@@ -5234,9 +5237,12 @@ static WERROR update_printer_sec(struct policy_handle *handle,
/* NT seems to like setting the security descriptor even though
nothing may have actually changed. */
-
- if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
- DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
+ result = winreg_get_printer_secdesc(p->mem_ctx,
+ p->server_info,
+ printer,
+ &old_secdesc);
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
result = WERR_BADFID;
goto done;
}
@@ -5245,9 +5251,9 @@ static WERROR update_printer_sec(struct policy_handle *handle,
struct security_acl *the_acl;
int i;
- the_acl = old_secdesc_ctr->sd->dacl;
+ the_acl = secdesc_ctr->sd->dacl;
DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
- lp_printername(snum), the_acl->num_aces));
+ printer, the_acl->num_aces));
for (i = 0; i < the_acl->num_aces; i++) {
DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
@@ -5259,7 +5265,7 @@ static WERROR update_printer_sec(struct policy_handle *handle,
if (the_acl) {
DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
- lp_printername(snum), the_acl->num_aces));
+ printer, the_acl->num_aces));
for (i = 0; i < the_acl->num_aces; i++) {
DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
@@ -5271,21 +5277,23 @@ static WERROR update_printer_sec(struct policy_handle *handle,
}
}
- new_secdesc_ctr = sec_desc_merge_buf(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
- if (!new_secdesc_ctr) {
+ new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
+ if (new_secdesc == NULL) {
result = WERR_NOMEM;
goto done;
}
- if (security_descriptor_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
+ if (security_descriptor_equal(new_secdesc, old_secdesc)) {
result = WERR_OK;
goto done;
}
- result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
+ result = winreg_set_printer_secdesc(p->mem_ctx,
+ p->server_info,
+ printer,
+ new_secdesc);
done:
-
return result;
}
@@ -5298,44 +5306,51 @@ static WERROR update_printer_sec(struct policy_handle *handle,
_spoolss_open_printer_ex().
********************************************************************/
-static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
+static bool check_printer_ok(TALLOC_CTX *mem_ctx,
+ struct spoolss_SetPrinterInfo2 *info2,
+ int snum)
{
fstring printername;
const char *p;
DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
"portname=%s drivername=%s comment=%s location=%s\n",
- info->servername, info->printername, info->sharename,
- info->portname, info->drivername, info->comment, info->location));
+ info2->servername, info2->printername, info2->sharename,
+ info2->portname, info2->drivername, info2->comment,
+ info2->location));
/* we force some elements to "correct" values */
- slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
- fstrcpy(info->sharename, lp_servicename(snum));
+ info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
+ if (info2->servername == NULL) {
+ return false;
+ }
+ info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
+ if (info2->sharename == NULL) {
+ return false;
+ }
/* check to see if we allow printername != sharename */
-
- if ( lp_force_printername(snum) ) {
- slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
- global_myname(), info->sharename );
+ if (lp_force_printername(snum)) {
+ info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
+ global_myname(), info2->sharename);
} else {
-
/* make sure printername is in \\server\printername format */
-
- fstrcpy( printername, info->printername );
+ fstrcpy(printername, info2->printername);
p = printername;
if ( printername[0] == '\\' && printername[1] == '\\' ) {
if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
p++;
}
- slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
- global_myname(), p );
+ info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
+ global_myname(), p);
+ }
+ if (info2->printername == NULL) {
+ return false;
}
- info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
- info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
-
-
+ info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
+ info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
return true;
}
@@ -5392,7 +5407,8 @@ static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *p
/****************************************************************************
****************************************************************************/
-bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
+bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
+ struct spoolss_SetPrinterInfo2 *info2)
{
char *cmd = lp_addprinter_cmd();
char **qlines;
@@ -5417,9 +5433,9 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV
command = talloc_asprintf(ctx,
"%s \"%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, printer->info_2->comment, remote_machine);
+ cmd, info2->printername, info2->sharename,
+ info2->portname, info2->drivername,
+ info2->location, info2->comment, remote_machine);
if (!command) {
return false;
}
@@ -5472,7 +5488,7 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV
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));
+ info2->portname = talloc_strdup(ctx, qlines[0]);
DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
}
@@ -5490,9 +5506,11 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
struct spoolss_SetPrinterInfoCtr *info_ctr,
struct spoolss_DeviceMode *devmode)
{
- int snum;
- NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
+ uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
+ struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
+ struct spoolss_PrinterInfo2 *old_printer;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+ int snum;
WERROR result;
DATA_BLOB buffer;
fstring asc_buffer;
@@ -5511,40 +5529,18 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
goto done;
}
- if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
- (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
+ result = winreg_get_printer(p->mem_ctx,
+ p->server_info,
+ NULL,
+ lp_const_servicename(snum),
+ &old_printer);
+ if (!W_ERROR_IS_OK(result)) {
result = WERR_BADFID;
goto done;
}
- DEBUGADD(8,("Converting info_2 struct\n"));
-
- /*
- * convert_printer_info converts the incoming
- * info from the client and overwrites the info
- * just read from the tdb in the pointer 'printer'.
- */
-
- if (!convert_printer_info(info_ctr, printer)) {
- result = WERR_NOMEM;
- goto done;
- }
-
- if (devmode) {
- /* we have a valid devmode
- convert it and link it*/
-
- DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
- result = copy_devicemode(printer->info_2, devmode,
- &printer->info_2->devmode);
- if (!W_ERROR_IS_OK(result)) {
- return result;
- }
- }
-
/* Do sanity check on the requested changes for Samba */
-
- if (!check_printer_ok(printer->info_2, snum)) {
+ if (!check_printer_ok(p->mem_ctx, printer, snum)) {
result = WERR_INVALID_PARAM;
goto done;
}
@@ -5553,7 +5549,6 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
it is installed before doing much else --jerry */
/* Check calling user has permission to update printer description */
-
if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
DEBUG(3, ("update_printer: printer property change denied by handle\n"));
result = WERR_ACCESS_DENIED;
@@ -5563,16 +5558,15 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
/* Call addprinter hook */
/* Check changes to see if this is really needed */
- if ( *lp_addprinter_cmd()
- && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
- || !strequal(printer->info_2->comment, old_printer->info_2->comment)
- || !strequal(printer->info_2->portname, old_printer->info_2->portname)
- || !strequal(printer->info_2->location, old_printer->info_2->location)) )
+ if (*lp_addprinter_cmd() &&
+ (!strequal(printer->drivername, old_printer->drivername) ||
+ !strequal(printer->comment, old_printer->comment) ||
+ !strequal(printer->portname, old_printer->portname) ||
+ !strequal(printer->location, old_printer->location)) )
{
/* add_printer_hook() will call reload_services() */
-
- if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
- printer) ) {
+ if (!add_printer_hook(p->mem_ctx, p->server_info->ptok,
+ printer) ) {
result = WERR_ACCESS_DENIED;
goto done;
}
@@ -5583,12 +5577,11 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
* lookup previously saved driver initialization info, which is then
* bound to the printer, simulating what happens in the Windows arch.
*/
- if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
- {
+ if (!strequal(printer->drivername, old_printer->drivername)) {
DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
- printer->info_2->drivername));
+ printer->drivername));
- notify_printer_driver(snum, printer->info_2->drivername);
+ notify_printer_driver(snum, printer->drivername);
}
/*
@@ -5596,48 +5589,46 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
* all the possible changes. We also have to update things in the
* DsSpooler key.
*/
-
- if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
- push_reg_sz(talloc_tos(), &buffer, printer->info_2->comment);
+ if (!strequal(printer->comment, old_printer->comment)) {
+ push_reg_sz(talloc_tos(), &buffer, printer->comment);
winreg_set_printer_dataex(p->mem_ctx,
p->server_info,
- printer->info_2->sharename,
+ printer->sharename,
SPOOL_DSSPOOLER_KEY,
"description",
REG_SZ,
buffer.data,
buffer.length);
- notify_printer_comment(snum, printer->info_2->comment);
+ notify_printer_comment(snum, printer->comment);
}
- if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
- push_reg_sz(talloc_tos(), &buffer, printer->info_2->sharename);
+ if (!strequal(printer->sharename, old_printer->sharename)) {
+ push_reg_sz(talloc_tos(), &buffer, printer->sharename);
winreg_set_printer_dataex(p->mem_ctx,
p->server_info,
- printer->info_2->sharename,
+ printer->sharename,
SPOOL_DSSPOOLER_KEY,
"shareName",
REG_SZ,
buffer.data,
buffer.length);
- notify_printer_sharename(snum, printer->info_2->sharename);
+ notify_printer_sharename(snum, printer->sharename);
}
- if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
- char *pname;
+ if (!strequal(printer->printername, old_printer->printername)) {
+ const char *pname;
- if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
+ if ( (pname = strchr_m( printer->printername+2, '\\' )) != NULL )
pname++;
else
- pname = printer->info_2->printername;
-
+ pname = printer->printername;
push_reg_sz(talloc_tos(), &buffer, pname);
winreg_set_printer_dataex(p->mem_ctx,
p->server_info,
- printer->info_2->sharename,
+ printer->sharename,
SPOOL_DSSPOOLER_KEY,
"printerName",
REG_SZ,
@@ -5647,32 +5638,32 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
notify_printer_printername( snum, pname );
}
- if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
- push_reg_sz(talloc_tos(), &buffer, printer->info_2->portname);
+ if (!strequal(printer->portname, old_printer->portname)) {
+ push_reg_sz(talloc_tos(), &buffer, printer->portname);
winreg_set_printer_dataex(p->mem_ctx,
p->server_info,
- printer->info_2->sharename,
+ printer->sharename,
SPOOL_DSSPOOLER_KEY,
"portName",
REG_SZ,
buffer.data,
buffer.length);
- notify_printer_port(snum, printer->info_2->portname);
+ notify_printer_port(snum, printer->portname);
}
- if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
- push_reg_sz(talloc_tos(), &buffer, printer->info_2->location);
+ if (!strequal(printer->location, old_printer->location)) {
+ push_reg_sz(talloc_tos(), &buffer, printer->location);
winreg_set_printer_dataex(p->mem_ctx,
p->server_info,
- printer->info_2->sharename,
+ printer->sharename,
SPOOL_DSSPOOLER_KEY,
"location",
REG_SZ,
buffer.data,
buffer.length);
- notify_printer_location(snum, printer->info_2->location);
+ notify_printer_location(snum, printer->location);
}
/* here we need to update some more DsSpooler keys */
@@ -5681,7 +5672,7 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
push_reg_sz(talloc_tos(), &buffer, global_myname());
winreg_set_printer_dataex(p->mem_ctx,
p->server_info,
- printer->info_2->sharename,
+ printer->sharename,
SPOOL_DSSPOOLER_KEY,
"serverName",
REG_SZ,
@@ -5689,7 +5680,7 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
buffer.length);
winreg_set_printer_dataex(p->mem_ctx,
p->server_info,
- printer->info_2->sharename,
+ printer->sharename,
SPOOL_DSSPOOLER_KEY,
"shortServerName",
REG_SZ,
@@ -5697,24 +5688,32 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
buffer.length);
slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
- global_myname(), printer->info_2->sharename );
+ global_myname(), printer->sharename );
push_reg_sz(talloc_tos(), &buffer, asc_buffer);
winreg_set_printer_dataex(p->mem_ctx,
p->server_info,
- printer->info_2->sharename,
+ printer->sharename,
SPOOL_DSSPOOLER_KEY,
"uNCName",
REG_SZ,
buffer.data,
buffer.length);
- /* Update printer info */
- result = mod_a_printer(printer, 2);
+ printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
-done:
- free_a_printer(&printer, 2);
- free_a_printer(&old_printer, 2);
+ if (devmode == NULL) {
+ printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
+ }
+ result = winreg_update_printer(p->mem_ctx,
+ p->server_info,
+ printer->sharename,
+ printer_mask,
+ printer,
+ devmode,
+ NULL);
+done:
+ talloc_free(old_printer);
return result;
}
@@ -5758,56 +5757,32 @@ static WERROR update_printer_devmode(pipes_struct *p, struct policy_handle *hand
struct spoolss_DeviceMode *devmode)
{
int snum;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
- WERROR result;
+ uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
DEBUG(8,("update_printer_devmode\n"));
- result = WERR_OK;
-
if (!Printer) {
- result = WERR_BADFID;
- goto done;
+ return WERR_BADFID;
}
if (!get_printer_snum(p, handle, &snum, NULL)) {
- result = WERR_BADFID;
- goto done;
- }
-
- if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)))) {
- result = WERR_BADFID;
- goto done;
- }
-
- if (devmode) {
- /* we have a valid devmode, copy it */
-
- DEBUGADD(8, ("update_printer: Copying the devicemode struct\n"));
- result = copy_devicemode(printer->info_2, devmode,
- &printer->info_2->devmode);
- if (!W_ERROR_IS_OK(result)) {
- goto done;
- }
+ return WERR_BADFID;
}
/* Check calling user has permission to update printer description */
-
if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
DEBUG(3, ("update_printer: printer property change denied by handle\n"));
- result = WERR_ACCESS_DENIED;
- goto done;
+ return WERR_ACCESS_DENIED;
}
-
- /* Update printer info */
- result = mod_a_printer(printer, 2);
-
-done:
- free_a_printer(&printer, 2);
-
- return result;
+ return winreg_update_printer(p->mem_ctx,
+ p->server_info,
+ lp_const_servicename(snum),
+ info2_mask,
+ NULL,
+ devmode,
+ NULL);
}
@@ -6927,72 +6902,51 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
const char *server,
struct spoolss_SetPrinterInfoCtr *info_ctr,
struct spoolss_DeviceMode *devmode,
- struct security_descriptor *sec_desc,
+ struct security_descriptor *secdesc,
struct spoolss_UserLevelCtr *user_ctr,
struct policy_handle *handle)
{
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- fstring name;
+ struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
+ uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
int snum;
WERROR err = WERR_OK;
- if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
- DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
- return WERR_NOMEM;
- }
-
- /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
- if (!convert_printer_info(info_ctr, printer)) {
- free_a_printer(&printer, 2);
- return WERR_NOMEM;
- }
-
/* samba does not have a concept of local, non-shared printers yet, so
* make sure we always setup sharename - gd */
- if ((printer->info_2->sharename[0] == '\0') && (printer->info_2->printername != '\0')) {
+ if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
+ (info2->printername != NULL && info2->printername[0] != '\0')) {
DEBUG(5, ("spoolss_addprinterex_level_2: "
"no sharename has been set, setting printername %s as sharename\n",
- printer->info_2->printername));
- fstrcpy(printer->info_2->sharename, printer->info_2->printername);
+ info2->printername));
+ info2->sharename = info2->printername;
}
/* check to see if the printer already exists */
-
- if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
+ if ((snum = print_queue_snum(info2->sharename)) != -1) {
DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
- printer->info_2->sharename));
- free_a_printer(&printer, 2);
+ info2->sharename));
return WERR_PRINTER_ALREADY_EXISTS;
}
if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
- if ((snum = print_queue_snum(printer->info_2->printername)) != -1) {
+ if ((snum = print_queue_snum(info2->printername)) != -1) {
DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
- printer->info_2->printername));
- free_a_printer(&printer, 2);
+ info2->printername));
return WERR_PRINTER_ALREADY_EXISTS;
}
}
/* validate printer info struct */
- if (!info_ctr->info.info2->printername ||
- strlen(info_ctr->info.info2->printername) == 0) {
- free_a_printer(&printer,2);
+ if (!info2->printername || strlen(info2->printername) == 0) {
return WERR_INVALID_PRINTER_NAME;
}
- if (!info_ctr->info.info2->portname ||
- strlen(info_ctr->info.info2->portname) == 0) {
- free_a_printer(&printer,2);
+ if (!info2->portname || strlen(info2->portname) == 0) {
return WERR_UNKNOWN_PORT;
}
- if (!info_ctr->info.info2->drivername ||
- strlen(info_ctr->info.info2->drivername) == 0) {
- free_a_printer(&printer,2);
+ if (!info2->drivername || strlen(info2->drivername) == 0) {
return WERR_UNKNOWN_PRINTER_DRIVER;
}
- if (!info_ctr->info.info2->printprocessor ||
- strlen(info_ctr->info.info2->printprocessor) == 0) {
- free_a_printer(&printer,2);
+ if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
return WERR_UNKNOWN_PRINTPROCESSOR;
}
@@ -7001,32 +6955,22 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
if (*lp_addprinter_cmd() ) {
if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
- printer) ) {
- free_a_printer(&printer,2);
+ info2) ) {
return WERR_ACCESS_DENIED;
}
} else {
DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
"smb.conf parameter \"addprinter command\" is defined. This"
"parameter must exist for this call to succeed\n",
- printer->info_2->sharename ));
+ info2->sharename ));
}
- /* use our primary netbios name since get_a_printer() will convert
- it to what the client expects on a case by case basis */
-
- slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
- printer->info_2->sharename);
-
-
- if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
- free_a_printer(&printer,2);
+ if ((snum = print_queue_snum(info2->sharename)) == -1) {
return WERR_ACCESS_DENIED;
}
/* you must be a printer admin to add a new printer */
if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
- free_a_printer(&printer,2);
return WERR_ACCESS_DENIED;
}
@@ -7034,47 +6978,32 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
* Do sanity check on the requested changes for Samba.
*/
- if (!check_printer_ok(printer->info_2, snum)) {
- free_a_printer(&printer,2);
+ if (!check_printer_ok(p->mem_ctx, info2, snum)) {
return WERR_INVALID_PARAM;
}
- /*
- * When a printer is created, the drivername bound to the printer is used
- * to lookup previously saved driver initialization info, which is then
- * bound to the new printer, simulating what happens in the Windows arch.
- */
-
- if (devmode)
- {
- /* A valid devmode was included, convert and link it
- */
- DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
-
- err = copy_devicemode(printer, devmode,
- &printer->info_2->devmode);
- if (!W_ERROR_IS_OK(err)) {
- return err;
- }
+ if (devmode == NULL) {
+ info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
}
- /* write the ASCII on disk */
- err = mod_a_printer(printer, 2);
+ err = winreg_update_printer(p->mem_ctx,
+ p->server_info,
+ info2->sharename,
+ info2_mask,
+ info2,
+ devmode,
+ secdesc);
if (!W_ERROR_IS_OK(err)) {
- free_a_printer(&printer,2);
return err;
}
- if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
+ if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
/* Handle open failed - remove addition. */
- del_a_printer(printer->info_2->sharename);
- free_a_printer(&printer,2);
ZERO_STRUCTP(handle);
return WERR_ACCESS_DENIED;
}
update_c_setprinter(false);
- free_a_printer(&printer,2);
return WERR_OK;
}