s3-spoolss: Added a winreg_update_printer function.
authorAndreas Schneider <asn@samba.org>
Thu, 15 Apr 2010 15:53:39 +0000 (17:53 +0200)
committerGünther Deschner <gd@samba.org>
Fri, 23 Apr 2010 14:31:04 +0000 (16:31 +0200)
Signed-off-by: Günther Deschner <gd@samba.org>
source3/rpc_server/srv_spoolss_util.c
source3/rpc_server/srv_spoolss_util.h

index f06b30bcc7cb611be9e74ca182df8450b6a096f9..4b2bab2876c8865fdefcb93039e47cbd499defc3 100644 (file)
@@ -1210,6 +1210,315 @@ static WERROR winreg_printer_ver_to_dword(const char *str, uint64_t *data)
  Public winreg function for spoolss
 ********************************************************************/
 
+WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
+                            struct auth_serversupplied_info *server_info,
+                            uint32_t info2_mask,
+                            struct spoolss_SetPrinterInfo2 *info2,
+                            struct spoolss_DeviceMode *devmode,
+                            struct security_descriptor *secdesc)
+{
+       uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       struct rpc_pipe_client *winreg_pipe = NULL;
+       struct policy_handle hive_hnd, key_hnd;
+       enum ndr_err_code ndr_err;
+       DATA_BLOB blob;
+       char *path;
+       WERROR result = WERR_OK;
+       TALLOC_CTX *tmp_ctx;
+
+       tmp_ctx = talloc_new(mem_ctx);
+       if (tmp_ctx == NULL) {
+               return WERR_NOMEM;
+       }
+
+       path = winreg_printer_data_keyname(tmp_ctx, info2->sharename);
+       if (path == NULL) {
+               TALLOC_FREE(tmp_ctx);
+               return WERR_NOMEM;
+       }
+
+       ZERO_STRUCT(hive_hnd);
+       ZERO_STRUCT(key_hnd);
+
+       result = winreg_printer_openkey(tmp_ctx,
+                                       server_info,
+                                       &winreg_pipe,
+                                       path,
+                                       "",
+                                       true,
+                                       access_mask,
+                                       &hive_hnd,
+                                       &key_hnd);
+       if (!W_ERROR_IS_OK(result)) {
+               DEBUG(0, ("winreg_update_printer: Could not open key %s: %s\n",
+                       path, win_errstr(result)));
+               goto done;
+       }
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_ATTRIBUTES) {
+               result = winreg_printer_write_dword(tmp_ctx,
+                                                   winreg_pipe,
+                                                   &key_hnd,
+                                                   "Attributes",
+                                                   info2->attributes);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+#if 0
+       if (info2_mask & SPOOLSS_PRINTER_INFO_AVERAGEPPM) {
+               result = winreg_printer_write_dword(tmp_ctx,
+                                                   winreg_pipe,
+                                                   &key_hnd,
+                                                   "AveragePpm",
+                                                   info2->attributes);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+#endif
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_COMMENT) {
+               result = winreg_printer_write_sz(tmp_ctx,
+                                                winreg_pipe,
+                                                &key_hnd,
+                                                "Description",
+                                                info2->comment);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_DATATYPE) {
+               result = winreg_printer_write_sz(tmp_ctx,
+                                                winreg_pipe,
+                                                &key_hnd,
+                                                "Datatype",
+                                                info2->datatype);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY) {
+               result = winreg_printer_write_dword(tmp_ctx,
+                                                   winreg_pipe,
+                                                   &key_hnd,
+                                                   "Default Priority",
+                                                   info2->defaultpriority);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_DEVMODE) {
+               ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, NULL, devmode,
+                               (ndr_push_flags_fn_t) ndr_push_spoolss_DeviceMode);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       DEBUG(0, ("winreg_update_printer: Failed to marshall device mode\n"));
+                       result = WERR_NOMEM;
+                       goto done;
+               }
+
+               result = winreg_printer_write_binary(tmp_ctx,
+                                                    winreg_pipe,
+                                                    &key_hnd,
+                                                    "Default DevMode",
+                                                    blob);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_LOCATION) {
+               result = winreg_printer_write_sz(tmp_ctx,
+                                                winreg_pipe,
+                                                &key_hnd,
+                                                "Location",
+                                                info2->location);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_PARAMETERS) {
+               result = winreg_printer_write_sz(tmp_ctx,
+                                                winreg_pipe,
+                                                &key_hnd,
+                                                "Parameters",
+                                                info2->parameters);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_PORTNAME) {
+               result = winreg_printer_write_sz(tmp_ctx,
+                                                winreg_pipe,
+                                                &key_hnd,
+                                                "Port",
+                                                info2->portname);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTERNAME) {
+               /*
+                * in addprinter: no servername and the printer is the name
+                * in setprinter: servername is \\server
+                *                and printer is \\server\\printer
+                *
+                * Samba manages only local printers.
+                * we currently don't support things like i
+                * path=\\other_server\printer
+                *
+                * We only store the printername, not \\server\printername
+                */
+               const char *p = strrchr(info2->printername, '\\');
+               if (p == NULL) {
+                       p = info2->printername;
+               } else {
+                       p++;
+               }
+               result = winreg_printer_write_sz(tmp_ctx,
+                                                winreg_pipe,
+                                                &key_hnd,
+                                                "Name",
+                                                p);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTPROCESSOR) {
+               result = winreg_printer_write_sz(tmp_ctx,
+                                                winreg_pipe,
+                                                &key_hnd,
+                                                "Print Processor",
+                                                info2->printprocessor);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_PRIORITY) {
+               result = winreg_printer_write_dword(tmp_ctx,
+                                                   winreg_pipe,
+                                                   &key_hnd,
+                                                   "Priority",
+                                                   info2->priority);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_SECDESC) {
+               /*
+                * We need a security descriptor, if it isn't specified by
+                * AddPrinter{Ex} then create a default descriptor.
+                */
+               if (secdesc == NULL) {
+                       secdesc = winreg_printer_create_default_secdesc(tmp_ctx);
+               }
+               ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, NULL, secdesc,
+                               (ndr_push_flags_fn_t) ndr_push_security_descriptor);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       DEBUG(0, ("winreg_update_printer: Failed to marshall security descriptor\n"));
+                       result = WERR_NOMEM;
+                       goto done;
+               }
+
+               result = winreg_printer_write_binary(tmp_ctx,
+                                                    winreg_pipe,
+                                                    &key_hnd,
+                                                    "Security",
+                                                    blob);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_SEPFILE) {
+               result = winreg_printer_write_sz(tmp_ctx,
+                                                winreg_pipe,
+                                                &key_hnd,
+                                                "Separator File",
+                                                info2->sepfile);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_SHARENAME) {
+               result = winreg_printer_write_sz(tmp_ctx,
+                                                winreg_pipe,
+                                                &key_hnd,
+                                                "Share Name",
+                                                info2->sharename);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_STARTTIME) {
+               result = winreg_printer_write_dword(tmp_ctx,
+                                                   winreg_pipe,
+                                                   &key_hnd,
+                                                   "StartTime",
+                                                   info2->starttime);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_STATUS) {
+               result = winreg_printer_write_dword(tmp_ctx,
+                                                   winreg_pipe,
+                                                   &key_hnd,
+                                                   "Status",
+                                                   info2->status);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2_mask & SPOOLSS_PRINTER_INFO_UNTILTIME) {
+               result = winreg_printer_write_dword(tmp_ctx,
+                                                   winreg_pipe,
+                                                   &key_hnd,
+                                                   "UntilTime",
+                                                   info2->untiltime);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       result = winreg_printer_write_dword(tmp_ctx,
+                                           winreg_pipe,
+                                           &key_hnd,
+                                           "ChangeID",
+                                           winreg_printer_rev_changeid());
+       if (!W_ERROR_IS_OK(result)) {
+               goto done;
+       }
+
+       result = WERR_OK;
+done:
+       if (winreg_pipe != NULL) {
+               if (is_valid_policy_hnd(&key_hnd)) {
+                       rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &key_hnd, NULL);
+               }
+               if (is_valid_policy_hnd(&hive_hnd)) {
+                       rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &hive_hnd, NULL);
+               }
+       }
+
+       TALLOC_FREE(tmp_ctx);
+       return result;
+}
+
 /* Set printer data over the winreg pipe. */
 WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx,
                                 struct auth_serversupplied_info *server_info,
