2 * Unix SMB/CIFS implementation.
4 * SPOOLSS RPC Pipe server / winreg client routines
6 * Copyright (c) 2010 Andreas Schneider <asn@samba.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 #include "srv_spoolss_util.h"
24 #include "../librpc/gen_ndr/srv_winreg.h"
25 #include "../librpc/gen_ndr/cli_winreg.h"
27 #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
28 #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
29 #define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print"
30 #define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
32 /********************************************************************
33 static helper functions
34 ********************************************************************/
39 * @brief Connect to the interal winreg server and open the given printer key.
41 * The function will create the needed subkeys if they don't exist.
43 * @param[in] mem_ctx The memory context to use.
45 * @param[in] server_info The supplied server info.
47 * @param[out] winreg_pipe A pointer for the winreg rpc client pipe.
49 * @param[in] path The path to the key to open.
51 * @param[in] key The key to open.
53 * @param[in] create_key Set to true if the key should be created if it
56 * @param[in] access_mask The access mask to open the key.
58 * @param[out] hive_handle A policy handle for the opened hive.
60 * @param[out] key_handle A policy handle for the opened key.
62 * @return WERR_OK on success, the corresponding DOS error
63 * code if something gone wrong.
65 static WERROR
winreg_printer_openkey(TALLOC_CTX
*mem_ctx
,
66 struct auth_serversupplied_info
*server_info
,
67 struct rpc_pipe_client
**winreg_pipe
,
72 struct policy_handle
*hive_handle
,
73 struct policy_handle
*key_handle
)
75 struct rpc_pipe_client
*pipe_handle
;
76 struct winreg_String wkey
, wkeyclass
;
79 WERROR result
= WERR_OK
;
81 /* create winreg connection */
82 status
= rpc_pipe_open_internal(mem_ctx
,
83 &ndr_table_winreg
.syntax_id
,
87 if (!NT_STATUS_IS_OK(status
)) {
88 DEBUG(0, ("winreg_printer_openkey: Could not connect to winreg_pipe: %s\n",
90 return ntstatus_to_werror(status
);
93 status
= rpccli_winreg_OpenHKLM(pipe_handle
,
99 if (!NT_STATUS_IS_OK(status
)) {
100 DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
102 talloc_free(pipe_handle
);
103 if (!W_ERROR_IS_OK(result
)) {
106 return ntstatus_to_werror(status
);
110 keyname
= talloc_asprintf(mem_ctx
, "%s\\%s", path
, key
);
112 keyname
= talloc_strdup(mem_ctx
, path
);
114 if (keyname
== NULL
) {
115 talloc_free(pipe_handle
);
123 enum winreg_CreateAction action
= REG_ACTION_NONE
;
125 ZERO_STRUCT(wkeyclass
);
128 status
= rpccli_winreg_CreateKey(pipe_handle
,
140 case REG_ACTION_NONE
:
141 DEBUG(8, ("winreg_printer_openkey:createkey did nothing -- huh?\n"));
143 case REG_CREATED_NEW_KEY
:
144 DEBUG(8, ("winreg_printer_openkey: createkey created %s\n", keyname
));
146 case REG_OPENED_EXISTING_KEY
:
147 DEBUG(8, ("winreg_printer_openkey: createkey opened existing %s\n", keyname
));
151 status
= rpccli_winreg_OpenKey(pipe_handle
,
160 if (!NT_STATUS_IS_OK(status
)) {
161 talloc_free(pipe_handle
);
162 if (!W_ERROR_IS_OK(result
)) {
165 return ntstatus_to_werror(status
);
168 *winreg_pipe
= pipe_handle
;
174 * @brief Create the registry keyname for the given printer.
176 * @param[in] mem_ctx The memory context to use.
178 * @param[in] printer The name of the printer to get the registry key.
180 * @return The registry key or NULL on error.
182 static char *winreg_printer_data_keyname(TALLOC_CTX
*mem_ctx
, const char *printer
) {
183 return talloc_asprintf(mem_ctx
, "%s\\%s", TOP_LEVEL_PRINT_PRINTERS_KEY
, printer
);
189 * @brief Enumerate values of an opened key handle and retrieve the data.
191 * @param[in] mem_ctx The memory context to use.
193 * @param[in] pipe_handle The pipe handle for the rpc connection.
195 * @param[in] key_hnd The opened key handle.
197 * @param[out] pnum_values A pointer to store he number of values found.
199 * @param[out] pnum_values A pointer to store the number of values we found.
201 * @return WERR_OK on success, the corresponding DOS error
202 * code if something gone wrong.
204 static WERROR
winreg_printer_enumvalues(TALLOC_CTX
*mem_ctx
,
205 struct rpc_pipe_client
*pipe_handle
,
206 struct policy_handle
*key_hnd
,
207 uint32_t *pnum_values
,
208 struct spoolss_PrinterEnumValues
**penum_values
)
211 uint32_t num_subkeys
, max_subkeylen
, max_classlen
;
212 uint32_t num_values
, max_valnamelen
, max_valbufsize
;
213 uint32_t secdescsize
;
215 NTTIME last_changed_time
;
216 struct winreg_String classname
;
218 struct spoolss_PrinterEnumValues
*enum_values
;
220 WERROR result
= WERR_OK
;
223 tmp_ctx
= talloc_new(mem_ctx
);
224 if (tmp_ctx
== NULL
) {
228 ZERO_STRUCT(classname
);
230 status
= rpccli_winreg_QueryInfoKey(pipe_handle
,
243 if (!NT_STATUS_IS_OK(status
)) {
244 DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n",
246 if (!W_ERROR_IS_OK(result
)) {
249 result
= ntstatus_to_werror(status
);
253 if (num_values
== 0) {
255 TALLOC_FREE(tmp_ctx
);
259 enum_values
= TALLOC_ARRAY(tmp_ctx
, struct spoolss_PrinterEnumValues
, num_values
);
260 if (enum_values
== NULL
) {
265 for (i
= 0; i
< num_values
; i
++) {
266 struct spoolss_PrinterEnumValues val
;
267 struct winreg_ValNameBuf name_buf
;
268 enum winreg_Type type
= REG_NONE
;
269 uint8_t *data
= NULL
;
275 name_buf
.size
= max_valnamelen
+ 2;
278 data_size
= max_valbufsize
;
279 data
= (uint8_t *) TALLOC(tmp_ctx
, data_size
);
282 status
= rpccli_winreg_EnumValue(pipe_handle
,
292 if (W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
) ) {
294 status
= NT_STATUS_OK
;
298 if (!NT_STATUS_IS_OK(status
)) {
299 DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n",
301 if (!W_ERROR_IS_OK(result
)) {
304 result
= ntstatus_to_werror(status
);
308 if (name_buf
.name
== NULL
) {
309 result
= WERR_INVALID_PARAMETER
;
313 val
.value_name
= talloc_strdup(enum_values
, name_buf
.name
);
314 if (val
.value_name
== NULL
) {
318 val
.value_name_len
= strlen_m_term(val
.value_name
) * 2;
321 val
.data_length
= data_size
;
322 if (val
.data_length
) {
323 val
.data
= talloc(enum_values
, DATA_BLOB
);
324 if (val
.data
== NULL
) {
328 *val
.data
= data_blob_talloc(enum_values
, data
, data_size
);
331 enum_values
[i
] = val
;
334 *pnum_values
= num_values
;
336 *penum_values
= talloc_move(mem_ctx
, &enum_values
);
342 TALLOC_FREE(tmp_ctx
);
349 * @brief Enumerate subkeys of an opened key handle and get the names.
351 * @param[in] mem_ctx The memory context to use.
353 * @param[in] pipe_handle The pipe handle for the rpc connection.
355 * @param[in] key_hnd The opened key handle.
357 * @param[in] pnum_subkeys A pointer to store the number of found subkeys.
359 * @param[in] psubkeys A pointer to an array to store the found names of
362 * @return WERR_OK on success, the corresponding DOS error
363 * code if something gone wrong.
365 static WERROR
winreg_printer_enumkeys(TALLOC_CTX
*mem_ctx
,
366 struct rpc_pipe_client
*pipe_handle
,
367 struct policy_handle
*key_hnd
,
368 uint32_t *pnum_subkeys
,
369 const char ***psubkeys
)
372 const char **subkeys
;
373 uint32_t num_subkeys
, max_subkeylen
, max_classlen
;
374 uint32_t num_values
, max_valnamelen
, max_valbufsize
;
376 NTTIME last_changed_time
;
377 uint32_t secdescsize
;
378 struct winreg_String classname
;
379 WERROR result
= WERR_OK
;
382 tmp_ctx
= talloc_new(mem_ctx
);
383 if (tmp_ctx
== NULL
) {
387 ZERO_STRUCT(classname
);
389 status
= rpccli_winreg_QueryInfoKey(pipe_handle
,
402 if (!NT_STATUS_IS_OK(status
)) {
403 DEBUG(0, ("winreg_printer_enumkeys: Could not query info: %s\n",
405 if (!W_ERROR_IS_OK(result
)) {
408 result
= ntstatus_to_werror(status
);
412 subkeys
= talloc_zero_array(tmp_ctx
, const char *, num_subkeys
+ 2);
413 if (subkeys
== NULL
) {
418 if (num_subkeys
== 0) {
419 subkeys
[0] = talloc_strdup(subkeys
, "");
420 if (subkeys
[0] == NULL
) {
426 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
429 TALLOC_FREE(tmp_ctx
);
433 for (i
= 0; i
< num_subkeys
; i
++) {
437 struct winreg_StringBuf class_buf
;
438 struct winreg_StringBuf name_buf
;
442 class_buf
.size
= max_classlen
+ 2;
443 class_buf
.length
= 0;
446 name_buf
.size
= max_subkeylen
+ 2;
449 ZERO_STRUCT(modtime
);
451 status
= rpccli_winreg_EnumKey(pipe_handle
,
459 if (W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
) ) {
461 status
= NT_STATUS_OK
;
465 if (!NT_STATUS_IS_OK(status
)) {
466 DEBUG(0, ("winreg_printer_enumkeys: Could not enumerate keys: %s\n",
468 if (!W_ERROR_IS_OK(result
)) {
471 result
= ntstatus_to_werror(status
);
475 if (name_buf
.name
== NULL
) {
476 result
= WERR_INVALID_PARAMETER
;
480 name
= talloc_strdup(subkeys
, name_buf
.name
);
489 *pnum_subkeys
= num_subkeys
;
491 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
495 TALLOC_FREE(tmp_ctx
);
502 * @brief A function to delete a key and its subkeys recurively.
504 * @param[in] mem_ctx The memory context to use.
506 * @param[in] pipe_handle The pipe handle for the rpc connection.
508 * @param[in] hive_handle A opened hive handle to the key.
510 * @param[in] access_mask The access mask to access the key.
512 * @param[in] key The key to delete
514 * @return WERR_OK on success, the corresponding DOS error
515 * code if something gone wrong.
517 static WERROR
winreg_printer_delete_subkeys(TALLOC_CTX
*mem_ctx
,
518 struct rpc_pipe_client
*pipe_handle
,
519 struct policy_handle
*hive_handle
,
520 uint32_t access_mask
,
523 const char **subkeys
= NULL
;
524 uint32_t num_subkeys
= 0;
525 struct policy_handle key_hnd
;
526 struct winreg_String wkey
;
527 WERROR result
= WERR_OK
;
531 ZERO_STRUCT(key_hnd
);
534 DEBUG(2, ("winreg_printer_delete_subkeys: delete key %s\n", key
));
536 status
= rpccli_winreg_OpenKey(pipe_handle
,
544 if (!NT_STATUS_IS_OK(status
)) {
545 DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n",
546 wkey
.name
, nt_errstr(status
)));
547 if (!W_ERROR_IS_OK(result
)) {
550 return ntstatus_to_werror(status
);
553 result
= winreg_printer_enumkeys(mem_ctx
,
558 if (!W_ERROR_IS_OK(result
)) {
562 for (i
= 0; i
< num_subkeys
; i
++) {
563 /* create key + subkey */
564 char *subkey
= talloc_asprintf(mem_ctx
, "%s\\%s", key
, subkeys
[i
]);
565 if (subkey
== NULL
) {
569 DEBUG(2, ("winreg_printer_delete_subkeys: delete subkey %s\n", subkey
));
570 result
= winreg_printer_delete_subkeys(mem_ctx
,
575 if (!W_ERROR_IS_OK(result
)) {
580 if (is_valid_policy_hnd(&key_hnd
)) {
581 rpccli_winreg_CloseKey(pipe_handle
, mem_ctx
, &key_hnd
, NULL
);
586 status
= rpccli_winreg_DeleteKey(pipe_handle
,
593 if (is_valid_policy_hnd(&key_hnd
)) {
594 rpccli_winreg_CloseKey(pipe_handle
, mem_ctx
, &key_hnd
, NULL
);
600 /********************************************************************
601 Public winreg function for spoolss
602 ********************************************************************/
604 /* Set printer data over the winreg pipe. */
605 WERROR
winreg_set_printer_dataex(struct pipes_struct
*p
,
609 enum winreg_Type type
,
613 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
614 struct rpc_pipe_client
*winreg_pipe
= NULL
;
615 struct policy_handle hive_hnd
, key_hnd
;
616 struct winreg_String wvalue
;
618 WERROR result
= WERR_OK
;
622 tmp_ctx
= talloc_new(p
->mem_ctx
);
623 if (tmp_ctx
== NULL
) {
627 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
629 TALLOC_FREE(tmp_ctx
);
633 ZERO_STRUCT(hive_hnd
);
634 ZERO_STRUCT(key_hnd
);
636 DEBUG(8, ("winreg_set_printer_dataex: Open printer key %s, value %s, access_mask: 0x%05x for [%s]\n",
637 key
, value
, access_mask
, printer
));
638 result
= winreg_printer_openkey(tmp_ctx
,
647 if (!W_ERROR_IS_OK(result
)) {
648 DEBUG(0, ("winreg_set_printer_dataex: Could not open key %s: %s\n",
649 key
, win_errstr(result
)));
654 status
= rpccli_winreg_SetValue(winreg_pipe
,
662 if (!NT_STATUS_IS_OK(status
)) {
663 DEBUG(0, ("winreg_set_printer_dataex: Could not set value %s: %s\n",
664 value
, nt_errstr(status
)));
665 if (!W_ERROR_IS_OK(result
)) {
668 result
= ntstatus_to_werror(status
);
674 if (winreg_pipe
!= NULL
) {
675 if (is_valid_policy_hnd(&key_hnd
)) {
676 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
678 if (is_valid_policy_hnd(&hive_hnd
)) {
679 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
683 TALLOC_FREE(tmp_ctx
);
687 /* Get printer data over a winreg pipe. */
688 WERROR
winreg_get_printer_dataex(struct pipes_struct
*p
,
692 enum winreg_Type
*type
,
696 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
697 struct rpc_pipe_client
*winreg_pipe
= NULL
;
698 struct policy_handle hive_hnd
, key_hnd
;
699 struct winreg_String wvalue
;
700 enum winreg_Type type_in
;
703 uint32_t data_in_size
= 0;
704 uint32_t value_len
= 0;
705 WERROR result
= WERR_OK
;
709 tmp_ctx
= talloc_new(p
->mem_ctx
);
710 if (tmp_ctx
== NULL
) {
714 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
716 TALLOC_FREE(tmp_ctx
);
720 ZERO_STRUCT(hive_hnd
);
721 ZERO_STRUCT(key_hnd
);
723 result
= winreg_printer_openkey(tmp_ctx
,
732 if (!W_ERROR_IS_OK(result
)) {
733 DEBUG(0, ("winreg_get_printer_dataex: Could not open key %s: %s\n",
734 key
, win_errstr(result
)));
741 * call QueryValue once with data == NULL to get the
742 * needed memory size to be allocated, then allocate
743 * data buffer and call again.
745 status
= rpccli_winreg_QueryValue(winreg_pipe
,
754 if (!NT_STATUS_IS_OK(status
)) {
755 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
756 value
, nt_errstr(status
)));
757 if (!W_ERROR_IS_OK(result
)) {
760 result
= ntstatus_to_werror(status
);
764 data_in
= (uint8_t *) TALLOC(tmp_ctx
, data_in_size
);
765 if (data_in
== NULL
) {
771 status
= rpccli_winreg_QueryValue(winreg_pipe
,
780 if (!NT_STATUS_IS_OK(status
)) {
781 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
782 value
, nt_errstr(status
)));
783 if (!W_ERROR_IS_OK(result
)) {
784 result
= ntstatus_to_werror(status
);
790 *data_size
= data_in_size
;
792 *data
= talloc_move(p
->mem_ctx
, &data_in
);
797 if (winreg_pipe
!= NULL
) {
798 if (is_valid_policy_hnd(&key_hnd
)) {
799 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
801 if (is_valid_policy_hnd(&hive_hnd
)) {
802 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
806 TALLOC_FREE(tmp_ctx
);
810 /* Enumerate on the values of a given key and provide the data. */
811 WERROR
winreg_enum_printer_dataex(struct pipes_struct
*p
,
814 uint32_t *pnum_values
,
815 struct spoolss_PrinterEnumValues
**penum_values
)
817 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
818 struct rpc_pipe_client
*winreg_pipe
= NULL
;
819 struct policy_handle hive_hnd
, key_hnd
;
821 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
822 uint32_t num_values
= 0;
824 WERROR result
= WERR_OK
;
828 tmp_ctx
= talloc_new(p
->mem_ctx
);
829 if (tmp_ctx
== NULL
) {
833 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
835 TALLOC_FREE(tmp_ctx
);
839 result
= winreg_printer_openkey(tmp_ctx
,
848 if (!W_ERROR_IS_OK(result
)) {
849 DEBUG(0, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
850 key
, win_errstr(result
)));
854 result
= winreg_printer_enumvalues(tmp_ctx
,
859 if (!W_ERROR_IS_OK(result
)) {
860 DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
861 key
, win_errstr(result
)));
865 *pnum_values
= num_values
;
867 *penum_values
= talloc_move(p
->mem_ctx
, &enum_values
);
872 if (winreg_pipe
!= NULL
) {
873 if (is_valid_policy_hnd(&key_hnd
)) {
874 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
876 if (is_valid_policy_hnd(&hive_hnd
)) {
877 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
881 TALLOC_FREE(tmp_ctx
);
885 /* Delete printer data over a winreg pipe. */
886 WERROR
winreg_delete_printer_dataex(struct pipes_struct
*p
,
891 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
892 struct rpc_pipe_client
*winreg_pipe
= NULL
;
893 struct policy_handle hive_hnd
, key_hnd
;
894 struct winreg_String wvalue
;
896 WERROR result
= WERR_OK
;
901 tmp_ctx
= talloc_new(p
->mem_ctx
);
902 if (tmp_ctx
== NULL
) {
906 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
908 TALLOC_FREE(tmp_ctx
);
912 ZERO_STRUCT(hive_hnd
);
913 ZERO_STRUCT(key_hnd
);
915 result
= winreg_printer_openkey(tmp_ctx
,
924 if (!W_ERROR_IS_OK(result
)) {
925 DEBUG(0, ("winreg_delete_printer_dataex: Could not open key %s: %s\n",
926 key
, win_errstr(result
)));
931 status
= rpccli_winreg_DeleteValue(winreg_pipe
,
936 if (!NT_STATUS_IS_OK(status
)) {
937 DEBUG(0, ("winreg_delete_printer_dataex: Could not delete value %s: %s\n",
938 value
, nt_errstr(status
)));
939 if (!W_ERROR_IS_OK(result
)) {
942 result
= ntstatus_to_werror(status
);
948 if (winreg_pipe
!= NULL
) {
949 if (is_valid_policy_hnd(&key_hnd
)) {
950 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
952 if (is_valid_policy_hnd(&hive_hnd
)) {
953 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
957 TALLOC_FREE(tmp_ctx
);
961 /* Enumerate on the subkeys of a given key and provide the data. */
962 WERROR
winreg_enum_printer_key(struct pipes_struct
*p
,
965 uint32_t *pnum_subkeys
,
966 const char ***psubkeys
)
968 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
969 struct rpc_pipe_client
*winreg_pipe
= NULL
;
970 struct policy_handle hive_hnd
, key_hnd
;
972 const char **subkeys
= NULL
;
973 uint32_t num_subkeys
= -1;
975 WERROR result
= WERR_OK
;
979 tmp_ctx
= talloc_new(p
->mem_ctx
);
980 if (tmp_ctx
== NULL
) {
984 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
986 TALLOC_FREE(tmp_ctx
);
990 ZERO_STRUCT(hive_hnd
);
991 ZERO_STRUCT(key_hnd
);
993 result
= winreg_printer_openkey(tmp_ctx
,
1002 if (!W_ERROR_IS_OK(result
)) {
1003 DEBUG(0, ("winreg_enum_printer_key: Could not open key %s: %s\n",
1004 key
, win_errstr(result
)));
1008 result
= winreg_printer_enumkeys(tmp_ctx
,
1013 if (!W_ERROR_IS_OK(result
)) {
1014 DEBUG(0, ("winreg_enum_printer_key: Could not enumerate subkeys in %s: %s\n",
1015 key
, win_errstr(result
)));
1019 *pnum_subkeys
= num_subkeys
;
1021 *psubkeys
= talloc_move(p
->mem_ctx
, &subkeys
);
1026 if (winreg_pipe
!= NULL
) {
1027 if (is_valid_policy_hnd(&key_hnd
)) {
1028 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1030 if (is_valid_policy_hnd(&hive_hnd
)) {
1031 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1035 TALLOC_FREE(tmp_ctx
);
1039 /* Delete a key with subkeys of a given printer. */
1040 WERROR
winreg_delete_printer_key(struct pipes_struct
*p
,
1041 const char *printer
,
1044 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1045 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1046 struct policy_handle hive_hnd
, key_hnd
;
1050 TALLOC_CTX
*tmp_ctx
;
1052 tmp_ctx
= talloc_new(p
->mem_ctx
);
1053 if (tmp_ctx
== NULL
) {
1057 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
1059 TALLOC_FREE(tmp_ctx
);
1063 result
= winreg_printer_openkey(tmp_ctx
,
1072 if (!W_ERROR_IS_OK(result
)) {
1073 /* key doesn't exist */
1074 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
1079 DEBUG(0, ("winreg_delete_printer_key: Could not open key %s: %s\n",
1080 key
, win_errstr(result
)));
1084 if (is_valid_policy_hnd(&key_hnd
)) {
1085 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1088 keyname
= talloc_asprintf(tmp_ctx
,
1092 if (keyname
== NULL
) {
1093 result
= WERR_NOMEM
;
1097 result
= winreg_printer_delete_subkeys(tmp_ctx
,
1102 if (!W_ERROR_IS_OK(result
)) {
1103 DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
1104 key
, win_errstr(result
)));
1109 if (winreg_pipe
!= NULL
) {
1110 if (is_valid_policy_hnd(&key_hnd
)) {
1111 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1113 if (is_valid_policy_hnd(&hive_hnd
)) {
1114 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1118 TALLOC_FREE(tmp_ctx
);