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 "nt_printing.h"
24 #include "srv_spoolss_util.h"
25 #include "../librpc/gen_ndr/ndr_spoolss.h"
26 #include "../librpc/gen_ndr/srv_winreg.h"
27 #include "../librpc/gen_ndr/cli_winreg.h"
28 #include "../librpc/gen_ndr/ndr_security.h"
31 #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
32 #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
33 #define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print"
34 #define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
36 #define EMPTY_STRING ""
38 #define FILL_STRING(mem_ctx, in, out) \
40 if (in && strlen(in)) { \
41 out = talloc_strdup(mem_ctx, in); \
43 out = talloc_strdup(mem_ctx, ""); \
45 W_ERROR_HAVE_NO_MEMORY(out); \
48 #define CHECK_ERROR(result) \
49 if (W_ERROR_IS_OK(result)) continue; \
50 if (W_ERROR_EQUAL(result, WERR_NOT_FOUND)) result = WERR_OK; \
51 if (!W_ERROR_IS_OK(result)) break
53 /* FLAGS, NAME, with, height, left, top, right, bottom */
54 static const struct spoolss_FormInfo1 builtin_forms1
[] = {
55 { SPOOLSS_FORM_BUILTIN
, "10x11", {0x3e030,0x44368}, {0x0,0x0,0x3e030,0x44368} },
56 { SPOOLSS_FORM_BUILTIN
, "10x14", {0x3e030,0x56d10}, {0x0,0x0,0x3e030,0x56d10} },
57 { SPOOLSS_FORM_BUILTIN
, "11x17", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
58 { SPOOLSS_FORM_BUILTIN
, "12x11", {0x4a724,0x443e1}, {0x0,0x0,0x4a724,0x443e1} },
59 { SPOOLSS_FORM_BUILTIN
, "15x11", {0x5d048,0x44368}, {0x0,0x0,0x5d048,0x44368} },
60 { SPOOLSS_FORM_BUILTIN
, "6 3/4 Envelope", {0x167ab,0x284ec}, {0x0,0x0,0x167ab,0x284ec} },
61 { SPOOLSS_FORM_BUILTIN
, "9x11", {0x37cf8,0x44368}, {0x0,0x0,0x37cf8,0x44368} },
62 { SPOOLSS_FORM_BUILTIN
, "A0", {0xcd528,0x122488},{0x0,0x0,0xcd528,0x122488} },
63 { SPOOLSS_FORM_BUILTIN
, "A1", {0x91050,0xcd528}, {0x0,0x0,0x91050,0xcd528} },
64 { SPOOLSS_FORM_BUILTIN
, "A2", {0x668a0,0x91050}, {0x0,0x0,0x668a0,0x91050} },
65 { SPOOLSS_FORM_BUILTIN
, "A3 Extra Transverse", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
66 { SPOOLSS_FORM_BUILTIN
, "A3 Extra", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
67 { SPOOLSS_FORM_BUILTIN
, "A3 Rotated", {0x668a0,0x48828}, {0x0,0x0,0x668a0,0x48828} },
68 { SPOOLSS_FORM_BUILTIN
, "A3 Transverse", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
69 { SPOOLSS_FORM_BUILTIN
, "A3", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
70 { SPOOLSS_FORM_BUILTIN
, "A4 Extra", {0x397c2,0x4eb16}, {0x0,0x0,0x397c2,0x4eb16} },
71 { SPOOLSS_FORM_BUILTIN
, "A4 Plus", {0x33450,0x50910}, {0x0,0x0,0x33450,0x50910} },
72 { SPOOLSS_FORM_BUILTIN
, "A4 Rotated", {0x48828,0x33450}, {0x0,0x0,0x48828,0x33450} },
73 { SPOOLSS_FORM_BUILTIN
, "A4 Small", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
74 { SPOOLSS_FORM_BUILTIN
, "A4 Transverse", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
75 { SPOOLSS_FORM_BUILTIN
, "A4", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
76 { SPOOLSS_FORM_BUILTIN
, "A5 Extra", {0x2a7b0,0x395f8}, {0x0,0x0,0x2a7b0,0x395f8} },
77 { SPOOLSS_FORM_BUILTIN
, "A5 Rotated", {0x33450,0x24220}, {0x0,0x0,0x33450,0x24220} },
78 { SPOOLSS_FORM_BUILTIN
, "A5 Transverse", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
79 { SPOOLSS_FORM_BUILTIN
, "A5", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
80 { SPOOLSS_FORM_BUILTIN
, "A6 Rotated", {0x24220,0x19a28}, {0x0,0x0,0x24220,0x19a28} },
81 { SPOOLSS_FORM_BUILTIN
, "A6", {0x19a28,0x24220}, {0x0,0x0,0x19a28,0x24220} },
82 { SPOOLSS_FORM_BUILTIN
, "B4 (ISO)", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
83 { SPOOLSS_FORM_BUILTIN
, "B4 (JIS) Rotated", {0x58de0,0x3ebe8}, {0x0,0x0,0x58de0,0x3ebe8} },
84 { SPOOLSS_FORM_BUILTIN
, "B4 (JIS)", {0x3ebe8,0x58de0}, {0x0,0x0,0x3ebe8,0x58de0} },
85 { SPOOLSS_FORM_BUILTIN
, "B5 (ISO) Extra", {0x31128,0x43620}, {0x0,0x0,0x31128,0x43620} },
86 { SPOOLSS_FORM_BUILTIN
, "B5 (JIS) Rotated", {0x3ebe8,0x2c6f0}, {0x0,0x0,0x3ebe8,0x2c6f0} },
87 { SPOOLSS_FORM_BUILTIN
, "B5 (JIS) Transverse", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
88 { SPOOLSS_FORM_BUILTIN
, "B5 (JIS)", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
89 { SPOOLSS_FORM_BUILTIN
, "B6 (JIS) Rotated", {0x2c6f0,0x1f400}, {0x0,0x0,0x2c6f0,0x1f400} },
90 { SPOOLSS_FORM_BUILTIN
, "B6 (JIS)", {0x1f400,0x2c6f0}, {0x0,0x0,0x1f400,0x2c6f0} },
91 { SPOOLSS_FORM_BUILTIN
, "C size sheet", {0x696b8,0x886d0}, {0x0,0x0,0x696b8,0x886d0} },
92 { SPOOLSS_FORM_BUILTIN
, "D size sheet", {0x886d0,0xd2d70}, {0x0,0x0,0x886d0,0xd2d70} },
93 { SPOOLSS_FORM_BUILTIN
, "Double Japan Postcard Rotated", {0x24220,0x30d40}, {0x0,0x0,0x24220,0x30d40} },
94 { SPOOLSS_FORM_BUILTIN
, "E size sheet", {0xd2d70,0x110da0},{0x0,0x0,0xd2d70,0x110da0} },
95 { SPOOLSS_FORM_BUILTIN
, "Envelope #10", {0x19947,0x3ae94}, {0x0,0x0,0x19947,0x3ae94} },
96 { SPOOLSS_FORM_BUILTIN
, "Envelope #11", {0x1be7c,0x40565}, {0x0,0x0,0x1be7c,0x40565} },
97 { SPOOLSS_FORM_BUILTIN
, "Envelope #12", {0x1d74a,0x44368}, {0x0,0x0,0x1d74a,0x44368} },
98 { SPOOLSS_FORM_BUILTIN
, "Envelope #14", {0x1f018,0x47504}, {0x0,0x0,0x1f018,0x47504} },
99 { SPOOLSS_FORM_BUILTIN
, "Envelope #9", {0x18079,0x37091}, {0x0,0x0,0x18079,0x37091} },
100 { SPOOLSS_FORM_BUILTIN
, "Envelope B4", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
101 { SPOOLSS_FORM_BUILTIN
, "Envelope B5", {0x2af80,0x3d090}, {0x0,0x0,0x2af80,0x3d090} },
102 { SPOOLSS_FORM_BUILTIN
, "Envelope B6", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
103 { SPOOLSS_FORM_BUILTIN
, "Envelope C3", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
104 { SPOOLSS_FORM_BUILTIN
, "Envelope C4", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
105 { SPOOLSS_FORM_BUILTIN
, "Envelope C5", {0x278d0,0x37e88}, {0x0,0x0,0x278d0,0x37e88} },
106 { SPOOLSS_FORM_BUILTIN
, "Envelope C6", {0x1bd50,0x278d0}, {0x0,0x0,0x1bd50,0x278d0} },
107 { SPOOLSS_FORM_BUILTIN
, "Envelope C65", {0x1bd50,0x37e88}, {0x0,0x0,0x1bd50,0x37e88} },
108 { SPOOLSS_FORM_BUILTIN
, "Envelope DL", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
109 { SPOOLSS_FORM_BUILTIN
, "Envelope Invite", {0x35b60,0x35b60}, {0x0,0x0,0x35b60,0x35b60} },
110 { SPOOLSS_FORM_BUILTIN
, "Envelope Monarch", {0x18079,0x2e824}, {0x0,0x0,0x18079,0x2e824} },
111 { SPOOLSS_FORM_BUILTIN
, "Envelope", {0x1adb0,0x38270}, {0x0,0x0,0x1adb0,0x38270} },
112 { SPOOLSS_FORM_BUILTIN
, "Executive", {0x2cf56,0x411cc}, {0x0,0x0,0x2cf56,0x411cc} },
113 { SPOOLSS_FORM_BUILTIN
, "Folio", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
114 { SPOOLSS_FORM_BUILTIN
, "German Legal Fanfold", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
115 { SPOOLSS_FORM_BUILTIN
, "German Std Fanfold", {0x34b5c,0x4a6a0}, {0x0,0x0,0x34b5c,0x4a6a0} },
116 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Chou #3 Rotated", {0x395f8,0x1d4c0}, {0x0,0x0,0x395f8,0x1d4c0} },
117 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Chou #4 Rotated", {0x320c8,0x15f90}, {0x0,0x0,0x320c8,0x15f90} },
118 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Kaku #2 Rotated", {0x510e0,0x3a980}, {0x0,0x0,0x510e0,0x3a980} },
119 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Kaku #3 Rotated", {0x43a08,0x34bc0}, {0x0,0x0,0x43a08,0x34bc0} },
120 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope You #4 Rotated", {0x395f8,0x19a28}, {0x0,0x0,0x395f8,0x19a28} },
121 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope You #4", {0x19a28,0x395f8}, {0x0,0x0,0x19a28,0x395f8} },
122 { SPOOLSS_FORM_BUILTIN
, "Japanese Double Postcard", {0x30d40,0x24220}, {0x0,0x0,0x30d40,0x24220} },
123 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Chou #3", {0x1d4c0,0x395f8}, {0x0,0x0,0x1d4c0,0x395f8} },
124 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Chou #4", {0x15f90,0x320c8}, {0x0,0x0,0x15f90,0x320c8} },
125 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Kaku #2", {0x3a980,0x510e0}, {0x0,0x0,0x3a980,0x510e0} },
126 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Kaku #3", {0x34bc0,0x43a08}, {0x0,0x0,0x34bc0,0x43a08} },
127 { SPOOLSS_FORM_BUILTIN
, "Japanese Postcard Rotated", {0x24220,0x186a0}, {0x0,0x0,0x24220,0x186a0} },
128 { SPOOLSS_FORM_BUILTIN
, "Japanese Postcard", {0x186a0,0x24220}, {0x0,0x0,0x186a0,0x24220} },
129 { SPOOLSS_FORM_BUILTIN
, "Ledger", {0x696b8,0x44368}, {0x0,0x0,0x696b8,0x44368} },
130 { SPOOLSS_FORM_BUILTIN
, "Legal Extra", {0x3ae94,0x5d048}, {0x0,0x0,0x3ae94,0x5d048} },
131 { SPOOLSS_FORM_BUILTIN
, "Legal", {0x34b5c,0x56d10}, {0x0,0x0,0x34b5c,0x56d10} },
132 { SPOOLSS_FORM_BUILTIN
, "Letter Extra Transverse", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
133 { SPOOLSS_FORM_BUILTIN
, "Letter Extra", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
134 { SPOOLSS_FORM_BUILTIN
, "Letter Plus", {0x34b5c,0x4eb16}, {0x0,0x0,0x34b5c,0x4eb16} },
135 { SPOOLSS_FORM_BUILTIN
, "Letter Rotated", {0x44368,0x34b5c}, {0x0,0x0,0x44368,0x34b5c} },
136 { SPOOLSS_FORM_BUILTIN
, "Letter Small", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
137 { SPOOLSS_FORM_BUILTIN
, "Letter Transverse", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
138 { SPOOLSS_FORM_BUILTIN
, "Letter", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
139 { SPOOLSS_FORM_BUILTIN
, "Note", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
140 { SPOOLSS_FORM_BUILTIN
, "PRC 16K Rotated", {0x3f7a0,0x2de60}, {0x0,0x0,0x3f7a0,0x2de60} },
141 { SPOOLSS_FORM_BUILTIN
, "PRC 16K", {0x2de60,0x3f7a0}, {0x0,0x0,0x2de60,0x3f7a0} },
142 { SPOOLSS_FORM_BUILTIN
, "PRC 32K Rotated", {0x2cec0,0x1fbd0}, {0x0,0x0,0x2cec0,0x1fbd0} },
143 { SPOOLSS_FORM_BUILTIN
, "PRC 32K", {0x1fbd0,0x2cec0}, {0x0,0x0,0x1fbd0,0x2cec0} },
144 { SPOOLSS_FORM_BUILTIN
, "PRC 32K(Big) Rotated", {0x318f8,0x222e0}, {0x0,0x0,0x318f8,0x222e0} },
145 { SPOOLSS_FORM_BUILTIN
, "PRC 32K(Big)", {0x222e0,0x318f8}, {0x0,0x0,0x222e0,0x318f8} },
146 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #1 Rotated", {0x28488,0x18e70}, {0x0,0x0,0x28488,0x18e70} },
147 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #1", {0x18e70,0x28488}, {0x0,0x0,0x18e70,0x28488} },
148 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #10 Rotated", {0x6fd10,0x4f1a0}, {0x0,0x0,0x6fd10,0x4f1a0} },
149 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #10", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
150 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #2 Rotated", {0x2af80,0x18e70}, {0x0,0x0,0x2af80,0x18e70} },
151 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #2", {0x18e70,0x2af80}, {0x0,0x0,0x18e70,0x2af80} },
152 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #3 Rotated", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
153 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #3", {0x1e848,0x2af80}, {0x0,0x0,0x1e848,0x2af80} },
154 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #4 Rotated", {0x32c80,0x1adb0}, {0x0,0x0,0x32c80,0x1adb0} },
155 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #4", {0x1adb0,0x32c80}, {0x0,0x0,0x1adb0,0x32c80} },
156 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #5 Rotated", {0x35b60,0x1adb0}, {0x0,0x0,0x35b60,0x1adb0} },
157 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #5", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
158 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #6 Rotated", {0x38270,0x1d4c0}, {0x0,0x0,0x38270,0x1d4c0} },
159 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #6", {0x1d4c0,0x38270}, {0x0,0x0,0x1d4c0,0x38270} },
160 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #7 Rotated", {0x38270,0x27100}, {0x0,0x0,0x38270,0x27100} },
161 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #7", {0x27100,0x38270}, {0x0,0x0,0x27100,0x38270} },
162 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #8 Rotated", {0x4b708,0x1d4c0}, {0x0,0x0,0x4b708,0x1d4c0} },
163 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #8", {0x1d4c0,0x4b708}, {0x0,0x0,0x1d4c0,0x4b708} },
164 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #9 Rotated", {0x4f1a0,0x37e88}, {0x0,0x0,0x4f1a0,0x37e88} },
165 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #9", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
166 { SPOOLSS_FORM_BUILTIN
, "Quarto", {0x347d8,0x43238}, {0x0,0x0,0x347d8,0x43238} },
167 { SPOOLSS_FORM_BUILTIN
, "Reserved48", {0x1,0x1}, {0x0,0x0,0x1,0x1} },
168 { SPOOLSS_FORM_BUILTIN
, "Reserved49", {0x1,0x1}, {0x0,0x0,0x1,0x1} },
169 { SPOOLSS_FORM_BUILTIN
, "Statement", {0x221b4,0x34b5c}, {0x0,0x0,0x221b4,0x34b5c} },
170 { SPOOLSS_FORM_BUILTIN
, "Super A", {0x376b8,0x56ea0}, {0x0,0x0,0x376b8,0x56ea0} },
171 { SPOOLSS_FORM_BUILTIN
, "Super B", {0x4a768,0x76e58}, {0x0,0x0,0x4a768,0x76e58} },
172 { SPOOLSS_FORM_BUILTIN
, "Tabloid Extra", {0x4a6a0,0x6f9f0}, {0x0,0x0,0x4a6a0,0x6f9f0} },
173 { SPOOLSS_FORM_BUILTIN
, "Tabloid", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
174 { SPOOLSS_FORM_BUILTIN
, "US Std Fanfold", {0x5c3e1,0x44368}, {0x0,0x0,0x5c3e1,0x44368} }
177 /********************************************************************
178 static helper functions
179 ********************************************************************/
181 /****************************************************************************
182 Update the changeid time.
183 ****************************************************************************/
187 * @brief Update the ChangeID time of a printer.
189 * This is SO NASTY as some drivers need this to change, others need it
190 * static. This value will change every second, and I must hope that this
191 * is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
194 * @return The ChangeID.
196 static uint32_t winreg_printer_rev_changeid(void)
200 get_process_uptime(&tv
);
203 /* Return changeid as msec since spooler restart */
204 return tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
207 * This setting seems to work well but is too untested
208 * to replace the above calculation. Left in for experiementation
209 * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002)
211 return tv
.tv_sec
* 10 + tv
.tv_usec
/ 100000;
218 * @brief Connect to the interal winreg server and open the given printer key.
220 * The function will create the needed subkeys if they don't exist.
222 * @param[in] mem_ctx The memory context to use.
224 * @param[in] server_info The supplied server info.
226 * @param[out] winreg_pipe A pointer for the winreg rpc client pipe.
228 * @param[in] path The path to the key to open.
230 * @param[in] key The key to open.
232 * @param[in] create_key Set to true if the key should be created if it
235 * @param[in] access_mask The access mask to open the key.
237 * @param[out] hive_handle A policy handle for the opened hive.
239 * @param[out] key_handle A policy handle for the opened key.
241 * @return WERR_OK on success, the corresponding DOS error
242 * code if something gone wrong.
244 static WERROR
winreg_printer_openkey(TALLOC_CTX
*mem_ctx
,
245 struct auth_serversupplied_info
*server_info
,
246 struct messaging_context
*msg_ctx
,
247 struct rpc_pipe_client
**winreg_pipe
,
251 uint32_t access_mask
,
252 struct policy_handle
*hive_handle
,
253 struct policy_handle
*key_handle
)
255 struct rpc_pipe_client
*pipe_handle
;
256 struct winreg_String wkey
, wkeyclass
;
259 WERROR result
= WERR_OK
;
261 /* create winreg connection */
262 status
= rpc_pipe_open_internal(mem_ctx
,
263 &ndr_table_winreg
.syntax_id
,
267 if (!NT_STATUS_IS_OK(status
)) {
268 DEBUG(0, ("winreg_printer_openkey: Could not connect to winreg_pipe: %s\n",
270 return ntstatus_to_werror(status
);
273 status
= rpccli_winreg_OpenHKLM(pipe_handle
,
279 if (!NT_STATUS_IS_OK(status
)) {
280 DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
282 talloc_free(pipe_handle
);
283 if (!W_ERROR_IS_OK(result
)) {
286 return ntstatus_to_werror(status
);
290 keyname
= talloc_asprintf(mem_ctx
, "%s\\%s", path
, key
);
292 keyname
= talloc_strdup(mem_ctx
, path
);
294 if (keyname
== NULL
) {
295 talloc_free(pipe_handle
);
303 enum winreg_CreateAction action
= REG_ACTION_NONE
;
305 ZERO_STRUCT(wkeyclass
);
308 status
= rpccli_winreg_CreateKey(pipe_handle
,
320 case REG_ACTION_NONE
:
321 DEBUG(8, ("winreg_printer_openkey:createkey did nothing -- huh?\n"));
323 case REG_CREATED_NEW_KEY
:
324 DEBUG(8, ("winreg_printer_openkey: createkey created %s\n", keyname
));
326 case REG_OPENED_EXISTING_KEY
:
327 DEBUG(8, ("winreg_printer_openkey: createkey opened existing %s\n", keyname
));
331 status
= rpccli_winreg_OpenKey(pipe_handle
,
340 if (!NT_STATUS_IS_OK(status
)) {
341 talloc_free(pipe_handle
);
342 if (!W_ERROR_IS_OK(result
)) {
345 return ntstatus_to_werror(status
);
348 *winreg_pipe
= pipe_handle
;
354 * @brief Create the registry keyname for the given printer.
356 * @param[in] mem_ctx The memory context to use.
358 * @param[in] printer The name of the printer to get the registry key.
360 * @return The registry key or NULL on error.
362 static char *winreg_printer_data_keyname(TALLOC_CTX
*mem_ctx
, const char *printer
) {
363 return talloc_asprintf(mem_ctx
, "%s\\%s", TOP_LEVEL_PRINT_PRINTERS_KEY
, printer
);
369 * @brief Enumerate values of an opened key handle and retrieve the data.
371 * @param[in] mem_ctx The memory context to use.
373 * @param[in] pipe_handle The pipe handle for the rpc connection.
375 * @param[in] key_hnd The opened key handle.
377 * @param[out] pnum_values A pointer to store he number of values found.
379 * @param[out] pnum_values A pointer to store the number of values we found.
381 * @return WERR_OK on success, the corresponding DOS error
382 * code if something gone wrong.
384 static WERROR
winreg_printer_enumvalues(TALLOC_CTX
*mem_ctx
,
385 struct rpc_pipe_client
*pipe_handle
,
386 struct policy_handle
*key_hnd
,
387 uint32_t *pnum_values
,
388 struct spoolss_PrinterEnumValues
**penum_values
)
391 uint32_t num_subkeys
, max_subkeylen
, max_classlen
;
392 uint32_t num_values
, max_valnamelen
, max_valbufsize
;
393 uint32_t secdescsize
;
395 NTTIME last_changed_time
;
396 struct winreg_String classname
;
398 struct spoolss_PrinterEnumValues
*enum_values
;
400 WERROR result
= WERR_OK
;
403 tmp_ctx
= talloc_stackframe();
404 if (tmp_ctx
== NULL
) {
408 ZERO_STRUCT(classname
);
410 status
= rpccli_winreg_QueryInfoKey(pipe_handle
,
423 if (!NT_STATUS_IS_OK(status
)) {
424 DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n",
426 if (!W_ERROR_IS_OK(result
)) {
429 result
= ntstatus_to_werror(status
);
433 if (num_values
== 0) {
435 TALLOC_FREE(tmp_ctx
);
439 enum_values
= TALLOC_ARRAY(tmp_ctx
, struct spoolss_PrinterEnumValues
, num_values
);
440 if (enum_values
== NULL
) {
445 for (i
= 0; i
< num_values
; i
++) {
446 struct spoolss_PrinterEnumValues val
;
447 struct winreg_ValNameBuf name_buf
;
448 enum winreg_Type type
= REG_NONE
;
455 name_buf
.size
= max_valnamelen
+ 2;
458 data_size
= max_valbufsize
;
461 data
= (uint8_t *) TALLOC(tmp_ctx
, data_size
);
465 status
= rpccli_winreg_EnumValue(pipe_handle
,
472 data_size
? &data_size
: NULL
,
475 if (W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
) ) {
477 status
= NT_STATUS_OK
;
481 if (!NT_STATUS_IS_OK(status
)) {
482 DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n",
484 if (!W_ERROR_IS_OK(result
)) {
487 result
= ntstatus_to_werror(status
);
491 if (name_buf
.name
== NULL
) {
492 result
= WERR_INVALID_PARAMETER
;
496 val
.value_name
= talloc_strdup(enum_values
, name_buf
.name
);
497 if (val
.value_name
== NULL
) {
501 val
.value_name_len
= strlen_m_term(val
.value_name
) * 2;
504 val
.data_length
= length
;
506 if (val
.data_length
) {
507 val
.data
= talloc(enum_values
, DATA_BLOB
);
508 if (val
.data
== NULL
) {
512 *val
.data
= data_blob_talloc(val
.data
, data
, val
.data_length
);
515 enum_values
[i
] = val
;
518 *pnum_values
= num_values
;
520 *penum_values
= talloc_move(mem_ctx
, &enum_values
);
526 TALLOC_FREE(tmp_ctx
);
533 * @brief Enumerate subkeys of an opened key handle and get the names.
535 * @param[in] mem_ctx The memory context to use.
537 * @param[in] pipe_handle The pipe handle for the rpc connection.
539 * @param[in] key_hnd The opened key handle.
541 * @param[in] pnum_subkeys A pointer to store the number of found subkeys.
543 * @param[in] psubkeys A pointer to an array to store the found names of
546 * @return WERR_OK on success, the corresponding DOS error
547 * code if something gone wrong.
549 static WERROR
winreg_printer_enumkeys(TALLOC_CTX
*mem_ctx
,
550 struct rpc_pipe_client
*pipe_handle
,
551 struct policy_handle
*key_hnd
,
552 uint32_t *pnum_subkeys
,
553 const char ***psubkeys
)
556 const char **subkeys
;
557 uint32_t num_subkeys
, max_subkeylen
, max_classlen
;
558 uint32_t num_values
, max_valnamelen
, max_valbufsize
;
560 NTTIME last_changed_time
;
561 uint32_t secdescsize
;
562 struct winreg_String classname
;
563 WERROR result
= WERR_OK
;
566 tmp_ctx
= talloc_stackframe();
567 if (tmp_ctx
== NULL
) {
571 ZERO_STRUCT(classname
);
573 status
= rpccli_winreg_QueryInfoKey(pipe_handle
,
586 if (!NT_STATUS_IS_OK(status
)) {
587 DEBUG(0, ("winreg_printer_enumkeys: Could not query info: %s\n",
589 if (!W_ERROR_IS_OK(result
)) {
592 result
= ntstatus_to_werror(status
);
596 subkeys
= talloc_zero_array(tmp_ctx
, const char *, num_subkeys
+ 2);
597 if (subkeys
== NULL
) {
602 if (num_subkeys
== 0) {
603 subkeys
[0] = talloc_strdup(subkeys
, "");
604 if (subkeys
[0] == NULL
) {
610 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
613 TALLOC_FREE(tmp_ctx
);
617 for (i
= 0; i
< num_subkeys
; i
++) {
621 struct winreg_StringBuf class_buf
;
622 struct winreg_StringBuf name_buf
;
626 class_buf
.size
= max_classlen
+ 2;
627 class_buf
.length
= 0;
630 name_buf
.size
= max_subkeylen
+ 2;
633 ZERO_STRUCT(modtime
);
635 status
= rpccli_winreg_EnumKey(pipe_handle
,
643 if (W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
) ) {
645 status
= NT_STATUS_OK
;
649 if (!NT_STATUS_IS_OK(status
)) {
650 DEBUG(0, ("winreg_printer_enumkeys: Could not enumerate keys: %s\n",
652 if (!W_ERROR_IS_OK(result
)) {
655 result
= ntstatus_to_werror(status
);
659 if (name_buf
.name
== NULL
) {
660 result
= WERR_INVALID_PARAMETER
;
664 name
= talloc_strdup(subkeys
, name_buf
.name
);
673 *pnum_subkeys
= num_subkeys
;
675 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
679 TALLOC_FREE(tmp_ctx
);
686 * @brief A function to delete a key and its subkeys recurively.
688 * @param[in] mem_ctx The memory context to use.
690 * @param[in] pipe_handle The pipe handle for the rpc connection.
692 * @param[in] hive_handle A opened hive handle to the key.
694 * @param[in] access_mask The access mask to access the key.
696 * @param[in] key The key to delete
698 * @return WERR_OK on success, the corresponding DOS error
699 * code if something gone wrong.
701 static WERROR
winreg_printer_delete_subkeys(TALLOC_CTX
*mem_ctx
,
702 struct rpc_pipe_client
*pipe_handle
,
703 struct policy_handle
*hive_handle
,
704 uint32_t access_mask
,
707 const char **subkeys
= NULL
;
708 uint32_t num_subkeys
= 0;
709 struct policy_handle key_hnd
;
710 struct winreg_String wkey
;
711 WERROR result
= WERR_OK
;
715 ZERO_STRUCT(key_hnd
);
718 DEBUG(2, ("winreg_printer_delete_subkeys: delete key %s\n", key
));
720 status
= rpccli_winreg_OpenKey(pipe_handle
,
728 if (!NT_STATUS_IS_OK(status
)) {
729 DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n",
730 wkey
.name
, nt_errstr(status
)));
731 if (!W_ERROR_IS_OK(result
)) {
734 return ntstatus_to_werror(status
);
737 result
= winreg_printer_enumkeys(mem_ctx
,
742 if (!W_ERROR_IS_OK(result
)) {
746 for (i
= 0; i
< num_subkeys
; i
++) {
747 /* create key + subkey */
748 char *subkey
= talloc_asprintf(mem_ctx
, "%s\\%s", key
, subkeys
[i
]);
749 if (subkey
== NULL
) {
753 DEBUG(2, ("winreg_printer_delete_subkeys: delete subkey %s\n", subkey
));
754 result
= winreg_printer_delete_subkeys(mem_ctx
,
759 if (!W_ERROR_IS_OK(result
)) {
764 if (is_valid_policy_hnd(&key_hnd
)) {
765 rpccli_winreg_CloseKey(pipe_handle
, mem_ctx
, &key_hnd
, NULL
);
770 status
= rpccli_winreg_DeleteKey(pipe_handle
,
777 if (is_valid_policy_hnd(&key_hnd
)) {
778 rpccli_winreg_CloseKey(pipe_handle
, mem_ctx
, &key_hnd
, NULL
);
784 static WERROR
winreg_printer_write_sz(TALLOC_CTX
*mem_ctx
,
785 struct rpc_pipe_client
*pipe_handle
,
786 struct policy_handle
*key_handle
,
790 struct winreg_String wvalue
;
792 WERROR result
= WERR_OK
;
797 blob
= data_blob_string_const("");
799 if (!push_reg_sz(mem_ctx
, &blob
, data
)) {
800 DEBUG(0, ("winreg_printer_write_sz: Could not marshall string %s for %s\n",
805 status
= rpccli_winreg_SetValue(pipe_handle
,
813 if (!NT_STATUS_IS_OK(status
)) {
814 DEBUG(0, ("winreg_printer_write_sz: Could not set value %s: %s\n",
815 wvalue
.name
, win_errstr(result
)));
816 if (!W_ERROR_IS_OK(result
)) {
817 result
= ntstatus_to_werror(status
);
824 static WERROR
winreg_printer_write_dword(TALLOC_CTX
*mem_ctx
,
825 struct rpc_pipe_client
*pipe_handle
,
826 struct policy_handle
*key_handle
,
830 struct winreg_String wvalue
;
832 WERROR result
= WERR_OK
;
836 blob
= data_blob_talloc(mem_ctx
, NULL
, 4);
837 SIVAL(blob
.data
, 0, data
);
839 status
= rpccli_winreg_SetValue(pipe_handle
,
847 if (!NT_STATUS_IS_OK(status
)) {
848 DEBUG(0, ("winreg_printer_write_dword: Could not set value %s: %s\n",
849 wvalue
.name
, win_errstr(result
)));
850 if (!W_ERROR_IS_OK(result
)) {
851 result
= ntstatus_to_werror(status
);
858 static WERROR
winreg_printer_write_binary(TALLOC_CTX
*mem_ctx
,
859 struct rpc_pipe_client
*pipe_handle
,
860 struct policy_handle
*key_handle
,
864 struct winreg_String wvalue
;
865 WERROR result
= WERR_OK
;
869 status
= rpccli_winreg_SetValue(pipe_handle
,
877 if (!NT_STATUS_IS_OK(status
)) {
878 DEBUG(0, ("winreg_printer_write_binary: Could not set value %s: %s\n",
879 wvalue
.name
, win_errstr(result
)));
880 if (!W_ERROR_IS_OK(result
)) {
881 result
= ntstatus_to_werror(status
);
888 static WERROR
winreg_printer_query_binary(TALLOC_CTX
*mem_ctx
,
889 struct rpc_pipe_client
*pipe_handle
,
890 struct policy_handle
*key_handle
,
894 struct winreg_String wvalue
;
895 enum winreg_Type type
;
896 WERROR result
= WERR_OK
;
897 uint32_t value_len
= 0;
898 uint32_t data_size
= 0;
903 status
= rpccli_winreg_QueryValue(pipe_handle
,
912 if (!NT_STATUS_IS_OK(status
)) {
913 DEBUG(2, ("winreg_printer_query_binary: Could not query value %s: %s\n",
914 wvalue
.name
, nt_errstr(status
)));
915 if (!W_ERROR_IS_OK(result
)) {
918 result
= ntstatus_to_werror(status
);
922 if (type
!= REG_BINARY
) {
923 result
= WERR_INVALID_DATATYPE
;
926 blob
= data_blob_talloc(mem_ctx
, NULL
, data_size
);
927 if (blob
.data
== NULL
) {
933 status
= rpccli_winreg_QueryValue(pipe_handle
,
942 if (!NT_STATUS_IS_OK(status
)) {
943 DEBUG(2, ("winreg_printer_query_binary: Could not query value %s: %s\n",
944 wvalue
.name
, nt_errstr(status
)));
945 if (!W_ERROR_IS_OK(result
)) {
946 result
= ntstatus_to_werror(status
);
952 data
->data
= blob
.data
;
953 data
->length
= blob
.length
;
959 static WERROR
winreg_printer_query_dword(TALLOC_CTX
*mem_ctx
,
960 struct rpc_pipe_client
*pipe_handle
,
961 struct policy_handle
*key_handle
,
965 struct winreg_String wvalue
;
966 enum winreg_Type type
;
967 WERROR result
= WERR_OK
;
968 uint32_t value_len
= 0;
969 uint32_t data_size
= 0;
974 status
= rpccli_winreg_QueryValue(pipe_handle
,
983 if (!NT_STATUS_IS_OK(status
)) {
984 DEBUG(2, ("winreg_printer_query_dword: Could not query value %s: %s\n",
985 wvalue
.name
, nt_errstr(status
)));
986 if (!W_ERROR_IS_OK(result
)) {
989 result
= ntstatus_to_werror(status
);
993 if (type
!= REG_DWORD
) {
994 result
= WERR_INVALID_DATATYPE
;
998 if (data_size
!= 4) {
999 result
= WERR_INVALID_DATA
;
1003 blob
= data_blob_talloc(mem_ctx
, NULL
, data_size
);
1004 if (blob
.data
== NULL
) {
1005 result
= WERR_NOMEM
;
1010 status
= rpccli_winreg_QueryValue(pipe_handle
,
1019 if (!NT_STATUS_IS_OK(status
)) {
1020 DEBUG(2, ("winreg_printer_query_dword: Could not query value %s: %s\n",
1021 wvalue
.name
, nt_errstr(status
)));
1022 if (!W_ERROR_IS_OK(result
)) {
1023 result
= ntstatus_to_werror(status
);
1029 *data
= IVAL(blob
.data
, 0);
1035 static WERROR
winreg_printer_write_multi_sz(TALLOC_CTX
*mem_ctx
,
1036 struct rpc_pipe_client
*pipe_handle
,
1037 struct policy_handle
*key_handle
,
1041 struct winreg_String wvalue
;
1043 WERROR result
= WERR_OK
;
1046 wvalue
.name
= value
;
1047 if (!push_reg_multi_sz(mem_ctx
, &blob
, data
)) {
1050 status
= rpccli_winreg_SetValue(pipe_handle
,
1058 if (!NT_STATUS_IS_OK(status
)) {
1059 DEBUG(0, ("winreg_printer_write_multi_sz: Could not set value %s: %s\n",
1060 wvalue
.name
, win_errstr(result
)));
1061 if (!W_ERROR_IS_OK(result
)) {
1062 result
= ntstatus_to_werror(status
);
1069 static WERROR
winreg_printer_opendriver(TALLOC_CTX
*mem_ctx
,
1070 struct auth_serversupplied_info
*server_info
,
1071 struct messaging_context
*msg_ctx
,
1072 const char *drivername
,
1073 const char *architecture
,
1075 uint32_t access_mask
,
1077 struct rpc_pipe_client
**winreg_pipe
,
1078 struct policy_handle
*hive_hnd
,
1079 struct policy_handle
*key_hnd
)
1084 key_name
= talloc_asprintf(mem_ctx
, "%s\\Environments\\%s\\Drivers\\Version-%u",
1085 TOP_LEVEL_CONTROL_KEY
,
1086 architecture
, version
);
1091 result
= winreg_printer_openkey(mem_ctx
,
1104 static WERROR
winreg_enumval_to_dword(TALLOC_CTX
*mem_ctx
,
1105 struct spoolss_PrinterEnumValues
*v
,
1106 const char *valuename
, uint32_t *dw
)
1108 /* just return if it is not the one we are looking for */
1109 if (strcmp(valuename
, v
->value_name
) != 0) {
1110 return WERR_NOT_FOUND
;
1113 if (v
->type
!= REG_DWORD
) {
1114 return WERR_INVALID_DATATYPE
;
1117 if (v
->data_length
!= 4) {
1122 *dw
= IVAL(v
->data
->data
, 0);
1126 static WERROR
winreg_enumval_to_sz(TALLOC_CTX
*mem_ctx
,
1127 struct spoolss_PrinterEnumValues
*v
,
1128 const char *valuename
, const char **_str
)
1130 /* just return if it is not the one we are looking for */
1131 if (strcmp(valuename
, v
->value_name
) != 0) {
1132 return WERR_NOT_FOUND
;
1135 if (v
->type
!= REG_SZ
) {
1136 return WERR_INVALID_DATATYPE
;
1139 if (v
->data_length
== 0) {
1140 *_str
= talloc_strdup(mem_ctx
, EMPTY_STRING
);
1141 if (*_str
== NULL
) {
1147 if (!pull_reg_sz(mem_ctx
, v
->data
, _str
)) {
1154 static WERROR
winreg_enumval_to_multi_sz(TALLOC_CTX
*mem_ctx
,
1155 struct spoolss_PrinterEnumValues
*v
,
1156 const char *valuename
,
1157 const char ***array
)
1159 /* just return if it is not the one we are looking for */
1160 if (strcmp(valuename
, v
->value_name
) != 0) {
1161 return WERR_NOT_FOUND
;
1164 if (v
->type
!= REG_MULTI_SZ
) {
1165 return WERR_INVALID_DATATYPE
;
1168 if (v
->data_length
== 0) {
1169 *array
= talloc_array(mem_ctx
, const char *, 1);
1170 if (*array
== NULL
) {
1177 if (!pull_reg_multi_sz(mem_ctx
, v
->data
, array
)) {
1184 static WERROR
winreg_printer_write_date(TALLOC_CTX
*mem_ctx
,
1185 struct rpc_pipe_client
*pipe_handle
,
1186 struct policy_handle
*key_handle
,
1190 struct winreg_String wvalue
;
1192 WERROR result
= WERR_OK
;
1198 t
= nt_time_to_unix(data
);
1200 str
= talloc_asprintf(mem_ctx
, "%02d/%02d/%04d",
1201 tm
->tm_mon
+ 1, tm
->tm_mday
, tm
->tm_year
+ 1900);
1206 wvalue
.name
= value
;
1207 if (!push_reg_sz(mem_ctx
, &blob
, str
)) {
1210 status
= rpccli_winreg_SetValue(pipe_handle
,
1218 if (!NT_STATUS_IS_OK(status
)) {
1219 DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
1220 wvalue
.name
, win_errstr(result
)));
1221 if (!W_ERROR_IS_OK(result
)) {
1222 result
= ntstatus_to_werror(status
);
1229 static WERROR
winreg_printer_date_to_NTTIME(const char *str
, NTTIME
*data
)
1236 if (sscanf(str
, "%d/%d/%d",
1237 &tm
.tm_mon
, &tm
.tm_mday
, &tm
.tm_year
) != 3) {
1238 return WERR_INVALID_PARAMETER
;
1245 unix_to_nt_time(data
, t
);
1250 static WERROR
winreg_printer_write_ver(TALLOC_CTX
*mem_ctx
,
1251 struct rpc_pipe_client
*pipe_handle
,
1252 struct policy_handle
*key_handle
,
1256 struct winreg_String wvalue
;
1258 WERROR result
= WERR_OK
;
1262 /* FIXME: check format is right,
1263 * this needs to be something like: 6.1.7600.16385 */
1264 str
= talloc_asprintf(mem_ctx
, "%u.%u.%u.%u",
1265 (unsigned)((data
>> 48) & 0xFFFF),
1266 (unsigned)((data
>> 32) & 0xFFFF),
1267 (unsigned)((data
>> 16) & 0xFFFF),
1268 (unsigned)(data
& 0xFFFF));
1273 wvalue
.name
= value
;
1274 if (!push_reg_sz(mem_ctx
, &blob
, str
)) {
1277 status
= rpccli_winreg_SetValue(pipe_handle
,
1285 if (!NT_STATUS_IS_OK(status
)) {
1286 DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
1287 wvalue
.name
, win_errstr(result
)));
1288 if (!W_ERROR_IS_OK(result
)) {
1289 result
= ntstatus_to_werror(status
);
1296 static WERROR
winreg_printer_ver_to_dword(const char *str
, uint64_t *data
)
1298 unsigned int v1
, v2
, v3
, v4
;
1300 if (sscanf(str
, "%u.%u.%u.%u", &v1
, &v2
, &v3
, &v4
) != 4) {
1301 return WERR_INVALID_PARAMETER
;
1304 *data
= ((uint64_t)(v1
& 0xFFFF) << 48) +
1305 ((uint64_t)(v2
& 0xFFFF) << 32) +
1306 ((uint64_t)(v3
& 0xFFFF) << 16) +
1307 (uint64_t)(v2
& 0xFFFF);
1312 /********************************************************************
1313 Public winreg function for spoolss
1314 ********************************************************************/
1316 WERROR
winreg_create_printer(TALLOC_CTX
*mem_ctx
,
1317 struct auth_serversupplied_info
*server_info
,
1318 struct messaging_context
*msg_ctx
,
1319 const char *servername
,
1320 const char *sharename
)
1322 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1323 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1324 struct policy_handle hive_hnd
, key_hnd
;
1325 struct spoolss_SetPrinterInfo2
*info2
;
1326 struct security_descriptor
*secdesc
;
1327 struct winreg_String wkey
, wkeyclass
;
1329 const char *subkeys
[] = { SPOOL_DSDRIVER_KEY
, SPOOL_DSSPOOLER_KEY
, SPOOL_PRINTERDATA_KEY
};
1330 uint32_t i
, count
= ARRAY_SIZE(subkeys
);
1331 uint32_t info2_mask
= 0;
1332 WERROR result
= WERR_OK
;
1333 TALLOC_CTX
*tmp_ctx
;
1335 tmp_ctx
= talloc_stackframe();
1336 if (tmp_ctx
== NULL
) {
1340 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
1342 TALLOC_FREE(tmp_ctx
);
1346 ZERO_STRUCT(hive_hnd
);
1347 ZERO_STRUCT(key_hnd
);
1349 result
= winreg_printer_openkey(tmp_ctx
,
1359 if (W_ERROR_IS_OK(result
)) {
1360 DEBUG(2, ("winreg_create_printer: Skipping, %s already exists\n", path
));
1362 } else if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
1363 DEBUG(2, ("winreg_create_printer: Creating default values in %s\n", path
));
1364 } else if (!W_ERROR_IS_OK(result
)) {
1365 DEBUG(0, ("winreg_create_printer: Could not open key %s: %s\n",
1366 path
, win_errstr(result
)));
1370 /* Create the main key */
1371 result
= winreg_printer_openkey(tmp_ctx
,
1381 if (!W_ERROR_IS_OK(result
)) {
1382 DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
1383 path
, win_errstr(result
)));
1387 if (is_valid_policy_hnd(&key_hnd
)) {
1388 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1391 /* Create subkeys */
1392 for (i
= 0; i
< count
; i
++) {
1394 enum winreg_CreateAction action
= REG_ACTION_NONE
;
1396 ZERO_STRUCT(key_hnd
);
1399 wkey
.name
= talloc_asprintf(tmp_ctx
, "%s\\%s", path
, subkeys
[i
]);
1400 if (wkey
.name
== NULL
) {
1401 result
= WERR_NOMEM
;
1405 ZERO_STRUCT(wkeyclass
);
1406 wkeyclass
.name
= "";
1408 status
= rpccli_winreg_CreateKey(winreg_pipe
,
1419 if (!NT_STATUS_IS_OK(status
)) {
1420 DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
1421 wkey
.name
, win_errstr(result
)));
1422 if (!W_ERROR_IS_OK(result
)) {
1423 result
= ntstatus_to_werror(status
);
1430 const char *dnssuffix
;
1431 const char *longname
;
1432 const char *uncname
;
1434 result
= winreg_printer_write_sz(tmp_ctx
,
1437 SPOOL_REG_PRINTERNAME
,
1439 if (!W_ERROR_IS_OK(result
)) {
1443 result
= winreg_printer_write_sz(tmp_ctx
,
1446 SPOOL_REG_SHORTSERVERNAME
,
1448 if (!W_ERROR_IS_OK(result
)) {
1452 /* We make the assumption that the netbios name
1453 * is the same as the DNS name since the former
1454 * will be what we used to join the domain
1456 dnssuffix
= get_mydnsdomname(tmp_ctx
);
1457 if (dnssuffix
!= NULL
&& dnssuffix
[0] != '\0') {
1458 longname
= talloc_asprintf(tmp_ctx
, "%s.%s", global_myname(), dnssuffix
);
1460 longname
= talloc_strdup(tmp_ctx
, global_myname());
1462 if (longname
== NULL
) {
1463 result
= WERR_NOMEM
;
1467 result
= winreg_printer_write_sz(tmp_ctx
,
1470 SPOOL_REG_SERVERNAME
,
1472 if (!W_ERROR_IS_OK(result
)) {
1476 uncname
= talloc_asprintf(tmp_ctx
, "\\\\%s\\%s",
1477 longname
, sharename
);
1478 if (uncname
== NULL
) {
1479 result
= WERR_NOMEM
;
1483 result
= winreg_printer_write_sz(tmp_ctx
,
1488 if (!W_ERROR_IS_OK(result
)) {
1492 result
= winreg_printer_write_dword(tmp_ctx
,
1495 SPOOL_REG_VERSIONNUMBER
,
1497 if (!W_ERROR_IS_OK(result
)) {
1501 result
= winreg_printer_write_dword(tmp_ctx
,
1504 SPOOL_REG_PRINTSTARTTIME
,
1506 if (!W_ERROR_IS_OK(result
)) {
1510 result
= winreg_printer_write_dword(tmp_ctx
,
1513 SPOOL_REG_PRINTENDTIME
,
1515 if (!W_ERROR_IS_OK(result
)) {
1519 result
= winreg_printer_write_dword(tmp_ctx
,
1524 if (!W_ERROR_IS_OK(result
)) {
1528 result
= winreg_printer_write_dword(tmp_ctx
,
1531 SPOOL_REG_PRINTKEEPPRINTEDJOBS
,
1533 if (!W_ERROR_IS_OK(result
)) {
1541 if (is_valid_policy_hnd(&key_hnd
)) {
1542 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1545 info2
= talloc_zero(tmp_ctx
, struct spoolss_SetPrinterInfo2
);
1546 if (info2
== NULL
) {
1547 result
= WERR_NOMEM
;
1551 if (servername
!= NULL
) {
1552 info2
->printername
= talloc_asprintf(tmp_ctx
, "\\\\%s\\%s",
1553 servername
, sharename
);
1555 info2
->printername
= sharename
;
1557 if (info2
->printername
== NULL
) {
1558 result
= WERR_NOMEM
;
1561 info2_mask
|= SPOOLSS_PRINTER_INFO_PRINTERNAME
;
1563 info2
->sharename
= sharename
;
1564 info2_mask
|= SPOOLSS_PRINTER_INFO_SHARENAME
;
1566 info2
->portname
= SAMBA_PRINTER_PORT_NAME
;
1567 info2_mask
|= SPOOLSS_PRINTER_INFO_PORTNAME
;
1569 info2
->printprocessor
= "winprint";
1570 info2_mask
|= SPOOLSS_PRINTER_INFO_PRINTPROCESSOR
;
1572 info2
->datatype
= "RAW";
1573 info2_mask
|= SPOOLSS_PRINTER_INFO_DATATYPE
;
1575 info2
->comment
= "";
1576 info2_mask
|= SPOOLSS_PRINTER_INFO_COMMENT
;
1578 info2
->attributes
= PRINTER_ATTRIBUTE_SAMBA
;
1579 info2_mask
|= SPOOLSS_PRINTER_INFO_ATTRIBUTES
;
1581 info2
->starttime
= 0; /* Minutes since 12:00am GMT */
1582 info2_mask
|= SPOOLSS_PRINTER_INFO_STARTTIME
;
1584 info2
->untiltime
= 0; /* Minutes since 12:00am GMT */
1585 info2_mask
|= SPOOLSS_PRINTER_INFO_UNTILTIME
;
1587 info2
->priority
= 1;
1588 info2_mask
|= SPOOLSS_PRINTER_INFO_PRIORITY
;
1590 info2
->defaultpriority
= 1;
1591 info2_mask
|= SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY
;
1593 result
= spoolss_create_default_secdesc(tmp_ctx
, &secdesc
);
1594 if (!W_ERROR_IS_OK(result
)) {
1597 info2_mask
|= SPOOLSS_PRINTER_INFO_SECDESC
;
1600 * Don't write a default Device Mode to the registry! The Device Mode is
1601 * only written to disk with a SetPrinter level 2 or 8.
1604 result
= winreg_update_printer(tmp_ctx
,
1614 if (winreg_pipe
!= NULL
) {
1615 if (is_valid_policy_hnd(&key_hnd
)) {
1616 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1618 if (is_valid_policy_hnd(&hive_hnd
)) {
1619 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1623 talloc_free(tmp_ctx
);
1627 WERROR
winreg_update_printer(TALLOC_CTX
*mem_ctx
,
1628 struct auth_serversupplied_info
*server_info
,
1629 struct messaging_context
*msg_ctx
,
1630 const char *sharename
,
1631 uint32_t info2_mask
,
1632 struct spoolss_SetPrinterInfo2
*info2
,
1633 struct spoolss_DeviceMode
*devmode
,
1634 struct security_descriptor
*secdesc
)
1636 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1637 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1638 struct policy_handle hive_hnd
, key_hnd
;
1639 int snum
= lp_servicenumber(sharename
);
1640 enum ndr_err_code ndr_err
;
1643 WERROR result
= WERR_OK
;
1644 TALLOC_CTX
*tmp_ctx
;
1646 tmp_ctx
= talloc_stackframe();
1647 if (tmp_ctx
== NULL
) {
1651 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
1653 TALLOC_FREE(tmp_ctx
);
1657 ZERO_STRUCT(hive_hnd
);
1658 ZERO_STRUCT(key_hnd
);
1660 result
= winreg_printer_openkey(tmp_ctx
,
1670 if (!W_ERROR_IS_OK(result
)) {
1671 DEBUG(0, ("winreg_update_printer: Could not open key %s: %s\n",
1672 path
, win_errstr(result
)));
1676 if (info2_mask
& SPOOLSS_PRINTER_INFO_ATTRIBUTES
) {
1677 result
= winreg_printer_write_dword(tmp_ctx
,
1682 if (!W_ERROR_IS_OK(result
)) {
1688 if (info2_mask
& SPOOLSS_PRINTER_INFO_AVERAGEPPM
) {
1689 result
= winreg_printer_write_dword(tmp_ctx
,
1694 if (!W_ERROR_IS_OK(result
)) {
1700 if (info2_mask
& SPOOLSS_PRINTER_INFO_COMMENT
) {
1701 result
= winreg_printer_write_sz(tmp_ctx
,
1706 if (!W_ERROR_IS_OK(result
)) {
1711 if (info2_mask
& SPOOLSS_PRINTER_INFO_DATATYPE
) {
1712 result
= winreg_printer_write_sz(tmp_ctx
,
1717 if (!W_ERROR_IS_OK(result
)) {
1722 if (info2_mask
& SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY
) {
1723 result
= winreg_printer_write_dword(tmp_ctx
,
1727 info2
->defaultpriority
);
1728 if (!W_ERROR_IS_OK(result
)) {
1733 if (info2_mask
& SPOOLSS_PRINTER_INFO_DEVMODE
) {
1735 * Some client drivers freak out if there is a NULL devmode
1736 * (probably the driver is not checking before accessing
1737 * the devmode pointer) --jerry
1739 if (devmode
== NULL
&& lp_default_devmode(snum
) && info2
!= NULL
) {
1740 result
= spoolss_create_default_devmode(tmp_ctx
,
1743 if (!W_ERROR_IS_OK(result
)) {
1747 ndr_err
= ndr_push_struct_blob(&blob
, tmp_ctx
, devmode
,
1748 (ndr_push_flags_fn_t
) ndr_push_spoolss_DeviceMode
);
1749 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1750 DEBUG(0, ("winreg_update_printer: Failed to marshall device mode\n"));
1751 result
= WERR_NOMEM
;
1755 result
= winreg_printer_write_binary(tmp_ctx
,
1760 if (!W_ERROR_IS_OK(result
)) {
1765 if (info2_mask
& SPOOLSS_PRINTER_INFO_DRIVERNAME
) {
1766 result
= winreg_printer_write_sz(tmp_ctx
,
1771 if (!W_ERROR_IS_OK(result
)) {
1776 if (info2_mask
& SPOOLSS_PRINTER_INFO_LOCATION
) {
1777 result
= winreg_printer_write_sz(tmp_ctx
,
1782 if (!W_ERROR_IS_OK(result
)) {
1787 if (info2_mask
& SPOOLSS_PRINTER_INFO_PARAMETERS
) {
1788 result
= winreg_printer_write_sz(tmp_ctx
,
1793 if (!W_ERROR_IS_OK(result
)) {
1798 if (info2_mask
& SPOOLSS_PRINTER_INFO_PORTNAME
) {
1799 result
= winreg_printer_write_sz(tmp_ctx
,
1804 if (!W_ERROR_IS_OK(result
)) {
1809 if (info2_mask
& SPOOLSS_PRINTER_INFO_PRINTERNAME
) {
1811 * in addprinter: no servername and the printer is the name
1812 * in setprinter: servername is \\server
1813 * and printer is \\server\\printer
1815 * Samba manages only local printers.
1816 * we currently don't support things like i
1817 * path=\\other_server\printer
1819 * We only store the printername, not \\server\printername
1821 const char *p
= strrchr(info2
->printername
, '\\');
1823 p
= info2
->printername
;
1827 result
= winreg_printer_write_sz(tmp_ctx
,
1832 if (!W_ERROR_IS_OK(result
)) {
1837 if (info2_mask
& SPOOLSS_PRINTER_INFO_PRINTPROCESSOR
) {
1838 result
= winreg_printer_write_sz(tmp_ctx
,
1842 info2
->printprocessor
);
1843 if (!W_ERROR_IS_OK(result
)) {
1848 if (info2_mask
& SPOOLSS_PRINTER_INFO_PRIORITY
) {
1849 result
= winreg_printer_write_dword(tmp_ctx
,
1854 if (!W_ERROR_IS_OK(result
)) {
1859 if (info2_mask
& SPOOLSS_PRINTER_INFO_SECDESC
) {
1861 * We need a security descriptor, if it isn't specified by
1862 * AddPrinter{Ex} then create a default descriptor.
1864 if (secdesc
== NULL
) {
1865 result
= spoolss_create_default_secdesc(tmp_ctx
, &secdesc
);
1866 if (!W_ERROR_IS_OK(result
)) {
1870 result
= winreg_set_printer_secdesc(tmp_ctx
,
1875 if (!W_ERROR_IS_OK(result
)) {
1880 if (info2_mask
& SPOOLSS_PRINTER_INFO_SEPFILE
) {
1881 result
= winreg_printer_write_sz(tmp_ctx
,
1886 if (!W_ERROR_IS_OK(result
)) {
1891 if (info2_mask
& SPOOLSS_PRINTER_INFO_SHARENAME
) {
1892 result
= winreg_printer_write_sz(tmp_ctx
,
1897 if (!W_ERROR_IS_OK(result
)) {
1902 if (info2_mask
& SPOOLSS_PRINTER_INFO_STARTTIME
) {
1903 result
= winreg_printer_write_dword(tmp_ctx
,
1908 if (!W_ERROR_IS_OK(result
)) {
1913 if (info2_mask
& SPOOLSS_PRINTER_INFO_STATUS
) {
1914 result
= winreg_printer_write_dword(tmp_ctx
,
1919 if (!W_ERROR_IS_OK(result
)) {
1924 if (info2_mask
& SPOOLSS_PRINTER_INFO_UNTILTIME
) {
1925 result
= winreg_printer_write_dword(tmp_ctx
,
1930 if (!W_ERROR_IS_OK(result
)) {
1935 result
= winreg_printer_write_dword(tmp_ctx
,
1939 winreg_printer_rev_changeid());
1940 if (!W_ERROR_IS_OK(result
)) {
1946 if (winreg_pipe
!= NULL
) {
1947 if (is_valid_policy_hnd(&key_hnd
)) {
1948 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1950 if (is_valid_policy_hnd(&hive_hnd
)) {
1951 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1955 TALLOC_FREE(tmp_ctx
);
1959 WERROR
winreg_get_printer(TALLOC_CTX
*mem_ctx
,
1960 struct auth_serversupplied_info
*server_info
,
1961 struct messaging_context
*msg_ctx
,
1962 const char *servername
,
1963 const char *printer
,
1964 struct spoolss_PrinterInfo2
**pinfo2
)
1966 struct spoolss_PrinterInfo2
*info2
;
1967 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1968 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1969 struct policy_handle hive_hnd
, key_hnd
;
1970 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
1971 struct spoolss_PrinterEnumValues
*v
;
1972 enum ndr_err_code ndr_err
;
1974 int snum
= lp_servicenumber(printer
);
1975 uint32_t num_values
= 0;
1978 WERROR result
= WERR_OK
;
1979 TALLOC_CTX
*tmp_ctx
;
1981 tmp_ctx
= talloc_stackframe();
1982 if (tmp_ctx
== NULL
) {
1986 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
1988 TALLOC_FREE(tmp_ctx
);
1992 result
= winreg_printer_openkey(tmp_ctx
,
2002 if (!W_ERROR_IS_OK(result
)) {
2003 DEBUG(2, ("winreg_get_printer: Could not open key %s: %s\n",
2004 path
, win_errstr(result
)));
2008 result
= winreg_printer_enumvalues(tmp_ctx
,
2013 if (!W_ERROR_IS_OK(result
)) {
2014 DEBUG(0, ("winreg_get_printer: Could not enumerate values in %s: %s\n",
2015 path
, win_errstr(result
)));
2019 info2
= talloc_zero(tmp_ctx
, struct spoolss_PrinterInfo2
);
2020 if (info2
== NULL
) {
2021 result
= WERR_NOMEM
;
2025 FILL_STRING(info2
, EMPTY_STRING
, info2
->servername
);
2026 FILL_STRING(info2
, EMPTY_STRING
, info2
->printername
);
2027 FILL_STRING(info2
, EMPTY_STRING
, info2
->sharename
);
2028 FILL_STRING(info2
, EMPTY_STRING
, info2
->portname
);
2029 FILL_STRING(info2
, EMPTY_STRING
, info2
->drivername
);
2030 FILL_STRING(info2
, EMPTY_STRING
, info2
->comment
);
2031 FILL_STRING(info2
, EMPTY_STRING
, info2
->location
);
2032 FILL_STRING(info2
, EMPTY_STRING
, info2
->sepfile
);
2033 FILL_STRING(info2
, EMPTY_STRING
, info2
->printprocessor
);
2034 FILL_STRING(info2
, EMPTY_STRING
, info2
->datatype
);
2035 FILL_STRING(info2
, EMPTY_STRING
, info2
->parameters
);
2037 if (servername
!= NULL
&& servername
[0] != '\0') {
2038 info2
->servername
= talloc_asprintf(info2
, "\\\\%s", servername
);
2039 if (info2
->servername
== NULL
) {
2040 result
= WERR_NOMEM
;
2045 for (i
= 0; i
< num_values
; i
++) {
2046 v
= &enum_values
[i
];
2048 result
= winreg_enumval_to_sz(info2
,
2051 &info2
->printername
);
2052 CHECK_ERROR(result
);
2054 result
= winreg_enumval_to_sz(info2
,
2058 CHECK_ERROR(result
);
2060 result
= winreg_enumval_to_sz(info2
,
2064 CHECK_ERROR(result
);
2066 result
= winreg_enumval_to_sz(info2
,
2070 CHECK_ERROR(result
);
2072 result
= winreg_enumval_to_sz(info2
,
2076 CHECK_ERROR(result
);
2078 result
= winreg_enumval_to_sz(info2
,
2082 CHECK_ERROR(result
);
2084 result
= winreg_enumval_to_sz(info2
,
2087 &info2
->printprocessor
);
2088 CHECK_ERROR(result
);
2090 result
= winreg_enumval_to_sz(info2
,
2094 CHECK_ERROR(result
);
2096 result
= winreg_enumval_to_sz(info2
,
2099 &info2
->parameters
);
2100 CHECK_ERROR(result
);
2102 result
= winreg_enumval_to_sz(info2
,
2105 &info2
->drivername
);
2106 CHECK_ERROR(result
);
2108 result
= winreg_enumval_to_dword(info2
,
2111 &info2
->attributes
);
2112 CHECK_ERROR(result
);
2114 result
= winreg_enumval_to_dword(info2
,
2118 CHECK_ERROR(result
);
2120 result
= winreg_enumval_to_dword(info2
,
2123 &info2
->defaultpriority
);
2124 CHECK_ERROR(result
);
2126 result
= winreg_enumval_to_dword(info2
,
2130 CHECK_ERROR(result
);
2132 result
= winreg_enumval_to_dword(info2
,
2136 CHECK_ERROR(result
);
2138 result
= winreg_enumval_to_dword(info2
,
2142 CHECK_ERROR(result
);
2144 result
= winreg_enumval_to_dword(info2
,
2148 CHECK_ERROR(result
);
2151 if (!W_ERROR_IS_OK(result
)) {
2152 DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed "
2155 win_errstr(result
)));
2159 /* Create the printername */
2160 if (info2
->servername
!= NULL
&& info2
->servername
[0] != '\0') {
2161 if (lp_force_printername(snum
)) {
2162 const char *p
= talloc_asprintf(info2
, "%s\\%s",
2166 result
= WERR_NOMEM
;
2169 info2
->printername
= p
;
2171 char *p
= talloc_asprintf(info2
, "%s\\%s",
2173 info2
->printername
);
2175 result
= WERR_NOMEM
;
2178 info2
->printername
= p
;
2182 /* Construct the Device Mode */
2183 result
= winreg_printer_query_binary(tmp_ctx
,
2188 if (W_ERROR_IS_OK(result
)) {
2189 info2
->devmode
= talloc_zero(info2
, struct spoolss_DeviceMode
);
2190 if (info2
->devmode
== NULL
) {
2191 result
= WERR_NOMEM
;
2194 ndr_err
= ndr_pull_struct_blob(&blob
,
2197 (ndr_pull_flags_fn_t
) ndr_pull_spoolss_DeviceMode
);
2198 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2199 DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n"));
2200 result
= WERR_NOMEM
;
2205 if (info2
->devmode
== NULL
&& lp_default_devmode(snum
)) {
2206 result
= spoolss_create_default_devmode(info2
,
2209 if (!W_ERROR_IS_OK(result
)) {
2214 if (info2
->devmode
!= NULL
) {
2215 info2
->devmode
->devicename
= talloc_strdup(info2
->devmode
,
2216 info2
->printername
);
2217 if (info2
->devmode
->devicename
== NULL
) {
2218 DEBUG(0, ("winreg_get_printer: Failed to set devicename\n"));
2219 result
= WERR_NOMEM
;
2224 result
= winreg_get_printer_secdesc(info2
,
2229 if (!W_ERROR_IS_OK(result
)) {
2233 /* Fix for OS/2 drivers. */
2234 if (get_remote_arch() == RA_OS2
) {
2235 spoolss_map_to_os2_driver(info2
, &info2
->drivername
);
2239 *pinfo2
= talloc_move(mem_ctx
, &info2
);
2244 if (winreg_pipe
!= NULL
) {
2245 if (is_valid_policy_hnd(&key_hnd
)) {
2246 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2248 if (is_valid_policy_hnd(&hive_hnd
)) {
2249 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2253 TALLOC_FREE(tmp_ctx
);
2257 WERROR
winreg_get_printer_secdesc(TALLOC_CTX
*mem_ctx
,
2258 struct auth_serversupplied_info
*server_info
,
2259 struct messaging_context
*msg_ctx
,
2260 const char *sharename
,
2261 struct spoolss_security_descriptor
**psecdesc
)
2263 struct spoolss_security_descriptor
*secdesc
;
2264 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2265 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2266 struct policy_handle hive_hnd
, key_hnd
;
2267 enum ndr_err_code ndr_err
;
2270 TALLOC_CTX
*tmp_ctx
;
2273 tmp_ctx
= talloc_stackframe();
2274 if (tmp_ctx
== NULL
) {
2278 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
2280 talloc_free(tmp_ctx
);
2284 ZERO_STRUCT(hive_hnd
);
2285 ZERO_STRUCT(key_hnd
);
2287 result
= winreg_printer_openkey(tmp_ctx
,
2297 if (!W_ERROR_IS_OK(result
)) {
2298 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
2299 goto create_default
;
2304 result
= winreg_printer_query_binary(tmp_ctx
,
2309 if (!W_ERROR_IS_OK(result
)) {
2310 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
2311 goto create_default
;
2316 secdesc
= talloc_zero(tmp_ctx
, struct spoolss_security_descriptor
);
2317 if (secdesc
== NULL
) {
2318 result
= WERR_NOMEM
;
2321 ndr_err
= ndr_pull_struct_blob(&blob
,
2324 (ndr_pull_flags_fn_t
) ndr_pull_security_descriptor
);
2325 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2326 DEBUG(0, ("winreg_get_secdesc: Failed to unmarshall security descriptor\n"));
2327 result
= WERR_NOMEM
;
2332 *psecdesc
= talloc_move(mem_ctx
, &secdesc
);
2339 result
= spoolss_create_default_secdesc(tmp_ctx
, &secdesc
);
2340 if (!W_ERROR_IS_OK(result
)) {
2344 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
2345 this security descriptor has been created when winbindd was
2346 down. Take ownership of security descriptor. */
2347 if (sid_equal(secdesc
->owner_sid
, &global_sid_World
)) {
2348 struct dom_sid owner_sid
;
2350 /* Change sd owner to workgroup administrator */
2352 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid
)) {
2353 struct spoolss_security_descriptor
*new_secdesc
;
2357 sid_append_rid(&owner_sid
, DOMAIN_RID_ADMINISTRATOR
);
2359 new_secdesc
= make_sec_desc(tmp_ctx
,
2368 if (new_secdesc
== NULL
) {
2369 result
= WERR_NOMEM
;
2373 /* Swap with other one */
2374 secdesc
= new_secdesc
;
2378 ndr_err
= ndr_push_struct_blob(&blob
, tmp_ctx
, secdesc
,
2379 (ndr_push_flags_fn_t
) ndr_push_security_descriptor
);
2380 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2381 DEBUG(0, ("winreg_set_secdesc: Failed to marshall security descriptor\n"));
2382 result
= WERR_NOMEM
;
2386 result
= winreg_printer_write_binary(tmp_ctx
,
2391 if (!W_ERROR_IS_OK(result
)) {
2396 *psecdesc
= talloc_move(mem_ctx
, &secdesc
);
2401 if (winreg_pipe
!= NULL
) {
2402 if (is_valid_policy_hnd(&key_hnd
)) {
2403 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2405 if (is_valid_policy_hnd(&hive_hnd
)) {
2406 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2410 talloc_free(tmp_ctx
);
2414 WERROR
winreg_set_printer_secdesc(TALLOC_CTX
*mem_ctx
,
2415 struct auth_serversupplied_info
*server_info
,
2416 struct messaging_context
*msg_ctx
,
2417 const char *sharename
,
2418 const struct spoolss_security_descriptor
*secdesc
)
2420 const struct spoolss_security_descriptor
*new_secdesc
= secdesc
;
2421 struct spoolss_security_descriptor
*old_secdesc
;
2422 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2423 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2424 struct policy_handle hive_hnd
, key_hnd
;
2425 enum ndr_err_code ndr_err
;
2428 TALLOC_CTX
*tmp_ctx
;
2431 tmp_ctx
= talloc_stackframe();
2432 if (tmp_ctx
== NULL
) {
2436 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
2438 talloc_free(tmp_ctx
);
2443 * The old owner and group sids of the security descriptor are not
2444 * present when new ACEs are added or removed by changing printer
2445 * permissions through NT. If they are NULL in the new security
2446 * descriptor then copy them over from the old one.
2448 if (!secdesc
->owner_sid
|| !secdesc
->group_sid
) {
2449 struct dom_sid
*owner_sid
, *group_sid
;
2450 struct security_acl
*dacl
, *sacl
;
2453 result
= winreg_get_printer_secdesc(tmp_ctx
,
2458 if (!W_ERROR_IS_OK(result
)) {
2459 talloc_free(tmp_ctx
);
2463 /* Pick out correct owner and group sids */
2464 owner_sid
= secdesc
->owner_sid
?
2465 secdesc
->owner_sid
:
2466 old_secdesc
->owner_sid
;
2468 group_sid
= secdesc
->group_sid
?
2469 secdesc
->group_sid
:
2470 old_secdesc
->group_sid
;
2472 dacl
= secdesc
->dacl
?
2476 sacl
= secdesc
->sacl
?
2480 /* Make a deep copy of the security descriptor */
2481 new_secdesc
= make_sec_desc(tmp_ctx
,
2489 if (new_secdesc
== NULL
) {
2490 talloc_free(tmp_ctx
);
2495 ZERO_STRUCT(hive_hnd
);
2496 ZERO_STRUCT(key_hnd
);
2498 result
= winreg_printer_openkey(tmp_ctx
,
2508 if (!W_ERROR_IS_OK(result
)) {
2512 ndr_err
= ndr_push_struct_blob(&blob
, tmp_ctx
, new_secdesc
,
2513 (ndr_push_flags_fn_t
) ndr_push_security_descriptor
);
2514 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2515 DEBUG(0, ("winreg_set_secdesc: Failed to marshall security descriptor\n"));
2516 result
= WERR_NOMEM
;
2520 result
= winreg_printer_write_binary(tmp_ctx
,
2527 if (winreg_pipe
!= NULL
) {
2528 if (is_valid_policy_hnd(&key_hnd
)) {
2529 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2531 if (is_valid_policy_hnd(&hive_hnd
)) {
2532 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2536 talloc_free(tmp_ctx
);
2540 /* Set printer data over the winreg pipe. */
2541 WERROR
winreg_set_printer_dataex(TALLOC_CTX
*mem_ctx
,
2542 struct auth_serversupplied_info
*server_info
,
2543 struct messaging_context
*msg_ctx
,
2544 const char *printer
,
2547 enum winreg_Type type
,
2551 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2552 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2553 struct policy_handle hive_hnd
, key_hnd
;
2554 struct winreg_String wvalue
;
2556 WERROR result
= WERR_OK
;
2558 TALLOC_CTX
*tmp_ctx
;
2560 tmp_ctx
= talloc_stackframe();
2561 if (tmp_ctx
== NULL
) {
2565 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2567 TALLOC_FREE(tmp_ctx
);
2571 ZERO_STRUCT(hive_hnd
);
2572 ZERO_STRUCT(key_hnd
);
2574 DEBUG(8, ("winreg_set_printer_dataex: Open printer key %s, value %s, access_mask: 0x%05x for [%s]\n",
2575 key
, value
, access_mask
, printer
));
2576 result
= winreg_printer_openkey(tmp_ctx
,
2586 if (!W_ERROR_IS_OK(result
)) {
2587 DEBUG(0, ("winreg_set_printer_dataex: Could not open key %s: %s\n",
2588 key
, win_errstr(result
)));
2592 wvalue
.name
= value
;
2593 status
= rpccli_winreg_SetValue(winreg_pipe
,
2601 if (!NT_STATUS_IS_OK(status
)) {
2602 DEBUG(0, ("winreg_set_printer_dataex: Could not set value %s: %s\n",
2603 value
, nt_errstr(status
)));
2604 if (!W_ERROR_IS_OK(result
)) {
2607 result
= ntstatus_to_werror(status
);
2613 if (winreg_pipe
!= NULL
) {
2614 if (is_valid_policy_hnd(&key_hnd
)) {
2615 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2617 if (is_valid_policy_hnd(&hive_hnd
)) {
2618 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2622 TALLOC_FREE(tmp_ctx
);
2626 /* Get printer data over a winreg pipe. */
2627 WERROR
winreg_get_printer_dataex(TALLOC_CTX
*mem_ctx
,
2628 struct auth_serversupplied_info
*server_info
,
2629 struct messaging_context
*msg_ctx
,
2630 const char *printer
,
2633 enum winreg_Type
*type
,
2635 uint32_t *data_size
)
2637 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2638 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2639 struct policy_handle hive_hnd
, key_hnd
;
2640 struct winreg_String wvalue
;
2641 enum winreg_Type type_in
;
2644 uint32_t data_in_size
= 0;
2645 uint32_t value_len
= 0;
2646 WERROR result
= WERR_OK
;
2648 TALLOC_CTX
*tmp_ctx
;
2650 tmp_ctx
= talloc_stackframe();
2651 if (tmp_ctx
== NULL
) {
2655 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2657 TALLOC_FREE(tmp_ctx
);
2661 ZERO_STRUCT(hive_hnd
);
2662 ZERO_STRUCT(key_hnd
);
2664 result
= winreg_printer_openkey(tmp_ctx
,
2674 if (!W_ERROR_IS_OK(result
)) {
2675 DEBUG(2, ("winreg_get_printer_dataex: Could not open key %s: %s\n",
2676 key
, win_errstr(result
)));
2680 wvalue
.name
= value
;
2683 * call QueryValue once with data == NULL to get the
2684 * needed memory size to be allocated, then allocate
2685 * data buffer and call again.
2687 status
= rpccli_winreg_QueryValue(winreg_pipe
,
2696 if (!NT_STATUS_IS_OK(status
)) {
2697 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
2698 value
, nt_errstr(status
)));
2699 if (!W_ERROR_IS_OK(result
)) {
2702 result
= ntstatus_to_werror(status
);
2706 data_in
= (uint8_t *) TALLOC(tmp_ctx
, data_in_size
);
2707 if (data_in
== NULL
) {
2708 result
= WERR_NOMEM
;
2713 status
= rpccli_winreg_QueryValue(winreg_pipe
,
2722 if (!NT_STATUS_IS_OK(status
)) {
2723 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
2724 value
, nt_errstr(status
)));
2725 if (!W_ERROR_IS_OK(result
)) {
2726 result
= ntstatus_to_werror(status
);
2732 *data_size
= data_in_size
;
2734 *data
= talloc_move(mem_ctx
, &data_in
);
2739 if (winreg_pipe
!= NULL
) {
2740 if (is_valid_policy_hnd(&key_hnd
)) {
2741 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2743 if (is_valid_policy_hnd(&hive_hnd
)) {
2744 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2748 TALLOC_FREE(tmp_ctx
);
2752 /* Enumerate on the values of a given key and provide the data. */
2753 WERROR
winreg_enum_printer_dataex(TALLOC_CTX
*mem_ctx
,
2754 struct auth_serversupplied_info
*server_info
,
2755 struct messaging_context
*msg_ctx
,
2756 const char *printer
,
2758 uint32_t *pnum_values
,
2759 struct spoolss_PrinterEnumValues
**penum_values
)
2761 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2762 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2763 struct policy_handle hive_hnd
, key_hnd
;
2765 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
2766 uint32_t num_values
= 0;
2768 WERROR result
= WERR_OK
;
2770 TALLOC_CTX
*tmp_ctx
;
2772 tmp_ctx
= talloc_stackframe();
2773 if (tmp_ctx
== NULL
) {
2777 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2779 TALLOC_FREE(tmp_ctx
);
2783 result
= winreg_printer_openkey(tmp_ctx
,
2793 if (!W_ERROR_IS_OK(result
)) {
2794 DEBUG(2, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
2795 key
, win_errstr(result
)));
2799 result
= winreg_printer_enumvalues(tmp_ctx
,
2804 if (!W_ERROR_IS_OK(result
)) {
2805 DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
2806 key
, win_errstr(result
)));
2810 *pnum_values
= num_values
;
2812 *penum_values
= talloc_move(mem_ctx
, &enum_values
);
2817 if (winreg_pipe
!= NULL
) {
2818 if (is_valid_policy_hnd(&key_hnd
)) {
2819 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2821 if (is_valid_policy_hnd(&hive_hnd
)) {
2822 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2826 TALLOC_FREE(tmp_ctx
);
2830 /* Delete printer data over a winreg pipe. */
2831 WERROR
winreg_delete_printer_dataex(TALLOC_CTX
*mem_ctx
,
2832 struct auth_serversupplied_info
*server_info
,
2833 struct messaging_context
*msg_ctx
,
2834 const char *printer
,
2838 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2839 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2840 struct policy_handle hive_hnd
, key_hnd
;
2841 struct winreg_String wvalue
;
2843 WERROR result
= WERR_OK
;
2846 TALLOC_CTX
*tmp_ctx
;
2848 tmp_ctx
= talloc_stackframe();
2849 if (tmp_ctx
== NULL
) {
2853 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2855 TALLOC_FREE(tmp_ctx
);
2859 ZERO_STRUCT(hive_hnd
);
2860 ZERO_STRUCT(key_hnd
);
2862 result
= winreg_printer_openkey(tmp_ctx
,
2872 if (!W_ERROR_IS_OK(result
)) {
2873 DEBUG(0, ("winreg_delete_printer_dataex: Could not open key %s: %s\n",
2874 key
, win_errstr(result
)));
2878 wvalue
.name
= value
;
2879 status
= rpccli_winreg_DeleteValue(winreg_pipe
,
2884 if (!NT_STATUS_IS_OK(status
)) {
2885 DEBUG(0, ("winreg_delete_printer_dataex: Could not delete value %s: %s\n",
2886 value
, nt_errstr(status
)));
2887 if (!W_ERROR_IS_OK(result
)) {
2890 result
= ntstatus_to_werror(status
);
2896 if (winreg_pipe
!= NULL
) {
2897 if (is_valid_policy_hnd(&key_hnd
)) {
2898 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2900 if (is_valid_policy_hnd(&hive_hnd
)) {
2901 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2905 TALLOC_FREE(tmp_ctx
);
2909 /* Enumerate on the subkeys of a given key and provide the data. */
2910 WERROR
winreg_enum_printer_key(TALLOC_CTX
*mem_ctx
,
2911 struct auth_serversupplied_info
*server_info
,
2912 struct messaging_context
*msg_ctx
,
2913 const char *printer
,
2915 uint32_t *pnum_subkeys
,
2916 const char ***psubkeys
)
2918 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2919 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2920 struct policy_handle hive_hnd
, key_hnd
;
2922 const char **subkeys
= NULL
;
2923 uint32_t num_subkeys
= -1;
2925 WERROR result
= WERR_OK
;
2927 TALLOC_CTX
*tmp_ctx
;
2929 tmp_ctx
= talloc_stackframe();
2930 if (tmp_ctx
== NULL
) {
2934 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2936 TALLOC_FREE(tmp_ctx
);
2940 ZERO_STRUCT(hive_hnd
);
2941 ZERO_STRUCT(key_hnd
);
2943 result
= winreg_printer_openkey(tmp_ctx
,
2953 if (!W_ERROR_IS_OK(result
)) {
2954 DEBUG(2, ("winreg_enum_printer_key: Could not open key %s: %s\n",
2955 key
, win_errstr(result
)));
2959 result
= winreg_printer_enumkeys(tmp_ctx
,
2964 if (!W_ERROR_IS_OK(result
)) {
2965 DEBUG(0, ("winreg_enum_printer_key: Could not enumerate subkeys in %s: %s\n",
2966 key
, win_errstr(result
)));
2970 *pnum_subkeys
= num_subkeys
;
2972 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
2977 if (winreg_pipe
!= NULL
) {
2978 if (is_valid_policy_hnd(&key_hnd
)) {
2979 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2981 if (is_valid_policy_hnd(&hive_hnd
)) {
2982 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2986 TALLOC_FREE(tmp_ctx
);
2990 /* Delete a key with subkeys of a given printer. */
2991 WERROR
winreg_delete_printer_key(TALLOC_CTX
*mem_ctx
,
2992 struct auth_serversupplied_info
*server_info
,
2993 struct messaging_context
*msg_ctx
,
2994 const char *printer
,
2997 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2998 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2999 struct policy_handle hive_hnd
, key_hnd
;
3003 TALLOC_CTX
*tmp_ctx
;
3005 tmp_ctx
= talloc_stackframe();
3006 if (tmp_ctx
== NULL
) {
3010 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
3012 TALLOC_FREE(tmp_ctx
);
3016 result
= winreg_printer_openkey(tmp_ctx
,
3026 if (!W_ERROR_IS_OK(result
)) {
3027 /* key doesn't exist */
3028 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
3033 DEBUG(0, ("winreg_delete_printer_key: Could not open key %s: %s\n",
3034 key
, win_errstr(result
)));
3038 if (is_valid_policy_hnd(&key_hnd
)) {
3039 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3042 if (key
== NULL
|| key
[0] == '\0') {
3045 keyname
= talloc_asprintf(tmp_ctx
,
3049 if (keyname
== NULL
) {
3050 result
= WERR_NOMEM
;
3055 result
= winreg_printer_delete_subkeys(tmp_ctx
,
3060 if (!W_ERROR_IS_OK(result
)) {
3061 DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
3062 key
, win_errstr(result
)));
3067 if (winreg_pipe
!= NULL
) {
3068 if (is_valid_policy_hnd(&key_hnd
)) {
3069 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3071 if (is_valid_policy_hnd(&hive_hnd
)) {
3072 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3076 TALLOC_FREE(tmp_ctx
);
3080 WERROR
winreg_printer_update_changeid(TALLOC_CTX
*mem_ctx
,
3081 struct auth_serversupplied_info
*server_info
,
3082 struct messaging_context
*msg_ctx
,
3083 const char *printer
)
3085 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3086 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3087 struct policy_handle hive_hnd
, key_hnd
;
3090 TALLOC_CTX
*tmp_ctx
;
3092 tmp_ctx
= talloc_stackframe();
3093 if (tmp_ctx
== NULL
) {
3097 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
3099 TALLOC_FREE(tmp_ctx
);
3103 ZERO_STRUCT(hive_hnd
);
3104 ZERO_STRUCT(key_hnd
);
3106 result
= winreg_printer_openkey(tmp_ctx
,
3116 if (!W_ERROR_IS_OK(result
)) {
3117 DEBUG(0, ("winreg_printer_update_changeid: Could not open key %s: %s\n",
3118 path
, win_errstr(result
)));
3122 result
= winreg_printer_write_dword(tmp_ctx
,
3126 winreg_printer_rev_changeid());
3127 if (!W_ERROR_IS_OK(result
)) {
3133 if (winreg_pipe
!= NULL
) {
3134 if (is_valid_policy_hnd(&key_hnd
)) {
3135 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3137 if (is_valid_policy_hnd(&hive_hnd
)) {
3138 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3142 TALLOC_FREE(tmp_ctx
);
3146 WERROR
winreg_printer_get_changeid(TALLOC_CTX
*mem_ctx
,
3147 struct auth_serversupplied_info
*server_info
,
3148 struct messaging_context
*msg_ctx
,
3149 const char *printer
,
3150 uint32_t *pchangeid
)
3152 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3153 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3154 struct policy_handle hive_hnd
, key_hnd
;
3155 uint32_t changeid
= 0;
3158 TALLOC_CTX
*tmp_ctx
;
3160 tmp_ctx
= talloc_stackframe();
3161 if (tmp_ctx
== NULL
) {
3165 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
3167 TALLOC_FREE(tmp_ctx
);
3171 ZERO_STRUCT(hive_hnd
);
3172 ZERO_STRUCT(key_hnd
);
3174 result
= winreg_printer_openkey(tmp_ctx
,
3184 if (!W_ERROR_IS_OK(result
)) {
3185 DEBUG(2, ("winreg_printer_get_changeid: Could not open key %s: %s\n",
3186 path
, win_errstr(result
)));
3190 DEBUG(10, ("winreg_printer_get_changeid: get changeid from %s\n", path
));
3192 result
= winreg_printer_query_dword(tmp_ctx
,
3197 if (!W_ERROR_IS_OK(result
)) {
3202 *pchangeid
= changeid
;
3207 if (winreg_pipe
!= NULL
) {
3208 if (is_valid_policy_hnd(&key_hnd
)) {
3209 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3211 if (is_valid_policy_hnd(&hive_hnd
)) {
3212 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3216 TALLOC_FREE(tmp_ctx
);
3221 * The special behaviour of the spoolss forms is documented at the website:
3223 * Managing Win32 Printserver Forms
3224 * http://unixwiz.net/techtips/winspooler-forms.html
3227 WERROR
winreg_printer_addform1(TALLOC_CTX
*mem_ctx
,
3228 struct auth_serversupplied_info
*server_info
,
3229 struct messaging_context
*msg_ctx
,
3230 struct spoolss_AddFormInfo1
*form
)
3232 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3233 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3234 struct policy_handle hive_hnd
, key_hnd
;
3235 struct winreg_String wvalue
;
3237 uint32_t num_info
= 0;
3238 union spoolss_FormInfo
*info
= NULL
;
3242 TALLOC_CTX
*tmp_ctx
;
3244 tmp_ctx
= talloc_stackframe();
3245 if (tmp_ctx
== NULL
) {
3249 ZERO_STRUCT(hive_hnd
);
3250 ZERO_STRUCT(key_hnd
);
3252 result
= winreg_printer_openkey(tmp_ctx
,
3256 TOP_LEVEL_CONTROL_FORMS_KEY
,
3262 if (!W_ERROR_IS_OK(result
)) {
3263 DEBUG(0, ("winreg_printer_addform1: Could not open key %s: %s\n",
3264 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3268 result
= winreg_printer_enumforms1(tmp_ctx
, server_info
, msg_ctx
,
3270 if (!W_ERROR_IS_OK(result
)) {
3271 DEBUG(0, ("winreg_printer_addform: Could not enum keys %s: %s\n",
3272 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3276 /* If form name already exists or is builtin return ALREADY_EXISTS */
3277 for (i
= 0; i
< num_info
; i
++) {
3278 if (strequal(info
[i
].info1
.form_name
, form
->form_name
)) {
3279 result
= WERR_FILE_EXISTS
;
3284 wvalue
.name
= form
->form_name
;
3286 blob
= data_blob_talloc(tmp_ctx
, NULL
, 32);
3287 SIVAL(blob
.data
, 0, form
->size
.width
);
3288 SIVAL(blob
.data
, 4, form
->size
.height
);
3289 SIVAL(blob
.data
, 8, form
->area
.left
);
3290 SIVAL(blob
.data
, 12, form
->area
.top
);
3291 SIVAL(blob
.data
, 16, form
->area
.right
);
3292 SIVAL(blob
.data
, 20, form
->area
.bottom
);
3293 SIVAL(blob
.data
, 24, num_info
+ 1); /* FIXME */
3294 SIVAL(blob
.data
, 28, form
->flags
);
3296 status
= rpccli_winreg_SetValue(winreg_pipe
,
3304 if (!NT_STATUS_IS_OK(status
)) {
3305 DEBUG(0, ("winreg_printer_addform1: Could not set value %s: %s\n",
3306 wvalue
.name
, nt_errstr(status
)));
3307 if (!W_ERROR_IS_OK(result
)) {
3310 result
= ntstatus_to_werror(status
);
3316 if (winreg_pipe
!= NULL
) {
3317 if (is_valid_policy_hnd(&key_hnd
)) {
3318 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3320 if (is_valid_policy_hnd(&hive_hnd
)) {
3321 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3326 TALLOC_FREE(tmp_ctx
);
3330 WERROR
winreg_printer_enumforms1(TALLOC_CTX
*mem_ctx
,
3331 struct auth_serversupplied_info
*server_info
,
3332 struct messaging_context
*msg_ctx
,
3333 uint32_t *pnum_info
,
3334 union spoolss_FormInfo
**pinfo
)
3336 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3337 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3338 struct policy_handle hive_hnd
, key_hnd
;
3339 union spoolss_FormInfo
*info
;
3340 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
3341 uint32_t num_values
= 0;
3342 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3345 TALLOC_CTX
*tmp_ctx
;
3347 tmp_ctx
= talloc_stackframe();
3348 if (tmp_ctx
== NULL
) {
3352 ZERO_STRUCT(hive_hnd
);
3353 ZERO_STRUCT(key_hnd
);
3355 result
= winreg_printer_openkey(tmp_ctx
,
3359 TOP_LEVEL_CONTROL_FORMS_KEY
,
3365 if (!W_ERROR_IS_OK(result
)) {
3366 /* key doesn't exist */
3367 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
3372 DEBUG(0, ("winreg_printer_enumforms1: Could not open key %s: %s\n",
3373 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3377 result
= winreg_printer_enumvalues(tmp_ctx
,
3382 if (!W_ERROR_IS_OK(result
)) {
3383 DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n",
3384 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3388 info
= TALLOC_ARRAY(tmp_ctx
, union spoolss_FormInfo
, num_builtin
+ num_values
);
3390 result
= WERR_NOMEM
;
3394 /* Enumerate BUILTIN forms */
3395 for (i
= 0; i
< num_builtin
; i
++) {
3396 info
[i
].info1
= builtin_forms1
[i
];
3399 /* Enumerate registry forms */
3400 for (i
= 0; i
< num_values
; i
++) {
3401 union spoolss_FormInfo val
;
3403 if (enum_values
[i
].type
!= REG_BINARY
||
3404 enum_values
[i
].data_length
!= 32) {
3408 val
.info1
.form_name
= talloc_strdup(info
, enum_values
[i
].value_name
);
3409 if (val
.info1
.form_name
== NULL
) {
3410 result
= WERR_NOMEM
;
3414 val
.info1
.size
.width
= IVAL(enum_values
[i
].data
->data
, 0);
3415 val
.info1
.size
.height
= IVAL(enum_values
[i
].data
->data
, 4);
3416 val
.info1
.area
.left
= IVAL(enum_values
[i
].data
->data
, 8);
3417 val
.info1
.area
.top
= IVAL(enum_values
[i
].data
->data
, 12);
3418 val
.info1
.area
.right
= IVAL(enum_values
[i
].data
->data
, 16);
3419 val
.info1
.area
.bottom
= IVAL(enum_values
[i
].data
->data
, 20);
3420 /* skip form index IVAL(enum_values[i].data->data, 24)));*/
3421 val
.info1
.flags
= (enum spoolss_FormFlags
) IVAL(enum_values
[i
].data
->data
, 28);
3423 info
[i
+ num_builtin
] = val
;
3426 *pnum_info
= num_builtin
+ num_values
;
3428 *pinfo
= talloc_move(mem_ctx
, &info
);
3432 if (winreg_pipe
!= NULL
) {
3433 if (is_valid_policy_hnd(&key_hnd
)) {
3434 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3436 if (is_valid_policy_hnd(&hive_hnd
)) {
3437 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3441 TALLOC_FREE(enum_values
);
3442 TALLOC_FREE(tmp_ctx
);
3446 WERROR
winreg_printer_deleteform1(TALLOC_CTX
*mem_ctx
,
3447 struct auth_serversupplied_info
*server_info
,
3448 struct messaging_context
*msg_ctx
,
3449 const char *form_name
)
3451 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3452 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3453 struct policy_handle hive_hnd
, key_hnd
;
3454 struct winreg_String wvalue
;
3455 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3457 WERROR result
= WERR_OK
;
3459 TALLOC_CTX
*tmp_ctx
;
3461 for (i
= 0; i
< num_builtin
; i
++) {
3462 if (strequal(builtin_forms1
[i
].form_name
, form_name
)) {
3463 return WERR_INVALID_PARAMETER
;
3467 tmp_ctx
= talloc_stackframe();
3468 if (tmp_ctx
== NULL
) {
3472 ZERO_STRUCT(hive_hnd
);
3473 ZERO_STRUCT(key_hnd
);
3475 result
= winreg_printer_openkey(tmp_ctx
,
3479 TOP_LEVEL_CONTROL_FORMS_KEY
,
3485 if (!W_ERROR_IS_OK(result
)) {
3486 DEBUG(0, ("winreg_printer_deleteform1: Could not open key %s: %s\n",
3487 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3488 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
3489 result
= WERR_INVALID_FORM_NAME
;
3494 wvalue
.name
= form_name
;
3495 status
= rpccli_winreg_DeleteValue(winreg_pipe
,
3500 if (!NT_STATUS_IS_OK(status
)) {
3501 /* If the value doesn't exist, return WERR_INVALID_FORM_NAME */
3502 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
3503 result
= WERR_INVALID_FORM_NAME
;
3506 DEBUG(0, ("winreg_printer_delteform1: Could not delete value %s: %s\n",
3507 wvalue
.name
, nt_errstr(status
)));
3508 if (!W_ERROR_IS_OK(result
)) {
3511 result
= ntstatus_to_werror(status
);
3517 if (winreg_pipe
!= NULL
) {
3518 if (is_valid_policy_hnd(&key_hnd
)) {
3519 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3521 if (is_valid_policy_hnd(&hive_hnd
)) {
3522 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3526 TALLOC_FREE(tmp_ctx
);
3530 WERROR
winreg_printer_setform1(TALLOC_CTX
*mem_ctx
,
3531 struct auth_serversupplied_info
*server_info
,
3532 struct messaging_context
*msg_ctx
,
3533 const char *form_name
,
3534 struct spoolss_AddFormInfo1
*form
)
3536 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3537 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3538 struct policy_handle hive_hnd
, key_hnd
;
3539 struct winreg_String wvalue
;
3541 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3545 TALLOC_CTX
*tmp_ctx
= NULL
;
3547 for (i
= 0; i
< num_builtin
; i
++) {
3548 if (strequal(builtin_forms1
[i
].form_name
, form
->form_name
)) {
3549 result
= WERR_INVALID_PARAM
;
3554 tmp_ctx
= talloc_stackframe();
3555 if (tmp_ctx
== NULL
) {
3559 ZERO_STRUCT(hive_hnd
);
3560 ZERO_STRUCT(key_hnd
);
3562 result
= winreg_printer_openkey(tmp_ctx
,
3566 TOP_LEVEL_CONTROL_FORMS_KEY
,
3572 if (!W_ERROR_IS_OK(result
)) {
3573 DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
3574 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3578 /* If form_name != form->form_name then we renamed the form */
3579 if (strequal(form_name
, form
->form_name
)) {
3580 result
= winreg_printer_deleteform1(tmp_ctx
, server_info
,
3581 msg_ctx
, form_name
);
3582 if (!W_ERROR_IS_OK(result
)) {
3583 DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
3584 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3589 wvalue
.name
= form
->form_name
;
3591 blob
= data_blob_talloc(tmp_ctx
, NULL
, 32);
3592 SIVAL(blob
.data
, 0, form
->size
.width
);
3593 SIVAL(blob
.data
, 4, form
->size
.height
);
3594 SIVAL(blob
.data
, 8, form
->area
.left
);
3595 SIVAL(blob
.data
, 12, form
->area
.top
);
3596 SIVAL(blob
.data
, 16, form
->area
.right
);
3597 SIVAL(blob
.data
, 20, form
->area
.bottom
);
3598 SIVAL(blob
.data
, 24, 42);
3599 SIVAL(blob
.data
, 28, form
->flags
);
3601 status
= rpccli_winreg_SetValue(winreg_pipe
,
3609 if (!NT_STATUS_IS_OK(status
)) {
3610 DEBUG(0, ("winreg_printer_setform1: Could not set value %s: %s\n",
3611 wvalue
.name
, nt_errstr(status
)));
3612 if (!W_ERROR_IS_OK(result
)) {
3615 result
= ntstatus_to_werror(status
);
3621 if (winreg_pipe
!= NULL
) {
3622 if (is_valid_policy_hnd(&key_hnd
)) {
3623 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3625 if (is_valid_policy_hnd(&hive_hnd
)) {
3626 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3630 TALLOC_FREE(tmp_ctx
);
3634 WERROR
winreg_printer_getform1(TALLOC_CTX
*mem_ctx
,
3635 struct auth_serversupplied_info
*server_info
,
3636 struct messaging_context
*msg_ctx
,
3637 const char *form_name
,
3638 struct spoolss_FormInfo1
*r
)
3640 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3641 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3642 struct policy_handle hive_hnd
, key_hnd
;
3643 struct winreg_String wvalue
;
3644 enum winreg_Type type_in
;
3646 uint32_t data_in_size
= 0;
3647 uint32_t value_len
= 0;
3648 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3652 TALLOC_CTX
*tmp_ctx
;
3654 /* check builtin forms first */
3655 for (i
= 0; i
< num_builtin
; i
++) {
3656 if (strequal(builtin_forms1
[i
].form_name
, form_name
)) {
3657 *r
= builtin_forms1
[i
];
3662 tmp_ctx
= talloc_stackframe();
3663 if (tmp_ctx
== NULL
) {
3667 ZERO_STRUCT(hive_hnd
);
3668 ZERO_STRUCT(key_hnd
);
3670 result
= winreg_printer_openkey(tmp_ctx
,
3674 TOP_LEVEL_CONTROL_FORMS_KEY
,
3680 if (!W_ERROR_IS_OK(result
)) {
3681 DEBUG(2, ("winreg_printer_getform1: Could not open key %s: %s\n",
3682 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3686 wvalue
.name
= form_name
;
3689 * call QueryValue once with data == NULL to get the
3690 * needed memory size to be allocated, then allocate
3691 * data buffer and call again.
3693 status
= rpccli_winreg_QueryValue(winreg_pipe
,
3702 if (!NT_STATUS_IS_OK(status
)) {
3703 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
3704 wvalue
.name
, nt_errstr(status
)));
3705 if (!W_ERROR_IS_OK(result
)) {
3708 result
= ntstatus_to_werror(status
);
3712 data_in
= (uint8_t *) TALLOC(tmp_ctx
, data_in_size
);
3713 if (data_in
== NULL
) {
3714 result
= WERR_NOMEM
;
3719 status
= rpccli_winreg_QueryValue(winreg_pipe
,
3728 if (!NT_STATUS_IS_OK(status
)) {
3729 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
3730 wvalue
.name
, nt_errstr(status
)));
3731 if (!W_ERROR_IS_OK(result
)) {
3734 result
= ntstatus_to_werror(status
);
3738 r
->form_name
= talloc_strdup(mem_ctx
, form_name
);
3739 if (r
->form_name
== NULL
) {
3740 result
= WERR_NOMEM
;
3744 r
->size
.width
= IVAL(data_in
, 0);
3745 r
->size
.height
= IVAL(data_in
, 4);
3746 r
->area
.left
= IVAL(data_in
, 8);
3747 r
->area
.top
= IVAL(data_in
, 12);
3748 r
->area
.right
= IVAL(data_in
, 16);
3749 r
->area
.bottom
= IVAL(data_in
, 20);
3750 /* skip index IVAL(data_in, 24)));*/
3751 r
->flags
= (enum spoolss_FormFlags
) IVAL(data_in
, 28);
3755 if (winreg_pipe
!= NULL
) {
3756 if (is_valid_policy_hnd(&key_hnd
)) {
3757 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3759 if (is_valid_policy_hnd(&hive_hnd
)) {
3760 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3764 TALLOC_FREE(tmp_ctx
);
3768 WERROR
winreg_add_driver(TALLOC_CTX
*mem_ctx
,
3769 struct auth_serversupplied_info
*server_info
,
3770 struct messaging_context
*msg_ctx
,
3771 struct spoolss_AddDriverInfoCtr
*r
,
3772 const char **driver_name
,
3773 uint32_t *driver_version
)
3775 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3776 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3777 struct policy_handle hive_hnd
, key_hnd
;
3778 struct spoolss_DriverInfo8 info8
;
3779 TALLOC_CTX
*tmp_ctx
= NULL
;
3782 ZERO_STRUCT(hive_hnd
);
3783 ZERO_STRUCT(key_hnd
);
3786 if (!driver_info_ctr_to_info8(r
, &info8
)) {
3787 result
= WERR_INVALID_PARAMETER
;
3791 tmp_ctx
= talloc_stackframe();
3792 if (tmp_ctx
== NULL
) {
3796 result
= winreg_printer_opendriver(tmp_ctx
,
3806 if (!W_ERROR_IS_OK(result
)) {
3807 DEBUG(0, ("winreg_add_driver: "
3808 "Could not open driver key (%s,%s,%d): %s\n",
3809 info8
.driver_name
, info8
.architecture
,
3810 info8
.version
, win_errstr(result
)));
3814 /* TODO: "Attributes" ? */
3816 result
= winreg_printer_write_dword(tmp_ctx
, winreg_pipe
,
3817 &key_hnd
, "Version",
3819 if (!W_ERROR_IS_OK(result
)) {
3823 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3826 if (!W_ERROR_IS_OK(result
)) {
3830 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3831 &key_hnd
, "Data File",
3833 if (!W_ERROR_IS_OK(result
)) {
3837 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3838 &key_hnd
, "Configuration File",
3840 if (!W_ERROR_IS_OK(result
)) {
3844 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3845 &key_hnd
, "Help File",
3847 if (!W_ERROR_IS_OK(result
)) {
3851 result
= winreg_printer_write_multi_sz(tmp_ctx
, winreg_pipe
,
3852 &key_hnd
, "Dependent Files",
3853 info8
.dependent_files
);
3854 if (!W_ERROR_IS_OK(result
)) {
3858 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3859 &key_hnd
, "Monitor",
3860 info8
.monitor_name
);
3861 if (!W_ERROR_IS_OK(result
)) {
3865 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3866 &key_hnd
, "Datatype",
3867 info8
.default_datatype
);
3868 if (!W_ERROR_IS_OK(result
)) {
3872 result
= winreg_printer_write_multi_sz(tmp_ctx
, winreg_pipe
,
3873 &key_hnd
, "Previous Names",
3874 info8
.previous_names
);
3875 if (!W_ERROR_IS_OK(result
)) {
3879 result
= winreg_printer_write_date(tmp_ctx
, winreg_pipe
,
3880 &key_hnd
, "DriverDate",
3882 if (!W_ERROR_IS_OK(result
)) {
3886 result
= winreg_printer_write_ver(tmp_ctx
, winreg_pipe
,
3887 &key_hnd
, "DriverVersion",
3888 info8
.driver_version
);
3889 if (!W_ERROR_IS_OK(result
)) {
3893 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3894 &key_hnd
, "Manufacturer",
3895 info8
.manufacturer_name
);
3896 if (!W_ERROR_IS_OK(result
)) {
3900 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3901 &key_hnd
, "OEM URL",
3902 info8
.manufacturer_url
);
3903 if (!W_ERROR_IS_OK(result
)) {
3907 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3908 &key_hnd
, "HardwareID",
3910 if (!W_ERROR_IS_OK(result
)) {
3914 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3915 &key_hnd
, "Provider",
3917 if (!W_ERROR_IS_OK(result
)) {
3921 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3922 &key_hnd
, "Print Processor",
3923 info8
.print_processor
);
3924 if (!W_ERROR_IS_OK(result
)) {
3928 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3929 &key_hnd
, "VendorSetup",
3930 info8
.vendor_setup
);
3931 if (!W_ERROR_IS_OK(result
)) {
3935 result
= winreg_printer_write_multi_sz(tmp_ctx
, winreg_pipe
,
3936 &key_hnd
, "Color Profiles",
3937 info8
.color_profiles
);
3938 if (!W_ERROR_IS_OK(result
)) {
3942 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3943 &key_hnd
, "InfPath",
3945 if (!W_ERROR_IS_OK(result
)) {
3949 result
= winreg_printer_write_dword(tmp_ctx
, winreg_pipe
, &key_hnd
,
3950 "PrinterDriverAttributes",
3951 info8
.printer_driver_attributes
);
3952 if (!W_ERROR_IS_OK(result
)) {
3956 result
= winreg_printer_write_multi_sz(tmp_ctx
, winreg_pipe
,
3957 &key_hnd
, "CoreDependencies",
3958 info8
.core_driver_dependencies
);
3959 if (!W_ERROR_IS_OK(result
)) {
3963 result
= winreg_printer_write_date(tmp_ctx
, winreg_pipe
,
3964 &key_hnd
, "MinInboxDriverVerDate",
3965 info8
.min_inbox_driver_ver_date
);
3966 if (!W_ERROR_IS_OK(result
)) {
3970 result
= winreg_printer_write_ver(tmp_ctx
, winreg_pipe
, &key_hnd
,
3971 "MinInboxDriverVerVersion",
3972 info8
.min_inbox_driver_ver_version
);
3973 if (!W_ERROR_IS_OK(result
)) {
3977 *driver_name
= info8
.driver_name
;
3978 *driver_version
= info8
.version
;
3981 if (winreg_pipe
!= NULL
) {
3982 if (is_valid_policy_hnd(&key_hnd
)) {
3983 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3985 if (is_valid_policy_hnd(&hive_hnd
)) {
3986 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3990 TALLOC_FREE(tmp_ctx
);
3994 WERROR
winreg_get_driver(TALLOC_CTX
*mem_ctx
,
3995 struct auth_serversupplied_info
*server_info
,
3996 struct messaging_context
*msg_ctx
,
3997 const char *architecture
,
3998 const char *driver_name
,
3999 uint32_t driver_version
,
4000 struct spoolss_DriverInfo8
**_info8
)
4002 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4003 struct rpc_pipe_client
*winreg_pipe
= NULL
;
4004 struct policy_handle hive_hnd
, key_hnd
;
4005 struct spoolss_DriverInfo8 i8
, *info8
;
4006 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
4007 struct spoolss_PrinterEnumValues
*v
;
4008 uint32_t num_values
= 0;
4009 TALLOC_CTX
*tmp_ctx
;
4013 ZERO_STRUCT(hive_hnd
);
4014 ZERO_STRUCT(key_hnd
);
4017 tmp_ctx
= talloc_stackframe();
4018 if (tmp_ctx
== NULL
) {
4022 if (driver_version
== DRIVER_ANY_VERSION
) {
4023 /* look for Win2k first and then for NT4 */
4024 result
= winreg_printer_opendriver(tmp_ctx
,
4034 if (!W_ERROR_IS_OK(result
)) {
4035 result
= winreg_printer_opendriver(tmp_ctx
,
4047 /* ok normal case */
4048 result
= winreg_printer_opendriver(tmp_ctx
,
4059 if (!W_ERROR_IS_OK(result
)) {
4060 DEBUG(5, ("winreg_get_driver: "
4061 "Could not open driver key (%s,%s,%d): %s\n",
4062 driver_name
, architecture
,
4063 driver_version
, win_errstr(result
)));
4067 result
= winreg_printer_enumvalues(tmp_ctx
,
4072 if (!W_ERROR_IS_OK(result
)) {
4073 DEBUG(0, ("winreg_get_driver: "
4074 "Could not enumerate values for (%s,%s,%d): %s\n",
4075 driver_name
, architecture
,
4076 driver_version
, win_errstr(result
)));
4080 info8
= talloc_zero(tmp_ctx
, struct spoolss_DriverInfo8
);
4081 if (info8
== NULL
) {
4082 result
= WERR_NOMEM
;
4086 info8
->driver_name
= talloc_strdup(info8
, driver_name
);
4087 if (info8
->driver_name
== NULL
) {
4088 result
= WERR_NOMEM
;
4092 info8
->architecture
= talloc_strdup(info8
, architecture
);
4093 if (info8
->architecture
== NULL
) {
4094 result
= WERR_NOMEM
;
4100 for (i
= 0; i
< num_values
; i
++) {
4101 const char *tmp_str
;
4104 v
= &enum_values
[i
];
4106 result
= winreg_enumval_to_dword(info8
, v
,
4109 if (NT_STATUS_IS_OK(result
)) {
4110 info8
->version
= (enum spoolss_DriverOSVersion
) tmp
;
4112 CHECK_ERROR(result
);
4114 result
= winreg_enumval_to_sz(info8
, v
,
4116 &info8
->driver_path
);
4117 CHECK_ERROR(result
);
4119 result
= winreg_enumval_to_sz(info8
, v
,
4122 CHECK_ERROR(result
);
4124 result
= winreg_enumval_to_sz(info8
, v
,
4125 "Configuration File",
4126 &info8
->config_file
);
4127 CHECK_ERROR(result
);
4129 result
= winreg_enumval_to_sz(info8
, v
,
4132 CHECK_ERROR(result
);
4134 result
= winreg_enumval_to_multi_sz(info8
, v
,
4136 &info8
->dependent_files
);
4137 CHECK_ERROR(result
);
4139 result
= winreg_enumval_to_sz(info8
, v
,
4141 &info8
->monitor_name
);
4142 CHECK_ERROR(result
);
4144 result
= winreg_enumval_to_sz(info8
, v
,
4146 &info8
->default_datatype
);
4147 CHECK_ERROR(result
);
4149 result
= winreg_enumval_to_multi_sz(info8
, v
,
4151 &info8
->previous_names
);
4152 CHECK_ERROR(result
);
4154 result
= winreg_enumval_to_sz(info8
, v
,
4157 if (W_ERROR_IS_OK(result
)) {
4158 result
= winreg_printer_date_to_NTTIME(tmp_str
,
4159 &info8
->driver_date
);
4161 CHECK_ERROR(result
);
4163 result
= winreg_enumval_to_sz(info8
, v
,
4166 if (W_ERROR_IS_OK(result
)) {
4167 result
= winreg_printer_ver_to_dword(tmp_str
,
4168 &info8
->driver_version
);
4170 CHECK_ERROR(result
);
4172 result
= winreg_enumval_to_sz(info8
, v
,
4174 &info8
->manufacturer_name
);
4175 CHECK_ERROR(result
);
4177 result
= winreg_enumval_to_sz(info8
, v
,
4179 &info8
->manufacturer_url
);
4180 CHECK_ERROR(result
);
4182 result
= winreg_enumval_to_sz(info8
, v
,
4184 &info8
->hardware_id
);
4185 CHECK_ERROR(result
);
4187 result
= winreg_enumval_to_sz(info8
, v
,
4190 CHECK_ERROR(result
);
4192 result
= winreg_enumval_to_sz(info8
, v
,
4194 &info8
->print_processor
);
4195 CHECK_ERROR(result
);
4197 result
= winreg_enumval_to_sz(info8
, v
,
4199 &info8
->vendor_setup
);
4200 CHECK_ERROR(result
);
4202 result
= winreg_enumval_to_multi_sz(info8
, v
,
4204 &info8
->color_profiles
);
4205 CHECK_ERROR(result
);
4207 result
= winreg_enumval_to_sz(info8
, v
,
4210 CHECK_ERROR(result
);
4212 result
= winreg_enumval_to_dword(info8
, v
,
4213 "PrinterDriverAttributes",
4214 &info8
->printer_driver_attributes
);
4215 CHECK_ERROR(result
);
4217 result
= winreg_enumval_to_multi_sz(info8
, v
,
4219 &info8
->core_driver_dependencies
);
4220 CHECK_ERROR(result
);
4222 result
= winreg_enumval_to_sz(info8
, v
,
4223 "MinInboxDriverVerDate",
4225 if (W_ERROR_IS_OK(result
)) {
4226 result
= winreg_printer_date_to_NTTIME(tmp_str
,
4227 &info8
->min_inbox_driver_ver_date
);
4229 CHECK_ERROR(result
);
4231 result
= winreg_enumval_to_sz(info8
, v
,
4232 "MinInboxDriverVerVersion",
4234 if (W_ERROR_IS_OK(result
)) {
4235 result
= winreg_printer_ver_to_dword(tmp_str
,
4236 &info8
->min_inbox_driver_ver_version
);
4238 CHECK_ERROR(result
);
4241 if (!W_ERROR_IS_OK(result
)) {
4242 DEBUG(0, ("winreg_enumval_to_TYPE() failed "
4243 "for %s: %s\n", v
->value_name
,
4244 win_errstr(result
)));
4248 *_info8
= talloc_steal(mem_ctx
, info8
);
4251 if (winreg_pipe
!= NULL
) {
4252 if (is_valid_policy_hnd(&key_hnd
)) {
4253 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
4255 if (is_valid_policy_hnd(&hive_hnd
)) {
4256 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
4260 TALLOC_FREE(tmp_ctx
);
4264 WERROR
winreg_del_driver(TALLOC_CTX
*mem_ctx
,
4265 struct auth_serversupplied_info
*server_info
,
4266 struct messaging_context
*msg_ctx
,
4267 struct spoolss_DriverInfo8
*info8
,
4270 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4271 struct rpc_pipe_client
*winreg_pipe
= NULL
;
4272 struct policy_handle hive_hnd
, key_hnd
;
4273 TALLOC_CTX
*tmp_ctx
;
4277 ZERO_STRUCT(hive_hnd
);
4278 ZERO_STRUCT(key_hnd
);
4280 tmp_ctx
= talloc_stackframe();
4281 if (tmp_ctx
== NULL
) {
4285 /* test that the key exists */
4286 result
= winreg_printer_opendriver(tmp_ctx
,
4290 info8
->architecture
,
4296 if (!W_ERROR_IS_OK(result
)) {
4297 /* key doesn't exist */
4298 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
4303 DEBUG(5, ("winreg_del_driver: "
4304 "Could not open driver (%s,%s,%u): %s\n",
4305 info8
->driver_name
, info8
->architecture
,
4306 version
, win_errstr(result
)));
4311 if (is_valid_policy_hnd(&key_hnd
)) {
4312 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
4315 key_name
= talloc_asprintf(tmp_ctx
,
4316 "%s\\Environments\\%s\\Drivers\\Version-%u",
4317 TOP_LEVEL_CONTROL_KEY
,
4318 info8
->architecture
, version
);
4319 if (key_name
== NULL
) {
4320 result
= WERR_NOMEM
;
4324 result
= winreg_printer_delete_subkeys(tmp_ctx
,
4329 if (!W_ERROR_IS_OK(result
)) {
4330 DEBUG(0, ("winreg_del_driver: "
4331 "Could not open driver (%s,%s,%u): %s\n",
4332 info8
->driver_name
, info8
->architecture
,
4333 version
, win_errstr(result
)));
4339 if (winreg_pipe
!= NULL
) {
4340 if (is_valid_policy_hnd(&key_hnd
)) {
4341 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
4343 if (is_valid_policy_hnd(&hive_hnd
)) {
4344 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
4348 TALLOC_FREE(tmp_ctx
);
4352 WERROR
winreg_get_driver_list(TALLOC_CTX
*mem_ctx
,
4353 struct auth_serversupplied_info
*server_info
,
4354 struct messaging_context
*msg_ctx
,
4355 const char *architecture
,
4357 uint32_t *num_drivers
,
4358 const char ***drivers_p
)
4360 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4361 struct rpc_pipe_client
*winreg_pipe
= NULL
;
4362 struct policy_handle hive_hnd
, key_hnd
;
4363 const char **drivers
;
4364 TALLOC_CTX
*tmp_ctx
;
4370 ZERO_STRUCT(hive_hnd
);
4371 ZERO_STRUCT(key_hnd
);
4373 tmp_ctx
= talloc_stackframe();
4374 if (tmp_ctx
== NULL
) {
4378 /* use NULL for the driver name so we open the key that is
4379 * parent of all drivers for this architecture and version */
4380 result
= winreg_printer_opendriver(tmp_ctx
,
4390 if (!W_ERROR_IS_OK(result
)) {
4391 DEBUG(5, ("winreg_get_driver_list: "
4392 "Could not open key (%s,%u): %s\n",
4393 architecture
, version
, win_errstr(result
)));
4398 result
= winreg_printer_enumkeys(tmp_ctx
,
4403 if (!W_ERROR_IS_OK(result
)) {
4404 DEBUG(0, ("winreg_get_driver_list: "
4405 "Could not enumerate drivers for (%s,%u): %s\n",
4406 architecture
, version
, win_errstr(result
)));
4410 *drivers_p
= talloc_steal(mem_ctx
, drivers
);
4414 if (winreg_pipe
!= NULL
) {
4415 if (is_valid_policy_hnd(&key_hnd
)) {
4416 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
4418 if (is_valid_policy_hnd(&hive_hnd
)) {
4419 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
4423 TALLOC_FREE(tmp_ctx
);