summaryrefslogtreecommitdiff
path: root/source3/rpc_server
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2011-07-22 11:59:41 -0400
committerAndreas Schneider <asn@samba.org>2011-07-27 08:49:58 +0200
commit99e03bee7ae5de37280a4e571caf36b0a8553fae (patch)
tree1b383441fdf5d2ba5a99fd98865cd86576b3de3a /source3/rpc_server
parent8831402596fab30f56ce6600c72a575e2e73e4d3 (diff)
downloadsamba-99e03bee7ae5de37280a4e571caf36b0a8553fae.tar.gz
samba-99e03bee7ae5de37280a4e571caf36b0a8553fae.tar.bz2
samba-99e03bee7ae5de37280a4e571caf36b0a8553fae.zip
s3-spoolss: Improve memory efficiency.
p->mem_ctx is a relatively long lived context as it will not be freed until a full request is served. In spoolss we do a lot of operations including opening new pipes to connect to winreg. Use more shortlived temporary contexts to avoid leaking a lot of memory on p->mem_ctx and carrying it around untill all the operations in the current call are done. Signed-off-by: Andreas Schneider <asn@samba.org>
Diffstat (limited to 'source3/rpc_server')
-rw-r--r--source3/rpc_server/spoolss/srv_spoolss_nt.c400
1 files changed, 242 insertions, 158 deletions
diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index cdacd5e033..b45712d936 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -2087,6 +2087,7 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
int version;
WERROR status;
struct dcerpc_binding_handle *b;
+ TALLOC_CTX *tmp_ctx = NULL;
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
and not a printer admin, then fail */
@@ -2105,18 +2106,24 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
/* check that we have a valid driver name first */
- if ((version = get_version_id(r->in.architecture)) == -1)
+ if ((version = get_version_id(r->in.architecture)) == -1) {
return WERR_INVALID_ENVIRONMENT;
+ }
+
+ tmp_ctx = talloc_new(p->mem_ctx);
+ if (!tmp_ctx) {
+ return WERR_NOMEM;
+ }
- status = winreg_printer_binding_handle(p->mem_ctx,
+ status = winreg_printer_binding_handle(tmp_ctx,
get_session_info_system(),
p->msg_ctx,
&b);
if (!W_ERROR_IS_OK(status)) {
- return status;
+ goto done;
}
- status = winreg_get_driver(p->mem_ctx, b,
+ status = winreg_get_driver(tmp_ctx, b,
r->in.architecture, r->in.driver,
version, &info);
if (!W_ERROR_IS_OK(status)) {
@@ -2125,7 +2132,7 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
if ( version == 2 ) {
version = 3;
- status = winreg_get_driver(p->mem_ctx, b,
+ status = winreg_get_driver(tmp_ctx, b,
r->in.architecture,
r->in.driver,
version, &info);
@@ -2142,7 +2149,7 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
}
- if (printer_driver_in_use(p->mem_ctx,
+ if (printer_driver_in_use(tmp_ctx,
get_session_info_system(),
p->msg_ctx,
info)) {
@@ -2151,14 +2158,14 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
}
if (version == 2) {
- status = winreg_get_driver(p->mem_ctx, b,
+ status = winreg_get_driver(tmp_ctx, b,
r->in.architecture,
r->in.driver, 3, &info_win2k);
if (W_ERROR_IS_OK(status)) {
/* if we get to here, we now have 2 driver info structures to remove */
/* remove the Win2k driver first*/
- status = winreg_del_driver(p->mem_ctx, b,
+ status = winreg_del_driver(tmp_ctx, b,
info_win2k, 3);
talloc_free(info_win2k);
@@ -2169,11 +2176,11 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
}
}
- status = winreg_del_driver(p->mem_ctx, b,
+ status = winreg_del_driver(tmp_ctx, b,
info, version);
done:
- talloc_free(info);
+ talloc_free(tmp_ctx);
return status;
}
@@ -2191,6 +2198,7 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
bool delete_files;
WERROR status;
struct dcerpc_binding_handle *b;
+ TALLOC_CTX *tmp_ctx = NULL;
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
and not a printer admin, then fail */
@@ -2212,18 +2220,24 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
return WERR_INVALID_ENVIRONMENT;
}
- if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
+ if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) {
version = r->in.version;
+ }
- status = winreg_printer_binding_handle(p->mem_ctx,
+ tmp_ctx = talloc_new(p->mem_ctx);
+ if (!tmp_ctx) {
+ return WERR_NOMEM;
+ }
+
+ status = winreg_printer_binding_handle(tmp_ctx,
get_session_info_system(),
p->msg_ctx,
&b);
if (!W_ERROR_IS_OK(status)) {
- return status;
+ goto done;
}
- status = winreg_get_driver(p->mem_ctx, b,
+ status = winreg_get_driver(tmp_ctx, b,
r->in.architecture,
r->in.driver,
version,
@@ -2351,7 +2365,7 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
}
done:
- talloc_free(info);
+ talloc_free(tmp_ctx);
return status;
}
@@ -4313,6 +4327,12 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
uint32_t count = 0;
WERROR result = WERR_OK;
struct dcerpc_binding_handle *b = NULL;
+ TALLOC_CTX *tmp_ctx = NULL;
+
+ tmp_ctx = talloc_new(mem_ctx);
+ if (!tmp_ctx) {
+ return WERR_NOMEM;
+ }
*count_p = 0;
*info_p = NULL;
@@ -4332,7 +4352,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
printer, snum));
if (b == NULL) {
- result = winreg_printer_binding_handle(mem_ctx,
+ result = winreg_printer_binding_handle(tmp_ctx,
session_info,
msg_ctx,
&b);
@@ -4341,13 +4361,13 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
}
}
- result = winreg_create_printer(mem_ctx, b,
+ result = winreg_create_printer(tmp_ctx, b,
printer);
if (!W_ERROR_IS_OK(result)) {
goto out;
}
- info = talloc_realloc(mem_ctx, info,
+ info = talloc_realloc(tmp_ctx, info,
union spoolss_PrinterInfo,
count + 1);
if (!info) {
@@ -4355,7 +4375,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
goto out;
}
- result = winreg_get_printer(mem_ctx, b,
+ result = winreg_get_printer(tmp_ctx, b,
printer, &info2);
if (!W_ERROR_IS_OK(result)) {
goto out;
@@ -4401,18 +4421,15 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
count++;
}
- *count_p = count;
- *info_p = info;
-
- out:
- if (!W_ERROR_IS_OK(result)) {
- TALLOC_FREE(info);
- return result;
+out:
+ if (W_ERROR_IS_OK(result)) {
+ *info_p = talloc_move(mem_ctx, &info);
+ *count_p = count;
}
- *info_p = info;
+ talloc_free(tmp_ctx);
- return WERR_OK;
+ return result;
}
/********************************************************************
@@ -5546,20 +5563,26 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
struct spoolss_DriverInfo8 *driver;
WERROR result;
struct dcerpc_binding_handle *b;
+ TALLOC_CTX *tmp_ctx = NULL;
if (level == 101) {
return WERR_UNKNOWN_LEVEL;
}
- result = winreg_printer_binding_handle(mem_ctx,
+ tmp_ctx = talloc_new(mem_ctx);
+ if (!tmp_ctx) {
+ return WERR_NOMEM;
+ }
+
+ result = winreg_printer_binding_handle(tmp_ctx,
session_info,
msg_ctx,
&b);
if (!W_ERROR_IS_OK(result)) {
- return result;
+ goto done;
}
- result = winreg_get_printer(mem_ctx, b,
+ result = winreg_get_printer(tmp_ctx, b,
lp_const_servicename(snum),
&pinfo2);
@@ -5567,10 +5590,11 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
win_errstr(result)));
if (!W_ERROR_IS_OK(result)) {
- return WERR_INVALID_PRINTER_NAME;
+ result = WERR_INVALID_PRINTER_NAME;
+ goto done;
}
- result = winreg_get_driver(mem_ctx, b,
+ result = winreg_get_driver(tmp_ctx, b,
architecture,
pinfo2->drivername, version, &driver);
@@ -5583,24 +5607,26 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
*/
if (version < 3) {
- talloc_free(pinfo2);
- return WERR_UNKNOWN_PRINTER_DRIVER;
+ result = WERR_UNKNOWN_PRINTER_DRIVER;
+ goto done;
}
/* Yes - try again with a WinNT driver. */
version = 2;
- result = winreg_get_driver(mem_ctx, b,
+ result = winreg_get_driver(tmp_ctx, b,
architecture,
pinfo2->drivername,
version, &driver);
DEBUG(8,("construct_printer_driver_level: status: %s\n",
win_errstr(result)));
if (!W_ERROR_IS_OK(result)) {
- talloc_free(pinfo2);
- return WERR_UNKNOWN_PRINTER_DRIVER;
+ result = WERR_UNKNOWN_PRINTER_DRIVER;
+ goto done;
}
}
+ /* these are allocated on mem_ctx and not tmp_ctx because they are
+ * the 'return value' and need to utlive this call */
switch (level) {
case 1:
result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
@@ -5633,9 +5659,8 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
break;
}
- talloc_free(pinfo2);
- talloc_free(driver);
-
+done:
+ talloc_free(tmp_ctx);
return result;
}
@@ -5991,6 +6016,7 @@ static WERROR update_printer_sec(struct policy_handle *handle,
int snum;
struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
struct dcerpc_binding_handle *b;
+ TALLOC_CTX *tmp_ctx = NULL;
if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
@@ -6018,7 +6044,12 @@ static WERROR update_printer_sec(struct policy_handle *handle,
goto done;
}
- result = winreg_printer_binding_handle(p->mem_ctx,
+ tmp_ctx = talloc_new(p->mem_ctx);
+ if (!tmp_ctx) {
+ return WERR_NOMEM;
+ }
+
+ result = winreg_printer_binding_handle(tmp_ctx,
get_session_info_system(),
p->msg_ctx,
&b);
@@ -6028,7 +6059,7 @@ static WERROR update_printer_sec(struct policy_handle *handle,
/* NT seems to like setting the security descriptor even though
nothing may have actually changed. */
- result = winreg_get_printer_secdesc(p->mem_ctx, b,
+ result = winreg_get_printer_secdesc(tmp_ctx, b,
printer,
&old_secdesc);
if (!W_ERROR_IS_OK(result)) {
@@ -6067,7 +6098,7 @@ static WERROR update_printer_sec(struct policy_handle *handle,
}
}
- new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
+ new_secdesc = sec_desc_merge(tmp_ctx, secdesc_ctr->sd, old_secdesc);
if (new_secdesc == NULL) {
result = WERR_NOMEM;
goto done;
@@ -6078,11 +6109,12 @@ static WERROR update_printer_sec(struct policy_handle *handle,
goto done;
}
- result = winreg_set_printer_secdesc(p->mem_ctx, b,
+ result = winreg_set_printer_secdesc(tmp_ctx, b,
printer,
new_secdesc);
- done:
+done:
+ talloc_free(tmp_ctx);
return result;
}
@@ -6285,18 +6317,24 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
DATA_BLOB buffer;
WERROR result = WERR_OK;
struct dcerpc_binding_handle *b;
+ TALLOC_CTX *tmp_ctx;
- result = winreg_printer_binding_handle(mem_ctx,
+ tmp_ctx = talloc_new(mem_ctx);
+ if (!tmp_ctx) {
+ return WERR_NOMEM;
+ }
+
+ result = winreg_printer_binding_handle(tmp_ctx,
session_info,
msg_ctx,
&b);
if (!W_ERROR_IS_OK(result)) {
- return result;
+ goto done;
}
if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
- push_reg_sz(mem_ctx, &buffer, printer->drivername);
- winreg_set_printer_dataex(mem_ctx, b,
+ push_reg_sz(tmp_ctx, &buffer, printer->drivername);
+ winreg_set_printer_dataex(tmp_ctx, b,
printer->sharename,
SPOOL_DSSPOOLER_KEY,
SPOOL_REG_DRIVERNAME,
@@ -6315,8 +6353,8 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
}
if (force_update || !strequal(printer->comment, old_printer->comment)) {
- push_reg_sz(mem_ctx, &buffer, printer->comment);
- winreg_set_printer_dataex(mem_ctx, b,
+ push_reg_sz(tmp_ctx, &buffer, printer->comment);
+ winreg_set_printer_dataex(tmp_ctx, b,
printer->sharename,
SPOOL_DSSPOOLER_KEY,
SPOOL_REG_DESCRIPTION,
@@ -6332,8 +6370,8 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
}
if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
- push_reg_sz(mem_ctx, &buffer, printer->sharename);
- winreg_set_printer_dataex(mem_ctx, b,
+ push_reg_sz(tmp_ctx, &buffer, printer->sharename);
+ winreg_set_printer_dataex(tmp_ctx, b,
printer->sharename,
SPOOL_DSSPOOLER_KEY,
SPOOL_REG_PRINTSHARENAME,
@@ -6359,8 +6397,8 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
p = printer->printername;
}
- push_reg_sz(mem_ctx, &buffer, p);
- winreg_set_printer_dataex(mem_ctx, b,
+ push_reg_sz(tmp_ctx, &buffer, p);
+ winreg_set_printer_dataex(tmp_ctx, b,
printer->sharename,
SPOOL_DSSPOOLER_KEY,
SPOOL_REG_PRINTERNAME,
@@ -6375,8 +6413,8 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
}
if (force_update || !strequal(printer->portname, old_printer->portname)) {
- push_reg_sz(mem_ctx, &buffer, printer->portname);
- winreg_set_printer_dataex(mem_ctx, b,
+ push_reg_sz(tmp_ctx, &buffer, printer->portname);
+ winreg_set_printer_dataex(tmp_ctx, b,
printer->sharename,
SPOOL_DSSPOOLER_KEY,
SPOOL_REG_PORTNAME,
@@ -6392,8 +6430,8 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
}
if (force_update || !strequal(printer->location, old_printer->location)) {
- push_reg_sz(mem_ctx, &buffer, printer->location);
- winreg_set_printer_dataex(mem_ctx, b,
+ push_reg_sz(tmp_ctx, &buffer, printer->location);
+ winreg_set_printer_dataex(tmp_ctx, b,
printer->sharename,
SPOOL_DSSPOOLER_KEY,
SPOOL_REG_LOCATION,
@@ -6410,8 +6448,8 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
}
if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
- push_reg_sz(mem_ctx, &buffer, printer->sepfile);
- winreg_set_printer_dataex(mem_ctx, b,
+ push_reg_sz(tmp_ctx, &buffer, printer->sepfile);
+ winreg_set_printer_dataex(tmp_ctx, b,
printer->sharename,
SPOOL_DSSPOOLER_KEY,
SPOOL_REG_PRINTSEPARATORFILE,
@@ -6428,9 +6466,9 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
}
if (force_update || printer->starttime != old_printer->starttime) {
- buffer = data_blob_talloc(mem_ctx, NULL, 4);
+ buffer = data_blob_talloc(tmp_ctx, NULL, 4);
SIVAL(buffer.data, 0, printer->starttime);
- winreg_set_printer_dataex(mem_ctx, b,
+ winreg_set_printer_dataex(tmp_ctx, b,
printer->sharename,
SPOOL_DSSPOOLER_KEY,
SPOOL_REG_PRINTSTARTTIME,
@@ -6440,9 +6478,9 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
}
if (force_update || printer->untiltime != old_printer->untiltime) {
- buffer = data_blob_talloc(mem_ctx, NULL, 4);
+ buffer = data_blob_talloc(tmp_ctx, NULL, 4);
SIVAL(buffer.data, 0, printer->untiltime);
- winreg_set_printer_dataex(mem_ctx, b,
+ winreg_set_printer_dataex(tmp_ctx, b,
printer->sharename,
SPOOL_DSSPOOLER_KEY,
SPOOL_REG_PRINTENDTIME,
@@ -6452,9 +6490,9 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
}
if (force_update || printer->priority != old_printer->priority) {
- buffer = data_blob_talloc(mem_ctx, NULL, 4);
+ buffer = data_blob_talloc(tmp_ctx, NULL, 4);
SIVAL(buffer.data, 0, printer->priority);
- winreg_set_printer_dataex(mem_ctx, b,
+ winreg_set_printer_dataex(tmp_ctx, b,
printer->sharename,
SPOOL_DSSPOOLER_KEY,
SPOOL_REG_PRIORITY,
@@ -6464,10 +6502,10 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
}
if (force_update || printer->attributes != old_printer->attributes) {
- buffer = data_blob_talloc(mem_ctx, NULL, 4);
+ buffer = data_blob_talloc(tmp_ctx, NULL, 4);
SIVAL(buffer.data, 0, (printer->attributes &
PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
- winreg_set_printer_dataex(mem_ctx, b,
+ winreg_set_printer_dataex(tmp_ctx, b,
printer->sharename,
SPOOL_DSSPOOLER_KEY,
SPOOL_REG_PRINTKEEPPRINTEDJOBS,
@@ -6488,8 +6526,8 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
default:
spooling = "unknown";
}
- push_reg_sz(mem_ctx, &buffer, spooling);
- winreg_set_printer_dataex(mem_ctx, b,
+ push_reg_sz(tmp_ctx, &buffer, spooling);
+ winreg_set_printer_dataex(tmp_ctx, b,
printer->sharename,
SPOOL_DSSPOOLER_KEY,
SPOOL_REG_PRINTSPOOLING,
@@ -6498,8 +6536,8 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
buffer.length);
}
- push_reg_sz(mem_ctx, &buffer, lp_netbios_name());
- winreg_set_printer_dataex(mem_ctx, b,
+ push_reg_sz(tmp_ctx, &buffer, lp_netbios_name());
+ winreg_set_printer_dataex(tmp_ctx, b,
printer->sharename,
SPOOL_DSSPOOLER_KEY,
SPOOL_REG_SHORTSERVERNAME,
@@ -6509,17 +6547,17 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
dnsdomname = get_mydnsfullname();
if (dnsdomname != NULL && dnsdomname[0] != '\0') {
- longname = talloc_strdup(mem_ctx, dnsdomname);
+ longname = talloc_strdup(tmp_ctx, dnsdomname);
} else {
- longname = talloc_strdup(mem_ctx, lp_netbios_name());
+ longname = talloc_strdup(tmp_ctx, lp_netbios_name());
}
if (longname == NULL) {
result = WERR_NOMEM;
goto done;
}
- push_reg_sz(mem_ctx, &buffer, longname);
- winreg_set_printer_dataex(mem_ctx, b,
+ push_reg_sz(tmp_ctx, &buffer, longname);
+ winreg_set_printer_dataex(tmp_ctx, b,
printer->sharename,
SPOOL_DSSPOOLER_KEY,
SPOOL_REG_SERVERNAME,
@@ -6527,10 +6565,10 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
buffer.data,
buffer.length);
- uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
+ uncname = talloc_asprintf(tmp_ctx, "\\\\%s\\%s",
lp_netbios_name(), printer->sharename);
- push_reg_sz(mem_ctx, &buffer, uncname);
- winreg_set_printer_dataex(mem_ctx, b,
+ push_reg_sz(tmp_ctx, &buffer, uncname);
+ winreg_set_printer_dataex(tmp_ctx, b,
printer->sharename,
SPOOL_DSSPOOLER_KEY,
SPOOL_REG_UNCNAME,
@@ -6539,6 +6577,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
buffer.length);
done:
+ talloc_free(tmp_ctx);
return result;
}
@@ -7336,11 +7375,17 @@ static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
uint32_t num_drivers;
const char **drivers;
struct dcerpc_binding_handle *b;
+ TALLOC_CTX *tmp_ctx = NULL;
*count_p = 0;
*info_p = NULL;
- result = winreg_printer_binding_handle(mem_ctx,
+ tmp_ctx = talloc_new(mem_ctx);
+ if (!tmp_ctx) {
+ return WERR_NOMEM;
+ }
+
+ result = winreg_printer_binding_handle(tmp_ctx,
session_info,
msg_ctx,
&b);
@@ -7349,7 +7394,7 @@ static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
}
for (version=0; version<DRIVER_MAX_VERSION; version++) {
- result = winreg_get_driver_list(mem_ctx, b,
+ result = winreg_get_driver_list(tmp_ctx, b,
architecture, version,
&num_drivers, &drivers);
if (!W_ERROR_IS_OK(result)) {
@@ -7360,7 +7405,7 @@ static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
num_drivers, architecture, version));
if (num_drivers != 0) {
- info = talloc_realloc(mem_ctx, info,
+ info = talloc_realloc(tmp_ctx, info,
union spoolss_DriverInfo,
count + num_drivers);
if (!info) {
@@ -7374,7 +7419,7 @@ static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
for (i = 0; i < num_drivers; i++) {
DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
- result = winreg_get_driver(mem_ctx, b,
+ result = winreg_get_driver(tmp_ctx, b,
architecture, drivers[i],
version, &driver);
if (!W_ERROR_IS_OK(result)) {
@@ -7426,18 +7471,14 @@ static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
TALLOC_FREE(drivers);
}
- out:
- TALLOC_FREE(drivers);
-
- if (!W_ERROR_IS_OK(result)) {
- TALLOC_FREE(info);
- return result;
+out:
+ if (W_ERROR_IS_OK(result)) {
+ *info_p = talloc_move(mem_ctx, &info);
+ *count_p = count;
}
- *info_p = info;
- *count_p = count;
-
- return WERR_OK;
+ talloc_free(tmp_ctx);
+ return result;
}
/****************************************************************************
@@ -8538,6 +8579,7 @@ WERROR _spoolss_AddForm(struct pipes_struct *p,
WERROR status = WERR_OK;
struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
struct dcerpc_binding_handle *b;
+ TALLOC_CTX *tmp_ctx = NULL;
DEBUG(5,("_spoolss_AddForm\n"));
@@ -8570,18 +8612,22 @@ WERROR _spoolss_AddForm(struct pipes_struct *p,
return WERR_INVALID_PARAM;
}
- status = winreg_printer_binding_handle(p->mem_ctx,
+ tmp_ctx = talloc_new(p->mem_ctx);
+ if (!tmp_ctx) {
+ return WERR_NOMEM;
+ }
+
+ status = winreg_printer_binding_handle(tmp_ctx,
get_session_info_system(),
p->msg_ctx,
&b);
if (!W_ERROR_IS_OK(status)) {
- return status;
+ goto done;
}
- status = winreg_printer_addform1(p->mem_ctx, b,
- form);
+ status = winreg_printer_addform1(tmp_ctx, b, form);
if (!W_ERROR_IS_OK(status)) {
- return status;
+ goto done;
}
/*
@@ -8589,16 +8635,16 @@ WERROR _spoolss_AddForm(struct pipes_struct *p,
*/
if (Printer->printer_type == SPLHND_PRINTER) {
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
- return WERR_BADFID;
+ status = WERR_BADFID;
+ goto done;
}
- status = winreg_printer_update_changeid(p->mem_ctx, b,
+ status = winreg_printer_update_changeid(tmp_ctx, b,
lp_const_servicename(snum));
- if (!W_ERROR_IS_OK(status)) {
- return status;
- }
}
+done:
+ talloc_free(tmp_ctx);
return status;
}
@@ -8614,6 +8660,7 @@ WERROR _spoolss_DeleteForm(struct pipes_struct *p,
int snum = -1;
WERROR status = WERR_OK;
struct dcerpc_binding_handle *b;
+ TALLOC_CTX *tmp_ctx = NULL;
DEBUG(5,("_spoolss_DeleteForm\n"));
@@ -8634,18 +8681,22 @@ WERROR _spoolss_DeleteForm(struct pipes_struct *p,
return WERR_ACCESS_DENIED;
}
- status = winreg_printer_binding_handle(p->mem_ctx,
+ tmp_ctx = talloc_new(p->mem_ctx);
+ if (!tmp_ctx) {
+ return WERR_NOMEM;
+ }
+
+ status = winreg_printer_binding_handle(tmp_ctx,
get_session_info_system(),
p->msg_ctx,
&b);
if (!W_ERROR_IS_OK(status)) {
- return status;
+ goto done;
}
- status = winreg_printer_deleteform1(p->mem_ctx, b,
- form_name);
+ status = winreg_printer_deleteform1(tmp_ctx, b, form_name);
if (!W_ERROR_IS_OK(status)) {
- return status;
+ goto done;
}
/*
@@ -8653,16 +8704,16 @@ WERROR _spoolss_DeleteForm(struct pipes_struct *p,
*/
if (Printer->printer_type == SPLHND_PRINTER) {
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
- return WERR_BADFID;
+ status = WERR_BADFID;
+ goto done;
}
- status = winreg_printer_update_changeid(p->mem_ctx, b,
+ status = winreg_printer_update_changeid(tmp_ctx, b,
lp_const_servicename(snum));
- if (!W_ERROR_IS_OK(status)) {
- return status;
- }
}
+done:
+ talloc_free(tmp_ctx);
return status;
}
@@ -8678,6 +8729,7 @@ WERROR _spoolss_SetForm(struct pipes_struct *p,
int snum = -1;
WERROR status = WERR_OK;
struct dcerpc_binding_handle *b;
+ TALLOC_CTX *tmp_ctx = NULL;
struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
@@ -8703,19 +8755,24 @@ WERROR _spoolss_SetForm(struct pipes_struct *p,
return WERR_ACCESS_DENIED;
}
- status = winreg_printer_binding_handle(p->mem_ctx,
+ tmp_ctx = talloc_new(p->mem_ctx);
+ if (!tmp_ctx) {
+ return WERR_NOMEM;
+ }
+
+ status = winreg_printer_binding_handle(tmp_ctx,
get_session_info_system(),
p->msg_ctx,
&b);
if (!W_ERROR_IS_OK(status)) {
- return status;
+ goto done;
}
- status = winreg_printer_setform1(p->mem_ctx, b,
+ status = winreg_printer_setform1(tmp_ctx, b,
form_name,
form);
if (!W_ERROR_IS_OK(status)) {
- return status;
+ goto done;
}
/*
@@ -8723,16 +8780,16 @@ WERROR _spoolss_SetForm(struct pipes_struct *p,
*/
if (Printer->printer_type == SPLHND_PRINTER) {
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
- return WERR_BADFID;
+ status = WERR_BADFID;
+ goto done;
}
- status = winreg_printer_update_changeid(p->mem_ctx, b,
+ status = winreg_printer_update_changeid(tmp_ctx, b,
lp_const_servicename(snum));
- if (!W_ERROR_IS_OK(status)) {
- return status;
- }
}
+done:
+ talloc_free(tmp_ctx);
return status;
}
@@ -9284,6 +9341,7 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
uint8_t *val_data = NULL;
uint32_t val_size = 0;
struct dcerpc_binding_handle *b;
+ TALLOC_CTX *tmp_ctx;
DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
@@ -9295,6 +9353,11 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
*r->out.needed = 0;
*r->out.type = REG_NONE;
+ tmp_ctx = talloc_new(p->mem_ctx);
+ if (!tmp_ctx) {
+ return WERR_NOMEM;
+ }
+
if (!Printer) {
DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
OUR_HANDLE(r->in.handle)));
@@ -9302,24 +9365,30 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
goto done;
}
+ /* check to see if the keyname is valid */
+ if (!strlen(r->in.key_name)) {
+ result = WERR_INVALID_PARAM;
+ goto done;
+ }
+
/* Is the handle to a printer or to the server? */
if (Printer->printer_type == SPLHND_SERVER) {
union spoolss_PrinterData data;
- result = getprinterdata_printer_server(p->mem_ctx,
+ result = getprinterdata_printer_server(tmp_ctx,
r->in.value_name,
r->out.type,
&data);
if (!W_ERROR_IS_OK(result)) {
- return result;
+ goto done;
}
- result = push_spoolss_PrinterData(p->mem_ctx, &blob,
+ result = push_spoolss_PrinterData(tmp_ctx, &blob,
*r->out.type, &data);
if (!W_ERROR_IS_OK(result)) {
- return result;
+ goto done;
}
*r->out.needed = blob.length;
@@ -9328,25 +9397,22 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
memcpy(r->out.data, blob.data, blob.length);
}
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
+ result = WERR_OK;
+ goto done;
}
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
- return WERR_BADFID;
+ result = WERR_BADFID;
+ goto done;
}
printer = lp_const_servicename(snum);
- /* check to see if the keyname is valid */
- if (!strlen(r->in.key_name)) {
- return WERR_INVALID_PARAM;
- }
-
- result = winreg_printer_binding_handle(p->mem_ctx,
+ result = winreg_printer_binding_handle(tmp_ctx,
get_session_info_system(),
p->msg_ctx,
&b);
if (!W_ERROR_IS_OK(result)) {
- return result;
+ goto done;
}
/* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
@@ -9357,11 +9423,11 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
if (r->in.offered >= *r->out.needed) {
uint32_t changeid = 0;
- result = winreg_printer_get_changeid(p->mem_ctx, b,
+ result = winreg_printer_get_changeid(tmp_ctx, b,
printer,
&changeid);
if (!W_ERROR_IS_OK(result)) {
- return result;
+ goto done;
}
SIVAL(r->out.data, 0, changeid);
@@ -9370,7 +9436,7 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
goto done;
}
- result = winreg_get_printer_dataex(p->mem_ctx, b,
+ result = winreg_get_printer_dataex(tmp_ctx, b,
printer,
r->in.key_name,
r->in.value_name,
@@ -9378,7 +9444,7 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
&val_data,
&val_size);
if (!W_ERROR_IS_OK(result)) {
- return result;
+ goto done;
}
*r->out.needed = val_size;
@@ -9388,11 +9454,15 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
memcpy(r->out.data, val_data, val_size);
}
- done:
- /* retain type when returning WERR_MORE_DATA */
- r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
+done:
+ /* NOTE: do not replace type when returning WERR_MORE_DATA */
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
+ if (W_ERROR_IS_OK(result)) {
+ result = SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
+ }
+
+ talloc_free(tmp_ctx);
+ return result;
}
/****************************************************************
@@ -9408,6 +9478,7 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
char *oid_string;
struct dcerpc_binding_handle *b;
+ TALLOC_CTX *tmp_ctx;
DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
@@ -9444,19 +9515,24 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
return WERR_ACCESS_DENIED;
}
- result = winreg_printer_binding_handle(p->mem_ctx,
+ tmp_ctx = talloc_new(p->mem_ctx);
+ if (!tmp_ctx) {
+ return WERR_NOMEM;
+ }
+
+ result = winreg_printer_binding_handle(tmp_ctx,
get_session_info_system(),
p->msg_ctx,
&b);
if (!W_ERROR_IS_OK(result)) {
- return result;
+ goto done;
}
- result = winreg_get_printer(Printer, b,
+ result = winreg_get_printer(tmp_ctx, b,
lp_servicename(snum),
&pinfo2);
if (!W_ERROR_IS_OK(result)) {
- return result;
+ goto done;
}
/* check for OID in valuename */
@@ -9469,7 +9545,7 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
/* save the registry data */
- result = winreg_set_printer_dataex(p->mem_ctx, b,
+ result = winreg_set_printer_dataex(tmp_ctx, b,
pinfo2->sharename,
r->in.key_name,
r->in.value_name,
@@ -9480,7 +9556,7 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
if (W_ERROR_IS_OK(result)) {
/* save the OID if one was specified */
if (oid_string) {
- char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
+ char *str = talloc_asprintf(tmp_ctx, "%s\\%s",
r->in.key_name, SPOOL_OID_KEY);
if (!str) {
result = WERR_NOMEM;
@@ -9493,7 +9569,7 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
* previous set_printer_dataex() call. I have no idea if
* this is right. --jerry
*/
- winreg_set_printer_dataex(p->mem_ctx, b,
+ winreg_set_printer_dataex(tmp_ctx, b,
pinfo2->sharename,
str,
r->in.value_name,
@@ -9502,13 +9578,13 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
strlen(oid_string) + 1);
}
- result = winreg_printer_update_changeid(p->mem_ctx, b,
+ result = winreg_printer_update_changeid(tmp_ctx, b,
lp_const_servicename(snum));
}
done:
- talloc_free(pinfo2);
+ talloc_free(tmp_ctx);
return result;
}
@@ -9639,6 +9715,7 @@ WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
WERROR status;
const char *printer;
struct dcerpc_binding_handle *b;
+ TALLOC_CTX *tmp_ctx;
DEBUG(5,("_spoolss_DeletePrinterKey\n"));
@@ -9664,23 +9741,30 @@ WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
printer = lp_const_servicename(snum);
- status = winreg_printer_binding_handle(p->mem_ctx,
+ tmp_ctx = talloc_new(p->mem_ctx);
+ if (!tmp_ctx) {
+ return WERR_NOMEM;
+ }
+
+ status = winreg_printer_binding_handle(tmp_ctx,
get_session_info_system(),
p->msg_ctx,
&b);
if (!W_ERROR_IS_OK(status)) {
- return status;
+ goto done;
}
/* delete the key and all subkeys */
- status = winreg_delete_printer_key(p->mem_ctx, b,
+ status = winreg_delete_printer_key(tmp_ctx, b,
printer,
r->in.key_name);
if (W_ERROR_IS_OK(status)) {
- status = winreg_printer_update_changeid(p->mem_ctx, b,
+ status = winreg_printer_update_changeid(tmp_ctx, b,
printer);
}
+done:
+ talloc_free(tmp_ctx);
return status;
}