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 #define EMPTY_STRING ""
33 static const char *empty_string_array
[1] = { NULL
};
34 #define EMPTY_STRING_ARRAY empty_string_array
36 #define CHECK_ERROR(result) \
37 if (W_ERROR_IS_OK(result)) continue; \
38 if (W_ERROR_EQUAL(result, WERR_NOT_FOUND)) result = WERR_OK; \
39 if (!W_ERROR_IS_OK(result)) break
41 /* FLAGS, NAME, with, height, left, top, right, bottom */
42 static const struct spoolss_FormInfo1 builtin_forms1
[] = {
43 { SPOOLSS_FORM_BUILTIN
, "10x11", {0x3e030,0x44368}, {0x0,0x0,0x3e030,0x44368} },
44 { SPOOLSS_FORM_BUILTIN
, "10x14", {0x3e030,0x56d10}, {0x0,0x0,0x3e030,0x56d10} },
45 { SPOOLSS_FORM_BUILTIN
, "11x17", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
46 { SPOOLSS_FORM_BUILTIN
, "12x11", {0x4a724,0x443e1}, {0x0,0x0,0x4a724,0x443e1} },
47 { SPOOLSS_FORM_BUILTIN
, "15x11", {0x5d048,0x44368}, {0x0,0x0,0x5d048,0x44368} },
48 { SPOOLSS_FORM_BUILTIN
, "6 3/4 Envelope", {0x167ab,0x284ec}, {0x0,0x0,0x167ab,0x284ec} },
49 { SPOOLSS_FORM_BUILTIN
, "9x11", {0x37cf8,0x44368}, {0x0,0x0,0x37cf8,0x44368} },
50 { SPOOLSS_FORM_BUILTIN
, "A0", {0xcd528,0x122488},{0x0,0x0,0xcd528,0x122488} },
51 { SPOOLSS_FORM_BUILTIN
, "A1", {0x91050,0xcd528}, {0x0,0x0,0x91050,0xcd528} },
52 { SPOOLSS_FORM_BUILTIN
, "A2", {0x668a0,0x91050}, {0x0,0x0,0x668a0,0x91050} },
53 { SPOOLSS_FORM_BUILTIN
, "A3 Extra Transverse", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
54 { SPOOLSS_FORM_BUILTIN
, "A3 Extra", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
55 { SPOOLSS_FORM_BUILTIN
, "A3 Rotated", {0x668a0,0x48828}, {0x0,0x0,0x668a0,0x48828} },
56 { SPOOLSS_FORM_BUILTIN
, "A3 Transverse", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
57 { SPOOLSS_FORM_BUILTIN
, "A3", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
58 { SPOOLSS_FORM_BUILTIN
, "A4 Extra", {0x397c2,0x4eb16}, {0x0,0x0,0x397c2,0x4eb16} },
59 { SPOOLSS_FORM_BUILTIN
, "A4 Plus", {0x33450,0x50910}, {0x0,0x0,0x33450,0x50910} },
60 { SPOOLSS_FORM_BUILTIN
, "A4 Rotated", {0x48828,0x33450}, {0x0,0x0,0x48828,0x33450} },
61 { SPOOLSS_FORM_BUILTIN
, "A4 Small", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
62 { SPOOLSS_FORM_BUILTIN
, "A4 Transverse", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
63 { SPOOLSS_FORM_BUILTIN
, "A4", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
64 { SPOOLSS_FORM_BUILTIN
, "A5 Extra", {0x2a7b0,0x395f8}, {0x0,0x0,0x2a7b0,0x395f8} },
65 { SPOOLSS_FORM_BUILTIN
, "A5 Rotated", {0x33450,0x24220}, {0x0,0x0,0x33450,0x24220} },
66 { SPOOLSS_FORM_BUILTIN
, "A5 Transverse", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
67 { SPOOLSS_FORM_BUILTIN
, "A5", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
68 { SPOOLSS_FORM_BUILTIN
, "A6 Rotated", {0x24220,0x19a28}, {0x0,0x0,0x24220,0x19a28} },
69 { SPOOLSS_FORM_BUILTIN
, "A6", {0x19a28,0x24220}, {0x0,0x0,0x19a28,0x24220} },
70 { SPOOLSS_FORM_BUILTIN
, "B4 (ISO)", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
71 { SPOOLSS_FORM_BUILTIN
, "B4 (JIS) Rotated", {0x58de0,0x3ebe8}, {0x0,0x0,0x58de0,0x3ebe8} },
72 { SPOOLSS_FORM_BUILTIN
, "B4 (JIS)", {0x3ebe8,0x58de0}, {0x0,0x0,0x3ebe8,0x58de0} },
73 { SPOOLSS_FORM_BUILTIN
, "B5 (ISO) Extra", {0x31128,0x43620}, {0x0,0x0,0x31128,0x43620} },
74 { SPOOLSS_FORM_BUILTIN
, "B5 (JIS) Rotated", {0x3ebe8,0x2c6f0}, {0x0,0x0,0x3ebe8,0x2c6f0} },
75 { SPOOLSS_FORM_BUILTIN
, "B5 (JIS) Transverse", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
76 { SPOOLSS_FORM_BUILTIN
, "B5 (JIS)", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
77 { SPOOLSS_FORM_BUILTIN
, "B6 (JIS) Rotated", {0x2c6f0,0x1f400}, {0x0,0x0,0x2c6f0,0x1f400} },
78 { SPOOLSS_FORM_BUILTIN
, "B6 (JIS)", {0x1f400,0x2c6f0}, {0x0,0x0,0x1f400,0x2c6f0} },
79 { SPOOLSS_FORM_BUILTIN
, "C size sheet", {0x696b8,0x886d0}, {0x0,0x0,0x696b8,0x886d0} },
80 { SPOOLSS_FORM_BUILTIN
, "D size sheet", {0x886d0,0xd2d70}, {0x0,0x0,0x886d0,0xd2d70} },
81 { SPOOLSS_FORM_BUILTIN
, "Double Japan Postcard Rotated", {0x24220,0x30d40}, {0x0,0x0,0x24220,0x30d40} },
82 { SPOOLSS_FORM_BUILTIN
, "E size sheet", {0xd2d70,0x110da0},{0x0,0x0,0xd2d70,0x110da0} },
83 { SPOOLSS_FORM_BUILTIN
, "Envelope #10", {0x19947,0x3ae94}, {0x0,0x0,0x19947,0x3ae94} },
84 { SPOOLSS_FORM_BUILTIN
, "Envelope #11", {0x1be7c,0x40565}, {0x0,0x0,0x1be7c,0x40565} },
85 { SPOOLSS_FORM_BUILTIN
, "Envelope #12", {0x1d74a,0x44368}, {0x0,0x0,0x1d74a,0x44368} },
86 { SPOOLSS_FORM_BUILTIN
, "Envelope #14", {0x1f018,0x47504}, {0x0,0x0,0x1f018,0x47504} },
87 { SPOOLSS_FORM_BUILTIN
, "Envelope #9", {0x18079,0x37091}, {0x0,0x0,0x18079,0x37091} },
88 { SPOOLSS_FORM_BUILTIN
, "Envelope B4", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
89 { SPOOLSS_FORM_BUILTIN
, "Envelope B5", {0x2af80,0x3d090}, {0x0,0x0,0x2af80,0x3d090} },
90 { SPOOLSS_FORM_BUILTIN
, "Envelope B6", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
91 { SPOOLSS_FORM_BUILTIN
, "Envelope C3", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
92 { SPOOLSS_FORM_BUILTIN
, "Envelope C4", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
93 { SPOOLSS_FORM_BUILTIN
, "Envelope C5", {0x278d0,0x37e88}, {0x0,0x0,0x278d0,0x37e88} },
94 { SPOOLSS_FORM_BUILTIN
, "Envelope C6", {0x1bd50,0x278d0}, {0x0,0x0,0x1bd50,0x278d0} },
95 { SPOOLSS_FORM_BUILTIN
, "Envelope C65", {0x1bd50,0x37e88}, {0x0,0x0,0x1bd50,0x37e88} },
96 { SPOOLSS_FORM_BUILTIN
, "Envelope DL", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
97 { SPOOLSS_FORM_BUILTIN
, "Envelope Invite", {0x35b60,0x35b60}, {0x0,0x0,0x35b60,0x35b60} },
98 { SPOOLSS_FORM_BUILTIN
, "Envelope Monarch", {0x18079,0x2e824}, {0x0,0x0,0x18079,0x2e824} },
99 { SPOOLSS_FORM_BUILTIN
, "Envelope", {0x1adb0,0x38270}, {0x0,0x0,0x1adb0,0x38270} },
100 { SPOOLSS_FORM_BUILTIN
, "Executive", {0x2cf56,0x411cc}, {0x0,0x0,0x2cf56,0x411cc} },
101 { SPOOLSS_FORM_BUILTIN
, "Folio", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
102 { SPOOLSS_FORM_BUILTIN
, "German Legal Fanfold", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
103 { SPOOLSS_FORM_BUILTIN
, "German Std Fanfold", {0x34b5c,0x4a6a0}, {0x0,0x0,0x34b5c,0x4a6a0} },
104 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Chou #3 Rotated", {0x395f8,0x1d4c0}, {0x0,0x0,0x395f8,0x1d4c0} },
105 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Chou #4 Rotated", {0x320c8,0x15f90}, {0x0,0x0,0x320c8,0x15f90} },
106 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Kaku #2 Rotated", {0x510e0,0x3a980}, {0x0,0x0,0x510e0,0x3a980} },
107 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Kaku #3 Rotated", {0x43a08,0x34bc0}, {0x0,0x0,0x43a08,0x34bc0} },
108 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope You #4 Rotated", {0x395f8,0x19a28}, {0x0,0x0,0x395f8,0x19a28} },
109 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope You #4", {0x19a28,0x395f8}, {0x0,0x0,0x19a28,0x395f8} },
110 { SPOOLSS_FORM_BUILTIN
, "Japanese Double Postcard", {0x30d40,0x24220}, {0x0,0x0,0x30d40,0x24220} },
111 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Chou #3", {0x1d4c0,0x395f8}, {0x0,0x0,0x1d4c0,0x395f8} },
112 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Chou #4", {0x15f90,0x320c8}, {0x0,0x0,0x15f90,0x320c8} },
113 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Kaku #2", {0x3a980,0x510e0}, {0x0,0x0,0x3a980,0x510e0} },
114 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Kaku #3", {0x34bc0,0x43a08}, {0x0,0x0,0x34bc0,0x43a08} },
115 { SPOOLSS_FORM_BUILTIN
, "Japanese Postcard Rotated", {0x24220,0x186a0}, {0x0,0x0,0x24220,0x186a0} },
116 { SPOOLSS_FORM_BUILTIN
, "Japanese Postcard", {0x186a0,0x24220}, {0x0,0x0,0x186a0,0x24220} },
117 { SPOOLSS_FORM_BUILTIN
, "Ledger", {0x696b8,0x44368}, {0x0,0x0,0x696b8,0x44368} },
118 { SPOOLSS_FORM_BUILTIN
, "Legal Extra", {0x3ae94,0x5d048}, {0x0,0x0,0x3ae94,0x5d048} },
119 { SPOOLSS_FORM_BUILTIN
, "Legal", {0x34b5c,0x56d10}, {0x0,0x0,0x34b5c,0x56d10} },
120 { SPOOLSS_FORM_BUILTIN
, "Letter Extra Transverse", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
121 { SPOOLSS_FORM_BUILTIN
, "Letter Extra", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
122 { SPOOLSS_FORM_BUILTIN
, "Letter Plus", {0x34b5c,0x4eb16}, {0x0,0x0,0x34b5c,0x4eb16} },
123 { SPOOLSS_FORM_BUILTIN
, "Letter Rotated", {0x44368,0x34b5c}, {0x0,0x0,0x44368,0x34b5c} },
124 { SPOOLSS_FORM_BUILTIN
, "Letter Small", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
125 { SPOOLSS_FORM_BUILTIN
, "Letter Transverse", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
126 { SPOOLSS_FORM_BUILTIN
, "Letter", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
127 { SPOOLSS_FORM_BUILTIN
, "Note", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
128 { SPOOLSS_FORM_BUILTIN
, "PRC 16K Rotated", {0x3f7a0,0x2de60}, {0x0,0x0,0x3f7a0,0x2de60} },
129 { SPOOLSS_FORM_BUILTIN
, "PRC 16K", {0x2de60,0x3f7a0}, {0x0,0x0,0x2de60,0x3f7a0} },
130 { SPOOLSS_FORM_BUILTIN
, "PRC 32K Rotated", {0x2cec0,0x1fbd0}, {0x0,0x0,0x2cec0,0x1fbd0} },
131 { SPOOLSS_FORM_BUILTIN
, "PRC 32K", {0x1fbd0,0x2cec0}, {0x0,0x0,0x1fbd0,0x2cec0} },
132 { SPOOLSS_FORM_BUILTIN
, "PRC 32K(Big) Rotated", {0x318f8,0x222e0}, {0x0,0x0,0x318f8,0x222e0} },
133 { SPOOLSS_FORM_BUILTIN
, "PRC 32K(Big)", {0x222e0,0x318f8}, {0x0,0x0,0x222e0,0x318f8} },
134 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #1 Rotated", {0x28488,0x18e70}, {0x0,0x0,0x28488,0x18e70} },
135 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #1", {0x18e70,0x28488}, {0x0,0x0,0x18e70,0x28488} },
136 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #10 Rotated", {0x6fd10,0x4f1a0}, {0x0,0x0,0x6fd10,0x4f1a0} },
137 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #10", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
138 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #2 Rotated", {0x2af80,0x18e70}, {0x0,0x0,0x2af80,0x18e70} },
139 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #2", {0x18e70,0x2af80}, {0x0,0x0,0x18e70,0x2af80} },
140 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #3 Rotated", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
141 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #3", {0x1e848,0x2af80}, {0x0,0x0,0x1e848,0x2af80} },
142 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #4 Rotated", {0x32c80,0x1adb0}, {0x0,0x0,0x32c80,0x1adb0} },
143 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #4", {0x1adb0,0x32c80}, {0x0,0x0,0x1adb0,0x32c80} },
144 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #5 Rotated", {0x35b60,0x1adb0}, {0x0,0x0,0x35b60,0x1adb0} },
145 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #5", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
146 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #6 Rotated", {0x38270,0x1d4c0}, {0x0,0x0,0x38270,0x1d4c0} },
147 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #6", {0x1d4c0,0x38270}, {0x0,0x0,0x1d4c0,0x38270} },
148 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #7 Rotated", {0x38270,0x27100}, {0x0,0x0,0x38270,0x27100} },
149 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #7", {0x27100,0x38270}, {0x0,0x0,0x27100,0x38270} },
150 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #8 Rotated", {0x4b708,0x1d4c0}, {0x0,0x0,0x4b708,0x1d4c0} },
151 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #8", {0x1d4c0,0x4b708}, {0x0,0x0,0x1d4c0,0x4b708} },
152 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #9 Rotated", {0x4f1a0,0x37e88}, {0x0,0x0,0x4f1a0,0x37e88} },
153 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #9", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
154 { SPOOLSS_FORM_BUILTIN
, "Quarto", {0x347d8,0x43238}, {0x0,0x0,0x347d8,0x43238} },
155 { SPOOLSS_FORM_BUILTIN
, "Reserved48", {0x1,0x1}, {0x0,0x0,0x1,0x1} },
156 { SPOOLSS_FORM_BUILTIN
, "Reserved49", {0x1,0x1}, {0x0,0x0,0x1,0x1} },
157 { SPOOLSS_FORM_BUILTIN
, "Statement", {0x221b4,0x34b5c}, {0x0,0x0,0x221b4,0x34b5c} },
158 { SPOOLSS_FORM_BUILTIN
, "Super A", {0x376b8,0x56ea0}, {0x0,0x0,0x376b8,0x56ea0} },
159 { SPOOLSS_FORM_BUILTIN
, "Super B", {0x4a768,0x76e58}, {0x0,0x0,0x4a768,0x76e58} },
160 { SPOOLSS_FORM_BUILTIN
, "Tabloid Extra", {0x4a6a0,0x6f9f0}, {0x0,0x0,0x4a6a0,0x6f9f0} },
161 { SPOOLSS_FORM_BUILTIN
, "Tabloid", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
162 { SPOOLSS_FORM_BUILTIN
, "US Std Fanfold", {0x5c3e1,0x44368}, {0x0,0x0,0x5c3e1,0x44368} }
165 /********************************************************************
166 static helper functions
167 ********************************************************************/
169 /****************************************************************************
170 Update the changeid time.
171 ****************************************************************************/
175 * @brief Update the ChangeID time of a printer.
177 * This is SO NASTY as some drivers need this to change, others need it
178 * static. This value will change every second, and I must hope that this
179 * is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
182 * @return The ChangeID.
184 static uint32_t winreg_printer_rev_changeid(void)
188 get_process_uptime(&tv
);
191 /* Return changeid as msec since spooler restart */
192 return tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
195 * This setting seems to work well but is too untested
196 * to replace the above calculation. Left in for experiementation
197 * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002)
199 return tv
.tv_sec
* 10 + tv
.tv_usec
/ 100000;
206 * @brief Connect to the interal winreg server and open the given printer key.
208 * The function will create the needed subkeys if they don't exist.
210 * @param[in] mem_ctx The memory context to use.
212 * @param[in] server_info The supplied server info.
214 * @param[out] winreg_pipe A pointer for the winreg rpc client pipe.
216 * @param[in] path The path to the key to open.
218 * @param[in] key The key to open.
220 * @param[in] create_key Set to true if the key should be created if it
223 * @param[in] access_mask The access mask to open the key.
225 * @param[out] hive_handle A policy handle for the opened hive.
227 * @param[out] key_handle A policy handle for the opened key.
229 * @return WERR_OK on success, the corresponding DOS error
230 * code if something gone wrong.
232 static WERROR
winreg_printer_openkey(TALLOC_CTX
*mem_ctx
,
233 struct auth_serversupplied_info
*server_info
,
234 struct rpc_pipe_client
**winreg_pipe
,
238 uint32_t access_mask
,
239 struct policy_handle
*hive_handle
,
240 struct policy_handle
*key_handle
)
242 struct rpc_pipe_client
*pipe_handle
;
243 struct winreg_String wkey
, wkeyclass
;
246 WERROR result
= WERR_OK
;
248 /* create winreg connection */
249 status
= rpc_pipe_open_internal(mem_ctx
,
250 &ndr_table_winreg
.syntax_id
,
254 if (!NT_STATUS_IS_OK(status
)) {
255 DEBUG(0, ("winreg_printer_openkey: Could not connect to winreg_pipe: %s\n",
257 return ntstatus_to_werror(status
);
260 status
= rpccli_winreg_OpenHKLM(pipe_handle
,
266 if (!NT_STATUS_IS_OK(status
)) {
267 DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
269 talloc_free(pipe_handle
);
270 if (!W_ERROR_IS_OK(result
)) {
273 return ntstatus_to_werror(status
);
277 keyname
= talloc_asprintf(mem_ctx
, "%s\\%s", path
, key
);
279 keyname
= talloc_strdup(mem_ctx
, path
);
281 if (keyname
== NULL
) {
282 talloc_free(pipe_handle
);
290 enum winreg_CreateAction action
= REG_ACTION_NONE
;
292 ZERO_STRUCT(wkeyclass
);
295 status
= rpccli_winreg_CreateKey(pipe_handle
,
307 case REG_ACTION_NONE
:
308 DEBUG(8, ("winreg_printer_openkey:createkey did nothing -- huh?\n"));
310 case REG_CREATED_NEW_KEY
:
311 DEBUG(8, ("winreg_printer_openkey: createkey created %s\n", keyname
));
313 case REG_OPENED_EXISTING_KEY
:
314 DEBUG(8, ("winreg_printer_openkey: createkey opened existing %s\n", keyname
));
318 status
= rpccli_winreg_OpenKey(pipe_handle
,
327 if (!NT_STATUS_IS_OK(status
)) {
328 talloc_free(pipe_handle
);
329 if (!W_ERROR_IS_OK(result
)) {
332 return ntstatus_to_werror(status
);
335 *winreg_pipe
= pipe_handle
;
341 * @brief Create the registry keyname for the given printer.
343 * @param[in] mem_ctx The memory context to use.
345 * @param[in] printer The name of the printer to get the registry key.
347 * @return The registry key or NULL on error.
349 static char *winreg_printer_data_keyname(TALLOC_CTX
*mem_ctx
, const char *printer
) {
350 return talloc_asprintf(mem_ctx
, "%s\\%s", TOP_LEVEL_PRINT_PRINTERS_KEY
, printer
);
356 * @brief Enumerate values of an opened key handle and retrieve the data.
358 * @param[in] mem_ctx The memory context to use.
360 * @param[in] pipe_handle The pipe handle for the rpc connection.
362 * @param[in] key_hnd The opened key handle.
364 * @param[out] pnum_values A pointer to store he number of values found.
366 * @param[out] pnum_values A pointer to store the number of values we found.
368 * @return WERR_OK on success, the corresponding DOS error
369 * code if something gone wrong.
371 static WERROR
winreg_printer_enumvalues(TALLOC_CTX
*mem_ctx
,
372 struct rpc_pipe_client
*pipe_handle
,
373 struct policy_handle
*key_hnd
,
374 uint32_t *pnum_values
,
375 struct spoolss_PrinterEnumValues
**penum_values
)
378 uint32_t num_subkeys
, max_subkeylen
, max_classlen
;
379 uint32_t num_values
, max_valnamelen
, max_valbufsize
;
380 uint32_t secdescsize
;
382 NTTIME last_changed_time
;
383 struct winreg_String classname
;
385 struct spoolss_PrinterEnumValues
*enum_values
;
387 WERROR result
= WERR_OK
;
390 tmp_ctx
= talloc_new(mem_ctx
);
391 if (tmp_ctx
== NULL
) {
395 ZERO_STRUCT(classname
);
397 status
= rpccli_winreg_QueryInfoKey(pipe_handle
,
410 if (!NT_STATUS_IS_OK(status
)) {
411 DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n",
413 if (!W_ERROR_IS_OK(result
)) {
416 result
= ntstatus_to_werror(status
);
420 if (num_values
== 0) {
422 TALLOC_FREE(tmp_ctx
);
426 enum_values
= TALLOC_ARRAY(tmp_ctx
, struct spoolss_PrinterEnumValues
, num_values
);
427 if (enum_values
== NULL
) {
432 for (i
= 0; i
< num_values
; i
++) {
433 struct spoolss_PrinterEnumValues val
;
434 struct winreg_ValNameBuf name_buf
;
435 enum winreg_Type type
= REG_NONE
;
436 uint8_t *data
= NULL
;
442 name_buf
.size
= max_valnamelen
+ 2;
445 data_size
= max_valbufsize
;
446 data
= (uint8_t *) TALLOC(tmp_ctx
, data_size
);
449 status
= rpccli_winreg_EnumValue(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_enumvalues: Could not enumerate values: %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 val
.value_name
= talloc_strdup(enum_values
, name_buf
.name
);
481 if (val
.value_name
== NULL
) {
485 val
.value_name_len
= strlen_m_term(val
.value_name
) * 2;
488 val
.data_length
= data_size
;
490 if (val
.data_length
) {
491 val
.data
= talloc(enum_values
, DATA_BLOB
);
492 if (val
.data
== NULL
) {
496 *val
.data
= data_blob_talloc(enum_values
, data
, data_size
);
499 enum_values
[i
] = val
;
502 *pnum_values
= num_values
;
504 *penum_values
= talloc_move(mem_ctx
, &enum_values
);
510 TALLOC_FREE(tmp_ctx
);
517 * @brief Enumerate subkeys of an opened key handle and get the names.
519 * @param[in] mem_ctx The memory context to use.
521 * @param[in] pipe_handle The pipe handle for the rpc connection.
523 * @param[in] key_hnd The opened key handle.
525 * @param[in] pnum_subkeys A pointer to store the number of found subkeys.
527 * @param[in] psubkeys A pointer to an array to store the found names of
530 * @return WERR_OK on success, the corresponding DOS error
531 * code if something gone wrong.
533 static WERROR
winreg_printer_enumkeys(TALLOC_CTX
*mem_ctx
,
534 struct rpc_pipe_client
*pipe_handle
,
535 struct policy_handle
*key_hnd
,
536 uint32_t *pnum_subkeys
,
537 const char ***psubkeys
)
540 const char **subkeys
;
541 uint32_t num_subkeys
, max_subkeylen
, max_classlen
;
542 uint32_t num_values
, max_valnamelen
, max_valbufsize
;
544 NTTIME last_changed_time
;
545 uint32_t secdescsize
;
546 struct winreg_String classname
;
547 WERROR result
= WERR_OK
;
550 tmp_ctx
= talloc_new(mem_ctx
);
551 if (tmp_ctx
== NULL
) {
555 ZERO_STRUCT(classname
);
557 status
= rpccli_winreg_QueryInfoKey(pipe_handle
,
570 if (!NT_STATUS_IS_OK(status
)) {
571 DEBUG(0, ("winreg_printer_enumkeys: Could not query info: %s\n",
573 if (!W_ERROR_IS_OK(result
)) {
576 result
= ntstatus_to_werror(status
);
580 subkeys
= talloc_zero_array(tmp_ctx
, const char *, num_subkeys
+ 2);
581 if (subkeys
== NULL
) {
586 if (num_subkeys
== 0) {
587 subkeys
[0] = talloc_strdup(subkeys
, "");
588 if (subkeys
[0] == NULL
) {
594 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
597 TALLOC_FREE(tmp_ctx
);
601 for (i
= 0; i
< num_subkeys
; i
++) {
605 struct winreg_StringBuf class_buf
;
606 struct winreg_StringBuf name_buf
;
610 class_buf
.size
= max_classlen
+ 2;
611 class_buf
.length
= 0;
614 name_buf
.size
= max_subkeylen
+ 2;
617 ZERO_STRUCT(modtime
);
619 status
= rpccli_winreg_EnumKey(pipe_handle
,
627 if (W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
) ) {
629 status
= NT_STATUS_OK
;
633 if (!NT_STATUS_IS_OK(status
)) {
634 DEBUG(0, ("winreg_printer_enumkeys: Could not enumerate keys: %s\n",
636 if (!W_ERROR_IS_OK(result
)) {
639 result
= ntstatus_to_werror(status
);
643 if (name_buf
.name
== NULL
) {
644 result
= WERR_INVALID_PARAMETER
;
648 name
= talloc_strdup(subkeys
, name_buf
.name
);
657 *pnum_subkeys
= num_subkeys
;
659 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
663 TALLOC_FREE(tmp_ctx
);
670 * @brief A function to delete a key and its subkeys recurively.
672 * @param[in] mem_ctx The memory context to use.
674 * @param[in] pipe_handle The pipe handle for the rpc connection.
676 * @param[in] hive_handle A opened hive handle to the key.
678 * @param[in] access_mask The access mask to access the key.
680 * @param[in] key The key to delete
682 * @return WERR_OK on success, the corresponding DOS error
683 * code if something gone wrong.
685 static WERROR
winreg_printer_delete_subkeys(TALLOC_CTX
*mem_ctx
,
686 struct rpc_pipe_client
*pipe_handle
,
687 struct policy_handle
*hive_handle
,
688 uint32_t access_mask
,
691 const char **subkeys
= NULL
;
692 uint32_t num_subkeys
= 0;
693 struct policy_handle key_hnd
;
694 struct winreg_String wkey
;
695 WERROR result
= WERR_OK
;
699 ZERO_STRUCT(key_hnd
);
702 DEBUG(2, ("winreg_printer_delete_subkeys: delete key %s\n", key
));
704 status
= rpccli_winreg_OpenKey(pipe_handle
,
712 if (!NT_STATUS_IS_OK(status
)) {
713 DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n",
714 wkey
.name
, nt_errstr(status
)));
715 if (!W_ERROR_IS_OK(result
)) {
718 return ntstatus_to_werror(status
);
721 result
= winreg_printer_enumkeys(mem_ctx
,
726 if (!W_ERROR_IS_OK(result
)) {
730 for (i
= 0; i
< num_subkeys
; i
++) {
731 /* create key + subkey */
732 char *subkey
= talloc_asprintf(mem_ctx
, "%s\\%s", key
, subkeys
[i
]);
733 if (subkey
== NULL
) {
737 DEBUG(2, ("winreg_printer_delete_subkeys: delete subkey %s\n", subkey
));
738 result
= winreg_printer_delete_subkeys(mem_ctx
,
743 if (!W_ERROR_IS_OK(result
)) {
748 if (is_valid_policy_hnd(&key_hnd
)) {
749 rpccli_winreg_CloseKey(pipe_handle
, mem_ctx
, &key_hnd
, NULL
);
754 status
= rpccli_winreg_DeleteKey(pipe_handle
,
761 if (is_valid_policy_hnd(&key_hnd
)) {
762 rpccli_winreg_CloseKey(pipe_handle
, mem_ctx
, &key_hnd
, NULL
);
768 static WERROR
winreg_printer_write_sz(TALLOC_CTX
*mem_ctx
,
769 struct rpc_pipe_client
*pipe_handle
,
770 struct policy_handle
*key_handle
,
774 struct winreg_String wvalue
;
776 WERROR result
= WERR_OK
;
781 blob
= data_blob_string_const("");
783 if (!push_reg_sz(mem_ctx
, &blob
, data
)) {
784 DEBUG(0, ("winreg_printer_write_sz: Could not marshall string %s for %s\n",
789 status
= rpccli_winreg_SetValue(pipe_handle
,
797 if (!NT_STATUS_IS_OK(status
)) {
798 DEBUG(0, ("winreg_printer_write_sz: Could not set value %s: %s\n",
799 wvalue
.name
, win_errstr(result
)));
800 if (!W_ERROR_IS_OK(result
)) {
801 result
= ntstatus_to_werror(status
);
808 static WERROR
winreg_printer_write_dword(TALLOC_CTX
*mem_ctx
,
809 struct rpc_pipe_client
*pipe_handle
,
810 struct policy_handle
*key_handle
,
814 struct winreg_String wvalue
;
816 WERROR result
= WERR_OK
;
820 blob
= data_blob_talloc(mem_ctx
, NULL
, 4);
821 SIVAL(blob
.data
, 0, data
);
823 status
= rpccli_winreg_SetValue(pipe_handle
,
831 if (!NT_STATUS_IS_OK(status
)) {
832 DEBUG(0, ("winreg_printer_write_dword: Could not set value %s: %s\n",
833 wvalue
.name
, win_errstr(result
)));
834 if (!W_ERROR_IS_OK(result
)) {
835 result
= ntstatus_to_werror(status
);
842 static WERROR
winreg_printer_write_binary(TALLOC_CTX
*mem_ctx
,
843 struct rpc_pipe_client
*pipe_handle
,
844 struct policy_handle
*key_handle
,
848 struct winreg_String wvalue
;
849 WERROR result
= WERR_OK
;
853 status
= rpccli_winreg_SetValue(pipe_handle
,
861 if (!NT_STATUS_IS_OK(status
)) {
862 DEBUG(0, ("winreg_printer_write_binary: Could not set value %s: %s\n",
863 wvalue
.name
, win_errstr(result
)));
864 if (!W_ERROR_IS_OK(result
)) {
865 result
= ntstatus_to_werror(status
);
872 static WERROR
winreg_printer_query_binary(TALLOC_CTX
*mem_ctx
,
873 struct rpc_pipe_client
*pipe_handle
,
874 struct policy_handle
*key_handle
,
878 struct winreg_String wvalue
;
879 enum winreg_Type type
;
880 WERROR result
= WERR_OK
;
881 uint32_t value_len
= 0;
882 uint32_t data_size
= 0;
887 status
= rpccli_winreg_QueryValue(pipe_handle
,
896 if (!NT_STATUS_IS_OK(status
)) {
897 DEBUG(0, ("winreg_printer_query_dword: Could not query value %s: %s\n",
898 wvalue
.name
, nt_errstr(status
)));
899 if (!W_ERROR_IS_OK(result
)) {
902 result
= ntstatus_to_werror(status
);
906 if (type
!= REG_BINARY
) {
907 result
= WERR_INVALID_DATATYPE
;
910 blob
= data_blob_talloc(mem_ctx
, NULL
, data_size
);
911 if (blob
.data
== NULL
) {
917 status
= rpccli_winreg_QueryValue(pipe_handle
,
926 if (!NT_STATUS_IS_OK(status
)) {
927 DEBUG(0, ("winreg_printer_query_dword: Could not query value %s: %s\n",
928 wvalue
.name
, nt_errstr(status
)));
929 if (!W_ERROR_IS_OK(result
)) {
930 result
= ntstatus_to_werror(status
);
936 data
->data
= blob
.data
;
937 data
->length
= blob
.length
;
943 static WERROR
winreg_printer_query_dword(TALLOC_CTX
*mem_ctx
,
944 struct rpc_pipe_client
*pipe_handle
,
945 struct policy_handle
*key_handle
,
949 struct winreg_String wvalue
;
950 enum winreg_Type type
;
951 WERROR result
= WERR_OK
;
952 uint32_t value_len
= 0;
953 uint32_t data_size
= 0;
958 status
= rpccli_winreg_QueryValue(pipe_handle
,
967 if (!NT_STATUS_IS_OK(status
)) {
968 DEBUG(0, ("winreg_printer_query_dword: Could not query value %s: %s\n",
969 wvalue
.name
, nt_errstr(status
)));
970 if (!W_ERROR_IS_OK(result
)) {
973 result
= ntstatus_to_werror(status
);
977 if (type
!= REG_DWORD
) {
978 result
= WERR_INVALID_DATATYPE
;
982 if (data_size
!= 4) {
983 result
= WERR_INVALID_DATA
;
987 blob
= data_blob_talloc(mem_ctx
, NULL
, data_size
);
988 if (blob
.data
== NULL
) {
994 status
= rpccli_winreg_QueryValue(pipe_handle
,
1003 if (!NT_STATUS_IS_OK(status
)) {
1004 DEBUG(0, ("winreg_printer_query_dword: Could not query value %s: %s\n",
1005 wvalue
.name
, nt_errstr(status
)));
1006 if (!W_ERROR_IS_OK(result
)) {
1007 result
= ntstatus_to_werror(status
);
1013 *data
= IVAL(blob
.data
, 0);
1019 static WERROR
winreg_printer_write_multi_sz(TALLOC_CTX
*mem_ctx
,
1020 struct rpc_pipe_client
*pipe_handle
,
1021 struct policy_handle
*key_handle
,
1025 struct winreg_String wvalue
;
1027 WERROR result
= WERR_OK
;
1030 wvalue
.name
= value
;
1031 if (!push_reg_multi_sz(mem_ctx
, &blob
, data
)) {
1034 status
= rpccli_winreg_SetValue(pipe_handle
,
1042 if (!NT_STATUS_IS_OK(status
)) {
1043 DEBUG(0, ("winreg_printer_write_multi_sz: Could not set value %s: %s\n",
1044 wvalue
.name
, win_errstr(result
)));
1045 if (!W_ERROR_IS_OK(result
)) {
1046 result
= ntstatus_to_werror(status
);
1053 static WERROR
winreg_printer_opendriver(TALLOC_CTX
*mem_ctx
,
1054 struct auth_serversupplied_info
*server_info
,
1055 const char *drivername
,
1056 const char *architecture
,
1058 uint32_t access_mask
,
1060 struct rpc_pipe_client
**winreg_pipe
,
1061 struct policy_handle
*hive_hnd
,
1062 struct policy_handle
*key_hnd
)
1067 key_name
= talloc_asprintf(mem_ctx
, "%s\\Environments\\%s\\Drivers\\Version-%u",
1068 TOP_LEVEL_CONTROL_KEY
,
1069 architecture
, version
);
1074 result
= winreg_printer_openkey(mem_ctx
,
1086 static WERROR
winreg_enumval_to_dword(TALLOC_CTX
*mem_ctx
,
1087 struct spoolss_PrinterEnumValues
*v
,
1088 const char *valuename
, uint32_t *dw
)
1090 /* just return if it is not the one we are looking for */
1091 if (strcmp(valuename
, v
->value_name
) != 0) {
1092 return WERR_NOT_FOUND
;
1095 if (v
->type
!= REG_DWORD
) {
1096 return WERR_INVALID_DATATYPE
;
1099 *dw
= IVAL(v
->data
->data
, 0);
1103 static WERROR
winreg_enumval_to_sz(TALLOC_CTX
*mem_ctx
,
1104 struct spoolss_PrinterEnumValues
*v
,
1105 const char *valuename
, const char **_str
)
1107 /* just return if it is not the one we are looking for */
1108 if (strcmp(valuename
, v
->value_name
) != 0) {
1109 return WERR_NOT_FOUND
;
1112 if (v
->type
!= REG_SZ
) {
1113 return WERR_INVALID_DATATYPE
;
1116 if (!pull_reg_sz(mem_ctx
, v
->data
, _str
)) {
1123 static WERROR
winreg_enumval_to_multi_sz(TALLOC_CTX
*mem_ctx
,
1124 struct spoolss_PrinterEnumValues
*v
,
1125 const char *valuename
,
1126 const char ***array
)
1128 /* just return if it is not the one we are looking for */
1129 if (strcmp(valuename
, v
->value_name
) != 0) {
1130 return WERR_NOT_FOUND
;
1133 if (v
->type
!= REG_MULTI_SZ
) {
1134 return WERR_INVALID_DATATYPE
;
1137 if (!pull_reg_multi_sz(mem_ctx
, v
->data
, array
)) {
1144 static WERROR
winreg_printer_write_date(TALLOC_CTX
*mem_ctx
,
1145 struct rpc_pipe_client
*pipe_handle
,
1146 struct policy_handle
*key_handle
,
1150 struct winreg_String wvalue
;
1152 WERROR result
= WERR_OK
;
1158 t
= nt_time_to_unix(data
);
1160 str
= talloc_asprintf(mem_ctx
, "%02d/%02d/%04d",
1161 tm
->tm_mon
+ 1, tm
->tm_mday
, tm
->tm_year
+ 1900);
1166 wvalue
.name
= value
;
1167 if (!push_reg_sz(mem_ctx
, &blob
, str
)) {
1170 status
= rpccli_winreg_SetValue(pipe_handle
,
1178 if (!NT_STATUS_IS_OK(status
)) {
1179 DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
1180 wvalue
.name
, win_errstr(result
)));
1181 if (!W_ERROR_IS_OK(result
)) {
1182 result
= ntstatus_to_werror(status
);
1189 static WERROR
winreg_printer_date_to_NTTIME(const char *str
, NTTIME
*data
)
1196 if (sscanf(str
, "%d/%d/%d",
1197 &tm
.tm_mon
, &tm
.tm_mday
, &tm
.tm_year
) != 3) {
1198 return WERR_INVALID_PARAMETER
;
1205 unix_to_nt_time(data
, t
);
1210 static WERROR
winreg_printer_write_ver(TALLOC_CTX
*mem_ctx
,
1211 struct rpc_pipe_client
*pipe_handle
,
1212 struct policy_handle
*key_handle
,
1216 struct winreg_String wvalue
;
1218 WERROR result
= WERR_OK
;
1222 /* FIXME: check format is right,
1223 * this needs to be something like: 6.1.7600.16385 */
1224 str
= talloc_asprintf(mem_ctx
, "%u.%u.%u.%u",
1225 (unsigned)((data
>> 48) & 0xFFFF),
1226 (unsigned)((data
>> 32) & 0xFFFF),
1227 (unsigned)((data
>> 16) & 0xFFFF),
1228 (unsigned)(data
& 0xFFFF));
1233 wvalue
.name
= value
;
1234 if (!push_reg_sz(mem_ctx
, &blob
, str
)) {
1237 status
= rpccli_winreg_SetValue(pipe_handle
,
1245 if (!NT_STATUS_IS_OK(status
)) {
1246 DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
1247 wvalue
.name
, win_errstr(result
)));
1248 if (!W_ERROR_IS_OK(result
)) {
1249 result
= ntstatus_to_werror(status
);
1256 static WERROR
winreg_printer_ver_to_dword(const char *str
, uint64_t *data
)
1258 unsigned int v1
, v2
, v3
, v4
;
1260 if (sscanf(str
, "%u.%u.%u.%u", &v1
, &v2
, &v3
, &v4
) != 4) {
1261 return WERR_INVALID_PARAMETER
;
1264 *data
= ((uint64_t)(v1
& 0xFFFF) << 48) +
1265 ((uint64_t)(v2
& 0xFFFF) << 32) +
1266 ((uint64_t)(v3
& 0xFFFF) << 16) +
1267 (uint64_t)(v2
& 0xFFFF);
1272 /********************************************************************
1273 Public winreg function for spoolss
1274 ********************************************************************/
1276 WERROR
winreg_create_printer(TALLOC_CTX
*mem_ctx
,
1277 struct auth_serversupplied_info
*server_info
,
1278 const char *servername
,
1279 const char *sharename
)
1281 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1282 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1283 struct policy_handle hive_hnd
, key_hnd
;
1284 struct spoolss_SetPrinterInfo2
*info2
;
1285 struct security_descriptor
*secdesc
;
1286 struct winreg_String wkey
, wkeyclass
;
1288 const char *subkeys
[] = { SPOOL_DSDRIVER_KEY
, SPOOL_DSSPOOLER_KEY
, SPOOL_PRINTERDATA_KEY
};
1289 uint32_t i
, count
= ARRAY_SIZE(subkeys
);
1290 uint32_t info2_mask
= 0;
1291 WERROR result
= WERR_OK
;
1292 TALLOC_CTX
*tmp_ctx
;
1294 tmp_ctx
= talloc_new(mem_ctx
);
1295 if (tmp_ctx
== NULL
) {
1299 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
1301 TALLOC_FREE(tmp_ctx
);
1305 ZERO_STRUCT(hive_hnd
);
1306 ZERO_STRUCT(key_hnd
);
1308 result
= winreg_printer_openkey(tmp_ctx
,
1317 if (W_ERROR_IS_OK(result
)) {
1318 DEBUG(2, ("winreg_create_printer: Skipping, %s already exists\n", path
));
1320 } else if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
1321 DEBUG(2, ("winreg_create_printer: Creating default values in %s\n", path
));
1322 } else if (!W_ERROR_IS_OK(result
)) {
1323 DEBUG(0, ("winreg_create_printer: Could not open key %s: %s\n",
1324 path
, win_errstr(result
)));
1328 /* Create the main key */
1329 result
= winreg_printer_openkey(tmp_ctx
,
1338 if (!W_ERROR_IS_OK(result
)) {
1339 DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
1340 path
, win_errstr(result
)));
1344 if (is_valid_policy_hnd(&key_hnd
)) {
1345 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1348 /* Create subkeys */
1349 for (i
= 0; i
< count
; i
++) {
1351 enum winreg_CreateAction action
= REG_ACTION_NONE
;
1353 ZERO_STRUCT(key_hnd
);
1356 wkey
.name
= talloc_asprintf(tmp_ctx
, "%s\\%s", path
, subkeys
[i
]);
1357 if (wkey
.name
== NULL
) {
1358 result
= WERR_NOMEM
;
1362 ZERO_STRUCT(wkeyclass
);
1363 wkeyclass
.name
= "";
1365 status
= rpccli_winreg_CreateKey(winreg_pipe
,
1376 if (!NT_STATUS_IS_OK(status
)) {
1377 DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
1378 wkey
.name
, win_errstr(result
)));
1379 if (!W_ERROR_IS_OK(result
)) {
1380 result
= ntstatus_to_werror(status
);
1387 const char *dnssuffix
;
1388 const char *longname
;
1389 const char *uncname
;
1391 result
= winreg_printer_write_sz(tmp_ctx
,
1394 SPOOL_REG_PRINTERNAME
,
1396 if (!W_ERROR_IS_OK(result
)) {
1400 result
= winreg_printer_write_sz(tmp_ctx
,
1403 SPOOL_REG_SHORTSERVERNAME
,
1405 if (!W_ERROR_IS_OK(result
)) {
1409 /* We make the assumption that the netbios name
1410 * is the same as the DNS name since the former
1411 * will be what we used to join the domain
1413 dnssuffix
= get_mydnsdomname(tmp_ctx
);
1414 if (dnssuffix
!= NULL
&& dnssuffix
[0] != '\0') {
1415 longname
= talloc_asprintf(tmp_ctx
, "%s.%s", global_myname(), dnssuffix
);
1417 longname
= talloc_strdup(tmp_ctx
, global_myname());
1419 if (longname
== NULL
) {
1420 result
= WERR_NOMEM
;
1424 result
= winreg_printer_write_sz(tmp_ctx
,
1427 SPOOL_REG_SERVERNAME
,
1429 if (!W_ERROR_IS_OK(result
)) {
1433 uncname
= talloc_asprintf(tmp_ctx
, "\\\\%s\\%s",
1434 longname
, sharename
);
1435 if (uncname
== NULL
) {
1436 result
= WERR_NOMEM
;
1440 result
= winreg_printer_write_sz(tmp_ctx
,
1445 if (!W_ERROR_IS_OK(result
)) {
1449 result
= winreg_printer_write_dword(tmp_ctx
,
1452 SPOOL_REG_VERSIONNUMBER
,
1454 if (!W_ERROR_IS_OK(result
)) {
1458 result
= winreg_printer_write_dword(tmp_ctx
,
1461 SPOOL_REG_PRINTSTARTTIME
,
1463 if (!W_ERROR_IS_OK(result
)) {
1467 result
= winreg_printer_write_dword(tmp_ctx
,
1470 SPOOL_REG_PRINTENDTIME
,
1472 if (!W_ERROR_IS_OK(result
)) {
1476 result
= winreg_printer_write_dword(tmp_ctx
,
1481 if (!W_ERROR_IS_OK(result
)) {
1485 result
= winreg_printer_write_dword(tmp_ctx
,
1488 SPOOL_REG_PRINTKEEPPRINTEDJOBS
,
1490 if (!W_ERROR_IS_OK(result
)) {
1498 if (is_valid_policy_hnd(&key_hnd
)) {
1499 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1502 info2
= talloc_zero(tmp_ctx
, struct spoolss_SetPrinterInfo2
);
1503 if (info2
== NULL
) {
1504 result
= WERR_NOMEM
;
1508 if (servername
!= NULL
) {
1509 info2
->printername
= talloc_asprintf(tmp_ctx
, "\\\\%s\\%s",
1510 servername
, sharename
);
1512 info2
->printername
= sharename
;
1514 if (info2
->printername
== NULL
) {
1515 result
= WERR_NOMEM
;
1518 info2_mask
|= SPOOLSS_PRINTER_INFO_PRINTERNAME
;
1520 info2
->sharename
= sharename
;
1521 info2_mask
|= SPOOLSS_PRINTER_INFO_SHARENAME
;
1523 info2
->portname
= SAMBA_PRINTER_PORT_NAME
;
1524 info2_mask
|= SPOOLSS_PRINTER_INFO_PORTNAME
;
1526 info2
->printprocessor
= "winprint";
1527 info2_mask
|= SPOOLSS_PRINTER_INFO_PRINTPROCESSOR
;
1529 info2
->datatype
= "RAW";
1530 info2_mask
|= SPOOLSS_PRINTER_INFO_DATATYPE
;
1532 info2
->comment
= "";
1533 info2_mask
|= SPOOLSS_PRINTER_INFO_COMMENT
;
1535 info2
->attributes
= PRINTER_ATTRIBUTE_SAMBA
;
1536 info2_mask
|= SPOOLSS_PRINTER_INFO_ATTRIBUTES
;
1538 info2
->starttime
= 0; /* Minutes since 12:00am GMT */
1539 info2_mask
|= SPOOLSS_PRINTER_INFO_STARTTIME
;
1541 info2
->untiltime
= 0; /* Minutes since 12:00am GMT */
1542 info2_mask
|= SPOOLSS_PRINTER_INFO_UNTILTIME
;
1544 info2
->priority
= 1;
1545 info2_mask
|= SPOOLSS_PRINTER_INFO_PRIORITY
;
1547 info2
->defaultpriority
= 1;
1548 info2_mask
|= SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY
;
1550 result
= spoolss_create_default_secdesc(tmp_ctx
, &secdesc
);
1551 if (!W_ERROR_IS_OK(result
)) {
1554 info2_mask
|= SPOOLSS_PRINTER_INFO_SECDESC
;
1557 * Don't write a default Device Mode to the registry! The Device Mode is
1558 * only written to disk with a SetPrinter level 2 or 8.
1561 result
= winreg_update_printer(tmp_ctx
,
1570 if (winreg_pipe
!= NULL
) {
1571 if (is_valid_policy_hnd(&key_hnd
)) {
1572 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1574 if (is_valid_policy_hnd(&hive_hnd
)) {
1575 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1579 talloc_free(tmp_ctx
);
1583 WERROR
winreg_update_printer(TALLOC_CTX
*mem_ctx
,
1584 struct auth_serversupplied_info
*server_info
,
1585 const char *sharename
,
1586 uint32_t info2_mask
,
1587 struct spoolss_SetPrinterInfo2
*info2
,
1588 struct spoolss_DeviceMode
*devmode
,
1589 struct security_descriptor
*secdesc
)
1591 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1592 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1593 struct policy_handle hive_hnd
, key_hnd
;
1594 int snum
= lp_servicenumber(sharename
);
1595 enum ndr_err_code ndr_err
;
1598 WERROR result
= WERR_OK
;
1599 TALLOC_CTX
*tmp_ctx
;
1601 tmp_ctx
= talloc_new(mem_ctx
);
1602 if (tmp_ctx
== NULL
) {
1606 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
1608 TALLOC_FREE(tmp_ctx
);
1612 ZERO_STRUCT(hive_hnd
);
1613 ZERO_STRUCT(key_hnd
);
1615 result
= winreg_printer_openkey(tmp_ctx
,
1624 if (!W_ERROR_IS_OK(result
)) {
1625 DEBUG(0, ("winreg_update_printer: Could not open key %s: %s\n",
1626 path
, win_errstr(result
)));
1630 if (info2_mask
& SPOOLSS_PRINTER_INFO_ATTRIBUTES
) {
1631 result
= winreg_printer_write_dword(tmp_ctx
,
1636 if (!W_ERROR_IS_OK(result
)) {
1642 if (info2_mask
& SPOOLSS_PRINTER_INFO_AVERAGEPPM
) {
1643 result
= winreg_printer_write_dword(tmp_ctx
,
1648 if (!W_ERROR_IS_OK(result
)) {
1654 if (info2_mask
& SPOOLSS_PRINTER_INFO_COMMENT
) {
1655 result
= winreg_printer_write_sz(tmp_ctx
,
1660 if (!W_ERROR_IS_OK(result
)) {
1665 if (info2_mask
& SPOOLSS_PRINTER_INFO_DATATYPE
) {
1666 result
= winreg_printer_write_sz(tmp_ctx
,
1671 if (!W_ERROR_IS_OK(result
)) {
1676 if (info2_mask
& SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY
) {
1677 result
= winreg_printer_write_dword(tmp_ctx
,
1681 info2
->defaultpriority
);
1682 if (!W_ERROR_IS_OK(result
)) {
1687 if (info2_mask
& SPOOLSS_PRINTER_INFO_DEVMODE
) {
1689 * Some client drivers freak out if there is a NULL devmode
1690 * (probably the driver is not checking before accessing
1691 * the devmode pointer) --jerry
1693 if (devmode
== NULL
&& lp_default_devmode(snum
) && info2
!= NULL
) {
1694 result
= spoolss_create_default_devmode(tmp_ctx
,
1697 if (!W_ERROR_IS_OK(result
)) {
1701 ndr_err
= ndr_push_struct_blob(&blob
, tmp_ctx
, devmode
,
1702 (ndr_push_flags_fn_t
) ndr_push_spoolss_DeviceMode
);
1703 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1704 DEBUG(0, ("winreg_update_printer: Failed to marshall device mode\n"));
1705 result
= WERR_NOMEM
;
1709 result
= winreg_printer_write_binary(tmp_ctx
,
1714 if (!W_ERROR_IS_OK(result
)) {
1719 if (info2_mask
& SPOOLSS_PRINTER_INFO_DRIVERNAME
) {
1720 result
= winreg_printer_write_sz(tmp_ctx
,
1725 if (!W_ERROR_IS_OK(result
)) {
1730 if (info2_mask
& SPOOLSS_PRINTER_INFO_LOCATION
) {
1731 result
= winreg_printer_write_sz(tmp_ctx
,
1736 if (!W_ERROR_IS_OK(result
)) {
1741 if (info2_mask
& SPOOLSS_PRINTER_INFO_PARAMETERS
) {
1742 result
= winreg_printer_write_sz(tmp_ctx
,
1747 if (!W_ERROR_IS_OK(result
)) {
1752 if (info2_mask
& SPOOLSS_PRINTER_INFO_PORTNAME
) {
1753 result
= winreg_printer_write_sz(tmp_ctx
,
1758 if (!W_ERROR_IS_OK(result
)) {
1763 if (info2_mask
& SPOOLSS_PRINTER_INFO_PRINTERNAME
) {
1765 * in addprinter: no servername and the printer is the name
1766 * in setprinter: servername is \\server
1767 * and printer is \\server\\printer
1769 * Samba manages only local printers.
1770 * we currently don't support things like i
1771 * path=\\other_server\printer
1773 * We only store the printername, not \\server\printername
1775 const char *p
= strrchr(info2
->printername
, '\\');
1777 p
= info2
->printername
;
1781 result
= winreg_printer_write_sz(tmp_ctx
,
1786 if (!W_ERROR_IS_OK(result
)) {
1791 if (info2_mask
& SPOOLSS_PRINTER_INFO_PRINTPROCESSOR
) {
1792 result
= winreg_printer_write_sz(tmp_ctx
,
1796 info2
->printprocessor
);
1797 if (!W_ERROR_IS_OK(result
)) {
1802 if (info2_mask
& SPOOLSS_PRINTER_INFO_PRIORITY
) {
1803 result
= winreg_printer_write_dword(tmp_ctx
,
1808 if (!W_ERROR_IS_OK(result
)) {
1813 if (info2_mask
& SPOOLSS_PRINTER_INFO_SECDESC
) {
1815 * We need a security descriptor, if it isn't specified by
1816 * AddPrinter{Ex} then create a default descriptor.
1818 if (secdesc
== NULL
) {
1819 result
= spoolss_create_default_secdesc(tmp_ctx
, &secdesc
);
1820 if (!W_ERROR_IS_OK(result
)) {
1824 result
= winreg_set_printer_secdesc(tmp_ctx
,
1828 if (!W_ERROR_IS_OK(result
)) {
1833 if (info2_mask
& SPOOLSS_PRINTER_INFO_SEPFILE
) {
1834 result
= winreg_printer_write_sz(tmp_ctx
,
1839 if (!W_ERROR_IS_OK(result
)) {
1844 if (info2_mask
& SPOOLSS_PRINTER_INFO_SHARENAME
) {
1845 result
= winreg_printer_write_sz(tmp_ctx
,
1850 if (!W_ERROR_IS_OK(result
)) {
1855 if (info2_mask
& SPOOLSS_PRINTER_INFO_STARTTIME
) {
1856 result
= winreg_printer_write_dword(tmp_ctx
,
1861 if (!W_ERROR_IS_OK(result
)) {
1866 if (info2_mask
& SPOOLSS_PRINTER_INFO_STATUS
) {
1867 result
= winreg_printer_write_dword(tmp_ctx
,
1872 if (!W_ERROR_IS_OK(result
)) {
1877 if (info2_mask
& SPOOLSS_PRINTER_INFO_UNTILTIME
) {
1878 result
= winreg_printer_write_dword(tmp_ctx
,
1883 if (!W_ERROR_IS_OK(result
)) {
1888 result
= winreg_printer_write_dword(tmp_ctx
,
1892 winreg_printer_rev_changeid());
1893 if (!W_ERROR_IS_OK(result
)) {
1899 if (winreg_pipe
!= NULL
) {
1900 if (is_valid_policy_hnd(&key_hnd
)) {
1901 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1903 if (is_valid_policy_hnd(&hive_hnd
)) {
1904 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1908 TALLOC_FREE(tmp_ctx
);
1912 WERROR
winreg_get_printer(TALLOC_CTX
*mem_ctx
,
1913 struct auth_serversupplied_info
*server_info
,
1914 const char *servername
,
1915 const char *printer
,
1916 struct spoolss_PrinterInfo2
**pinfo2
)
1918 struct spoolss_PrinterInfo2
*info2
;
1919 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1920 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1921 struct policy_handle hive_hnd
, key_hnd
;
1922 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
1923 struct spoolss_PrinterEnumValues
*v
;
1924 enum ndr_err_code ndr_err
;
1926 int snum
= lp_servicenumber(printer
);
1927 uint32_t num_values
= 0;
1930 WERROR result
= WERR_OK
;
1931 TALLOC_CTX
*tmp_ctx
;
1933 tmp_ctx
= talloc_new(mem_ctx
);
1934 if (tmp_ctx
== NULL
) {
1938 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
1940 TALLOC_FREE(tmp_ctx
);
1944 result
= winreg_printer_openkey(tmp_ctx
,
1953 if (!W_ERROR_IS_OK(result
)) {
1954 DEBUG(0, ("winreg_get_printer: Could not open key %s: %s\n",
1955 path
, win_errstr(result
)));
1959 result
= winreg_printer_enumvalues(tmp_ctx
,
1964 if (!W_ERROR_IS_OK(result
)) {
1965 DEBUG(0, ("winreg_get_printer: Could not enumerate values in %s: %s\n",
1966 path
, win_errstr(result
)));
1970 info2
= talloc_zero(tmp_ctx
, struct spoolss_PrinterInfo2
);
1971 if (info2
== NULL
) {
1972 result
= WERR_NOMEM
;
1976 info2
->servername
= EMPTY_STRING
;
1977 info2
->printername
= EMPTY_STRING
;
1978 info2
->sharename
= EMPTY_STRING
;
1979 info2
->portname
= EMPTY_STRING
;
1980 info2
->drivername
= EMPTY_STRING
;
1981 info2
->comment
= EMPTY_STRING
;
1982 info2
->location
= EMPTY_STRING
;
1983 info2
->sepfile
= EMPTY_STRING
;
1984 info2
->printprocessor
= EMPTY_STRING
;
1985 info2
->datatype
= EMPTY_STRING
;
1986 info2
->parameters
= EMPTY_STRING
;
1988 if (servername
!= NULL
&& servername
[0] != '\0') {
1989 info2
->servername
= talloc_asprintf(info2
, "\\\\%s", servername
);
1990 if (info2
->servername
== NULL
) {
1991 result
= WERR_NOMEM
;
1996 for (i
= 0; i
< num_values
; i
++) {
1997 v
= &enum_values
[i
];
1999 result
= winreg_enumval_to_sz(info2
,
2002 &info2
->printername
);
2003 CHECK_ERROR(result
);
2005 result
= winreg_enumval_to_sz(info2
,
2009 CHECK_ERROR(result
);
2011 result
= winreg_enumval_to_sz(info2
,
2015 CHECK_ERROR(result
);
2017 result
= winreg_enumval_to_sz(info2
,
2021 CHECK_ERROR(result
);
2023 result
= winreg_enumval_to_sz(info2
,
2027 CHECK_ERROR(result
);
2029 result
= winreg_enumval_to_sz(info2
,
2033 CHECK_ERROR(result
);
2035 result
= winreg_enumval_to_sz(info2
,
2038 &info2
->printprocessor
);
2039 CHECK_ERROR(result
);
2041 result
= winreg_enumval_to_sz(info2
,
2045 CHECK_ERROR(result
);
2047 result
= winreg_enumval_to_sz(info2
,
2050 &info2
->parameters
);
2051 CHECK_ERROR(result
);
2053 result
= winreg_enumval_to_sz(info2
,
2056 &info2
->drivername
);
2057 CHECK_ERROR(result
);
2059 result
= winreg_enumval_to_dword(info2
,
2062 &info2
->attributes
);
2063 CHECK_ERROR(result
);
2065 result
= winreg_enumval_to_dword(info2
,
2069 CHECK_ERROR(result
);
2071 result
= winreg_enumval_to_dword(info2
,
2074 &info2
->defaultpriority
);
2075 CHECK_ERROR(result
);
2077 result
= winreg_enumval_to_dword(info2
,
2081 CHECK_ERROR(result
);
2083 result
= winreg_enumval_to_dword(info2
,
2087 CHECK_ERROR(result
);
2089 result
= winreg_enumval_to_dword(info2
,
2093 CHECK_ERROR(result
);
2095 result
= winreg_enumval_to_dword(info2
,
2099 CHECK_ERROR(result
);
2102 if (!W_ERROR_IS_OK(result
)) {
2103 DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed "
2106 win_errstr(result
)));
2110 /* Create the printername */
2111 if (info2
->servername
[0] != '\0') {
2112 if (lp_force_printername(snum
)) {
2113 const char *p
= talloc_asprintf(info2
, "%s\\%s",
2117 result
= WERR_NOMEM
;
2120 info2
->printername
= p
;
2122 char *p
= talloc_asprintf(info2
, "%s\\%s",
2124 info2
->printername
);
2126 result
= WERR_NOMEM
;
2129 info2
->printername
= p
;
2133 /* Construct the Device Mode */
2134 result
= winreg_printer_query_binary(tmp_ctx
,
2139 if (W_ERROR_IS_OK(result
)) {
2140 info2
->devmode
= talloc_zero(info2
, struct spoolss_DeviceMode
);
2141 if (info2
->devmode
== NULL
) {
2142 result
= WERR_NOMEM
;
2145 ndr_err
= ndr_pull_struct_blob(&blob
,
2148 (ndr_pull_flags_fn_t
) ndr_pull_spoolss_DeviceMode
);
2149 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2150 DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n"));
2151 result
= WERR_NOMEM
;
2156 if (info2
->devmode
== NULL
&& lp_default_devmode(snum
)) {
2157 result
= spoolss_create_default_devmode(info2
,
2160 if (!W_ERROR_IS_OK(result
)) {
2165 if (info2
->devmode
!= NULL
) {
2166 info2
->devmode
->devicename
= talloc_strdup(info2
->devmode
,
2167 info2
->printername
);
2168 if (info2
->devmode
->devicename
== NULL
) {
2169 DEBUG(0, ("winreg_get_printer: Failed to set devicename\n"));
2170 result
= WERR_NOMEM
;
2175 result
= winreg_get_printer_secdesc(info2
,
2179 if (!W_ERROR_IS_OK(result
)) {
2183 /* Fix for OS/2 drivers. */
2184 if (get_remote_arch() == RA_OS2
) {
2185 spoolss_map_to_os2_driver(info2
, &info2
->drivername
);
2189 *pinfo2
= talloc_move(mem_ctx
, &info2
);
2194 if (winreg_pipe
!= NULL
) {
2195 if (is_valid_policy_hnd(&key_hnd
)) {
2196 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2198 if (is_valid_policy_hnd(&hive_hnd
)) {
2199 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2203 TALLOC_FREE(tmp_ctx
);
2207 WERROR
winreg_get_printer_secdesc(TALLOC_CTX
*mem_ctx
,
2208 struct auth_serversupplied_info
*server_info
,
2209 const char *sharename
,
2210 struct spoolss_security_descriptor
**psecdesc
)
2212 struct spoolss_security_descriptor
*secdesc
;
2213 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2214 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2215 struct policy_handle hive_hnd
, key_hnd
;
2216 enum ndr_err_code ndr_err
;
2219 TALLOC_CTX
*tmp_ctx
;
2222 tmp_ctx
= talloc_new(mem_ctx
);
2223 if (tmp_ctx
== NULL
) {
2227 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
2229 talloc_free(tmp_ctx
);
2233 ZERO_STRUCT(hive_hnd
);
2234 ZERO_STRUCT(key_hnd
);
2236 result
= winreg_printer_openkey(tmp_ctx
,
2245 if (!W_ERROR_IS_OK(result
)) {
2246 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
2247 goto create_default
;
2252 result
= winreg_printer_query_binary(tmp_ctx
,
2257 if (!W_ERROR_IS_OK(result
)) {
2258 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
2259 goto create_default
;
2264 secdesc
= talloc_zero(tmp_ctx
, struct spoolss_security_descriptor
);
2265 if (secdesc
== NULL
) {
2266 result
= WERR_NOMEM
;
2269 ndr_err
= ndr_pull_struct_blob(&blob
,
2272 (ndr_pull_flags_fn_t
) ndr_pull_security_descriptor
);
2273 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2274 DEBUG(0, ("winreg_get_secdesc: Failed to unmarshall security descriptor\n"));
2275 result
= WERR_NOMEM
;
2280 *psecdesc
= talloc_move(mem_ctx
, &secdesc
);
2287 result
= spoolss_create_default_secdesc(tmp_ctx
, &secdesc
);
2288 if (!W_ERROR_IS_OK(result
)) {
2292 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
2293 this security descriptor has been created when winbindd was
2294 down. Take ownership of security descriptor. */
2295 if (sid_equal(secdesc
->owner_sid
, &global_sid_World
)) {
2298 /* Change sd owner to workgroup administrator */
2300 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid
)) {
2301 struct spoolss_security_descriptor
*new_secdesc
;
2305 sid_append_rid(&owner_sid
, DOMAIN_RID_ADMINISTRATOR
);
2307 new_secdesc
= make_sec_desc(tmp_ctx
,
2316 if (new_secdesc
== NULL
) {
2317 result
= WERR_NOMEM
;
2321 /* Swap with other one */
2322 secdesc
= new_secdesc
;
2326 ndr_err
= ndr_push_struct_blob(&blob
, tmp_ctx
, secdesc
,
2327 (ndr_push_flags_fn_t
) ndr_push_security_descriptor
);
2328 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2329 DEBUG(0, ("winreg_set_secdesc: Failed to marshall security descriptor\n"));
2330 result
= WERR_NOMEM
;
2334 result
= winreg_printer_write_binary(tmp_ctx
,
2339 if (!W_ERROR_IS_OK(result
)) {
2344 *psecdesc
= talloc_move(mem_ctx
, &secdesc
);
2349 if (winreg_pipe
!= NULL
) {
2350 if (is_valid_policy_hnd(&key_hnd
)) {
2351 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2353 if (is_valid_policy_hnd(&hive_hnd
)) {
2354 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2358 talloc_free(tmp_ctx
);
2362 WERROR
winreg_set_printer_secdesc(TALLOC_CTX
*mem_ctx
,
2363 struct auth_serversupplied_info
*server_info
,
2364 const char *sharename
,
2365 const struct spoolss_security_descriptor
*secdesc
)
2367 const struct spoolss_security_descriptor
*new_secdesc
= secdesc
;
2368 struct spoolss_security_descriptor
*old_secdesc
;
2369 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2370 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2371 struct policy_handle hive_hnd
, key_hnd
;
2372 enum ndr_err_code ndr_err
;
2375 TALLOC_CTX
*tmp_ctx
;
2378 tmp_ctx
= talloc_new(mem_ctx
);
2379 if (tmp_ctx
== NULL
) {
2383 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
2385 talloc_free(tmp_ctx
);
2390 * The old owner and group sids of the security descriptor are not
2391 * present when new ACEs are added or removed by changing printer
2392 * permissions through NT. If they are NULL in the new security
2393 * descriptor then copy them over from the old one.
2395 if (!secdesc
->owner_sid
|| !secdesc
->group_sid
) {
2396 DOM_SID
*owner_sid
, *group_sid
;
2397 struct security_acl
*dacl
, *sacl
;
2400 result
= winreg_get_printer_secdesc(tmp_ctx
,
2404 if (!W_ERROR_IS_OK(result
)) {
2405 talloc_free(tmp_ctx
);
2409 /* Pick out correct owner and group sids */
2410 owner_sid
= secdesc
->owner_sid
?
2411 secdesc
->owner_sid
:
2412 old_secdesc
->owner_sid
;
2414 group_sid
= secdesc
->group_sid
?
2415 secdesc
->group_sid
:
2416 old_secdesc
->group_sid
;
2418 dacl
= secdesc
->dacl
?
2422 sacl
= secdesc
->sacl
?
2426 /* Make a deep copy of the security descriptor */
2427 new_secdesc
= make_sec_desc(tmp_ctx
,
2435 if (new_secdesc
== NULL
) {
2436 talloc_free(tmp_ctx
);
2441 ZERO_STRUCT(hive_hnd
);
2442 ZERO_STRUCT(key_hnd
);
2444 result
= winreg_printer_openkey(tmp_ctx
,
2453 if (!W_ERROR_IS_OK(result
)) {
2457 ndr_err
= ndr_push_struct_blob(&blob
, tmp_ctx
, new_secdesc
,
2458 (ndr_push_flags_fn_t
) ndr_push_security_descriptor
);
2459 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2460 DEBUG(0, ("winreg_set_secdesc: Failed to marshall security descriptor\n"));
2461 result
= WERR_NOMEM
;
2465 result
= winreg_printer_write_binary(tmp_ctx
,
2472 if (winreg_pipe
!= NULL
) {
2473 if (is_valid_policy_hnd(&key_hnd
)) {
2474 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2476 if (is_valid_policy_hnd(&hive_hnd
)) {
2477 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2481 talloc_free(tmp_ctx
);
2485 /* Set printer data over the winreg pipe. */
2486 WERROR
winreg_set_printer_dataex(TALLOC_CTX
*mem_ctx
,
2487 struct auth_serversupplied_info
*server_info
,
2488 const char *printer
,
2491 enum winreg_Type type
,
2495 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2496 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2497 struct policy_handle hive_hnd
, key_hnd
;
2498 struct winreg_String wvalue
;
2500 WERROR result
= WERR_OK
;
2502 TALLOC_CTX
*tmp_ctx
;
2504 tmp_ctx
= talloc_new(mem_ctx
);
2505 if (tmp_ctx
== NULL
) {
2509 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2511 TALLOC_FREE(tmp_ctx
);
2515 ZERO_STRUCT(hive_hnd
);
2516 ZERO_STRUCT(key_hnd
);
2518 DEBUG(8, ("winreg_set_printer_dataex: Open printer key %s, value %s, access_mask: 0x%05x for [%s]\n",
2519 key
, value
, access_mask
, printer
));
2520 result
= winreg_printer_openkey(tmp_ctx
,
2529 if (!W_ERROR_IS_OK(result
)) {
2530 DEBUG(0, ("winreg_set_printer_dataex: Could not open key %s: %s\n",
2531 key
, win_errstr(result
)));
2535 wvalue
.name
= value
;
2536 status
= rpccli_winreg_SetValue(winreg_pipe
,
2544 if (!NT_STATUS_IS_OK(status
)) {
2545 DEBUG(0, ("winreg_set_printer_dataex: Could not set value %s: %s\n",
2546 value
, nt_errstr(status
)));
2547 if (!W_ERROR_IS_OK(result
)) {
2550 result
= ntstatus_to_werror(status
);
2556 if (winreg_pipe
!= NULL
) {
2557 if (is_valid_policy_hnd(&key_hnd
)) {
2558 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2560 if (is_valid_policy_hnd(&hive_hnd
)) {
2561 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2565 TALLOC_FREE(tmp_ctx
);
2569 /* Get printer data over a winreg pipe. */
2570 WERROR
winreg_get_printer_dataex(TALLOC_CTX
*mem_ctx
,
2571 struct auth_serversupplied_info
*server_info
,
2572 const char *printer
,
2575 enum winreg_Type
*type
,
2577 uint32_t *data_size
)
2579 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2580 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2581 struct policy_handle hive_hnd
, key_hnd
;
2582 struct winreg_String wvalue
;
2583 enum winreg_Type type_in
;
2586 uint32_t data_in_size
= 0;
2587 uint32_t value_len
= 0;
2588 WERROR result
= WERR_OK
;
2590 TALLOC_CTX
*tmp_ctx
;
2592 tmp_ctx
= talloc_new(mem_ctx
);
2593 if (tmp_ctx
== NULL
) {
2597 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2599 TALLOC_FREE(tmp_ctx
);
2603 ZERO_STRUCT(hive_hnd
);
2604 ZERO_STRUCT(key_hnd
);
2606 result
= winreg_printer_openkey(tmp_ctx
,
2615 if (!W_ERROR_IS_OK(result
)) {
2616 DEBUG(0, ("winreg_get_printer_dataex: Could not open key %s: %s\n",
2617 key
, win_errstr(result
)));
2621 wvalue
.name
= value
;
2624 * call QueryValue once with data == NULL to get the
2625 * needed memory size to be allocated, then allocate
2626 * data buffer and call again.
2628 status
= rpccli_winreg_QueryValue(winreg_pipe
,
2637 if (!NT_STATUS_IS_OK(status
)) {
2638 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
2639 value
, nt_errstr(status
)));
2640 if (!W_ERROR_IS_OK(result
)) {
2643 result
= ntstatus_to_werror(status
);
2647 data_in
= (uint8_t *) TALLOC(tmp_ctx
, data_in_size
);
2648 if (data_in
== NULL
) {
2649 result
= WERR_NOMEM
;
2654 status
= rpccli_winreg_QueryValue(winreg_pipe
,
2663 if (!NT_STATUS_IS_OK(status
)) {
2664 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
2665 value
, nt_errstr(status
)));
2666 if (!W_ERROR_IS_OK(result
)) {
2667 result
= ntstatus_to_werror(status
);
2673 *data_size
= data_in_size
;
2675 *data
= talloc_move(mem_ctx
, &data_in
);
2680 if (winreg_pipe
!= NULL
) {
2681 if (is_valid_policy_hnd(&key_hnd
)) {
2682 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2684 if (is_valid_policy_hnd(&hive_hnd
)) {
2685 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2689 TALLOC_FREE(tmp_ctx
);
2693 /* Enumerate on the values of a given key and provide the data. */
2694 WERROR
winreg_enum_printer_dataex(TALLOC_CTX
*mem_ctx
,
2695 struct auth_serversupplied_info
*server_info
,
2696 const char *printer
,
2698 uint32_t *pnum_values
,
2699 struct spoolss_PrinterEnumValues
**penum_values
)
2701 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2702 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2703 struct policy_handle hive_hnd
, key_hnd
;
2705 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
2706 uint32_t num_values
= 0;
2708 WERROR result
= WERR_OK
;
2710 TALLOC_CTX
*tmp_ctx
;
2712 tmp_ctx
= talloc_new(mem_ctx
);
2713 if (tmp_ctx
== NULL
) {
2717 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2719 TALLOC_FREE(tmp_ctx
);
2723 result
= winreg_printer_openkey(tmp_ctx
,
2732 if (!W_ERROR_IS_OK(result
)) {
2733 DEBUG(0, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
2734 key
, win_errstr(result
)));
2738 result
= winreg_printer_enumvalues(tmp_ctx
,
2743 if (!W_ERROR_IS_OK(result
)) {
2744 DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
2745 key
, win_errstr(result
)));
2749 *pnum_values
= num_values
;
2751 *penum_values
= talloc_move(mem_ctx
, &enum_values
);
2756 if (winreg_pipe
!= NULL
) {
2757 if (is_valid_policy_hnd(&key_hnd
)) {
2758 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2760 if (is_valid_policy_hnd(&hive_hnd
)) {
2761 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2765 TALLOC_FREE(tmp_ctx
);
2769 /* Delete printer data over a winreg pipe. */
2770 WERROR
winreg_delete_printer_dataex(TALLOC_CTX
*mem_ctx
,
2771 struct auth_serversupplied_info
*server_info
,
2772 const char *printer
,
2776 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2777 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2778 struct policy_handle hive_hnd
, key_hnd
;
2779 struct winreg_String wvalue
;
2781 WERROR result
= WERR_OK
;
2784 TALLOC_CTX
*tmp_ctx
;
2786 tmp_ctx
= talloc_new(mem_ctx
);
2787 if (tmp_ctx
== NULL
) {
2791 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2793 TALLOC_FREE(tmp_ctx
);
2797 ZERO_STRUCT(hive_hnd
);
2798 ZERO_STRUCT(key_hnd
);
2800 result
= winreg_printer_openkey(tmp_ctx
,
2809 if (!W_ERROR_IS_OK(result
)) {
2810 DEBUG(0, ("winreg_delete_printer_dataex: Could not open key %s: %s\n",
2811 key
, win_errstr(result
)));
2815 wvalue
.name
= value
;
2816 status
= rpccli_winreg_DeleteValue(winreg_pipe
,
2821 if (!NT_STATUS_IS_OK(status
)) {
2822 DEBUG(0, ("winreg_delete_printer_dataex: Could not delete value %s: %s\n",
2823 value
, nt_errstr(status
)));
2824 if (!W_ERROR_IS_OK(result
)) {
2827 result
= ntstatus_to_werror(status
);
2833 if (winreg_pipe
!= NULL
) {
2834 if (is_valid_policy_hnd(&key_hnd
)) {
2835 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2837 if (is_valid_policy_hnd(&hive_hnd
)) {
2838 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2842 TALLOC_FREE(tmp_ctx
);
2846 /* Enumerate on the subkeys of a given key and provide the data. */
2847 WERROR
winreg_enum_printer_key(TALLOC_CTX
*mem_ctx
,
2848 struct auth_serversupplied_info
*server_info
,
2849 const char *printer
,
2851 uint32_t *pnum_subkeys
,
2852 const char ***psubkeys
)
2854 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2855 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2856 struct policy_handle hive_hnd
, key_hnd
;
2858 const char **subkeys
= NULL
;
2859 uint32_t num_subkeys
= -1;
2861 WERROR result
= WERR_OK
;
2863 TALLOC_CTX
*tmp_ctx
;
2865 tmp_ctx
= talloc_new(mem_ctx
);
2866 if (tmp_ctx
== NULL
) {
2870 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2872 TALLOC_FREE(tmp_ctx
);
2876 ZERO_STRUCT(hive_hnd
);
2877 ZERO_STRUCT(key_hnd
);
2879 result
= winreg_printer_openkey(tmp_ctx
,
2888 if (!W_ERROR_IS_OK(result
)) {
2889 DEBUG(0, ("winreg_enum_printer_key: Could not open key %s: %s\n",
2890 key
, win_errstr(result
)));
2894 result
= winreg_printer_enumkeys(tmp_ctx
,
2899 if (!W_ERROR_IS_OK(result
)) {
2900 DEBUG(0, ("winreg_enum_printer_key: Could not enumerate subkeys in %s: %s\n",
2901 key
, win_errstr(result
)));
2905 *pnum_subkeys
= num_subkeys
;
2907 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
2912 if (winreg_pipe
!= NULL
) {
2913 if (is_valid_policy_hnd(&key_hnd
)) {
2914 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2916 if (is_valid_policy_hnd(&hive_hnd
)) {
2917 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2921 TALLOC_FREE(tmp_ctx
);
2925 /* Delete a key with subkeys of a given printer. */
2926 WERROR
winreg_delete_printer_key(TALLOC_CTX
*mem_ctx
,
2927 struct auth_serversupplied_info
*server_info
,
2928 const char *printer
,
2931 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2932 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2933 struct policy_handle hive_hnd
, key_hnd
;
2937 TALLOC_CTX
*tmp_ctx
;
2939 tmp_ctx
= talloc_new(mem_ctx
);
2940 if (tmp_ctx
== NULL
) {
2944 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2946 TALLOC_FREE(tmp_ctx
);
2950 result
= winreg_printer_openkey(tmp_ctx
,
2959 if (!W_ERROR_IS_OK(result
)) {
2960 /* key doesn't exist */
2961 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
2966 DEBUG(0, ("winreg_delete_printer_key: Could not open key %s: %s\n",
2967 key
, win_errstr(result
)));
2971 if (is_valid_policy_hnd(&key_hnd
)) {
2972 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2975 if (key
== NULL
|| key
[0] == '\0') {
2978 keyname
= talloc_asprintf(tmp_ctx
,
2982 if (keyname
== NULL
) {
2983 result
= WERR_NOMEM
;
2988 result
= winreg_printer_delete_subkeys(tmp_ctx
,
2993 if (!W_ERROR_IS_OK(result
)) {
2994 DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
2995 key
, win_errstr(result
)));
3000 if (winreg_pipe
!= NULL
) {
3001 if (is_valid_policy_hnd(&key_hnd
)) {
3002 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3004 if (is_valid_policy_hnd(&hive_hnd
)) {
3005 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3009 TALLOC_FREE(tmp_ctx
);
3013 WERROR
winreg_printer_update_changeid(TALLOC_CTX
*mem_ctx
,
3014 struct auth_serversupplied_info
*server_info
,
3015 const char *printer
)
3017 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3018 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3019 struct policy_handle hive_hnd
, key_hnd
;
3022 TALLOC_CTX
*tmp_ctx
;
3024 tmp_ctx
= talloc_new(mem_ctx
);
3025 if (tmp_ctx
== NULL
) {
3029 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
3031 TALLOC_FREE(tmp_ctx
);
3035 ZERO_STRUCT(hive_hnd
);
3036 ZERO_STRUCT(key_hnd
);
3038 result
= winreg_printer_openkey(tmp_ctx
,
3047 if (!W_ERROR_IS_OK(result
)) {
3048 DEBUG(0, ("winreg_printer_update_changeid: Could not open key %s: %s\n",
3049 path
, win_errstr(result
)));
3053 result
= winreg_printer_write_dword(tmp_ctx
,
3057 winreg_printer_rev_changeid());
3058 if (!W_ERROR_IS_OK(result
)) {
3064 if (winreg_pipe
!= NULL
) {
3065 if (is_valid_policy_hnd(&key_hnd
)) {
3066 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3068 if (is_valid_policy_hnd(&hive_hnd
)) {
3069 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3073 TALLOC_FREE(tmp_ctx
);
3077 WERROR
winreg_printer_get_changeid(TALLOC_CTX
*mem_ctx
,
3078 struct auth_serversupplied_info
*server_info
,
3079 const char *printer
,
3080 uint32_t *pchangeid
)
3082 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3083 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3084 struct policy_handle hive_hnd
, key_hnd
;
3085 uint32_t changeid
= 0;
3088 TALLOC_CTX
*tmp_ctx
;
3090 tmp_ctx
= talloc_new(mem_ctx
);
3091 if (tmp_ctx
== NULL
) {
3095 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
3097 TALLOC_FREE(tmp_ctx
);
3101 ZERO_STRUCT(hive_hnd
);
3102 ZERO_STRUCT(key_hnd
);
3104 result
= winreg_printer_openkey(tmp_ctx
,
3113 if (!W_ERROR_IS_OK(result
)) {
3114 DEBUG(0, ("winreg_printer_get_changeid: Could not open key %s: %s\n",
3115 path
, win_errstr(result
)));
3119 DEBUG(0, ("winreg_printer_get_changeid: get changeid from %s\n", path
));
3120 result
= winreg_printer_query_dword(tmp_ctx
,
3125 if (!W_ERROR_IS_OK(result
)) {
3130 *pchangeid
= changeid
;
3135 if (winreg_pipe
!= NULL
) {
3136 if (is_valid_policy_hnd(&key_hnd
)) {
3137 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3139 if (is_valid_policy_hnd(&hive_hnd
)) {
3140 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3144 TALLOC_FREE(tmp_ctx
);
3149 * The special behaviour of the spoolss forms is documented at the website:
3151 * Managing Win32 Printserver Forms
3152 * http://unixwiz.net/techtips/winspooler-forms.html
3155 WERROR
winreg_printer_addform1(TALLOC_CTX
*mem_ctx
,
3156 struct auth_serversupplied_info
*server_info
,
3157 struct spoolss_AddFormInfo1
*form
)
3159 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3160 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3161 struct policy_handle hive_hnd
, key_hnd
;
3162 struct winreg_String wvalue
;
3164 uint32_t num_info
= 0;
3165 union spoolss_FormInfo
*info
= NULL
;
3169 TALLOC_CTX
*tmp_ctx
;
3171 tmp_ctx
= talloc_new(mem_ctx
);
3172 if (tmp_ctx
== NULL
) {
3176 ZERO_STRUCT(hive_hnd
);
3177 ZERO_STRUCT(key_hnd
);
3179 result
= winreg_printer_openkey(tmp_ctx
,
3182 TOP_LEVEL_CONTROL_FORMS_KEY
,
3188 if (!W_ERROR_IS_OK(result
)) {
3189 DEBUG(0, ("winreg_printer_addform1: Could not open key %s: %s\n",
3190 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3194 result
= winreg_printer_enumforms1(tmp_ctx
, server_info
, &num_info
, &info
);
3195 if (!W_ERROR_IS_OK(result
)) {
3196 DEBUG(0, ("winreg_printer_addform: Could not enum keys %s: %s\n",
3197 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3201 /* If form name already exists or is builtin return ALREADY_EXISTS */
3202 for (i
= 0; i
< num_info
; i
++) {
3203 if (strequal(info
[i
].info1
.form_name
, form
->form_name
)) {
3204 result
= WERR_FILE_EXISTS
;
3209 wvalue
.name
= form
->form_name
;
3211 blob
= data_blob_talloc(tmp_ctx
, NULL
, 32);
3212 SIVAL(blob
.data
, 0, form
->size
.width
);
3213 SIVAL(blob
.data
, 4, form
->size
.height
);
3214 SIVAL(blob
.data
, 8, form
->area
.left
);
3215 SIVAL(blob
.data
, 12, form
->area
.top
);
3216 SIVAL(blob
.data
, 16, form
->area
.right
);
3217 SIVAL(blob
.data
, 20, form
->area
.bottom
);
3218 SIVAL(blob
.data
, 24, num_info
+ 1); /* FIXME */
3219 SIVAL(blob
.data
, 28, form
->flags
);
3221 status
= rpccli_winreg_SetValue(winreg_pipe
,
3229 if (!NT_STATUS_IS_OK(status
)) {
3230 DEBUG(0, ("winreg_printer_addform1: Could not set value %s: %s\n",
3231 wvalue
.name
, nt_errstr(status
)));
3232 if (!W_ERROR_IS_OK(result
)) {
3235 result
= ntstatus_to_werror(status
);
3241 if (winreg_pipe
!= NULL
) {
3242 if (is_valid_policy_hnd(&key_hnd
)) {
3243 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3245 if (is_valid_policy_hnd(&hive_hnd
)) {
3246 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3251 TALLOC_FREE(tmp_ctx
);
3255 WERROR
winreg_printer_enumforms1(TALLOC_CTX
*mem_ctx
,
3256 struct auth_serversupplied_info
*server_info
,
3257 uint32_t *pnum_info
,
3258 union spoolss_FormInfo
**pinfo
)
3260 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3261 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3262 struct policy_handle hive_hnd
, key_hnd
;
3263 union spoolss_FormInfo
*info
;
3264 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
3265 uint32_t num_values
= 0;
3266 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3269 TALLOC_CTX
*tmp_ctx
;
3271 tmp_ctx
= talloc_new(mem_ctx
);
3272 if (tmp_ctx
== NULL
) {
3276 ZERO_STRUCT(hive_hnd
);
3277 ZERO_STRUCT(key_hnd
);
3279 result
= winreg_printer_openkey(tmp_ctx
,
3282 TOP_LEVEL_CONTROL_FORMS_KEY
,
3288 if (!W_ERROR_IS_OK(result
)) {
3289 /* key doesn't exist */
3290 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
3295 DEBUG(0, ("winreg_printer_enumforms1: Could not open key %s: %s\n",
3296 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3300 result
= winreg_printer_enumvalues(tmp_ctx
,
3305 if (!W_ERROR_IS_OK(result
)) {
3306 DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n",
3307 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3311 info
= TALLOC_ARRAY(tmp_ctx
, union spoolss_FormInfo
, num_builtin
+ num_values
);
3313 result
= WERR_NOMEM
;
3317 /* Enumerate BUILTIN forms */
3318 for (i
= 0; i
< num_builtin
; i
++) {
3319 info
[i
].info1
= builtin_forms1
[i
];
3322 /* Enumerate registry forms */
3323 for (i
= 0; i
< num_values
; i
++) {
3324 union spoolss_FormInfo val
;
3326 if (enum_values
[i
].type
!= REG_BINARY
||
3327 enum_values
[i
].data_length
!= 32) {
3331 val
.info1
.form_name
= talloc_strdup(info
, enum_values
[i
].value_name
);
3332 if (val
.info1
.form_name
== NULL
) {
3333 result
= WERR_NOMEM
;
3337 val
.info1
.size
.width
= IVAL(enum_values
[i
].data
->data
, 0);
3338 val
.info1
.size
.height
= IVAL(enum_values
[i
].data
->data
, 4);
3339 val
.info1
.area
.left
= IVAL(enum_values
[i
].data
->data
, 8);
3340 val
.info1
.area
.top
= IVAL(enum_values
[i
].data
->data
, 12);
3341 val
.info1
.area
.right
= IVAL(enum_values
[i
].data
->data
, 16);
3342 val
.info1
.area
.bottom
= IVAL(enum_values
[i
].data
->data
, 20);
3343 /* skip form index IVAL(enum_values[i].data->data, 24)));*/
3344 val
.info1
.flags
= IVAL(enum_values
[i
].data
->data
, 28);
3346 info
[i
+ num_builtin
] = val
;
3349 *pnum_info
= num_builtin
+ num_values
;
3351 *pinfo
= talloc_move(mem_ctx
, &info
);
3355 if (winreg_pipe
!= NULL
) {
3356 if (is_valid_policy_hnd(&key_hnd
)) {
3357 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3359 if (is_valid_policy_hnd(&hive_hnd
)) {
3360 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3364 TALLOC_FREE(enum_values
);
3365 TALLOC_FREE(tmp_ctx
);
3369 WERROR
winreg_printer_deleteform1(TALLOC_CTX
*mem_ctx
,
3370 struct auth_serversupplied_info
*server_info
,
3371 const char *form_name
)
3373 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3374 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3375 struct policy_handle hive_hnd
, key_hnd
;
3376 struct winreg_String wvalue
;
3377 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3379 WERROR result
= WERR_OK
;
3381 TALLOC_CTX
*tmp_ctx
;
3383 for (i
= 0; i
< num_builtin
; i
++) {
3384 if (strequal(builtin_forms1
[i
].form_name
, form_name
)) {
3385 return WERR_INVALID_PARAMETER
;
3389 tmp_ctx
= talloc_new(mem_ctx
);
3390 if (tmp_ctx
== NULL
) {
3394 ZERO_STRUCT(hive_hnd
);
3395 ZERO_STRUCT(key_hnd
);
3397 result
= winreg_printer_openkey(tmp_ctx
,
3400 TOP_LEVEL_CONTROL_FORMS_KEY
,
3406 if (!W_ERROR_IS_OK(result
)) {
3407 DEBUG(0, ("winreg_printer_deleteform1: Could not open key %s: %s\n",
3408 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3409 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
3410 result
= WERR_INVALID_FORM_NAME
;
3415 wvalue
.name
= form_name
;
3416 status
= rpccli_winreg_DeleteValue(winreg_pipe
,
3421 if (!NT_STATUS_IS_OK(status
)) {
3422 /* If the value doesn't exist, return WERR_INVALID_FORM_NAME */
3423 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
3424 result
= WERR_INVALID_FORM_NAME
;
3427 DEBUG(0, ("winreg_printer_delteform1: Could not delete value %s: %s\n",
3428 wvalue
.name
, nt_errstr(status
)));
3429 if (!W_ERROR_IS_OK(result
)) {
3432 result
= ntstatus_to_werror(status
);
3438 if (winreg_pipe
!= NULL
) {
3439 if (is_valid_policy_hnd(&key_hnd
)) {
3440 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3442 if (is_valid_policy_hnd(&hive_hnd
)) {
3443 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3447 TALLOC_FREE(tmp_ctx
);
3451 WERROR
winreg_printer_setform1(TALLOC_CTX
*mem_ctx
,
3452 struct auth_serversupplied_info
*server_info
,
3453 const char *form_name
,
3454 struct spoolss_AddFormInfo1
*form
)
3456 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3457 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3458 struct policy_handle hive_hnd
, key_hnd
;
3459 struct winreg_String wvalue
;
3461 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3465 TALLOC_CTX
*tmp_ctx
= NULL
;
3467 for (i
= 0; i
< num_builtin
; i
++) {
3468 if (strequal(builtin_forms1
[i
].form_name
, form
->form_name
)) {
3469 result
= WERR_INVALID_PARAM
;
3474 tmp_ctx
= talloc_new(mem_ctx
);
3475 if (tmp_ctx
== NULL
) {
3479 ZERO_STRUCT(hive_hnd
);
3480 ZERO_STRUCT(key_hnd
);
3482 result
= winreg_printer_openkey(tmp_ctx
,
3485 TOP_LEVEL_CONTROL_FORMS_KEY
,
3491 if (!W_ERROR_IS_OK(result
)) {
3492 DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
3493 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3497 /* If form_name != form->form_name then we renamed the form */
3498 if (strequal(form_name
, form
->form_name
)) {
3499 result
= winreg_printer_deleteform1(tmp_ctx
, server_info
, form_name
);
3500 if (!W_ERROR_IS_OK(result
)) {
3501 DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
3502 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3507 wvalue
.name
= form
->form_name
;
3509 blob
= data_blob_talloc(tmp_ctx
, NULL
, 32);
3510 SIVAL(blob
.data
, 0, form
->size
.width
);
3511 SIVAL(blob
.data
, 4, form
->size
.height
);
3512 SIVAL(blob
.data
, 8, form
->area
.left
);
3513 SIVAL(blob
.data
, 12, form
->area
.top
);
3514 SIVAL(blob
.data
, 16, form
->area
.right
);
3515 SIVAL(blob
.data
, 20, form
->area
.bottom
);
3516 SIVAL(blob
.data
, 24, 42);
3517 SIVAL(blob
.data
, 28, form
->flags
);
3519 status
= rpccli_winreg_SetValue(winreg_pipe
,
3527 if (!NT_STATUS_IS_OK(status
)) {
3528 DEBUG(0, ("winreg_printer_setform1: Could not set value %s: %s\n",
3529 wvalue
.name
, nt_errstr(status
)));
3530 if (!W_ERROR_IS_OK(result
)) {
3533 result
= ntstatus_to_werror(status
);
3539 if (winreg_pipe
!= NULL
) {
3540 if (is_valid_policy_hnd(&key_hnd
)) {
3541 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3543 if (is_valid_policy_hnd(&hive_hnd
)) {
3544 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3548 TALLOC_FREE(tmp_ctx
);
3552 WERROR
winreg_printer_getform1(TALLOC_CTX
*mem_ctx
,
3553 struct auth_serversupplied_info
*server_info
,
3554 const char *form_name
,
3555 struct spoolss_FormInfo1
*r
)
3557 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3558 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3559 struct policy_handle hive_hnd
, key_hnd
;
3560 struct winreg_String wvalue
;
3561 enum winreg_Type type_in
;
3563 uint32_t data_in_size
= 0;
3564 uint32_t value_len
= 0;
3565 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3569 TALLOC_CTX
*tmp_ctx
;
3571 /* check builtin forms first */
3572 for (i
= 0; i
< num_builtin
; i
++) {
3573 if (strequal(builtin_forms1
[i
].form_name
, form_name
)) {
3574 *r
= builtin_forms1
[i
];
3579 tmp_ctx
= talloc_new(mem_ctx
);
3580 if (tmp_ctx
== NULL
) {
3584 ZERO_STRUCT(hive_hnd
);
3585 ZERO_STRUCT(key_hnd
);
3587 result
= winreg_printer_openkey(tmp_ctx
,
3590 TOP_LEVEL_CONTROL_FORMS_KEY
,
3596 if (!W_ERROR_IS_OK(result
)) {
3597 DEBUG(0, ("winreg_printer_getform1: Could not open key %s: %s\n",
3598 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3602 wvalue
.name
= form_name
;
3605 * call QueryValue once with data == NULL to get the
3606 * needed memory size to be allocated, then allocate
3607 * data buffer and call again.
3609 status
= rpccli_winreg_QueryValue(winreg_pipe
,
3618 if (!NT_STATUS_IS_OK(status
)) {
3619 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
3620 wvalue
.name
, nt_errstr(status
)));
3621 if (!W_ERROR_IS_OK(result
)) {
3624 result
= ntstatus_to_werror(status
);
3628 data_in
= (uint8_t *) TALLOC(tmp_ctx
, data_in_size
);
3629 if (data_in
== NULL
) {
3630 result
= WERR_NOMEM
;
3635 status
= rpccli_winreg_QueryValue(winreg_pipe
,
3644 if (!NT_STATUS_IS_OK(status
)) {
3645 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
3646 wvalue
.name
, nt_errstr(status
)));
3647 if (!W_ERROR_IS_OK(result
)) {
3650 result
= ntstatus_to_werror(status
);
3654 r
->form_name
= talloc_strdup(mem_ctx
, form_name
);
3655 if (r
->form_name
== NULL
) {
3656 result
= WERR_NOMEM
;
3660 r
->size
.width
= IVAL(data_in
, 0);
3661 r
->size
.height
= IVAL(data_in
, 4);
3662 r
->area
.left
= IVAL(data_in
, 8);
3663 r
->area
.top
= IVAL(data_in
, 12);
3664 r
->area
.right
= IVAL(data_in
, 16);
3665 r
->area
.bottom
= IVAL(data_in
, 20);
3666 /* skip index IVAL(data_in, 24)));*/
3667 r
->flags
= IVAL(data_in
, 28);
3671 if (winreg_pipe
!= NULL
) {
3672 if (is_valid_policy_hnd(&key_hnd
)) {
3673 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3675 if (is_valid_policy_hnd(&hive_hnd
)) {
3676 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3680 TALLOC_FREE(tmp_ctx
);
3684 WERROR
winreg_add_driver(TALLOC_CTX
*mem_ctx
,
3685 struct auth_serversupplied_info
*server_info
,
3686 struct spoolss_AddDriverInfoCtr
*r
,
3687 const char **driver_name
,
3688 uint32_t *driver_version
)
3690 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3691 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3692 struct policy_handle hive_hnd
, key_hnd
;
3693 struct spoolss_DriverInfo8 info8
;
3694 TALLOC_CTX
*tmp_ctx
= NULL
;
3697 ZERO_STRUCT(hive_hnd
);
3698 ZERO_STRUCT(key_hnd
);
3701 if (!driver_info_ctr_to_info8(r
, &info8
)) {
3702 result
= WERR_INVALID_PARAMETER
;
3706 tmp_ctx
= talloc_new(mem_ctx
);
3707 if (tmp_ctx
== NULL
) {
3711 result
= winreg_printer_opendriver(tmp_ctx
,
3720 if (!W_ERROR_IS_OK(result
)) {
3721 DEBUG(0, ("winreg_add_driver: "
3722 "Could not open driver key (%s,%s,%d): %s\n",
3723 info8
.driver_name
, info8
.architecture
,
3724 info8
.version
, win_errstr(result
)));
3728 /* TODO: "Attributes" ? */
3730 result
= winreg_printer_write_dword(tmp_ctx
, winreg_pipe
,
3731 &key_hnd
, "Version",
3733 if (!W_ERROR_IS_OK(result
)) {
3737 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3740 if (!W_ERROR_IS_OK(result
)) {
3744 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3745 &key_hnd
, "Data File",
3747 if (!W_ERROR_IS_OK(result
)) {
3751 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3752 &key_hnd
, "Configuration File",
3754 if (!W_ERROR_IS_OK(result
)) {
3758 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3759 &key_hnd
, "Help File",
3761 if (!W_ERROR_IS_OK(result
)) {
3765 result
= winreg_printer_write_multi_sz(tmp_ctx
, winreg_pipe
,
3766 &key_hnd
, "Dependent Files",
3767 info8
.dependent_files
);
3768 if (!W_ERROR_IS_OK(result
)) {
3772 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3773 &key_hnd
, "Monitor",
3774 info8
.monitor_name
);
3775 if (!W_ERROR_IS_OK(result
)) {
3779 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3780 &key_hnd
, "Datatype",
3781 info8
.default_datatype
);
3782 if (!W_ERROR_IS_OK(result
)) {
3786 result
= winreg_printer_write_multi_sz(tmp_ctx
, winreg_pipe
,
3787 &key_hnd
, "Previous Names",
3788 info8
.previous_names
);
3789 if (!W_ERROR_IS_OK(result
)) {
3793 result
= winreg_printer_write_date(tmp_ctx
, winreg_pipe
,
3794 &key_hnd
, "DriverDate",
3796 if (!W_ERROR_IS_OK(result
)) {
3800 result
= winreg_printer_write_ver(tmp_ctx
, winreg_pipe
,
3801 &key_hnd
, "DriverVersion",
3802 info8
.driver_version
);
3803 if (!W_ERROR_IS_OK(result
)) {
3807 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3808 &key_hnd
, "Manufacturer",
3809 info8
.manufacturer_name
);
3810 if (!W_ERROR_IS_OK(result
)) {
3814 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3815 &key_hnd
, "OEM URL",
3816 info8
.manufacturer_url
);
3817 if (!W_ERROR_IS_OK(result
)) {
3821 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3822 &key_hnd
, "HardwareID",
3824 if (!W_ERROR_IS_OK(result
)) {
3828 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3829 &key_hnd
, "Provider",
3831 if (!W_ERROR_IS_OK(result
)) {
3835 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3836 &key_hnd
, "Print Processor",
3837 info8
.print_processor
);
3838 if (!W_ERROR_IS_OK(result
)) {
3842 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3843 &key_hnd
, "VendorSetup",
3844 info8
.vendor_setup
);
3845 if (!W_ERROR_IS_OK(result
)) {
3849 result
= winreg_printer_write_multi_sz(tmp_ctx
, winreg_pipe
,
3850 &key_hnd
, "Color Profiles",
3851 info8
.color_profiles
);
3852 if (!W_ERROR_IS_OK(result
)) {
3856 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3857 &key_hnd
, "InfPath",
3859 if (!W_ERROR_IS_OK(result
)) {
3863 result
= winreg_printer_write_dword(tmp_ctx
, winreg_pipe
, &key_hnd
,
3864 "PrinterDriverAttributes",
3865 info8
.printer_driver_attributes
);
3866 if (!W_ERROR_IS_OK(result
)) {
3870 result
= winreg_printer_write_multi_sz(tmp_ctx
, winreg_pipe
,
3871 &key_hnd
, "CoreDependencies",
3872 info8
.core_driver_dependencies
);
3873 if (!W_ERROR_IS_OK(result
)) {
3877 result
= winreg_printer_write_date(tmp_ctx
, winreg_pipe
,
3878 &key_hnd
, "MinInboxDriverVerDate",
3879 info8
.min_inbox_driver_ver_date
);
3880 if (!W_ERROR_IS_OK(result
)) {
3884 result
= winreg_printer_write_ver(tmp_ctx
, winreg_pipe
, &key_hnd
,
3885 "MinInboxDriverVerVersion",
3886 info8
.min_inbox_driver_ver_version
);
3887 if (!W_ERROR_IS_OK(result
)) {
3891 *driver_name
= info8
.driver_name
;
3892 *driver_version
= info8
.version
;
3895 if (winreg_pipe
!= NULL
) {
3896 if (is_valid_policy_hnd(&key_hnd
)) {
3897 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3899 if (is_valid_policy_hnd(&hive_hnd
)) {
3900 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3904 TALLOC_FREE(tmp_ctx
);
3908 WERROR
winreg_get_driver(TALLOC_CTX
*mem_ctx
,
3909 struct auth_serversupplied_info
*server_info
,
3910 const char *architecture
,
3911 const char *driver_name
,
3912 uint32_t driver_version
,
3913 struct spoolss_DriverInfo8
**_info8
)
3915 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3916 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3917 struct policy_handle hive_hnd
, key_hnd
;
3918 struct spoolss_DriverInfo8 i8
, *info8
;
3919 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
3920 struct spoolss_PrinterEnumValues
*v
;
3921 uint32_t num_values
= 0;
3922 TALLOC_CTX
*tmp_ctx
;
3926 ZERO_STRUCT(hive_hnd
);
3927 ZERO_STRUCT(key_hnd
);
3930 tmp_ctx
= talloc_new(mem_ctx
);
3931 if (tmp_ctx
== NULL
) {
3935 if (driver_version
== DRIVER_ANY_VERSION
) {
3936 /* look for Win2k first and then for NT4 */
3937 result
= winreg_printer_opendriver(tmp_ctx
,
3946 if (!W_ERROR_IS_OK(result
)) {
3947 result
= winreg_printer_opendriver(tmp_ctx
,
3958 /* ok normal case */
3959 result
= winreg_printer_opendriver(tmp_ctx
,
3969 if (!W_ERROR_IS_OK(result
)) {
3970 DEBUG(5, ("winreg_get_driver: "
3971 "Could not open driver key (%s,%s,%d): %s\n",
3972 driver_name
, architecture
,
3973 driver_version
, win_errstr(result
)));
3977 result
= winreg_printer_enumvalues(tmp_ctx
,
3982 if (!W_ERROR_IS_OK(result
)) {
3983 DEBUG(0, ("winreg_get_driver: "
3984 "Could not enumerate values for (%s,%s,%d): %s\n",
3985 driver_name
, architecture
,
3986 driver_version
, win_errstr(result
)));
3990 info8
= talloc_zero(tmp_ctx
, struct spoolss_DriverInfo8
);
3991 if (info8
== NULL
) {
3992 result
= WERR_NOMEM
;
3996 info8
->driver_name
= talloc_strdup(info8
, driver_name
);
3997 if (info8
->driver_name
== NULL
) {
3998 result
= WERR_NOMEM
;
4002 info8
->architecture
= talloc_strdup(info8
, architecture
);
4003 if (info8
->architecture
== NULL
) {
4004 result
= WERR_NOMEM
;
4008 info8
->config_file
= EMPTY_STRING
;
4009 info8
->data_file
= EMPTY_STRING
;
4010 info8
->default_datatype
= EMPTY_STRING
;
4011 info8
->driver_path
= EMPTY_STRING
;
4012 info8
->hardware_id
= EMPTY_STRING
;
4013 info8
->help_file
= EMPTY_STRING
;
4014 info8
->inf_path
= EMPTY_STRING
;
4015 info8
->manufacturer_name
= EMPTY_STRING
;
4016 info8
->manufacturer_url
= EMPTY_STRING
;
4017 info8
->monitor_name
= EMPTY_STRING
;
4018 info8
->print_processor
= EMPTY_STRING
;
4019 info8
->provider
= EMPTY_STRING
;
4020 info8
->vendor_setup
= EMPTY_STRING
;
4022 info8
->color_profiles
= empty_string_array
;
4023 info8
->core_driver_dependencies
= EMPTY_STRING_ARRAY
;
4024 info8
->dependent_files
= EMPTY_STRING_ARRAY
;
4025 info8
->previous_names
= EMPTY_STRING_ARRAY
;
4029 for (i
= 0; i
< num_values
; i
++) {
4030 const char *tmp_str
;
4032 v
= &enum_values
[i
];
4034 result
= winreg_enumval_to_dword(info8
, v
,
4037 CHECK_ERROR(result
);
4039 result
= winreg_enumval_to_sz(info8
, v
,
4041 &info8
->driver_path
);
4042 CHECK_ERROR(result
);
4044 result
= winreg_enumval_to_sz(info8
, v
,
4047 CHECK_ERROR(result
);
4049 result
= winreg_enumval_to_sz(info8
, v
,
4050 "Configuration File",
4051 &info8
->config_file
);
4052 CHECK_ERROR(result
);
4054 result
= winreg_enumval_to_sz(info8
, v
,
4057 CHECK_ERROR(result
);
4059 result
= winreg_enumval_to_multi_sz(info8
, v
,
4061 &info8
->dependent_files
);
4062 CHECK_ERROR(result
);
4064 result
= winreg_enumval_to_sz(info8
, v
,
4066 &info8
->monitor_name
);
4067 CHECK_ERROR(result
);
4069 result
= winreg_enumval_to_sz(info8
, v
,
4071 &info8
->default_datatype
);
4072 CHECK_ERROR(result
);
4074 result
= winreg_enumval_to_multi_sz(info8
, v
,
4076 &info8
->previous_names
);
4077 CHECK_ERROR(result
);
4079 result
= winreg_enumval_to_sz(info8
, v
,
4082 if (W_ERROR_IS_OK(result
)) {
4083 result
= winreg_printer_date_to_NTTIME(tmp_str
,
4084 &info8
->driver_date
);
4086 CHECK_ERROR(result
);
4088 result
= winreg_enumval_to_sz(info8
, v
,
4091 if (W_ERROR_IS_OK(result
)) {
4092 result
= winreg_printer_ver_to_dword(tmp_str
,
4093 &info8
->driver_version
);
4095 CHECK_ERROR(result
);
4097 result
= winreg_enumval_to_sz(info8
, v
,
4099 &info8
->manufacturer_name
);
4100 CHECK_ERROR(result
);
4102 result
= winreg_enumval_to_sz(info8
, v
,
4104 &info8
->manufacturer_url
);
4105 CHECK_ERROR(result
);
4107 result
= winreg_enumval_to_sz(info8
, v
,
4109 &info8
->hardware_id
);
4110 CHECK_ERROR(result
);
4112 result
= winreg_enumval_to_sz(info8
, v
,
4115 CHECK_ERROR(result
);
4117 result
= winreg_enumval_to_sz(info8
, v
,
4119 &info8
->print_processor
);
4120 CHECK_ERROR(result
);
4122 result
= winreg_enumval_to_sz(info8
, v
,
4124 &info8
->vendor_setup
);
4125 CHECK_ERROR(result
);
4127 result
= winreg_enumval_to_multi_sz(info8
, v
,
4129 &info8
->color_profiles
);
4130 CHECK_ERROR(result
);
4132 result
= winreg_enumval_to_sz(info8
, v
,
4135 CHECK_ERROR(result
);
4137 result
= winreg_enumval_to_dword(info8
, v
,
4138 "PrinterDriverAttributes",
4139 &info8
->printer_driver_attributes
);
4140 CHECK_ERROR(result
);
4142 result
= winreg_enumval_to_multi_sz(info8
, v
,
4144 &info8
->core_driver_dependencies
);
4145 CHECK_ERROR(result
);
4147 result
= winreg_enumval_to_sz(info8
, v
,
4148 "MinInboxDriverVerDate",
4150 if (W_ERROR_IS_OK(result
)) {
4151 result
= winreg_printer_date_to_NTTIME(tmp_str
,
4152 &info8
->min_inbox_driver_ver_date
);
4154 CHECK_ERROR(result
);
4156 result
= winreg_enumval_to_sz(info8
, v
,
4157 "MinInboxDriverVerVersion",
4159 if (W_ERROR_IS_OK(result
)) {
4160 result
= winreg_printer_ver_to_dword(tmp_str
,
4161 &info8
->min_inbox_driver_ver_version
);
4163 CHECK_ERROR(result
);
4166 if (!W_ERROR_IS_OK(result
)) {
4167 DEBUG(0, ("winreg_enumval_to_TYPE() failed "
4168 "for %s: %s\n", v
->value_name
,
4169 win_errstr(result
)));
4173 *_info8
= talloc_steal(mem_ctx
, info8
);
4176 if (winreg_pipe
!= NULL
) {
4177 if (is_valid_policy_hnd(&key_hnd
)) {
4178 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
4180 if (is_valid_policy_hnd(&hive_hnd
)) {
4181 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
4185 TALLOC_FREE(tmp_ctx
);
4189 WERROR
winreg_del_driver(TALLOC_CTX
*mem_ctx
,
4190 struct auth_serversupplied_info
*server_info
,
4191 struct spoolss_DriverInfo8
*info8
,
4194 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4195 struct rpc_pipe_client
*winreg_pipe
= NULL
;
4196 struct policy_handle hive_hnd
, key_hnd
;
4197 TALLOC_CTX
*tmp_ctx
;
4201 ZERO_STRUCT(hive_hnd
);
4202 ZERO_STRUCT(key_hnd
);
4204 tmp_ctx
= talloc_new(mem_ctx
);
4205 if (tmp_ctx
== NULL
) {
4209 /* test that the key exists */
4210 result
= winreg_printer_opendriver(tmp_ctx
,
4213 info8
->architecture
,
4219 if (!W_ERROR_IS_OK(result
)) {
4220 /* key doesn't exist */
4221 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
4226 DEBUG(5, ("winreg_del_driver: "
4227 "Could not open driver (%s,%s,%u): %s\n",
4228 info8
->driver_name
, info8
->architecture
,
4229 version
, win_errstr(result
)));
4234 if (is_valid_policy_hnd(&key_hnd
)) {
4235 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
4238 key_name
= talloc_asprintf(tmp_ctx
,
4239 "%s\\Environments\\%s\\Drivers\\Version-%u",
4240 TOP_LEVEL_CONTROL_KEY
,
4241 info8
->architecture
, version
);
4242 if (key_name
== NULL
) {
4243 result
= WERR_NOMEM
;
4247 result
= winreg_printer_delete_subkeys(tmp_ctx
,
4252 if (!W_ERROR_IS_OK(result
)) {
4253 DEBUG(0, ("winreg_del_driver: "
4254 "Could not open driver (%s,%s,%u): %s\n",
4255 info8
->driver_name
, info8
->architecture
,
4256 version
, win_errstr(result
)));
4262 if (winreg_pipe
!= NULL
) {
4263 if (is_valid_policy_hnd(&key_hnd
)) {
4264 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
4266 if (is_valid_policy_hnd(&hive_hnd
)) {
4267 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
4271 TALLOC_FREE(tmp_ctx
);
4275 WERROR
winreg_get_driver_list(TALLOC_CTX
*mem_ctx
,
4276 struct auth_serversupplied_info
*server_info
,
4277 const char *architecture
,
4279 uint32_t *num_drivers
,
4280 const char ***drivers_p
)
4282 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4283 struct rpc_pipe_client
*winreg_pipe
= NULL
;
4284 struct policy_handle hive_hnd
, key_hnd
;
4285 const char **drivers
;
4286 TALLOC_CTX
*tmp_ctx
;
4292 ZERO_STRUCT(hive_hnd
);
4293 ZERO_STRUCT(key_hnd
);
4295 tmp_ctx
= talloc_new(mem_ctx
);
4296 if (tmp_ctx
== NULL
) {
4300 /* use NULL for the driver name so we open the key that is
4301 * parent of all drivers for this architecture and version */
4302 result
= winreg_printer_opendriver(tmp_ctx
,
4311 if (!W_ERROR_IS_OK(result
)) {
4312 DEBUG(5, ("winreg_get_driver_list: "
4313 "Could not open key (%s,%u): %s\n",
4314 architecture
, version
, win_errstr(result
)));
4319 result
= winreg_printer_enumkeys(tmp_ctx
,
4324 if (!W_ERROR_IS_OK(result
)) {
4325 DEBUG(0, ("winreg_get_driver_list: "
4326 "Could not enumerate drivers for (%s,%u): %s\n",
4327 architecture
, version
, win_errstr(result
)));
4331 *drivers_p
= talloc_steal(mem_ctx
, drivers
);
4335 if (winreg_pipe
!= NULL
) {
4336 if (is_valid_policy_hnd(&key_hnd
)) {
4337 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
4339 if (is_valid_policy_hnd(&hive_hnd
)) {
4340 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
4344 TALLOC_FREE(tmp_ctx
);