spoolss: handle SetPrinter for info level 4
authorGarming Sam <garming@catalyst.net.nz>
Mon, 17 Nov 2014 23:41:30 +0000 (12:41 +1300)
committerJeremy Allison <jra@samba.org>
Tue, 1 Sep 2015 01:33:13 +0000 (03:33 +0200)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=10770

Signed-off-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Tue Sep  1 03:33:13 CEST 2015 on sn-devel-104

source3/rpc_server/spoolss/srv_spoolss_nt.c

index 0639b87a559bfd91616b5cccbf95826f66122cd1..2778ba8ca87fc7930af3d719d7062ce97fa11dd0 100644 (file)
@@ -7015,6 +7015,89 @@ WERROR _spoolss_SetPrinter(struct pipes_struct *p,
                case 3:
                        return update_printer_sec(r->in.handle, p,
                                                  r->in.secdesc_ctr);
+               case 4: {
+                       struct spoolss_PrinterInfo2 *old_printer;
+                       struct spoolss_SetPrinterInfo2 *set_old_printer;
+                       struct spoolss_SetPrinterInfoCtr *info_ctr;
+                       struct dcerpc_binding_handle *b;
+                       int snum;
+                       TALLOC_CTX *tmp_ctx;
+
+                       tmp_ctx = talloc_new(p->mem_ctx);
+                       if (tmp_ctx == NULL) {
+                               return WERR_NOMEM;
+                       }
+
+                       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
+                               TALLOC_FREE(tmp_ctx);
+                               return WERR_BADFID;
+                       }
+
+                       result = winreg_printer_binding_handle(tmp_ctx,
+                                                              get_session_info_system(),
+                                                              p->msg_ctx,
+                                                              &b);
+                       if (!W_ERROR_IS_OK(result)) {
+                               TALLOC_FREE(tmp_ctx);
+                               return result;
+                       }
+
+                       result = winreg_get_printer(tmp_ctx, b,
+                                                   lp_const_servicename(snum),
+                                                   &old_printer);
+                       if (!W_ERROR_IS_OK(result)) {
+                               TALLOC_FREE(tmp_ctx);
+                               return WERR_BADFID;
+                       }
+
+                       old_printer->servername = talloc_strdup(tmp_ctx, r->in.info_ctr->info.info4->servername);
+                       if (old_printer->servername == NULL) {
+                               TALLOC_FREE(tmp_ctx);
+                               return WERR_NOMEM;
+                       }
+
+                       old_printer->printername = talloc_strdup(tmp_ctx, r->in.info_ctr->info.info4->printername);
+                       if (old_printer->printername == NULL) {
+                               TALLOC_FREE(tmp_ctx);
+                               return WERR_NOMEM;
+                       }
+
+                       old_printer->attributes = r->in.info_ctr->info.info4->attributes;
+
+                       set_old_printer = talloc_zero(tmp_ctx, struct spoolss_SetPrinterInfo2);
+                       if (set_old_printer == NULL) {
+                               TALLOC_FREE(tmp_ctx);
+                               return WERR_NOMEM;
+                       }
+
+                       spoolss_printerinfo2_to_setprinterinfo2(old_printer, set_old_printer);
+
+                       info_ctr = talloc_zero(tmp_ctx, struct spoolss_SetPrinterInfoCtr);
+                       if (info_ctr == NULL) {
+                               TALLOC_FREE(tmp_ctx);
+                               return WERR_NOMEM;
+                       }
+
+                       info_ctr->level = 2;
+                       info_ctr->info.info2 = set_old_printer;
+
+                       result = update_printer(p, r->in.handle,
+                                               info_ctr,
+                                               r->in.devmode_ctr->devmode);
+
+                       if (!W_ERROR_IS_OK(result)) {
+                               TALLOC_FREE(tmp_ctx);
+                               return result;
+                       }
+
+                       if (r->in.secdesc_ctr->sd) {
+                               result = update_printer_sec(r->in.handle, p,
+                                                           r->in.secdesc_ctr);
+                       }
+
+                       TALLOC_FREE(tmp_ctx);
+                       return result;
+               }
                case 7:
                        return publish_or_unpublish_printer(p, r->in.handle,
                                                            r->in.info_ctr->info.info7);