index 35a47283e2faf2fa0557e8972fa4389b9e4ffbeb..ede313fc3fba6a1f9abd4c77f2c688cd7b6778df 100644 (file)
 #ifndef _SRV_SPOOLSS_UITL_H
 #define _SRV_SPOOLSS_UITL_H
 
+
+enum spoolss_PrinterInfo2Mask {
+       SPOOLSS_PRINTER_INFO_ATTRIBUTES      = (int)(0x00000001),
+       SPOOLSS_PRINTER_INFO_AVERAGEPPM      = (int)(0x00000002),
+       SPOOLSS_PRINTER_INFO_CJOBS           = (int)(0x00000004),
+       SPOOLSS_PRINTER_INFO_COMMENT         = (int)(0x00000008),
+       SPOOLSS_PRINTER_INFO_DATATYPE        = (int)(0x00000010),
+       SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY = (int)(0x00000020),
+       SPOOLSS_PRINTER_INFO_DEVMODE         = (int)(0x00000040),
+       SPOOLSS_PRINTER_INFO_DRIVERNAME      = (int)(0x00000080),
+       SPOOLSS_PRINTER_INFO_LOCATION        = (int)(0x00000100),
+       SPOOLSS_PRINTER_INFO_NAME            = (int)(0x00000200),
+       SPOOLSS_PRINTER_INFO_PARAMETERS      = (int)(0x00000400),
+       SPOOLSS_PRINTER_INFO_PORTNAME        = (int)(0x00000800),
+       SPOOLSS_PRINTER_INFO_PRINTERNAME     = (int)(0x00001000),
+       SPOOLSS_PRINTER_INFO_PRINTPROCESSOR  = (int)(0x00002000),
+       SPOOLSS_PRINTER_INFO_PRIORITY        = (int)(0x00004000),
+       SPOOLSS_PRINTER_INFO_SECDESC         = (int)(0x00008000),
+       SPOOLSS_PRINTER_INFO_SEPFILE         = (int)(0x00010000),
+       SPOOLSS_PRINTER_INFO_SERVERNAME      = (int)(0x00020000),
+       SPOOLSS_PRINTER_INFO_SHARENAME       = (int)(0x00040000),
+       SPOOLSS_PRINTER_INFO_STARTTIME       = (int)(0x00080000),
+       SPOOLSS_PRINTER_INFO_STATUS          = (int)(0x00100000),
+       SPOOLSS_PRINTER_INFO_UNTILTIME       = (int)(0x00200000)
+};
+
+#define SPOOLSS_PRINTER_INFO_ALL SPOOLSS_PRINTER_INFO_ATTRIBUTES      | \
+                                 SPOOLSS_PRINTER_INFO_AVERAGEPPM      | \
+                                 SPOOLSS_PRINTER_INFO_CJOBS           | \
+                                 SPOOLSS_PRINTER_INFO_COMMENT         | \
+                                 SPOOLSS_PRINTER_INFO_DATATYPE        | \
+                                 SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY | \
+                                 SPOOLSS_PRINTER_INFO_DEVMODE         | \
+                                 SPOOLSS_PRINTER_INFO_DRIVERNAME      | \
+                                 SPOOLSS_PRINTER_INFO_LOCATION        | \
+                                 SPOOLSS_PRINTER_INFO_NAME            | \
+                                 SPOOLSS_PRINTER_INFO_PARAMETERS      | \
+                                 SPOOLSS_PRINTER_INFO_PORTNAME        | \
+                                 SPOOLSS_PRINTER_INFO_PRINTERNAME     | \
+                                 SPOOLSS_PRINTER_INFO_PRINTPROCESSOR  | \
+                                 SPOOLSS_PRINTER_INFO_PRIORITY        | \
+                                 SPOOLSS_PRINTER_INFO_SECDESC         | \
+                                 SPOOLSS_PRINTER_INFO_SEPFILE         | \
+                                 SPOOLSS_PRINTER_INFO_SERVERNAME      | \
+                                 SPOOLSS_PRINTER_INFO_SHARENAME       | \
+                                 SPOOLSS_PRINTER_INFO_STARTTIME       | \
+                                 SPOOLSS_PRINTER_INFO_STATUS          | \
+                                 SPOOLSS_PRINTER_INFO_UNTILTIME
+
+/**
+ * @internal
+ *
+ * @brief Update the information of a printer in the registry.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  server_info The server supplied session info.
+ *
+ * @param[in]  info2_mask A bitmask which defines which values should be set.
+ *
+ * @param[in]  info2    A SetPrinterInfo2 structure with the data to set.
+ *
+ * @param[in]  devmode  A device mode structure with the data to set.
+ *
+ * @param[in]  secdesc  A security descriptor structure with the data to set.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
+                            struct auth_serversupplied_info *server_info,
+                            uint32_t info2_mask,
+                            struct spoolss_SetPrinterInfo2 *info2,
+                            struct spoolss_DeviceMode *devmode,
+                            struct security_descriptor *secdesc);
+
 /**
  * @internal
  *