From 99e03bee7ae5de37280a4e571caf36b0a8553fae Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 22 Jul 2011 11:59:41 -0400 Subject: 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 --- source3/rpc_server/spoolss/srv_spoolss_nt.c | 400 +++++++++++++++++----------- 1 file 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; versionin.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; } -- cgit