s3-spoolss: Added a delete_printer_key function using the winreg pipe.
authorAndreas Schneider <asn@samba.org>
Tue, 6 Apr 2010 15:01:15 +0000 (17:01 +0200)
committerGünther Deschner <gd@samba.org>
Wed, 7 Apr 2010 13:16:52 +0000 (15:16 +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 2f13cf49f87708f828976ccf3394512e773c04b6..d4c4f91ceb516f1cfade59d9103056045208dc55 100644 (file)
@@ -483,6 +483,107 @@ static WERROR winreg_printer_enumkeys(TALLOC_CTX *mem_ctx,
        return result;
 }
 
+/**
+ * @internal
+ *
+ * @brief A function to delete a key and its subkeys recurively.
+ *
+ * @param[in]  mem_ctx  The memory context to use.
+ *
+ * @param[in]  pipe_handle The pipe handle for the rpc connection.
+ *
+ * @param[in]  hive_handle A opened hive handle to the key.
+ *
+ * @param[in]  access_mask The access mask to access the key.
+ *
+ * @param[in]  key      The key to delete
+ *
+ * @return              WERR_OK on success, the corresponding DOS error
+ *                      code if something gone wrong.
+ */
+static WERROR winreg_printer_delete_subkeys(TALLOC_CTX *mem_ctx,
+                                           struct rpc_pipe_client *pipe_handle,
+                                           struct policy_handle *hive_handle,
+                                           uint32_t access_mask,
+                                           const char *key)
+{
+       const char **subkeys = NULL;
+       uint32_t num_subkeys = 0;
+       struct policy_handle key_hnd;
+       struct winreg_String wkey;
+       WERROR result = WERR_OK;
+       NTSTATUS status;
+       uint32_t i;
+
+       ZERO_STRUCT(key_hnd);
+       wkey.name = key;
+
+       DEBUG(2, ("winreg_printer_delete_subkeys: delete key %s\n", key));
+       /* open the key */
+       status = rpccli_winreg_OpenKey(pipe_handle,
+                                      mem_ctx,
+                                      hive_handle,
+                                      wkey,
+                                      0,
+                                      access_mask,
+                                      &key_hnd,
+                                      &result);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n",
+                         wkey.name, nt_errstr(status)));
+               if (!W_ERROR_IS_OK(result)) {
+                       return result;
+               }
+               return ntstatus_to_werror(status);
+       }
+
+       result = winreg_printer_enumkeys(mem_ctx,
+                                        pipe_handle,
+                                        &key_hnd,
+                                        &num_subkeys,
+                                        &subkeys);
+       if (!W_ERROR_IS_OK(result)) {
+               goto done;
+       }
+
+       for (i = 0; i < num_subkeys; i++) {
+               /* create key + subkey */
+               char *subkey = talloc_asprintf(mem_ctx, "%s\\%s", key, subkeys[i]);
+               if (subkey == NULL) {
+                       goto done;
+               }
+
+               DEBUG(2, ("winreg_printer_delete_subkeys: delete subkey %s\n", subkey));
+               result = winreg_printer_delete_subkeys(mem_ctx,
+                                                      pipe_handle,
+                                                      hive_handle,
+                                                      access_mask,
+                                                      subkey);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (is_valid_policy_hnd(&key_hnd)) {
+               rpccli_winreg_CloseKey(pipe_handle, mem_ctx, &key_hnd, NULL);
+       }
+
+       wkey.name = key;
+
+       status = rpccli_winreg_DeleteKey(pipe_handle,
+                                        mem_ctx,
+                                        hive_handle,
+                                        wkey,
+                                        &result);
+
+done:
+       if (is_valid_policy_hnd(&key_hnd)) {
+               rpccli_winreg_CloseKey(pipe_handle, mem_ctx, &key_hnd, NULL);
+       }
+
+       return result;
+}
+
 /********************************************************************
  Public winreg function for spoolss
 ********************************************************************/
@@ -888,3 +989,79 @@ done:
        TALLOC_FREE(tmp_ctx);
        return result;
 }
+
+/* Delete a key with subkeys of a given printer. */
+WERROR winreg_delete_printer_key(struct pipes_struct *p,
+                                const char *printer,
+                                const char *key)
+{
+       uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       struct rpc_pipe_client *winreg_pipe = NULL;
+       struct policy_handle hive_hnd, key_hnd;
+       char *keyname;
+       WERROR result;
+       TALLOC_CTX *tmp_ctx;
+
+       tmp_ctx = talloc_new(p->mem_ctx);
+       if (tmp_ctx == NULL) {
+               return WERR_NOMEM;
+       }
+
+       result = winreg_printer_openkey(tmp_ctx,
+                                       p->server_info,
+                                       &winreg_pipe,
+                                       printer,
+                                       key,
+                                       false,
+                                       access_mask,
+                                       &hive_hnd,
+                                       &key_hnd);
+       if (!W_ERROR_IS_OK(result)) {
+               /* key doesn't exist */
+               if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
+                       result = WERR_OK;
+                       goto done;
+               }
+
+               DEBUG(0, ("winreg_delete_printer_key: Could not open key %s: %s\n",
+                         key, win_errstr(result)));
+               goto done;
+       }
+
+       if (is_valid_policy_hnd(&key_hnd)) {
+               rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &key_hnd, NULL);
+       }
+
+       keyname = talloc_asprintf(tmp_ctx,
+                                 "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers\\%s\\%s",
+                                 printer,
+                                 key);
+       if (keyname == NULL) {
+               result = WERR_NOMEM;
+               goto done;
+       }
+
+       result = winreg_printer_delete_subkeys(tmp_ctx,
+                                              winreg_pipe,
+                                              &hive_hnd,
+                                              access_mask,
+                                              keyname);
+       if (!W_ERROR_IS_OK(result)) {
+               DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
+                         key, win_errstr(result)));
+               goto done;
+       }
+
+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;
+}
index 21e3d3581be9dab3e31a9442bade67548b6977ff..0ef57bca3d814847dc6ac6392724d69b04f5e340 100644 (file)
@@ -152,4 +152,22 @@ WERROR winreg_enum_printer_key(struct pipes_struct *p,
                               uint32_t *pnum_subkeys,
                               const char ***psubkeys);
 
+/**
+ * @internal
+ *
+ * @brief Delete a key with subkeys of a given printer.
+ *
+ * @param[in]  p        The pipes structure to be able to open a new pipe.
+ *
+ * @param[in]  printer  The printer name.
+ *
+ * @param[in]  key      The key of the printer to delete.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+WERROR winreg_delete_printer_key(struct pipes_struct *p,
+                                const char *printer,
+                                const char *key);
+
 #endif /* _SRV_SPOOLSS_UITL_H */