s3-torture: run_fdpasstest(): replace cli_read_old() with cli_read()
[Samba/gebeck_regimport.git] / source3 / rpc_client / cli_winreg_spoolss.c
blob9b7c72421cedb9470724a40662a3e51328394d31
1 /*
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/>.
22 #include "includes.h"
23 #include "nt_printing.h"
24 #include "../librpc/gen_ndr/ndr_spoolss.h"
25 #include "../librpc/gen_ndr/ndr_winreg_c.h"
26 #include "../librpc/gen_ndr/ndr_security.h"
27 #include "secrets.h"
28 #include "../libcli/security/security.h"
29 #include "rpc_client/cli_winreg.h"
30 #include "../libcli/registry/util_reg.h"
31 #include "rpc_client/cli_winreg_spoolss.h"
32 #include "printing/nt_printing_os2.h"
33 #include "rpc_client/init_spoolss.h"
35 #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
36 #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
37 #define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print"
38 #define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
40 #define EMPTY_STRING ""
42 #define FILL_STRING(mem_ctx, in, out) \
43 do { \
44 if (in && strlen(in)) { \
45 out = talloc_strdup(mem_ctx, in); \
46 } else { \
47 out = talloc_strdup(mem_ctx, ""); \
48 } \
49 W_ERROR_HAVE_NO_MEMORY(out); \
50 } while (0);
52 #define CHECK_ERROR(result) \
53 if (W_ERROR_IS_OK(result)) continue; \
54 if (W_ERROR_EQUAL(result, WERR_NOT_FOUND)) result = WERR_OK; \
55 if (!W_ERROR_IS_OK(result)) break
57 /* FLAGS, NAME, with, height, left, top, right, bottom */
58 static const struct spoolss_FormInfo1 builtin_forms1[] = {
59 { SPOOLSS_FORM_BUILTIN, "10x11", {0x3e030,0x44368}, {0x0,0x0,0x3e030,0x44368} },
60 { SPOOLSS_FORM_BUILTIN, "10x14", {0x3e030,0x56d10}, {0x0,0x0,0x3e030,0x56d10} },
61 { SPOOLSS_FORM_BUILTIN, "11x17", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
62 { SPOOLSS_FORM_BUILTIN, "12x11", {0x4a724,0x443e1}, {0x0,0x0,0x4a724,0x443e1} },
63 { SPOOLSS_FORM_BUILTIN, "15x11", {0x5d048,0x44368}, {0x0,0x0,0x5d048,0x44368} },
64 { SPOOLSS_FORM_BUILTIN, "6 3/4 Envelope", {0x167ab,0x284ec}, {0x0,0x0,0x167ab,0x284ec} },
65 { SPOOLSS_FORM_BUILTIN, "9x11", {0x37cf8,0x44368}, {0x0,0x0,0x37cf8,0x44368} },
66 { SPOOLSS_FORM_BUILTIN, "A0", {0xcd528,0x122488},{0x0,0x0,0xcd528,0x122488} },
67 { SPOOLSS_FORM_BUILTIN, "A1", {0x91050,0xcd528}, {0x0,0x0,0x91050,0xcd528} },
68 { SPOOLSS_FORM_BUILTIN, "A2", {0x668a0,0x91050}, {0x0,0x0,0x668a0,0x91050} },
69 { SPOOLSS_FORM_BUILTIN, "A3 Extra Transverse", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
70 { SPOOLSS_FORM_BUILTIN, "A3 Extra", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
71 { SPOOLSS_FORM_BUILTIN, "A3 Rotated", {0x668a0,0x48828}, {0x0,0x0,0x668a0,0x48828} },
72 { SPOOLSS_FORM_BUILTIN, "A3 Transverse", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
73 { SPOOLSS_FORM_BUILTIN, "A3", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
74 { SPOOLSS_FORM_BUILTIN, "A4 Extra", {0x397c2,0x4eb16}, {0x0,0x0,0x397c2,0x4eb16} },
75 { SPOOLSS_FORM_BUILTIN, "A4 Plus", {0x33450,0x50910}, {0x0,0x0,0x33450,0x50910} },
76 { SPOOLSS_FORM_BUILTIN, "A4 Rotated", {0x48828,0x33450}, {0x0,0x0,0x48828,0x33450} },
77 { SPOOLSS_FORM_BUILTIN, "A4 Small", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
78 { SPOOLSS_FORM_BUILTIN, "A4 Transverse", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
79 { SPOOLSS_FORM_BUILTIN, "A4", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
80 { SPOOLSS_FORM_BUILTIN, "A5 Extra", {0x2a7b0,0x395f8}, {0x0,0x0,0x2a7b0,0x395f8} },
81 { SPOOLSS_FORM_BUILTIN, "A5 Rotated", {0x33450,0x24220}, {0x0,0x0,0x33450,0x24220} },
82 { SPOOLSS_FORM_BUILTIN, "A5 Transverse", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
83 { SPOOLSS_FORM_BUILTIN, "A5", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
84 { SPOOLSS_FORM_BUILTIN, "A6 Rotated", {0x24220,0x19a28}, {0x0,0x0,0x24220,0x19a28} },
85 { SPOOLSS_FORM_BUILTIN, "A6", {0x19a28,0x24220}, {0x0,0x0,0x19a28,0x24220} },
86 { SPOOLSS_FORM_BUILTIN, "B4 (ISO)", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
87 { SPOOLSS_FORM_BUILTIN, "B4 (JIS) Rotated", {0x58de0,0x3ebe8}, {0x0,0x0,0x58de0,0x3ebe8} },
88 { SPOOLSS_FORM_BUILTIN, "B4 (JIS)", {0x3ebe8,0x58de0}, {0x0,0x0,0x3ebe8,0x58de0} },
89 { SPOOLSS_FORM_BUILTIN, "B5 (ISO) Extra", {0x31128,0x43620}, {0x0,0x0,0x31128,0x43620} },
90 { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Rotated", {0x3ebe8,0x2c6f0}, {0x0,0x0,0x3ebe8,0x2c6f0} },
91 { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Transverse", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
92 { SPOOLSS_FORM_BUILTIN, "B5 (JIS)", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
93 { SPOOLSS_FORM_BUILTIN, "B6 (JIS) Rotated", {0x2c6f0,0x1f400}, {0x0,0x0,0x2c6f0,0x1f400} },
94 { SPOOLSS_FORM_BUILTIN, "B6 (JIS)", {0x1f400,0x2c6f0}, {0x0,0x0,0x1f400,0x2c6f0} },
95 { SPOOLSS_FORM_BUILTIN, "C size sheet", {0x696b8,0x886d0}, {0x0,0x0,0x696b8,0x886d0} },
96 { SPOOLSS_FORM_BUILTIN, "D size sheet", {0x886d0,0xd2d70}, {0x0,0x0,0x886d0,0xd2d70} },
97 { SPOOLSS_FORM_BUILTIN, "Double Japan Postcard Rotated", {0x24220,0x30d40}, {0x0,0x0,0x24220,0x30d40} },
98 { SPOOLSS_FORM_BUILTIN, "E size sheet", {0xd2d70,0x110da0},{0x0,0x0,0xd2d70,0x110da0} },
99 { SPOOLSS_FORM_BUILTIN, "Envelope #10", {0x19947,0x3ae94}, {0x0,0x0,0x19947,0x3ae94} },
100 { SPOOLSS_FORM_BUILTIN, "Envelope #11", {0x1be7c,0x40565}, {0x0,0x0,0x1be7c,0x40565} },
101 { SPOOLSS_FORM_BUILTIN, "Envelope #12", {0x1d74a,0x44368}, {0x0,0x0,0x1d74a,0x44368} },
102 { SPOOLSS_FORM_BUILTIN, "Envelope #14", {0x1f018,0x47504}, {0x0,0x0,0x1f018,0x47504} },
103 { SPOOLSS_FORM_BUILTIN, "Envelope #9", {0x18079,0x37091}, {0x0,0x0,0x18079,0x37091} },
104 { SPOOLSS_FORM_BUILTIN, "Envelope B4", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
105 { SPOOLSS_FORM_BUILTIN, "Envelope B5", {0x2af80,0x3d090}, {0x0,0x0,0x2af80,0x3d090} },
106 { SPOOLSS_FORM_BUILTIN, "Envelope B6", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
107 { SPOOLSS_FORM_BUILTIN, "Envelope C3", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
108 { SPOOLSS_FORM_BUILTIN, "Envelope C4", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
109 { SPOOLSS_FORM_BUILTIN, "Envelope C5", {0x278d0,0x37e88}, {0x0,0x0,0x278d0,0x37e88} },
110 { SPOOLSS_FORM_BUILTIN, "Envelope C6", {0x1bd50,0x278d0}, {0x0,0x0,0x1bd50,0x278d0} },
111 { SPOOLSS_FORM_BUILTIN, "Envelope C65", {0x1bd50,0x37e88}, {0x0,0x0,0x1bd50,0x37e88} },
112 { SPOOLSS_FORM_BUILTIN, "Envelope DL", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
113 { SPOOLSS_FORM_BUILTIN, "Envelope Invite", {0x35b60,0x35b60}, {0x0,0x0,0x35b60,0x35b60} },
114 { SPOOLSS_FORM_BUILTIN, "Envelope Monarch", {0x18079,0x2e824}, {0x0,0x0,0x18079,0x2e824} },
115 { SPOOLSS_FORM_BUILTIN, "Envelope", {0x1adb0,0x38270}, {0x0,0x0,0x1adb0,0x38270} },
116 { SPOOLSS_FORM_BUILTIN, "Executive", {0x2cf56,0x411cc}, {0x0,0x0,0x2cf56,0x411cc} },
117 { SPOOLSS_FORM_BUILTIN, "Folio", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
118 { SPOOLSS_FORM_BUILTIN, "German Legal Fanfold", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
119 { SPOOLSS_FORM_BUILTIN, "German Std Fanfold", {0x34b5c,0x4a6a0}, {0x0,0x0,0x34b5c,0x4a6a0} },
120 { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #3 Rotated", {0x395f8,0x1d4c0}, {0x0,0x0,0x395f8,0x1d4c0} },
121 { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #4 Rotated", {0x320c8,0x15f90}, {0x0,0x0,0x320c8,0x15f90} },
122 { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #2 Rotated", {0x510e0,0x3a980}, {0x0,0x0,0x510e0,0x3a980} },
123 { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #3 Rotated", {0x43a08,0x34bc0}, {0x0,0x0,0x43a08,0x34bc0} },
124 { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4 Rotated", {0x395f8,0x19a28}, {0x0,0x0,0x395f8,0x19a28} },
125 { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4", {0x19a28,0x395f8}, {0x0,0x0,0x19a28,0x395f8} },
126 { SPOOLSS_FORM_BUILTIN, "Japanese Double Postcard", {0x30d40,0x24220}, {0x0,0x0,0x30d40,0x24220} },
127 { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #3", {0x1d4c0,0x395f8}, {0x0,0x0,0x1d4c0,0x395f8} },
128 { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #4", {0x15f90,0x320c8}, {0x0,0x0,0x15f90,0x320c8} },
129 { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #2", {0x3a980,0x510e0}, {0x0,0x0,0x3a980,0x510e0} },
130 { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #3", {0x34bc0,0x43a08}, {0x0,0x0,0x34bc0,0x43a08} },
131 { SPOOLSS_FORM_BUILTIN, "Japanese Postcard Rotated", {0x24220,0x186a0}, {0x0,0x0,0x24220,0x186a0} },
132 { SPOOLSS_FORM_BUILTIN, "Japanese Postcard", {0x186a0,0x24220}, {0x0,0x0,0x186a0,0x24220} },
133 { SPOOLSS_FORM_BUILTIN, "Ledger", {0x696b8,0x44368}, {0x0,0x0,0x696b8,0x44368} },
134 { SPOOLSS_FORM_BUILTIN, "Legal Extra", {0x3ae94,0x5d048}, {0x0,0x0,0x3ae94,0x5d048} },
135 { SPOOLSS_FORM_BUILTIN, "Legal", {0x34b5c,0x56d10}, {0x0,0x0,0x34b5c,0x56d10} },
136 { SPOOLSS_FORM_BUILTIN, "Letter Extra Transverse", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
137 { SPOOLSS_FORM_BUILTIN, "Letter Extra", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
138 { SPOOLSS_FORM_BUILTIN, "Letter Plus", {0x34b5c,0x4eb16}, {0x0,0x0,0x34b5c,0x4eb16} },
139 { SPOOLSS_FORM_BUILTIN, "Letter Rotated", {0x44368,0x34b5c}, {0x0,0x0,0x44368,0x34b5c} },
140 { SPOOLSS_FORM_BUILTIN, "Letter Small", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
141 { SPOOLSS_FORM_BUILTIN, "Letter Transverse", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
142 { SPOOLSS_FORM_BUILTIN, "Letter", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
143 { SPOOLSS_FORM_BUILTIN, "Note", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
144 { SPOOLSS_FORM_BUILTIN, "PRC 16K Rotated", {0x3f7a0,0x2de60}, {0x0,0x0,0x3f7a0,0x2de60} },
145 { SPOOLSS_FORM_BUILTIN, "PRC 16K", {0x2de60,0x3f7a0}, {0x0,0x0,0x2de60,0x3f7a0} },
146 { SPOOLSS_FORM_BUILTIN, "PRC 32K Rotated", {0x2cec0,0x1fbd0}, {0x0,0x0,0x2cec0,0x1fbd0} },
147 { SPOOLSS_FORM_BUILTIN, "PRC 32K", {0x1fbd0,0x2cec0}, {0x0,0x0,0x1fbd0,0x2cec0} },
148 { SPOOLSS_FORM_BUILTIN, "PRC 32K(Big) Rotated", {0x318f8,0x222e0}, {0x0,0x0,0x318f8,0x222e0} },
149 { SPOOLSS_FORM_BUILTIN, "PRC 32K(Big)", {0x222e0,0x318f8}, {0x0,0x0,0x222e0,0x318f8} },
150 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #1 Rotated", {0x28488,0x18e70}, {0x0,0x0,0x28488,0x18e70} },
151 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #1", {0x18e70,0x28488}, {0x0,0x0,0x18e70,0x28488} },
152 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #10 Rotated", {0x6fd10,0x4f1a0}, {0x0,0x0,0x6fd10,0x4f1a0} },
153 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #10", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
154 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #2 Rotated", {0x2af80,0x18e70}, {0x0,0x0,0x2af80,0x18e70} },
155 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #2", {0x18e70,0x2af80}, {0x0,0x0,0x18e70,0x2af80} },
156 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #3 Rotated", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
157 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #3", {0x1e848,0x2af80}, {0x0,0x0,0x1e848,0x2af80} },
158 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #4 Rotated", {0x32c80,0x1adb0}, {0x0,0x0,0x32c80,0x1adb0} },
159 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #4", {0x1adb0,0x32c80}, {0x0,0x0,0x1adb0,0x32c80} },
160 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #5 Rotated", {0x35b60,0x1adb0}, {0x0,0x0,0x35b60,0x1adb0} },
161 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #5", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
162 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #6 Rotated", {0x38270,0x1d4c0}, {0x0,0x0,0x38270,0x1d4c0} },
163 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #6", {0x1d4c0,0x38270}, {0x0,0x0,0x1d4c0,0x38270} },
164 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #7 Rotated", {0x38270,0x27100}, {0x0,0x0,0x38270,0x27100} },
165 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #7", {0x27100,0x38270}, {0x0,0x0,0x27100,0x38270} },
166 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #8 Rotated", {0x4b708,0x1d4c0}, {0x0,0x0,0x4b708,0x1d4c0} },
167 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #8", {0x1d4c0,0x4b708}, {0x0,0x0,0x1d4c0,0x4b708} },
168 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #9 Rotated", {0x4f1a0,0x37e88}, {0x0,0x0,0x4f1a0,0x37e88} },
169 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #9", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
170 { SPOOLSS_FORM_BUILTIN, "Quarto", {0x347d8,0x43238}, {0x0,0x0,0x347d8,0x43238} },
171 { SPOOLSS_FORM_BUILTIN, "Reserved48", {0x1,0x1}, {0x0,0x0,0x1,0x1} },
172 { SPOOLSS_FORM_BUILTIN, "Reserved49", {0x1,0x1}, {0x0,0x0,0x1,0x1} },
173 { SPOOLSS_FORM_BUILTIN, "Statement", {0x221b4,0x34b5c}, {0x0,0x0,0x221b4,0x34b5c} },
174 { SPOOLSS_FORM_BUILTIN, "Super A", {0x376b8,0x56ea0}, {0x0,0x0,0x376b8,0x56ea0} },
175 { SPOOLSS_FORM_BUILTIN, "Super B", {0x4a768,0x76e58}, {0x0,0x0,0x4a768,0x76e58} },
176 { SPOOLSS_FORM_BUILTIN, "Tabloid Extra", {0x4a6a0,0x6f9f0}, {0x0,0x0,0x4a6a0,0x6f9f0} },
177 { SPOOLSS_FORM_BUILTIN, "Tabloid", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
178 { SPOOLSS_FORM_BUILTIN, "US Std Fanfold", {0x5c3e1,0x44368}, {0x0,0x0,0x5c3e1,0x44368} }
181 /********************************************************************
182 static helper functions
183 ********************************************************************/
185 /****************************************************************************
186 Update the changeid time.
187 ****************************************************************************/
189 * @internal
191 * @brief Update the ChangeID time of a printer.
193 * This is SO NASTY as some drivers need this to change, others need it
194 * static. This value will change every second, and I must hope that this
195 * is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
196 * UTAH ! JRA.
198 * @return The ChangeID.
200 static uint32_t winreg_printer_rev_changeid(void)
202 struct timeval tv;
204 get_process_uptime(&tv);
206 #if 1 /* JERRY */
207 /* Return changeid as msec since spooler restart */
208 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
209 #else
211 * This setting seems to work well but is too untested
212 * to replace the above calculation. Left in for experimentation
213 * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002)
215 return tv.tv_sec * 10 + tv.tv_usec / 100000;
216 #endif
219 static WERROR winreg_printer_openkey(TALLOC_CTX *mem_ctx,
220 struct dcerpc_binding_handle *binding_handle,
221 const char *path,
222 const char *key,
223 bool create_key,
224 uint32_t access_mask,
225 struct policy_handle *hive_handle,
226 struct policy_handle *key_handle)
228 struct winreg_String wkey, wkeyclass;
229 char *keyname;
230 NTSTATUS status;
231 WERROR result = WERR_OK;
233 status = dcerpc_winreg_OpenHKLM(binding_handle,
234 mem_ctx,
235 NULL,
236 access_mask,
237 hive_handle,
238 &result);
239 if (!NT_STATUS_IS_OK(status)) {
240 DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
241 nt_errstr(status)));
242 return ntstatus_to_werror(status);
244 if (!W_ERROR_IS_OK(result)) {
245 DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
246 win_errstr(result)));
247 return result;
250 if (key && *key) {
251 keyname = talloc_asprintf(mem_ctx, "%s\\%s", path, key);
252 } else {
253 keyname = talloc_strdup(mem_ctx, path);
255 if (keyname == NULL) {
256 return WERR_NOMEM;
259 ZERO_STRUCT(wkey);
260 wkey.name = keyname;
262 if (create_key) {
263 enum winreg_CreateAction action = REG_ACTION_NONE;
265 ZERO_STRUCT(wkeyclass);
266 wkeyclass.name = "";
268 status = dcerpc_winreg_CreateKey(binding_handle,
269 mem_ctx,
270 hive_handle,
271 wkey,
272 wkeyclass,
274 access_mask,
275 NULL,
276 key_handle,
277 &action,
278 &result);
279 switch (action) {
280 case REG_ACTION_NONE:
281 DEBUG(8, ("winreg_printer_openkey:createkey did nothing -- huh?\n"));
282 break;
283 case REG_CREATED_NEW_KEY:
284 DEBUG(8, ("winreg_printer_openkey: createkey created %s\n", keyname));
285 break;
286 case REG_OPENED_EXISTING_KEY:
287 DEBUG(8, ("winreg_printer_openkey: createkey opened existing %s\n", keyname));
288 break;
290 } else {
291 status = dcerpc_winreg_OpenKey(binding_handle,
292 mem_ctx,
293 hive_handle,
294 wkey,
296 access_mask,
297 key_handle,
298 &result);
300 if (!NT_STATUS_IS_OK(status)) {
301 return ntstatus_to_werror(status);
303 if (!W_ERROR_IS_OK(result)) {
304 return result;
307 return WERR_OK;
311 * @brief Create the registry keyname for the given printer.
313 * @param[in] mem_ctx The memory context to use.
315 * @param[in] printer The name of the printer to get the registry key.
317 * @return The registry key or NULL on error.
319 static char *winreg_printer_data_keyname(TALLOC_CTX *mem_ctx, const char *printer) {
320 return talloc_asprintf(mem_ctx, "%s\\%s", TOP_LEVEL_PRINT_PRINTERS_KEY, printer);
323 static WERROR winreg_printer_opendriver(TALLOC_CTX *mem_ctx,
324 struct dcerpc_binding_handle *winreg_handle,
325 const char *drivername,
326 const char *architecture,
327 uint32_t version,
328 uint32_t access_mask,
329 bool create,
330 struct policy_handle *hive_hnd,
331 struct policy_handle *key_hnd)
333 WERROR result;
334 char *key_name;
336 key_name = talloc_asprintf(mem_ctx, "%s\\Environments\\%s\\Drivers\\Version-%u",
337 TOP_LEVEL_CONTROL_KEY,
338 architecture, version);
339 if (!key_name) {
340 return WERR_NOMEM;
343 result = winreg_printer_openkey(mem_ctx,
344 winreg_handle,
345 key_name,
346 drivername,
347 create,
348 access_mask,
349 hive_hnd,
350 key_hnd);
351 return result;
354 static WERROR winreg_enumval_to_dword(TALLOC_CTX *mem_ctx,
355 struct spoolss_PrinterEnumValues *v,
356 const char *valuename, uint32_t *dw)
358 /* just return if it is not the one we are looking for */
359 if (strcmp(valuename, v->value_name) != 0) {
360 return WERR_NOT_FOUND;
363 if (v->type != REG_DWORD) {
364 return WERR_INVALID_DATATYPE;
367 if (v->data_length != 4) {
368 *dw = 0;
369 return WERR_OK;
372 *dw = IVAL(v->data->data, 0);
373 return WERR_OK;
376 static WERROR winreg_enumval_to_sz(TALLOC_CTX *mem_ctx,
377 struct spoolss_PrinterEnumValues *v,
378 const char *valuename, const char **_str)
380 /* just return if it is not the one we are looking for */
381 if (strcmp(valuename, v->value_name) != 0) {
382 return WERR_NOT_FOUND;
385 if (v->type != REG_SZ) {
386 return WERR_INVALID_DATATYPE;
389 if (v->data_length == 0) {
390 *_str = talloc_strdup(mem_ctx, EMPTY_STRING);
391 if (*_str == NULL) {
392 return WERR_NOMEM;
394 return WERR_OK;
397 if (!pull_reg_sz(mem_ctx, v->data, _str)) {
398 return WERR_NOMEM;
401 return WERR_OK;
404 static WERROR winreg_enumval_to_multi_sz(TALLOC_CTX *mem_ctx,
405 struct spoolss_PrinterEnumValues *v,
406 const char *valuename,
407 const char ***array)
409 /* just return if it is not the one we are looking for */
410 if (strcmp(valuename, v->value_name) != 0) {
411 return WERR_NOT_FOUND;
414 if (v->type != REG_MULTI_SZ) {
415 return WERR_INVALID_DATATYPE;
418 if (v->data_length == 0) {
419 *array = talloc_array(mem_ctx, const char *, 1);
420 if (*array == NULL) {
421 return WERR_NOMEM;
423 *array[0] = NULL;
424 return WERR_OK;
427 if (!pull_reg_multi_sz(mem_ctx, v->data, array)) {
428 return WERR_NOMEM;
431 return WERR_OK;
434 static WERROR winreg_printer_write_date(TALLOC_CTX *mem_ctx,
435 struct dcerpc_binding_handle *winreg_handle,
436 struct policy_handle *key_handle,
437 const char *value,
438 NTTIME data)
440 struct winreg_String wvalue = { 0, };
441 DATA_BLOB blob;
442 WERROR result = WERR_OK;
443 NTSTATUS status;
444 const char *str;
445 struct tm *tm;
446 time_t t;
448 if (data == 0) {
449 str = talloc_strdup(mem_ctx, "01/01/1601");
450 } else {
451 t = nt_time_to_unix(data);
452 tm = localtime(&t);
453 if (tm == NULL) {
454 return map_werror_from_unix(errno);
456 str = talloc_asprintf(mem_ctx, "%02d/%02d/%04d",
457 tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900);
459 if (!str) {
460 return WERR_NOMEM;
463 wvalue.name = value;
464 if (!push_reg_sz(mem_ctx, &blob, str)) {
465 return WERR_NOMEM;
467 status = dcerpc_winreg_SetValue(winreg_handle,
468 mem_ctx,
469 key_handle,
470 wvalue,
471 REG_SZ,
472 blob.data,
473 blob.length,
474 &result);
475 if (!NT_STATUS_IS_OK(status)) {
476 result = ntstatus_to_werror(status);
478 if (!W_ERROR_IS_OK(result)) {
479 DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
480 wvalue.name, win_errstr(result)));
483 return result;
486 static WERROR winreg_printer_date_to_NTTIME(const char *str, NTTIME *data)
488 struct tm tm;
489 time_t t;
491 if (strequal(str, "01/01/1601")) {
492 *data = 0;
493 return WERR_OK;
496 ZERO_STRUCT(tm);
498 if (sscanf(str, "%d/%d/%d",
499 &tm.tm_mon, &tm.tm_mday, &tm.tm_year) != 3) {
500 return WERR_INVALID_PARAMETER;
502 tm.tm_mon -= 1;
503 tm.tm_year -= 1900;
504 tm.tm_isdst = -1;
506 t = mktime(&tm);
507 unix_to_nt_time(data, t);
509 return WERR_OK;
512 static WERROR winreg_printer_write_ver(TALLOC_CTX *mem_ctx,
513 struct dcerpc_binding_handle *winreg_handle,
514 struct policy_handle *key_handle,
515 const char *value,
516 uint64_t data)
518 struct winreg_String wvalue = { 0, };
519 DATA_BLOB blob;
520 WERROR result = WERR_OK;
521 NTSTATUS status;
522 char *str;
524 /* FIXME: check format is right,
525 * this needs to be something like: 6.1.7600.16385 */
526 str = talloc_asprintf(mem_ctx, "%u.%u.%u.%u",
527 (unsigned)((data >> 48) & 0xFFFF),
528 (unsigned)((data >> 32) & 0xFFFF),
529 (unsigned)((data >> 16) & 0xFFFF),
530 (unsigned)(data & 0xFFFF));
531 if (!str) {
532 return WERR_NOMEM;
535 wvalue.name = value;
536 if (!push_reg_sz(mem_ctx, &blob, str)) {
537 return WERR_NOMEM;
539 status = dcerpc_winreg_SetValue(winreg_handle,
540 mem_ctx,
541 key_handle,
542 wvalue,
543 REG_SZ,
544 blob.data,
545 blob.length,
546 &result);
547 if (!NT_STATUS_IS_OK(status)) {
548 result = ntstatus_to_werror(status);
550 if (!W_ERROR_IS_OK(result)) {
551 DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
552 wvalue.name, win_errstr(result)));
555 return result;
558 static WERROR winreg_printer_ver_to_dword(const char *str, uint64_t *data)
560 unsigned int v1, v2, v3, v4;
562 if (sscanf(str, "%u.%u.%u.%u", &v1, &v2, &v3, &v4) != 4) {
563 return WERR_INVALID_PARAMETER;
566 *data = ((uint64_t)(v1 & 0xFFFF) << 48) +
567 ((uint64_t)(v2 & 0xFFFF) << 32) +
568 ((uint64_t)(v3 & 0xFFFF) << 16) +
569 (uint64_t)(v2 & 0xFFFF);
571 return WERR_OK;
574 /********************************************************************
575 Public winreg function for spoolss
576 ********************************************************************/
578 WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
579 struct dcerpc_binding_handle *winreg_handle,
580 const char *sharename)
582 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
583 struct policy_handle hive_hnd, key_hnd;
584 struct spoolss_SetPrinterInfo2 *info2;
585 struct security_descriptor *secdesc;
586 struct winreg_String wkey, wkeyclass;
587 const char *path;
588 const char *subkeys[] = { SPOOL_DSDRIVER_KEY, SPOOL_DSSPOOLER_KEY, SPOOL_PRINTERDATA_KEY };
589 uint32_t i, count = ARRAY_SIZE(subkeys);
590 uint32_t info2_mask = 0;
591 WERROR result = WERR_OK;
592 TALLOC_CTX *tmp_ctx;
594 tmp_ctx = talloc_stackframe();
595 if (tmp_ctx == NULL) {
596 return WERR_NOMEM;
599 path = winreg_printer_data_keyname(tmp_ctx, sharename);
600 if (path == NULL) {
601 TALLOC_FREE(tmp_ctx);
602 return WERR_NOMEM;
605 ZERO_STRUCT(hive_hnd);
606 ZERO_STRUCT(key_hnd);
608 result = winreg_printer_openkey(tmp_ctx,
609 winreg_handle,
610 path,
612 false,
613 access_mask,
614 &hive_hnd,
615 &key_hnd);
616 if (W_ERROR_IS_OK(result)) {
617 DEBUG(2, ("winreg_create_printer: Skipping, %s already exists\n", path));
618 goto done;
619 } else if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
620 DEBUG(2, ("winreg_create_printer: Creating default values in %s\n", path));
621 } else if (!W_ERROR_IS_OK(result)) {
622 DEBUG(0, ("winreg_create_printer: Could not open key %s: %s\n",
623 path, win_errstr(result)));
624 goto done;
627 /* Create the main key */
628 result = winreg_printer_openkey(tmp_ctx,
629 winreg_handle,
630 path,
632 true,
633 access_mask,
634 &hive_hnd,
635 &key_hnd);
636 if (!W_ERROR_IS_OK(result)) {
637 DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
638 path, win_errstr(result)));
639 goto done;
642 if (is_valid_policy_hnd(&key_hnd)) {
643 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
646 /* Create subkeys */
647 for (i = 0; i < count; i++) {
648 NTSTATUS status;
649 enum winreg_CreateAction action = REG_ACTION_NONE;
651 ZERO_STRUCT(key_hnd);
652 ZERO_STRUCT(wkey);
654 wkey.name = talloc_asprintf(tmp_ctx, "%s\\%s", path, subkeys[i]);
655 if (wkey.name == NULL) {
656 result = WERR_NOMEM;
657 goto done;
660 ZERO_STRUCT(wkeyclass);
661 wkeyclass.name = "";
663 status = dcerpc_winreg_CreateKey(winreg_handle,
664 tmp_ctx,
665 &hive_hnd,
666 wkey,
667 wkeyclass,
669 access_mask,
670 NULL,
671 &key_hnd,
672 &action,
673 &result);
674 if (!NT_STATUS_IS_OK(status)) {
675 result = ntstatus_to_werror(status);
677 if (!W_ERROR_IS_OK(result)) {
678 DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
679 wkey.name, win_errstr(result)));
680 goto done;
683 if (strequal(subkeys[i], SPOOL_DSSPOOLER_KEY)) {
684 const char *dnssuffix;
685 const char *longname;
686 const char *uncname;
688 status = dcerpc_winreg_set_sz(tmp_ctx,
689 winreg_handle,
690 &key_hnd,
691 SPOOL_REG_PRINTERNAME,
692 sharename,
693 &result);
694 if (!NT_STATUS_IS_OK(status)) {
695 result = ntstatus_to_werror(status);
697 if (!W_ERROR_IS_OK(result)) {
698 goto done;
701 status = dcerpc_winreg_set_sz(tmp_ctx,
702 winreg_handle,
703 &key_hnd,
704 SPOOL_REG_SHORTSERVERNAME,
705 lp_netbios_name(),
706 &result);
707 if (!NT_STATUS_IS_OK(status)) {
708 result = ntstatus_to_werror(status);
710 if (!W_ERROR_IS_OK(result)) {
711 goto done;
714 /* We make the assumption that the netbios name
715 * is the same as the DNS name since the former
716 * will be what we used to join the domain
718 dnssuffix = get_mydnsdomname(tmp_ctx);
719 if (dnssuffix != NULL && dnssuffix[0] != '\0') {
720 longname = talloc_asprintf(tmp_ctx, "%s.%s", lp_netbios_name(), dnssuffix);
721 } else {
722 longname = talloc_strdup(tmp_ctx, lp_netbios_name());
724 if (longname == NULL) {
725 result = WERR_NOMEM;
726 goto done;
729 status = dcerpc_winreg_set_sz(tmp_ctx,
730 winreg_handle,
731 &key_hnd,
732 SPOOL_REG_SERVERNAME,
733 longname,
734 &result);
735 if (!NT_STATUS_IS_OK(status)) {
736 result = ntstatus_to_werror(status);
738 if (!W_ERROR_IS_OK(result)) {
739 goto done;
742 uncname = talloc_asprintf(tmp_ctx, "\\\\%s\\%s",
743 longname, sharename);
744 if (uncname == NULL) {
745 result = WERR_NOMEM;
746 goto done;
749 status = dcerpc_winreg_set_sz(tmp_ctx,
750 winreg_handle,
751 &key_hnd,
752 SPOOL_REG_UNCNAME,
753 uncname,
754 &result);
755 if (!NT_STATUS_IS_OK(status)) {
756 result = ntstatus_to_werror(status);
758 if (!W_ERROR_IS_OK(result)) {
759 goto done;
762 status = dcerpc_winreg_set_dword(tmp_ctx,
763 winreg_handle,
764 &key_hnd,
765 SPOOL_REG_VERSIONNUMBER,
767 &result);
768 if (!NT_STATUS_IS_OK(status)) {
769 result = ntstatus_to_werror(status);
771 if (!W_ERROR_IS_OK(result)) {
772 goto done;
775 status = dcerpc_winreg_set_dword(tmp_ctx,
776 winreg_handle,
777 &key_hnd,
778 SPOOL_REG_PRINTSTARTTIME,
780 &result);
781 if (!NT_STATUS_IS_OK(status)) {
782 result = ntstatus_to_werror(status);
784 if (!W_ERROR_IS_OK(result)) {
785 goto done;
788 status = dcerpc_winreg_set_dword(tmp_ctx,
789 winreg_handle,
790 &key_hnd,
791 SPOOL_REG_PRINTENDTIME,
793 &result);
794 if (!NT_STATUS_IS_OK(status)) {
795 result = ntstatus_to_werror(status);
797 if (!W_ERROR_IS_OK(result)) {
798 goto done;
801 status = dcerpc_winreg_set_dword(tmp_ctx,
802 winreg_handle,
803 &key_hnd,
804 SPOOL_REG_PRIORITY,
806 &result);
807 if (!NT_STATUS_IS_OK(status)) {
808 result = ntstatus_to_werror(status);
810 if (!W_ERROR_IS_OK(result)) {
811 goto done;
814 status = dcerpc_winreg_set_dword(tmp_ctx,
815 winreg_handle,
816 &key_hnd,
817 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
819 &result);
820 if (!NT_STATUS_IS_OK(status)) {
821 result = ntstatus_to_werror(status);
823 if (!W_ERROR_IS_OK(result)) {
824 goto done;
828 if (is_valid_policy_hnd(&key_hnd)) {
829 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
832 info2 = talloc_zero(tmp_ctx, struct spoolss_SetPrinterInfo2);
833 if (info2 == NULL) {
834 result = WERR_NOMEM;
835 goto done;
838 info2->printername = sharename;
839 if (info2->printername == NULL) {
840 result = WERR_NOMEM;
841 goto done;
843 info2_mask |= SPOOLSS_PRINTER_INFO_PRINTERNAME;
845 info2->sharename = sharename;
846 info2_mask |= SPOOLSS_PRINTER_INFO_SHARENAME;
848 info2->portname = SAMBA_PRINTER_PORT_NAME;
849 info2_mask |= SPOOLSS_PRINTER_INFO_PORTNAME;
851 info2->printprocessor = "winprint";
852 info2_mask |= SPOOLSS_PRINTER_INFO_PRINTPROCESSOR;
854 info2->datatype = "RAW";
855 info2_mask |= SPOOLSS_PRINTER_INFO_DATATYPE;
857 info2->comment = "";
858 info2_mask |= SPOOLSS_PRINTER_INFO_COMMENT;
860 info2->attributes = PRINTER_ATTRIBUTE_SAMBA;
861 info2_mask |= SPOOLSS_PRINTER_INFO_ATTRIBUTES;
863 info2->starttime = 0; /* Minutes since 12:00am GMT */
864 info2_mask |= SPOOLSS_PRINTER_INFO_STARTTIME;
866 info2->untiltime = 0; /* Minutes since 12:00am GMT */
867 info2_mask |= SPOOLSS_PRINTER_INFO_UNTILTIME;
869 info2->priority = 1;
870 info2_mask |= SPOOLSS_PRINTER_INFO_PRIORITY;
872 info2->defaultpriority = 1;
873 info2_mask |= SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY;
875 result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
876 if (!W_ERROR_IS_OK(result)) {
877 goto done;
879 info2_mask |= SPOOLSS_PRINTER_INFO_SECDESC;
882 * Don't write a default Device Mode to the registry! The Device Mode is
883 * only written to disk with a SetPrinter level 2 or 8.
886 result = winreg_update_printer(tmp_ctx,
887 winreg_handle,
888 sharename,
889 info2_mask,
890 info2,
891 NULL,
892 secdesc);
894 done:
895 if (winreg_handle != NULL) {
896 WERROR ignore;
898 if (is_valid_policy_hnd(&key_hnd)) {
899 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
901 if (is_valid_policy_hnd(&hive_hnd)) {
902 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
906 talloc_free(tmp_ctx);
907 return result;
910 WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
911 struct dcerpc_binding_handle *winreg_handle,
912 const char *sharename,
913 uint32_t info2_mask,
914 struct spoolss_SetPrinterInfo2 *info2,
915 struct spoolss_DeviceMode *devmode,
916 struct security_descriptor *secdesc)
918 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
919 struct policy_handle hive_hnd, key_hnd;
920 int snum = lp_servicenumber(sharename);
921 enum ndr_err_code ndr_err;
922 DATA_BLOB blob;
923 char *path;
924 WERROR result = WERR_OK;
925 NTSTATUS status;
926 TALLOC_CTX *tmp_ctx;
928 tmp_ctx = talloc_stackframe();
929 if (tmp_ctx == NULL) {
930 return WERR_NOMEM;
933 path = winreg_printer_data_keyname(tmp_ctx, sharename);
934 if (path == NULL) {
935 TALLOC_FREE(tmp_ctx);
936 return WERR_NOMEM;
939 ZERO_STRUCT(hive_hnd);
940 ZERO_STRUCT(key_hnd);
942 result = winreg_printer_openkey(tmp_ctx,
943 winreg_handle,
944 path,
946 true,
947 access_mask,
948 &hive_hnd,
949 &key_hnd);
950 if (!W_ERROR_IS_OK(result)) {
951 DEBUG(0, ("winreg_update_printer: Could not open key %s: %s\n",
952 path, win_errstr(result)));
953 goto done;
956 if (info2_mask & SPOOLSS_PRINTER_INFO_ATTRIBUTES) {
957 status = dcerpc_winreg_set_dword(tmp_ctx,
958 winreg_handle,
959 &key_hnd,
960 "Attributes",
961 info2->attributes,
962 &result);
963 if (!NT_STATUS_IS_OK(status)) {
964 result = ntstatus_to_werror(status);
966 if (!W_ERROR_IS_OK(result)) {
967 goto done;
971 #if 0
972 if (info2_mask & SPOOLSS_PRINTER_INFO_AVERAGEPPM) {
973 status = dcerpc_winreg_set_dword(tmp_ctx,
974 winreg_handle,
975 &key_hnd,
976 "AveragePpm",
977 info2->attributes,
978 &result);
979 if (!NT_STATUS_IS_OK(status)) {
980 result = ntstatus_to_werror(status);
982 if (!W_ERROR_IS_OK(result)) {
983 goto done;
986 #endif
988 if (info2_mask & SPOOLSS_PRINTER_INFO_COMMENT) {
989 status = dcerpc_winreg_set_sz(tmp_ctx,
990 winreg_handle,
991 &key_hnd,
992 "Description",
993 info2->comment,
994 &result);
995 if (!NT_STATUS_IS_OK(status)) {
996 result = ntstatus_to_werror(status);
998 if (!W_ERROR_IS_OK(result)) {
999 goto done;
1003 if (info2_mask & SPOOLSS_PRINTER_INFO_DATATYPE) {
1004 status = dcerpc_winreg_set_sz(tmp_ctx,
1005 winreg_handle,
1006 &key_hnd,
1007 "Datatype",
1008 info2->datatype,
1009 &result);
1010 if (!NT_STATUS_IS_OK(status)) {
1011 result = ntstatus_to_werror(status);
1013 if (!W_ERROR_IS_OK(result)) {
1014 goto done;
1018 if (info2_mask & SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY) {
1019 status = dcerpc_winreg_set_dword(tmp_ctx,
1020 winreg_handle,
1021 &key_hnd,
1022 "Default Priority",
1023 info2->defaultpriority,
1024 &result);
1025 if (!NT_STATUS_IS_OK(status)) {
1026 result = ntstatus_to_werror(status);
1028 if (!W_ERROR_IS_OK(result)) {
1029 goto done;
1033 if (info2_mask & SPOOLSS_PRINTER_INFO_DEVMODE) {
1035 * Some client drivers freak out if there is a NULL devmode
1036 * (probably the driver is not checking before accessing
1037 * the devmode pointer) --jerry
1039 if (devmode == NULL && lp_default_devmode(snum) && info2 != NULL) {
1040 result = spoolss_create_default_devmode(tmp_ctx,
1041 info2->printername,
1042 &devmode);
1043 if (!W_ERROR_IS_OK(result)) {
1044 goto done;
1048 if (devmode->size != (ndr_size_spoolss_DeviceMode(devmode, 0) - devmode->__driverextra_length)) {
1049 result = WERR_INVALID_PARAM;
1050 goto done;
1053 ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, devmode,
1054 (ndr_push_flags_fn_t) ndr_push_spoolss_DeviceMode);
1055 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1056 DEBUG(0, ("winreg_update_printer: Failed to marshall device mode\n"));
1057 result = WERR_NOMEM;
1058 goto done;
1061 status = dcerpc_winreg_set_binary(tmp_ctx,
1062 winreg_handle,
1063 &key_hnd,
1064 "Default DevMode",
1065 &blob,
1066 &result);
1067 if (!NT_STATUS_IS_OK(status)) {
1068 result = ntstatus_to_werror(status);
1070 if (!W_ERROR_IS_OK(result)) {
1071 goto done;
1075 if (info2_mask & SPOOLSS_PRINTER_INFO_DRIVERNAME) {
1076 status = dcerpc_winreg_set_sz(tmp_ctx,
1077 winreg_handle,
1078 &key_hnd,
1079 "Printer Driver",
1080 info2->drivername,
1081 &result);
1082 if (!NT_STATUS_IS_OK(status)) {
1083 result = ntstatus_to_werror(status);
1085 if (!W_ERROR_IS_OK(result)) {
1086 goto done;
1090 if (info2_mask & SPOOLSS_PRINTER_INFO_LOCATION) {
1091 status = dcerpc_winreg_set_sz(tmp_ctx,
1092 winreg_handle,
1093 &key_hnd,
1094 "Location",
1095 info2->location,
1096 &result);
1097 if (!NT_STATUS_IS_OK(status)) {
1098 result = ntstatus_to_werror(status);
1100 if (!W_ERROR_IS_OK(result)) {
1101 goto done;
1105 if (info2_mask & SPOOLSS_PRINTER_INFO_PARAMETERS) {
1106 status = dcerpc_winreg_set_sz(tmp_ctx,
1107 winreg_handle,
1108 &key_hnd,
1109 "Parameters",
1110 info2->parameters,
1111 &result);
1112 if (!NT_STATUS_IS_OK(status)) {
1113 result = ntstatus_to_werror(status);
1115 if (!W_ERROR_IS_OK(result)) {
1116 goto done;
1120 if (info2_mask & SPOOLSS_PRINTER_INFO_PORTNAME) {
1121 status = dcerpc_winreg_set_sz(tmp_ctx,
1122 winreg_handle,
1123 &key_hnd,
1124 "Port",
1125 info2->portname,
1126 &result);
1127 if (!NT_STATUS_IS_OK(status)) {
1128 result = ntstatus_to_werror(status);
1130 if (!W_ERROR_IS_OK(result)) {
1131 goto done;
1135 if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTERNAME) {
1137 * in addprinter: no servername and the printer is the name
1138 * in setprinter: servername is \\server
1139 * and printer is \\server\\printer
1141 * Samba manages only local printers.
1142 * we currently don't support things like i
1143 * path=\\other_server\printer
1145 * We only store the printername, not \\server\printername
1147 const char *p = strrchr(info2->printername, '\\');
1148 if (p == NULL) {
1149 p = info2->printername;
1150 } else {
1151 p++;
1153 status = dcerpc_winreg_set_sz(tmp_ctx,
1154 winreg_handle,
1155 &key_hnd,
1156 "Name",
1158 &result);
1159 if (!NT_STATUS_IS_OK(status)) {
1160 result = ntstatus_to_werror(status);
1162 if (!W_ERROR_IS_OK(result)) {
1163 goto done;
1167 if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTPROCESSOR) {
1168 status = dcerpc_winreg_set_sz(tmp_ctx,
1169 winreg_handle,
1170 &key_hnd,
1171 "Print Processor",
1172 info2->printprocessor,
1173 &result);
1174 if (!NT_STATUS_IS_OK(status)) {
1175 result = ntstatus_to_werror(status);
1177 if (!W_ERROR_IS_OK(result)) {
1178 goto done;
1182 if (info2_mask & SPOOLSS_PRINTER_INFO_PRIORITY) {
1183 status = dcerpc_winreg_set_dword(tmp_ctx,
1184 winreg_handle,
1185 &key_hnd,
1186 "Priority",
1187 info2->priority,
1188 &result);
1189 if (!NT_STATUS_IS_OK(status)) {
1190 result = ntstatus_to_werror(status);
1192 if (!W_ERROR_IS_OK(result)) {
1193 goto done;
1197 if (info2_mask & SPOOLSS_PRINTER_INFO_SECDESC) {
1199 * We need a security descriptor, if it isn't specified by
1200 * AddPrinter{Ex} then create a default descriptor.
1202 if (secdesc == NULL) {
1203 result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
1204 if (!W_ERROR_IS_OK(result)) {
1205 goto done;
1208 result = winreg_set_printer_secdesc(tmp_ctx,
1209 winreg_handle,
1210 sharename,
1211 secdesc);
1212 if (!W_ERROR_IS_OK(result)) {
1213 goto done;
1217 if (info2_mask & SPOOLSS_PRINTER_INFO_SEPFILE) {
1218 status = dcerpc_winreg_set_sz(tmp_ctx,
1219 winreg_handle,
1220 &key_hnd,
1221 "Separator File",
1222 info2->sepfile,
1223 &result);
1224 if (!NT_STATUS_IS_OK(status)) {
1225 result = ntstatus_to_werror(status);
1227 if (!W_ERROR_IS_OK(result)) {
1228 goto done;
1232 if (info2_mask & SPOOLSS_PRINTER_INFO_SHARENAME) {
1233 status = dcerpc_winreg_set_sz(tmp_ctx,
1234 winreg_handle,
1235 &key_hnd,
1236 "Share Name",
1237 info2->sharename,
1238 &result);
1239 if (!NT_STATUS_IS_OK(status)) {
1240 result = ntstatus_to_werror(status);
1242 if (!W_ERROR_IS_OK(result)) {
1243 goto done;
1247 if (info2_mask & SPOOLSS_PRINTER_INFO_STARTTIME) {
1248 status = dcerpc_winreg_set_dword(tmp_ctx,
1249 winreg_handle,
1250 &key_hnd,
1251 "StartTime",
1252 info2->starttime,
1253 &result);
1254 if (!NT_STATUS_IS_OK(status)) {
1255 result = ntstatus_to_werror(status);
1257 if (!W_ERROR_IS_OK(result)) {
1258 goto done;
1262 if (info2_mask & SPOOLSS_PRINTER_INFO_STATUS) {
1263 status = dcerpc_winreg_set_dword(tmp_ctx,
1264 winreg_handle,
1265 &key_hnd,
1266 "Status",
1267 info2->status,
1268 &result);
1269 if (!NT_STATUS_IS_OK(status)) {
1270 result = ntstatus_to_werror(status);
1272 if (!W_ERROR_IS_OK(result)) {
1273 goto done;
1277 if (info2_mask & SPOOLSS_PRINTER_INFO_UNTILTIME) {
1278 status = dcerpc_winreg_set_dword(tmp_ctx,
1279 winreg_handle,
1280 &key_hnd,
1281 "UntilTime",
1282 info2->untiltime,
1283 &result);
1284 if (!NT_STATUS_IS_OK(status)) {
1285 result = ntstatus_to_werror(status);
1287 if (!W_ERROR_IS_OK(result)) {
1288 goto done;
1292 status = dcerpc_winreg_set_dword(tmp_ctx,
1293 winreg_handle,
1294 &key_hnd,
1295 "ChangeID",
1296 winreg_printer_rev_changeid(),
1297 &result);
1298 if (!NT_STATUS_IS_OK(status)) {
1299 result = ntstatus_to_werror(status);
1301 if (!W_ERROR_IS_OK(result)) {
1302 goto done;
1305 result = WERR_OK;
1306 done:
1307 if (winreg_handle != NULL) {
1308 WERROR ignore;
1310 if (is_valid_policy_hnd(&key_hnd)) {
1311 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
1313 if (is_valid_policy_hnd(&hive_hnd)) {
1314 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
1318 TALLOC_FREE(tmp_ctx);
1319 return result;
1322 WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
1323 struct dcerpc_binding_handle *winreg_handle,
1324 const char *printer,
1325 struct spoolss_PrinterInfo2 **pinfo2)
1327 struct spoolss_PrinterInfo2 *info2;
1328 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1329 struct policy_handle hive_hnd, key_hnd;
1330 struct spoolss_PrinterEnumValues enum_value;
1331 struct spoolss_PrinterEnumValues *v = NULL;
1332 enum ndr_err_code ndr_err;
1333 DATA_BLOB blob;
1334 int snum = lp_servicenumber(printer);
1335 uint32_t num_values = 0;
1336 uint32_t i;
1337 char *path;
1338 NTSTATUS status;
1339 WERROR result = WERR_OK;
1340 const char **enum_names = NULL;
1341 enum winreg_Type *enum_types = NULL;
1342 DATA_BLOB *enum_data_blobs = NULL;
1343 TALLOC_CTX *tmp_ctx;
1345 tmp_ctx = talloc_stackframe();
1346 if (tmp_ctx == NULL) {
1347 return WERR_NOMEM;
1350 path = winreg_printer_data_keyname(tmp_ctx, printer);
1351 if (path == NULL) {
1352 TALLOC_FREE(tmp_ctx);
1353 return WERR_NOMEM;
1356 result = winreg_printer_openkey(tmp_ctx,
1357 winreg_handle,
1358 path,
1360 false,
1361 access_mask,
1362 &hive_hnd,
1363 &key_hnd);
1364 if (!W_ERROR_IS_OK(result)) {
1365 DEBUG(2, ("winreg_get_printer: Could not open key %s: %s\n",
1366 path, win_errstr(result)));
1367 goto done;
1370 status = dcerpc_winreg_enumvals(tmp_ctx,
1371 winreg_handle,
1372 &key_hnd,
1373 &num_values,
1374 &enum_names,
1375 &enum_types,
1376 &enum_data_blobs,
1377 &result);
1378 if (!NT_STATUS_IS_OK(status)){
1379 result = ntstatus_to_werror(status);
1382 if (!W_ERROR_IS_OK(result)) {
1383 DEBUG(0, ("winreg_get_printer: Could not enumerate values in %s: %s\n",
1384 path, win_errstr(result)));
1385 goto done;
1388 info2 = talloc_zero(tmp_ctx, struct spoolss_PrinterInfo2);
1389 if (info2 == NULL) {
1390 result = WERR_NOMEM;
1391 goto done;
1394 FILL_STRING(info2, EMPTY_STRING, info2->servername);
1395 FILL_STRING(info2, EMPTY_STRING, info2->printername);
1396 FILL_STRING(info2, EMPTY_STRING, info2->sharename);
1397 FILL_STRING(info2, EMPTY_STRING, info2->portname);
1398 FILL_STRING(info2, EMPTY_STRING, info2->drivername);
1399 FILL_STRING(info2, EMPTY_STRING, info2->comment);
1400 FILL_STRING(info2, EMPTY_STRING, info2->location);
1401 FILL_STRING(info2, EMPTY_STRING, info2->sepfile);
1402 FILL_STRING(info2, EMPTY_STRING, info2->printprocessor);
1403 FILL_STRING(info2, EMPTY_STRING, info2->datatype);
1404 FILL_STRING(info2, EMPTY_STRING, info2->parameters);
1406 for (i = 0; i < num_values; i++) {
1407 enum_value.value_name = enum_names[i];
1408 enum_value.value_name_len = 2*strlen_m_term(enum_names[i]);
1409 enum_value.type = enum_types[i];
1410 enum_value.data_length = enum_data_blobs[i].length;
1411 enum_value.data = NULL;
1412 if (enum_value.data_length != 0){
1413 enum_value.data = &enum_data_blobs[i];
1415 v = &enum_value;
1417 result = winreg_enumval_to_sz(info2,
1419 "Name",
1420 &info2->printername);
1421 CHECK_ERROR(result);
1423 result = winreg_enumval_to_sz(info2,
1425 "Share Name",
1426 &info2->sharename);
1427 CHECK_ERROR(result);
1429 result = winreg_enumval_to_sz(info2,
1431 "Port",
1432 &info2->portname);
1433 CHECK_ERROR(result);
1435 result = winreg_enumval_to_sz(info2,
1437 "Description",
1438 &info2->comment);
1439 CHECK_ERROR(result);
1441 result = winreg_enumval_to_sz(info2,
1443 "Location",
1444 &info2->location);
1445 CHECK_ERROR(result);
1447 result = winreg_enumval_to_sz(info2,
1449 "Separator File",
1450 &info2->sepfile);
1451 CHECK_ERROR(result);
1453 result = winreg_enumval_to_sz(info2,
1455 "Print Processor",
1456 &info2->printprocessor);
1457 CHECK_ERROR(result);
1459 result = winreg_enumval_to_sz(info2,
1461 "Datatype",
1462 &info2->datatype);
1463 CHECK_ERROR(result);
1465 result = winreg_enumval_to_sz(info2,
1467 "Parameters",
1468 &info2->parameters);
1469 CHECK_ERROR(result);
1471 result = winreg_enumval_to_sz(info2,
1473 "Printer Driver",
1474 &info2->drivername);
1475 CHECK_ERROR(result);
1477 result = winreg_enumval_to_dword(info2,
1479 "Attributes",
1480 &info2->attributes);
1481 CHECK_ERROR(result);
1483 result = winreg_enumval_to_dword(info2,
1485 "Priority",
1486 &info2->priority);
1487 CHECK_ERROR(result);
1489 result = winreg_enumval_to_dword(info2,
1491 "Default Priority",
1492 &info2->defaultpriority);
1493 CHECK_ERROR(result);
1495 result = winreg_enumval_to_dword(info2,
1497 "StartTime",
1498 &info2->starttime);
1499 CHECK_ERROR(result);
1501 result = winreg_enumval_to_dword(info2,
1503 "UntilTime",
1504 &info2->untiltime);
1505 CHECK_ERROR(result);
1507 result = winreg_enumval_to_dword(info2,
1509 "Status",
1510 &info2->status);
1511 CHECK_ERROR(result);
1513 result = winreg_enumval_to_dword(info2,
1515 "StartTime",
1516 &info2->starttime);
1517 CHECK_ERROR(result);
1520 if (!W_ERROR_IS_OK(result)) {
1521 DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed "
1522 "for %s: %s\n",
1523 v->value_name,
1524 win_errstr(result)));
1525 goto done;
1528 /* Construct the Device Mode */
1529 status = dcerpc_winreg_query_binary(tmp_ctx,
1530 winreg_handle,
1531 &key_hnd,
1532 "Default DevMode",
1533 &blob,
1534 &result);
1535 if (!NT_STATUS_IS_OK(status)) {
1536 result = ntstatus_to_werror(status);
1538 if (W_ERROR_IS_OK(result)) {
1539 info2->devmode = talloc_zero(info2, struct spoolss_DeviceMode);
1540 if (info2->devmode == NULL) {
1541 result = WERR_NOMEM;
1542 goto done;
1544 ndr_err = ndr_pull_struct_blob(&blob,
1545 info2->devmode,
1546 info2->devmode,
1547 (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeviceMode);
1548 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1549 DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n"));
1550 result = WERR_NOMEM;
1551 goto done;
1555 if (info2->devmode == NULL && lp_default_devmode(snum)) {
1556 result = spoolss_create_default_devmode(info2,
1557 info2->printername,
1558 &info2->devmode);
1559 if (!W_ERROR_IS_OK(result)) {
1560 goto done;
1564 if (info2->devmode) {
1565 info2->devmode->size = ndr_size_spoolss_DeviceMode(info2->devmode, 0) - info2->devmode->driverextra_data.length;
1568 result = winreg_get_printer_secdesc(info2,
1569 winreg_handle,
1570 printer,
1571 &info2->secdesc);
1572 if (!W_ERROR_IS_OK(result)) {
1573 goto done;
1576 /* Fix for OS/2 drivers. */
1577 if (get_remote_arch() == RA_OS2) {
1578 spoolss_map_to_os2_driver(info2, &info2->drivername);
1581 if (pinfo2) {
1582 *pinfo2 = talloc_move(mem_ctx, &info2);
1585 result = WERR_OK;
1586 done:
1587 if (winreg_handle != NULL) {
1588 WERROR ignore;
1590 if (is_valid_policy_hnd(&key_hnd)) {
1591 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
1593 if (is_valid_policy_hnd(&hive_hnd)) {
1594 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
1598 TALLOC_FREE(tmp_ctx);
1599 return result;
1602 WERROR winreg_get_printer_secdesc(TALLOC_CTX *mem_ctx,
1603 struct dcerpc_binding_handle *winreg_handle,
1604 const char *sharename,
1605 struct spoolss_security_descriptor **psecdesc)
1607 struct spoolss_security_descriptor *secdesc;
1608 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1609 struct policy_handle hive_hnd, key_hnd;
1610 const char *path;
1611 TALLOC_CTX *tmp_ctx;
1612 NTSTATUS status;
1613 WERROR result;
1615 tmp_ctx = talloc_stackframe();
1616 if (tmp_ctx == NULL) {
1617 return WERR_NOMEM;
1620 path = winreg_printer_data_keyname(tmp_ctx, sharename);
1621 if (path == NULL) {
1622 talloc_free(tmp_ctx);
1623 return WERR_NOMEM;
1626 ZERO_STRUCT(hive_hnd);
1627 ZERO_STRUCT(key_hnd);
1629 result = winreg_printer_openkey(tmp_ctx,
1630 winreg_handle,
1631 path,
1633 false,
1634 access_mask,
1635 &hive_hnd,
1636 &key_hnd);
1637 if (!W_ERROR_IS_OK(result)) {
1638 if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
1639 goto create_default;
1641 goto done;
1644 status = dcerpc_winreg_query_sd(tmp_ctx,
1645 winreg_handle,
1646 &key_hnd,
1647 "Security",
1648 &secdesc,
1649 &result);
1650 if (!NT_STATUS_IS_OK(status)) {
1651 result = ntstatus_to_werror(status);
1653 if (!W_ERROR_IS_OK(result)) {
1654 if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
1655 goto create_default;
1657 goto done;
1660 if (psecdesc) {
1661 *psecdesc = talloc_move(mem_ctx, &secdesc);
1664 result = WERR_OK;
1665 goto done;
1667 create_default:
1668 result = winreg_printer_openkey(tmp_ctx,
1669 winreg_handle,
1670 path,
1672 true,
1673 access_mask,
1674 &hive_hnd,
1675 &key_hnd);
1676 if (!W_ERROR_IS_OK(result)) {
1677 goto done;
1680 result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
1681 if (!W_ERROR_IS_OK(result)) {
1682 goto done;
1685 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
1686 this security descriptor has been created when winbindd was
1687 down. Take ownership of security descriptor. */
1688 if (dom_sid_equal(secdesc->owner_sid, &global_sid_World)) {
1689 struct dom_sid owner_sid;
1691 /* Change sd owner to workgroup administrator */
1693 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
1694 struct spoolss_security_descriptor *new_secdesc;
1695 size_t size;
1697 /* Create new sd */
1698 sid_append_rid(&owner_sid, DOMAIN_RID_ADMINISTRATOR);
1700 new_secdesc = make_sec_desc(tmp_ctx,
1701 secdesc->revision,
1702 secdesc->type,
1703 &owner_sid,
1704 secdesc->group_sid,
1705 secdesc->sacl,
1706 secdesc->dacl,
1707 &size);
1709 if (new_secdesc == NULL) {
1710 result = WERR_NOMEM;
1711 goto done;
1714 /* Swap with other one */
1715 secdesc = new_secdesc;
1719 status = dcerpc_winreg_set_sd(tmp_ctx,
1720 winreg_handle,
1721 &key_hnd,
1722 "Security",
1723 secdesc,
1724 &result);
1725 if (!NT_STATUS_IS_OK(status)) {
1726 result = ntstatus_to_werror(status);
1728 if (!W_ERROR_IS_OK(result)) {
1729 return result;
1732 if (psecdesc) {
1733 *psecdesc = talloc_move(mem_ctx, &secdesc);
1736 result = WERR_OK;
1737 done:
1738 if (winreg_handle != NULL) {
1739 WERROR ignore;
1741 if (is_valid_policy_hnd(&key_hnd)) {
1742 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
1744 if (is_valid_policy_hnd(&hive_hnd)) {
1745 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
1749 talloc_free(tmp_ctx);
1750 return result;
1753 WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx,
1754 struct dcerpc_binding_handle *winreg_handle,
1755 const char *sharename,
1756 const struct spoolss_security_descriptor *secdesc)
1758 const struct spoolss_security_descriptor *new_secdesc = secdesc;
1759 struct spoolss_security_descriptor *old_secdesc;
1760 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1761 struct policy_handle hive_hnd, key_hnd;
1762 const char *path;
1763 TALLOC_CTX *tmp_ctx;
1764 NTSTATUS status;
1765 WERROR result;
1767 tmp_ctx = talloc_stackframe();
1768 if (tmp_ctx == NULL) {
1769 return WERR_NOMEM;
1772 path = winreg_printer_data_keyname(tmp_ctx, sharename);
1773 if (path == NULL) {
1774 talloc_free(tmp_ctx);
1775 return WERR_NOMEM;
1779 * The old owner and group sids of the security descriptor are not
1780 * present when new ACEs are added or removed by changing printer
1781 * permissions through NT. If they are NULL in the new security
1782 * descriptor then copy them over from the old one.
1784 if (!secdesc->owner_sid || !secdesc->group_sid) {
1785 struct dom_sid *owner_sid, *group_sid;
1786 struct security_acl *dacl, *sacl;
1787 size_t size;
1789 result = winreg_get_printer_secdesc(tmp_ctx,
1790 winreg_handle,
1791 sharename,
1792 &old_secdesc);
1793 if (!W_ERROR_IS_OK(result)) {
1794 talloc_free(tmp_ctx);
1795 return result;
1798 /* Pick out correct owner and group sids */
1799 owner_sid = secdesc->owner_sid ?
1800 secdesc->owner_sid :
1801 old_secdesc->owner_sid;
1803 group_sid = secdesc->group_sid ?
1804 secdesc->group_sid :
1805 old_secdesc->group_sid;
1807 dacl = secdesc->dacl ?
1808 secdesc->dacl :
1809 old_secdesc->dacl;
1811 sacl = secdesc->sacl ?
1812 secdesc->sacl :
1813 old_secdesc->sacl;
1815 /* Make a deep copy of the security descriptor */
1816 new_secdesc = make_sec_desc(tmp_ctx,
1817 secdesc->revision,
1818 secdesc->type,
1819 owner_sid,
1820 group_sid,
1821 sacl,
1822 dacl,
1823 &size);
1824 if (new_secdesc == NULL) {
1825 talloc_free(tmp_ctx);
1826 return WERR_NOMEM;
1830 ZERO_STRUCT(hive_hnd);
1831 ZERO_STRUCT(key_hnd);
1833 result = winreg_printer_openkey(tmp_ctx,
1834 winreg_handle,
1835 path,
1837 false,
1838 access_mask,
1839 &hive_hnd,
1840 &key_hnd);
1841 if (!W_ERROR_IS_OK(result)) {
1842 goto done;
1845 status = dcerpc_winreg_set_sd(tmp_ctx,
1846 winreg_handle,
1847 &key_hnd,
1848 "Security",
1849 new_secdesc,
1850 &result);
1851 if (!NT_STATUS_IS_OK(status)) {
1852 result = ntstatus_to_werror(status);
1855 done:
1856 if (winreg_handle != NULL) {
1857 WERROR ignore;
1859 if (is_valid_policy_hnd(&key_hnd)) {
1860 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
1862 if (is_valid_policy_hnd(&hive_hnd)) {
1863 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
1867 talloc_free(tmp_ctx);
1868 return result;
1871 /* Set printer data over the winreg pipe. */
1872 WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx,
1873 struct dcerpc_binding_handle *winreg_handle,
1874 const char *printer,
1875 const char *key,
1876 const char *value,
1877 enum winreg_Type type,
1878 uint8_t *data,
1879 uint32_t data_size)
1881 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1882 struct policy_handle hive_hnd, key_hnd;
1883 struct winreg_String wvalue = { 0, };
1884 char *path;
1885 WERROR result = WERR_OK;
1886 NTSTATUS status;
1887 TALLOC_CTX *tmp_ctx;
1889 tmp_ctx = talloc_stackframe();
1890 if (tmp_ctx == NULL) {
1891 return WERR_NOMEM;
1894 path = winreg_printer_data_keyname(tmp_ctx, printer);
1895 if (path == NULL) {
1896 TALLOC_FREE(tmp_ctx);
1897 return WERR_NOMEM;
1900 ZERO_STRUCT(hive_hnd);
1901 ZERO_STRUCT(key_hnd);
1903 DEBUG(8, ("winreg_set_printer_dataex: Open printer key %s, value %s, access_mask: 0x%05x for [%s]\n",
1904 key, value, access_mask, printer));
1905 result = winreg_printer_openkey(tmp_ctx,
1906 winreg_handle,
1907 path,
1908 key,
1909 true,
1910 access_mask,
1911 &hive_hnd,
1912 &key_hnd);
1913 if (!W_ERROR_IS_OK(result)) {
1914 DEBUG(0, ("winreg_set_printer_dataex: Could not open key %s: %s\n",
1915 key, win_errstr(result)));
1916 goto done;
1919 wvalue.name = value;
1920 status = dcerpc_winreg_SetValue(winreg_handle,
1921 tmp_ctx,
1922 &key_hnd,
1923 wvalue,
1924 type,
1925 data,
1926 data_size,
1927 &result);
1928 if (!NT_STATUS_IS_OK(status)) {
1929 DEBUG(0, ("winreg_set_printer_dataex: Could not set value %s: %s\n",
1930 value, nt_errstr(status)));
1931 result = ntstatus_to_werror(status);
1934 done:
1935 if (winreg_handle != NULL) {
1936 WERROR ignore;
1938 if (is_valid_policy_hnd(&key_hnd)) {
1939 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
1941 if (is_valid_policy_hnd(&hive_hnd)) {
1942 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
1946 TALLOC_FREE(tmp_ctx);
1947 return result;
1950 /* Get printer data over a winreg pipe. */
1951 WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx,
1952 struct dcerpc_binding_handle *winreg_handle,
1953 const char *printer,
1954 const char *key,
1955 const char *value,
1956 enum winreg_Type *type,
1957 uint8_t **data,
1958 uint32_t *data_size)
1960 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1961 struct policy_handle hive_hnd, key_hnd;
1962 struct winreg_String wvalue;
1963 enum winreg_Type type_in = REG_NONE;
1964 char *path;
1965 uint8_t *data_in = NULL;
1966 uint32_t data_in_size = 0;
1967 uint32_t value_len = 0;
1968 WERROR result = WERR_OK;
1969 NTSTATUS status;
1970 TALLOC_CTX *tmp_ctx;
1972 tmp_ctx = talloc_stackframe();
1973 if (tmp_ctx == NULL) {
1974 return WERR_NOMEM;
1977 path = winreg_printer_data_keyname(tmp_ctx, printer);
1978 if (path == NULL) {
1979 TALLOC_FREE(tmp_ctx);
1980 return WERR_NOMEM;
1983 ZERO_STRUCT(hive_hnd);
1984 ZERO_STRUCT(key_hnd);
1986 result = winreg_printer_openkey(tmp_ctx,
1987 winreg_handle,
1988 path,
1989 key,
1990 false,
1991 access_mask,
1992 &hive_hnd,
1993 &key_hnd);
1994 if (!W_ERROR_IS_OK(result)) {
1995 DEBUG(2, ("winreg_get_printer_dataex: Could not open key %s: %s\n",
1996 key, win_errstr(result)));
1997 goto done;
2000 wvalue.name = value;
2003 * call QueryValue once with data == NULL to get the
2004 * needed memory size to be allocated, then allocate
2005 * data buffer and call again.
2007 status = dcerpc_winreg_QueryValue(winreg_handle,
2008 tmp_ctx,
2009 &key_hnd,
2010 &wvalue,
2011 &type_in,
2012 NULL,
2013 &data_in_size,
2014 &value_len,
2015 &result);
2016 if (!NT_STATUS_IS_OK(status)) {
2017 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
2018 value, nt_errstr(status)));
2019 result = ntstatus_to_werror(status);
2020 goto done;
2022 if (!W_ERROR_IS_OK(result)) {
2023 goto done;
2026 data_in = (uint8_t *) TALLOC(tmp_ctx, data_in_size);
2027 if (data_in == NULL) {
2028 result = WERR_NOMEM;
2029 goto done;
2031 value_len = 0;
2033 status = dcerpc_winreg_QueryValue(winreg_handle,
2034 tmp_ctx,
2035 &key_hnd,
2036 &wvalue,
2037 &type_in,
2038 data_in,
2039 &data_in_size,
2040 &value_len,
2041 &result);
2042 if (!NT_STATUS_IS_OK(status)) {
2043 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
2044 value, nt_errstr(status)));
2045 result = ntstatus_to_werror(status);
2046 goto done;
2048 if (!W_ERROR_IS_OK(result)) {
2049 goto done;
2052 *type = type_in;
2053 *data_size = data_in_size;
2054 if (data_in_size) {
2055 *data = talloc_move(mem_ctx, &data_in);
2058 result = WERR_OK;
2059 done:
2060 if (winreg_handle != NULL) {
2061 WERROR ignore;
2063 if (is_valid_policy_hnd(&key_hnd)) {
2064 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2066 if (is_valid_policy_hnd(&hive_hnd)) {
2067 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2071 TALLOC_FREE(tmp_ctx);
2072 return result;
2075 /* Enumerate on the values of a given key and provide the data. */
2076 WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx,
2077 struct dcerpc_binding_handle *winreg_handle,
2078 const char *printer,
2079 const char *key,
2080 uint32_t *pnum_values,
2081 struct spoolss_PrinterEnumValues **penum_values)
2083 uint32_t i;
2084 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2085 struct policy_handle hive_hnd, key_hnd;
2087 struct spoolss_PrinterEnumValues *enum_values = NULL;
2088 uint32_t num_values = 0;
2089 char *path;
2090 WERROR result = WERR_OK;
2091 NTSTATUS status;
2092 const char **enum_names = NULL;
2093 enum winreg_Type *enum_types = NULL;
2094 DATA_BLOB *enum_data_blobs = NULL;
2096 TALLOC_CTX *tmp_ctx;
2098 tmp_ctx = talloc_stackframe();
2099 if (tmp_ctx == NULL) {
2100 return WERR_NOMEM;
2103 path = winreg_printer_data_keyname(tmp_ctx, printer);
2104 if (path == NULL) {
2105 TALLOC_FREE(tmp_ctx);
2106 return WERR_NOMEM;
2109 result = winreg_printer_openkey(tmp_ctx,
2110 winreg_handle,
2111 path,
2112 key,
2113 false,
2114 access_mask,
2115 &hive_hnd,
2116 &key_hnd);
2117 if (!W_ERROR_IS_OK(result)) {
2118 DEBUG(2, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
2119 key, win_errstr(result)));
2120 goto done;
2123 status = dcerpc_winreg_enumvals(tmp_ctx,
2124 winreg_handle,
2125 &key_hnd,
2126 &num_values,
2127 &enum_names,
2128 &enum_types,
2129 &enum_data_blobs,
2130 &result);
2131 if (!NT_STATUS_IS_OK(status)){
2132 result = ntstatus_to_werror(status);
2135 if (!W_ERROR_IS_OK(result)) {
2136 DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
2137 key, win_errstr(result)));
2138 goto done;
2141 enum_values = talloc_array(tmp_ctx, struct spoolss_PrinterEnumValues, num_values);
2142 if (enum_values == NULL){
2143 result = WERR_NOMEM;
2144 DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
2145 key, win_errstr(result)));
2146 goto done;
2149 for (i = 0; i < num_values; i++){
2150 enum_values[i].value_name = enum_names[i];
2151 enum_values[i].value_name_len = strlen_m_term(enum_names[i]) * 2;
2152 enum_values[i].type = enum_types[i];
2153 enum_values[i].data_length = enum_data_blobs[i].length;
2154 enum_values[i].data = NULL;
2156 if (enum_values[i].data_length != 0){
2157 enum_values[i].data = &enum_data_blobs[i];
2161 enum_names = talloc_move(mem_ctx, &enum_names);
2162 enum_types = talloc_move(mem_ctx, &enum_types);
2163 enum_data_blobs = talloc_move(mem_ctx, &enum_data_blobs);
2165 *pnum_values = num_values;
2166 if (penum_values) {
2167 *penum_values = talloc_move(mem_ctx, &enum_values);
2170 result = WERR_OK;
2171 done:
2172 if (winreg_handle != NULL) {
2173 WERROR ignore;
2175 if (is_valid_policy_hnd(&key_hnd)) {
2176 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2178 if (is_valid_policy_hnd(&hive_hnd)) {
2179 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2183 TALLOC_FREE(tmp_ctx);
2184 return result;
2187 /* Delete printer data over a winreg pipe. */
2188 WERROR winreg_delete_printer_dataex(TALLOC_CTX *mem_ctx,
2189 struct dcerpc_binding_handle *winreg_handle,
2190 const char *printer,
2191 const char *key,
2192 const char *value)
2194 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2195 struct policy_handle hive_hnd, key_hnd;
2196 struct winreg_String wvalue = { 0, };
2197 char *path;
2198 WERROR result = WERR_OK;
2199 NTSTATUS status;
2201 TALLOC_CTX *tmp_ctx;
2203 tmp_ctx = talloc_stackframe();
2204 if (tmp_ctx == NULL) {
2205 return WERR_NOMEM;
2208 path = winreg_printer_data_keyname(tmp_ctx, printer);
2209 if (path == NULL) {
2210 TALLOC_FREE(tmp_ctx);
2211 return WERR_NOMEM;
2214 ZERO_STRUCT(hive_hnd);
2215 ZERO_STRUCT(key_hnd);
2217 result = winreg_printer_openkey(tmp_ctx,
2218 winreg_handle,
2219 path,
2220 key,
2221 false,
2222 access_mask,
2223 &hive_hnd,
2224 &key_hnd);
2225 if (!W_ERROR_IS_OK(result)) {
2226 DEBUG(0, ("winreg_delete_printer_dataex: Could not open key %s: %s\n",
2227 key, win_errstr(result)));
2228 goto done;
2231 wvalue.name = value;
2232 status = dcerpc_winreg_DeleteValue(winreg_handle,
2233 tmp_ctx,
2234 &key_hnd,
2235 wvalue,
2236 &result);
2237 if (!NT_STATUS_IS_OK(status)) {
2238 DEBUG(0, ("winreg_delete_printer_dataex: Could not delete value %s: %s\n",
2239 value, nt_errstr(status)));
2240 result = ntstatus_to_werror(status);
2243 done:
2244 if (winreg_handle != NULL) {
2245 WERROR ignore;
2247 if (is_valid_policy_hnd(&key_hnd)) {
2248 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2250 if (is_valid_policy_hnd(&hive_hnd)) {
2251 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2255 TALLOC_FREE(tmp_ctx);
2256 return result;
2259 /* Enumerate on the subkeys of a given key and provide the data. */
2260 WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx,
2261 struct dcerpc_binding_handle *winreg_handle,
2262 const char *printer,
2263 const char *key,
2264 uint32_t *pnum_subkeys,
2265 const char ***psubkeys)
2267 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2268 struct policy_handle hive_hnd, key_hnd;
2269 char *path;
2270 const char **subkeys = NULL;
2271 uint32_t num_subkeys = -1;
2273 WERROR result = WERR_OK;
2274 NTSTATUS status;
2276 TALLOC_CTX *tmp_ctx;
2278 tmp_ctx = talloc_stackframe();
2279 if (tmp_ctx == NULL) {
2280 return WERR_NOMEM;
2283 path = winreg_printer_data_keyname(tmp_ctx, printer);
2284 if (path == NULL) {
2285 TALLOC_FREE(tmp_ctx);
2286 return WERR_NOMEM;
2289 ZERO_STRUCT(hive_hnd);
2290 ZERO_STRUCT(key_hnd);
2292 result = winreg_printer_openkey(tmp_ctx,
2293 winreg_handle,
2294 path,
2295 key,
2296 false,
2297 access_mask,
2298 &hive_hnd,
2299 &key_hnd);
2300 if (!W_ERROR_IS_OK(result)) {
2301 DEBUG(2, ("winreg_enum_printer_key: Could not open key %s: %s\n",
2302 key, win_errstr(result)));
2303 goto done;
2306 status = dcerpc_winreg_enum_keys(tmp_ctx,
2307 winreg_handle,
2308 &key_hnd,
2309 &num_subkeys,
2310 &subkeys,
2311 &result);
2312 if (!NT_STATUS_IS_OK(status)) {
2313 result = ntstatus_to_werror(status);
2315 if (!W_ERROR_IS_OK(result)) {
2316 DEBUG(0, ("winreg_enum_printer_key: Could not enumerate subkeys in %s: %s\n",
2317 key, win_errstr(result)));
2318 goto done;
2321 *pnum_subkeys = num_subkeys;
2322 if (psubkeys) {
2323 *psubkeys = talloc_move(mem_ctx, &subkeys);
2326 result = WERR_OK;
2327 done:
2328 if (winreg_handle != NULL) {
2329 WERROR ignore;
2331 if (is_valid_policy_hnd(&key_hnd)) {
2332 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2334 if (is_valid_policy_hnd(&hive_hnd)) {
2335 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2339 TALLOC_FREE(tmp_ctx);
2340 return result;
2343 /* Delete a key with subkeys of a given printer. */
2344 WERROR winreg_delete_printer_key(TALLOC_CTX *mem_ctx,
2345 struct dcerpc_binding_handle *winreg_handle,
2346 const char *printer,
2347 const char *key)
2349 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2350 struct policy_handle hive_hnd, key_hnd;
2351 char *keyname;
2352 char *path;
2353 WERROR result;
2354 NTSTATUS status;
2355 TALLOC_CTX *tmp_ctx;
2357 tmp_ctx = talloc_stackframe();
2358 if (tmp_ctx == NULL) {
2359 return WERR_NOMEM;
2362 path = winreg_printer_data_keyname(tmp_ctx, printer);
2363 if (path == NULL) {
2364 TALLOC_FREE(tmp_ctx);
2365 return WERR_NOMEM;
2368 result = winreg_printer_openkey(tmp_ctx,
2369 winreg_handle,
2370 path,
2371 key,
2372 false,
2373 access_mask,
2374 &hive_hnd,
2375 &key_hnd);
2376 if (!W_ERROR_IS_OK(result)) {
2377 /* key doesn't exist */
2378 if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
2379 result = WERR_OK;
2380 goto done;
2383 DEBUG(0, ("winreg_delete_printer_key: Could not open key %s: %s\n",
2384 key, win_errstr(result)));
2385 goto done;
2388 if (is_valid_policy_hnd(&key_hnd)) {
2389 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
2392 if (key == NULL || key[0] == '\0') {
2393 keyname = path;
2394 } else {
2395 keyname = talloc_asprintf(tmp_ctx,
2396 "%s\\%s",
2397 path,
2398 key);
2399 if (keyname == NULL) {
2400 result = WERR_NOMEM;
2401 goto done;
2405 status = dcerpc_winreg_delete_subkeys_recursive(tmp_ctx,
2406 winreg_handle,
2407 &hive_hnd,
2408 access_mask,
2409 keyname,
2410 &result);
2412 if (!NT_STATUS_IS_OK(status)) {
2413 DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
2414 key, nt_errstr(status)));
2415 result = ntstatus_to_werror(status);
2416 goto done;
2419 if (!W_ERROR_IS_OK(result)) {
2420 DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
2421 key, win_errstr(result)));
2422 goto done;
2425 done:
2426 if (winreg_handle != NULL) {
2427 WERROR ignore;
2429 if (is_valid_policy_hnd(&key_hnd)) {
2430 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2432 if (is_valid_policy_hnd(&hive_hnd)) {
2433 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2437 TALLOC_FREE(tmp_ctx);
2438 return result;
2441 WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx,
2442 struct dcerpc_binding_handle *winreg_handle,
2443 const char *printer)
2445 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2446 struct policy_handle hive_hnd, key_hnd;
2447 char *path;
2448 NTSTATUS status;
2449 WERROR result;
2450 TALLOC_CTX *tmp_ctx;
2452 tmp_ctx = talloc_stackframe();
2453 if (tmp_ctx == NULL) {
2454 return WERR_NOMEM;
2457 path = winreg_printer_data_keyname(tmp_ctx, printer);
2458 if (path == NULL) {
2459 TALLOC_FREE(tmp_ctx);
2460 return WERR_NOMEM;
2463 ZERO_STRUCT(hive_hnd);
2464 ZERO_STRUCT(key_hnd);
2466 result = winreg_printer_openkey(tmp_ctx,
2467 winreg_handle,
2468 path,
2470 false,
2471 access_mask,
2472 &hive_hnd,
2473 &key_hnd);
2474 if (!W_ERROR_IS_OK(result)) {
2475 DEBUG(0, ("winreg_printer_update_changeid: Could not open key %s: %s\n",
2476 path, win_errstr(result)));
2477 goto done;
2480 status = dcerpc_winreg_set_dword(tmp_ctx,
2481 winreg_handle,
2482 &key_hnd,
2483 "ChangeID",
2484 winreg_printer_rev_changeid(),
2485 &result);
2486 if (!NT_STATUS_IS_OK(status)) {
2487 result = ntstatus_to_werror(status);
2489 if (!W_ERROR_IS_OK(result)) {
2490 goto done;
2493 result = WERR_OK;
2494 done:
2495 if (winreg_handle != NULL) {
2496 WERROR ignore;
2498 if (is_valid_policy_hnd(&key_hnd)) {
2499 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2501 if (is_valid_policy_hnd(&hive_hnd)) {
2502 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2506 TALLOC_FREE(tmp_ctx);
2507 return result;
2510 WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx,
2511 struct dcerpc_binding_handle *winreg_handle,
2512 const char *printer,
2513 uint32_t *pchangeid)
2515 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2516 struct policy_handle hive_hnd, key_hnd;
2517 uint32_t changeid = 0;
2518 char *path;
2519 NTSTATUS status;
2520 WERROR result;
2521 TALLOC_CTX *tmp_ctx;
2523 tmp_ctx = talloc_stackframe();
2524 if (tmp_ctx == NULL) {
2525 return WERR_NOMEM;
2528 path = winreg_printer_data_keyname(tmp_ctx, printer);
2529 if (path == NULL) {
2530 TALLOC_FREE(tmp_ctx);
2531 return WERR_NOMEM;
2534 ZERO_STRUCT(hive_hnd);
2535 ZERO_STRUCT(key_hnd);
2537 result = winreg_printer_openkey(tmp_ctx,
2538 winreg_handle,
2539 path,
2541 false,
2542 access_mask,
2543 &hive_hnd,
2544 &key_hnd);
2545 if (!W_ERROR_IS_OK(result)) {
2546 DEBUG(2, ("winreg_printer_get_changeid: Could not open key %s: %s\n",
2547 path, win_errstr(result)));
2548 goto done;
2551 DEBUG(10, ("winreg_printer_get_changeid: get changeid from %s\n", path));
2553 status = dcerpc_winreg_query_dword(tmp_ctx,
2554 winreg_handle,
2555 &key_hnd,
2556 "ChangeID",
2557 &changeid,
2558 &result);
2559 if (!NT_STATUS_IS_OK(status)) {
2560 result = ntstatus_to_werror(status);
2562 if (!W_ERROR_IS_OK(result)) {
2563 goto done;
2566 if (pchangeid) {
2567 *pchangeid = changeid;
2570 result = WERR_OK;
2571 done:
2572 if (winreg_handle != NULL) {
2573 WERROR ignore;
2575 if (is_valid_policy_hnd(&key_hnd)) {
2576 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2578 if (is_valid_policy_hnd(&hive_hnd)) {
2579 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2583 TALLOC_FREE(tmp_ctx);
2584 return result;
2588 * The special behaviour of the spoolss forms is documented at the website:
2590 * Managing Win32 Printserver Forms
2591 * http://unixwiz.net/techtips/winspooler-forms.html
2594 WERROR winreg_printer_addform1(TALLOC_CTX *mem_ctx,
2595 struct dcerpc_binding_handle *winreg_handle,
2596 struct spoolss_AddFormInfo1 *form)
2598 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2599 struct policy_handle hive_hnd, key_hnd;
2600 struct winreg_String wvalue = { 0, };
2601 DATA_BLOB blob;
2602 uint32_t num_info = 0;
2603 union spoolss_FormInfo *info = NULL;
2604 uint32_t i;
2605 WERROR result;
2606 NTSTATUS status;
2607 TALLOC_CTX *tmp_ctx;
2609 tmp_ctx = talloc_stackframe();
2610 if (tmp_ctx == NULL) {
2611 return WERR_NOMEM;
2614 ZERO_STRUCT(hive_hnd);
2615 ZERO_STRUCT(key_hnd);
2617 result = winreg_printer_openkey(tmp_ctx,
2618 winreg_handle,
2619 TOP_LEVEL_CONTROL_FORMS_KEY,
2621 true,
2622 access_mask,
2623 &hive_hnd,
2624 &key_hnd);
2625 if (!W_ERROR_IS_OK(result)) {
2626 DEBUG(0, ("winreg_printer_addform1: Could not open key %s: %s\n",
2627 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
2628 goto done;
2631 result = winreg_printer_enumforms1(tmp_ctx, winreg_handle,
2632 &num_info, &info);
2633 if (!W_ERROR_IS_OK(result)) {
2634 DEBUG(0, ("winreg_printer_addform: Could not enum keys %s: %s\n",
2635 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
2636 goto done;
2639 /* If form name already exists or is builtin return ALREADY_EXISTS */
2640 for (i = 0; i < num_info; i++) {
2641 if (strequal(info[i].info1.form_name, form->form_name)) {
2642 result = WERR_FILE_EXISTS;
2643 goto done;
2647 wvalue.name = form->form_name;
2649 blob = data_blob_talloc(tmp_ctx, NULL, 32);
2650 SIVAL(blob.data, 0, form->size.width);
2651 SIVAL(blob.data, 4, form->size.height);
2652 SIVAL(blob.data, 8, form->area.left);
2653 SIVAL(blob.data, 12, form->area.top);
2654 SIVAL(blob.data, 16, form->area.right);
2655 SIVAL(blob.data, 20, form->area.bottom);
2656 SIVAL(blob.data, 24, num_info + 1); /* FIXME */
2657 SIVAL(blob.data, 28, form->flags);
2659 status = dcerpc_winreg_SetValue(winreg_handle,
2660 tmp_ctx,
2661 &key_hnd,
2662 wvalue,
2663 REG_BINARY,
2664 blob.data,
2665 blob.length,
2666 &result);
2667 if (!NT_STATUS_IS_OK(status)) {
2668 DEBUG(0, ("winreg_printer_addform1: Could not set value %s: %s\n",
2669 wvalue.name, nt_errstr(status)));
2670 result = ntstatus_to_werror(status);
2673 done:
2674 if (winreg_handle != NULL) {
2675 WERROR ignore;
2677 if (is_valid_policy_hnd(&key_hnd)) {
2678 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2680 if (is_valid_policy_hnd(&hive_hnd)) {
2681 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2685 TALLOC_FREE(info);
2686 TALLOC_FREE(tmp_ctx);
2687 return result;
2690 WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx,
2691 struct dcerpc_binding_handle *winreg_handle,
2692 uint32_t *pnum_info,
2693 union spoolss_FormInfo **pinfo)
2695 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2696 struct policy_handle hive_hnd, key_hnd;
2697 union spoolss_FormInfo *info;
2698 struct spoolss_PrinterEnumValues *enum_values = NULL;
2699 uint32_t num_values = 0;
2700 uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
2701 uint32_t i;
2702 WERROR result;
2703 NTSTATUS status;
2704 const char **enum_names = NULL;
2705 enum winreg_Type *enum_types = NULL;
2706 DATA_BLOB *enum_data_blobs = NULL;
2707 TALLOC_CTX *tmp_ctx;
2709 tmp_ctx = talloc_stackframe();
2710 if (tmp_ctx == NULL) {
2711 return WERR_NOMEM;
2714 ZERO_STRUCT(hive_hnd);
2715 ZERO_STRUCT(key_hnd);
2717 result = winreg_printer_openkey(tmp_ctx,
2718 winreg_handle,
2719 TOP_LEVEL_CONTROL_FORMS_KEY,
2721 true,
2722 access_mask,
2723 &hive_hnd,
2724 &key_hnd);
2725 if (!W_ERROR_IS_OK(result)) {
2726 /* key doesn't exist */
2727 if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
2728 result = WERR_OK;
2729 goto done;
2732 DEBUG(0, ("winreg_printer_enumforms1: Could not open key %s: %s\n",
2733 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
2734 goto done;
2737 status = dcerpc_winreg_enumvals(tmp_ctx,
2738 winreg_handle,
2739 &key_hnd,
2740 &num_values,
2741 &enum_names,
2742 &enum_types,
2743 &enum_data_blobs,
2744 &result);
2745 if (!NT_STATUS_IS_OK(status)){
2746 result = ntstatus_to_werror(status);
2749 if (!W_ERROR_IS_OK(result)) {
2750 DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n",
2751 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
2752 goto done;
2755 enum_values = talloc_zero_array(tmp_ctx,
2756 struct spoolss_PrinterEnumValues,
2757 num_values);
2758 if (enum_values == NULL){
2759 result = WERR_NOMEM;
2760 goto done;
2763 for (i = 0; i < num_values; i++){
2764 enum_values[i].value_name = enum_names[i];
2765 enum_values[i].value_name_len = strlen_m_term(enum_names[i]) * 2;
2766 enum_values[i].type = enum_types[i];
2767 enum_values[i].data_length = enum_data_blobs[i].length;
2768 enum_values[i].data = NULL;
2769 if (enum_values[i].data_length != 0){
2770 enum_values[i].data = &enum_data_blobs[i];
2774 if (!W_ERROR_IS_OK(result)) {
2775 DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n",
2776 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
2777 goto done;
2780 info = talloc_array(tmp_ctx, union spoolss_FormInfo, num_builtin + num_values);
2781 if (info == NULL) {
2782 result = WERR_NOMEM;
2783 goto done;
2786 /* Enumerate BUILTIN forms */
2787 for (i = 0; i < num_builtin; i++) {
2788 info[i].info1 = builtin_forms1[i];
2791 /* Enumerate registry forms */
2792 for (i = 0; i < num_values; i++) {
2793 union spoolss_FormInfo val;
2795 if (enum_values[i].type != REG_BINARY ||
2796 enum_values[i].data_length != 32) {
2797 continue;
2800 val.info1.form_name = talloc_strdup(info, enum_values[i].value_name);
2801 if (val.info1.form_name == NULL) {
2802 result = WERR_NOMEM;
2803 goto done;
2806 val.info1.size.width = IVAL(enum_values[i].data->data, 0);
2807 val.info1.size.height = IVAL(enum_values[i].data->data, 4);
2808 val.info1.area.left = IVAL(enum_values[i].data->data, 8);
2809 val.info1.area.top = IVAL(enum_values[i].data->data, 12);
2810 val.info1.area.right = IVAL(enum_values[i].data->data, 16);
2811 val.info1.area.bottom = IVAL(enum_values[i].data->data, 20);
2812 /* skip form index IVAL(enum_values[i].data->data, 24)));*/
2813 val.info1.flags = (enum spoolss_FormFlags) IVAL(enum_values[i].data->data, 28);
2815 info[i + num_builtin] = val;
2818 *pnum_info = num_builtin + num_values;
2819 if (pinfo) {
2820 *pinfo = talloc_move(mem_ctx, &info);
2823 done:
2824 if (winreg_handle != NULL) {
2825 WERROR ignore;
2827 if (is_valid_policy_hnd(&key_hnd)) {
2828 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2830 if (is_valid_policy_hnd(&hive_hnd)) {
2831 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2835 TALLOC_FREE(enum_values);
2836 TALLOC_FREE(tmp_ctx);
2837 return result;
2840 WERROR winreg_printer_deleteform1(TALLOC_CTX *mem_ctx,
2841 struct dcerpc_binding_handle *winreg_handle,
2842 const char *form_name)
2844 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2845 struct policy_handle hive_hnd, key_hnd;
2846 struct winreg_String wvalue = { 0, };
2847 uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
2848 uint32_t i;
2849 WERROR result = WERR_OK;
2850 NTSTATUS status;
2851 TALLOC_CTX *tmp_ctx;
2853 for (i = 0; i < num_builtin; i++) {
2854 if (strequal(builtin_forms1[i].form_name, form_name)) {
2855 return WERR_INVALID_PARAMETER;
2859 tmp_ctx = talloc_stackframe();
2860 if (tmp_ctx == NULL) {
2861 return WERR_NOMEM;
2864 ZERO_STRUCT(hive_hnd);
2865 ZERO_STRUCT(key_hnd);
2867 result = winreg_printer_openkey(tmp_ctx,
2868 winreg_handle,
2869 TOP_LEVEL_CONTROL_FORMS_KEY,
2871 false,
2872 access_mask,
2873 &hive_hnd,
2874 &key_hnd);
2875 if (!W_ERROR_IS_OK(result)) {
2876 DEBUG(0, ("winreg_printer_deleteform1: Could not open key %s: %s\n",
2877 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
2878 if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
2879 result = WERR_INVALID_FORM_NAME;
2881 goto done;
2884 wvalue.name = form_name;
2885 status = dcerpc_winreg_DeleteValue(winreg_handle,
2886 tmp_ctx,
2887 &key_hnd,
2888 wvalue,
2889 &result);
2890 if (!NT_STATUS_IS_OK(status)) {
2891 /* If the value doesn't exist, return WERR_INVALID_FORM_NAME */
2892 DEBUG(0, ("winreg_printer_delteform1: Could not delete value %s: %s\n",
2893 wvalue.name, nt_errstr(status)));
2894 result = ntstatus_to_werror(status);
2895 goto done;
2898 if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
2899 result = WERR_INVALID_FORM_NAME;
2902 done:
2903 if (winreg_handle != NULL) {
2904 WERROR ignore;
2906 if (is_valid_policy_hnd(&key_hnd)) {
2907 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2909 if (is_valid_policy_hnd(&hive_hnd)) {
2910 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2914 TALLOC_FREE(tmp_ctx);
2915 return result;
2918 WERROR winreg_printer_setform1(TALLOC_CTX *mem_ctx,
2919 struct dcerpc_binding_handle *winreg_handle,
2920 const char *form_name,
2921 struct spoolss_AddFormInfo1 *form)
2923 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2924 struct policy_handle hive_hnd, key_hnd;
2925 struct winreg_String wvalue = { 0, };
2926 DATA_BLOB blob;
2927 uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
2928 uint32_t i;
2929 WERROR result;
2930 NTSTATUS status;
2931 TALLOC_CTX *tmp_ctx = NULL;
2933 for (i = 0; i < num_builtin; i++) {
2934 if (strequal(builtin_forms1[i].form_name, form->form_name)) {
2935 result = WERR_INVALID_PARAM;
2936 goto done;
2940 tmp_ctx = talloc_stackframe();
2941 if (tmp_ctx == NULL) {
2942 return WERR_NOMEM;
2945 ZERO_STRUCT(hive_hnd);
2946 ZERO_STRUCT(key_hnd);
2948 result = winreg_printer_openkey(tmp_ctx,
2949 winreg_handle,
2950 TOP_LEVEL_CONTROL_FORMS_KEY,
2952 true,
2953 access_mask,
2954 &hive_hnd,
2955 &key_hnd);
2956 if (!W_ERROR_IS_OK(result)) {
2957 DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
2958 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
2959 goto done;
2962 /* If form_name != form->form_name then we renamed the form */
2963 if (strequal(form_name, form->form_name)) {
2964 result = winreg_printer_deleteform1(tmp_ctx, winreg_handle,
2965 form_name);
2966 if (!W_ERROR_IS_OK(result)) {
2967 DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
2968 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
2969 goto done;
2973 wvalue.name = form->form_name;
2975 blob = data_blob_talloc(tmp_ctx, NULL, 32);
2976 SIVAL(blob.data, 0, form->size.width);
2977 SIVAL(blob.data, 4, form->size.height);
2978 SIVAL(blob.data, 8, form->area.left);
2979 SIVAL(blob.data, 12, form->area.top);
2980 SIVAL(blob.data, 16, form->area.right);
2981 SIVAL(blob.data, 20, form->area.bottom);
2982 SIVAL(blob.data, 24, 42);
2983 SIVAL(blob.data, 28, form->flags);
2985 status = dcerpc_winreg_SetValue(winreg_handle,
2986 tmp_ctx,
2987 &key_hnd,
2988 wvalue,
2989 REG_BINARY,
2990 blob.data,
2991 blob.length,
2992 &result);
2993 if (!NT_STATUS_IS_OK(status)) {
2994 DEBUG(0, ("winreg_printer_setform1: Could not set value %s: %s\n",
2995 wvalue.name, nt_errstr(status)));
2996 result = ntstatus_to_werror(status);
2999 done:
3000 if (winreg_handle != NULL) {
3001 WERROR ignore;
3003 if (is_valid_policy_hnd(&key_hnd)) {
3004 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
3006 if (is_valid_policy_hnd(&hive_hnd)) {
3007 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
3011 TALLOC_FREE(tmp_ctx);
3012 return result;
3015 WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx,
3016 struct dcerpc_binding_handle *winreg_handle,
3017 const char *form_name,
3018 struct spoolss_FormInfo1 *r)
3020 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3021 struct policy_handle hive_hnd, key_hnd;
3022 struct winreg_String wvalue;
3023 enum winreg_Type type_in = REG_NONE;
3024 uint8_t *data_in = NULL;
3025 uint32_t data_in_size = 0;
3026 uint32_t value_len = 0;
3027 uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
3028 uint32_t i;
3029 WERROR result;
3030 NTSTATUS status;
3031 TALLOC_CTX *tmp_ctx;
3033 /* check builtin forms first */
3034 for (i = 0; i < num_builtin; i++) {
3035 if (strequal(builtin_forms1[i].form_name, form_name)) {
3036 *r = builtin_forms1[i];
3037 return WERR_OK;
3041 tmp_ctx = talloc_stackframe();
3042 if (tmp_ctx == NULL) {
3043 return WERR_NOMEM;
3046 ZERO_STRUCT(hive_hnd);
3047 ZERO_STRUCT(key_hnd);
3049 result = winreg_printer_openkey(tmp_ctx,
3050 winreg_handle,
3051 TOP_LEVEL_CONTROL_FORMS_KEY,
3053 true,
3054 access_mask,
3055 &hive_hnd,
3056 &key_hnd);
3057 if (!W_ERROR_IS_OK(result)) {
3058 DEBUG(2, ("winreg_printer_getform1: Could not open key %s: %s\n",
3059 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
3060 goto done;
3063 wvalue.name = form_name;
3066 * call QueryValue once with data == NULL to get the
3067 * needed memory size to be allocated, then allocate
3068 * data buffer and call again.
3070 status = dcerpc_winreg_QueryValue(winreg_handle,
3071 tmp_ctx,
3072 &key_hnd,
3073 &wvalue,
3074 &type_in,
3075 NULL,
3076 &data_in_size,
3077 &value_len,
3078 &result);
3079 if (!NT_STATUS_IS_OK(status)) {
3080 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
3081 wvalue.name, nt_errstr(status)));
3082 result = ntstatus_to_werror(status);
3083 goto done;
3085 if (!W_ERROR_IS_OK(result)) {
3086 goto done;
3089 data_in = (uint8_t *) TALLOC(tmp_ctx, data_in_size);
3090 if (data_in == NULL) {
3091 result = WERR_NOMEM;
3092 goto done;
3094 value_len = 0;
3096 status = dcerpc_winreg_QueryValue(winreg_handle,
3097 tmp_ctx,
3098 &key_hnd,
3099 &wvalue,
3100 &type_in,
3101 data_in,
3102 &data_in_size,
3103 &value_len,
3104 &result);
3105 if (!NT_STATUS_IS_OK(status)) {
3106 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
3107 wvalue.name, nt_errstr(status)));
3108 result = ntstatus_to_werror(status);
3109 goto done;
3111 if (!W_ERROR_IS_OK(result)) {
3112 goto done;
3115 r->form_name = talloc_strdup(mem_ctx, form_name);
3116 if (r->form_name == NULL) {
3117 result = WERR_NOMEM;
3118 goto done;
3121 r->size.width = IVAL(data_in, 0);
3122 r->size.height = IVAL(data_in, 4);
3123 r->area.left = IVAL(data_in, 8);
3124 r->area.top = IVAL(data_in, 12);
3125 r->area.right = IVAL(data_in, 16);
3126 r->area.bottom = IVAL(data_in, 20);
3127 /* skip index IVAL(data_in, 24)));*/
3128 r->flags = (enum spoolss_FormFlags) IVAL(data_in, 28);
3130 result = WERR_OK;
3131 done:
3132 if (winreg_handle != NULL) {
3133 WERROR ignore;
3135 if (is_valid_policy_hnd(&key_hnd)) {
3136 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
3138 if (is_valid_policy_hnd(&hive_hnd)) {
3139 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
3143 TALLOC_FREE(tmp_ctx);
3144 return result;
3147 WERROR winreg_add_driver(TALLOC_CTX *mem_ctx,
3148 struct dcerpc_binding_handle *winreg_handle,
3149 struct spoolss_AddDriverInfoCtr *r,
3150 const char **driver_name,
3151 uint32_t *driver_version)
3153 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3154 struct policy_handle hive_hnd, key_hnd;
3155 struct spoolss_DriverInfo8 info8;
3156 TALLOC_CTX *tmp_ctx = NULL;
3157 NTSTATUS status;
3158 WERROR result;
3160 ZERO_STRUCT(hive_hnd);
3161 ZERO_STRUCT(key_hnd);
3162 ZERO_STRUCT(info8);
3164 if (!driver_info_ctr_to_info8(r, &info8)) {
3165 result = WERR_INVALID_PARAMETER;
3166 goto done;
3169 tmp_ctx = talloc_stackframe();
3170 if (tmp_ctx == NULL) {
3171 return WERR_NOMEM;
3174 result = winreg_printer_opendriver(tmp_ctx,
3175 winreg_handle,
3176 info8.driver_name,
3177 info8.architecture,
3178 info8.version,
3179 access_mask, true,
3180 &hive_hnd,
3181 &key_hnd);
3182 if (!W_ERROR_IS_OK(result)) {
3183 DEBUG(0, ("winreg_add_driver: "
3184 "Could not open driver key (%s,%s,%d): %s\n",
3185 info8.driver_name, info8.architecture,
3186 info8.version, win_errstr(result)));
3187 goto done;
3190 /* TODO: "Attributes" ? */
3192 status = dcerpc_winreg_set_dword(tmp_ctx,
3193 winreg_handle,
3194 &key_hnd,
3195 "Version",
3196 info8.version,
3197 &result);
3198 if (!NT_STATUS_IS_OK(status)) {
3199 result = ntstatus_to_werror(status);
3201 if (!W_ERROR_IS_OK(result)) {
3202 goto done;
3205 status = dcerpc_winreg_set_sz(tmp_ctx,
3206 winreg_handle,
3207 &key_hnd,
3208 "Driver",
3209 info8.driver_path,
3210 &result);
3211 if (!NT_STATUS_IS_OK(status)) {
3212 result = ntstatus_to_werror(status);
3214 if (!W_ERROR_IS_OK(result)) {
3215 goto done;
3218 status = dcerpc_winreg_set_sz(tmp_ctx,
3219 winreg_handle,
3220 &key_hnd,
3221 "Data File",
3222 info8.data_file,
3223 &result);
3224 if (!NT_STATUS_IS_OK(status)) {
3225 result = ntstatus_to_werror(status);
3227 if (!W_ERROR_IS_OK(result)) {
3228 goto done;
3231 status = dcerpc_winreg_set_sz(tmp_ctx,
3232 winreg_handle,
3233 &key_hnd,
3234 "Configuration File",
3235 info8.config_file,
3236 &result);
3237 if (!NT_STATUS_IS_OK(status)) {
3238 result = ntstatus_to_werror(status);
3240 if (!W_ERROR_IS_OK(result)) {
3241 goto done;
3244 status = dcerpc_winreg_set_sz(tmp_ctx,
3245 winreg_handle,
3246 &key_hnd,
3247 "Help File",
3248 info8.help_file,
3249 &result);
3250 if (!NT_STATUS_IS_OK(status)) {
3251 result = ntstatus_to_werror(status);
3253 if (!W_ERROR_IS_OK(result)) {
3254 goto done;
3257 status = dcerpc_winreg_set_multi_sz(tmp_ctx,
3258 winreg_handle,
3259 &key_hnd,
3260 "Dependent Files",
3261 info8.dependent_files,
3262 &result);
3263 if (!NT_STATUS_IS_OK(status)) {
3264 result = ntstatus_to_werror(status);
3266 if (!W_ERROR_IS_OK(result)) {
3267 goto done;
3270 status = dcerpc_winreg_set_sz(tmp_ctx,
3271 winreg_handle,
3272 &key_hnd,
3273 "Monitor",
3274 info8.monitor_name,
3275 &result);
3276 if (!NT_STATUS_IS_OK(status)) {
3277 result = ntstatus_to_werror(status);
3279 if (!W_ERROR_IS_OK(result)) {
3280 goto done;
3283 status = dcerpc_winreg_set_sz(tmp_ctx,
3284 winreg_handle,
3285 &key_hnd,
3286 "Datatype",
3287 info8.default_datatype,
3288 &result);
3289 if (!NT_STATUS_IS_OK(status)) {
3290 result = ntstatus_to_werror(status);
3292 if (!W_ERROR_IS_OK(result)) {
3293 goto done;
3296 status = dcerpc_winreg_set_multi_sz(tmp_ctx,
3297 winreg_handle,
3298 &key_hnd, "Previous Names",
3299 info8.previous_names,
3300 &result);
3301 if (!NT_STATUS_IS_OK(status)) {
3302 result = ntstatus_to_werror(status);
3304 if (!W_ERROR_IS_OK(result)) {
3305 goto done;
3308 result = winreg_printer_write_date(tmp_ctx, winreg_handle,
3309 &key_hnd, "DriverDate",
3310 info8.driver_date);
3311 if (!W_ERROR_IS_OK(result)) {
3312 goto done;
3315 result = winreg_printer_write_ver(tmp_ctx, winreg_handle,
3316 &key_hnd, "DriverVersion",
3317 info8.driver_version);
3318 if (!W_ERROR_IS_OK(result)) {
3319 goto done;
3322 status = dcerpc_winreg_set_sz(tmp_ctx,
3323 winreg_handle,
3324 &key_hnd,
3325 "Manufacturer",
3326 info8.manufacturer_name,
3327 &result);
3328 if (!NT_STATUS_IS_OK(status)) {
3329 result = ntstatus_to_werror(status);
3331 if (!W_ERROR_IS_OK(result)) {
3332 goto done;
3335 status = dcerpc_winreg_set_sz(tmp_ctx,
3336 winreg_handle,
3337 &key_hnd,
3338 "OEM URL",
3339 info8.manufacturer_url,
3340 &result);
3341 if (!NT_STATUS_IS_OK(status)) {
3342 result = ntstatus_to_werror(status);
3344 if (!W_ERROR_IS_OK(result)) {
3345 goto done;
3348 status = dcerpc_winreg_set_sz(tmp_ctx,
3349 winreg_handle,
3350 &key_hnd,
3351 "HardwareID",
3352 info8.hardware_id,
3353 &result);
3354 if (!NT_STATUS_IS_OK(status)) {
3355 result = ntstatus_to_werror(status);
3357 if (!W_ERROR_IS_OK(result)) {
3358 goto done;
3361 status = dcerpc_winreg_set_sz(tmp_ctx,
3362 winreg_handle,
3363 &key_hnd,
3364 "Provider",
3365 info8.provider,
3366 &result);
3367 if (!NT_STATUS_IS_OK(status)) {
3368 result = ntstatus_to_werror(status);
3370 if (!W_ERROR_IS_OK(result)) {
3371 goto done;
3374 status = dcerpc_winreg_set_sz(tmp_ctx,
3375 winreg_handle,
3376 &key_hnd,
3377 "Print Processor",
3378 info8.print_processor,
3379 &result);
3380 if (!NT_STATUS_IS_OK(status)) {
3381 result = ntstatus_to_werror(status);
3383 if (!W_ERROR_IS_OK(result)) {
3384 goto done;
3387 status = dcerpc_winreg_set_sz(tmp_ctx,
3388 winreg_handle,
3389 &key_hnd,
3390 "VendorSetup",
3391 info8.vendor_setup,
3392 &result);
3393 if (!NT_STATUS_IS_OK(status)) {
3394 result = ntstatus_to_werror(status);
3396 if (!W_ERROR_IS_OK(result)) {
3397 goto done;
3400 status = dcerpc_winreg_set_multi_sz(tmp_ctx,
3401 winreg_handle,
3402 &key_hnd,
3403 "Color Profiles",
3404 info8.color_profiles,
3405 &result);
3406 if (!NT_STATUS_IS_OK(status)) {
3407 result = ntstatus_to_werror(status);
3409 if (!W_ERROR_IS_OK(result)) {
3410 goto done;
3413 status = dcerpc_winreg_set_sz(tmp_ctx,
3414 winreg_handle,
3415 &key_hnd,
3416 "InfPath",
3417 info8.inf_path,
3418 &result);
3419 if (!NT_STATUS_IS_OK(status)) {
3420 result = ntstatus_to_werror(status);
3422 if (!W_ERROR_IS_OK(result)) {
3423 goto done;
3426 status = dcerpc_winreg_set_dword(tmp_ctx,
3427 winreg_handle,
3428 &key_hnd,
3429 "PrinterDriverAttributes",
3430 info8.printer_driver_attributes,
3431 &result);
3432 if (!NT_STATUS_IS_OK(status)) {
3433 result = ntstatus_to_werror(status);
3435 if (!W_ERROR_IS_OK(result)) {
3436 goto done;
3439 status = dcerpc_winreg_set_multi_sz(tmp_ctx,
3440 winreg_handle,
3441 &key_hnd,
3442 "CoreDependencies",
3443 info8.core_driver_dependencies,
3444 &result);
3445 if (!NT_STATUS_IS_OK(status)) {
3446 result = ntstatus_to_werror(status);
3448 if (!W_ERROR_IS_OK(result)) {
3449 goto done;
3452 result = winreg_printer_write_date(tmp_ctx, winreg_handle,
3453 &key_hnd, "MinInboxDriverVerDate",
3454 info8.min_inbox_driver_ver_date);
3455 if (!W_ERROR_IS_OK(result)) {
3456 goto done;
3459 result = winreg_printer_write_ver(tmp_ctx, winreg_handle, &key_hnd,
3460 "MinInboxDriverVerVersion",
3461 info8.min_inbox_driver_ver_version);
3462 if (!W_ERROR_IS_OK(result)) {
3463 goto done;
3466 *driver_name = info8.driver_name;
3467 *driver_version = info8.version;
3468 result = WERR_OK;
3469 done:
3470 if (winreg_handle != NULL) {
3471 WERROR ignore;
3473 if (is_valid_policy_hnd(&key_hnd)) {
3474 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
3476 if (is_valid_policy_hnd(&hive_hnd)) {
3477 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
3481 TALLOC_FREE(tmp_ctx);
3482 return result;
3485 WERROR winreg_get_driver(TALLOC_CTX *mem_ctx,
3486 struct dcerpc_binding_handle *winreg_handle,
3487 const char *architecture,
3488 const char *driver_name,
3489 uint32_t driver_version,
3490 struct spoolss_DriverInfo8 **_info8)
3492 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3493 struct policy_handle hive_hnd, key_hnd;
3494 struct spoolss_DriverInfo8 i8, *info8;
3495 struct spoolss_PrinterEnumValues *enum_values = NULL;
3496 struct spoolss_PrinterEnumValues *v;
3497 uint32_t num_values = 0;
3498 TALLOC_CTX *tmp_ctx;
3499 WERROR result;
3500 NTSTATUS status;
3501 uint32_t i;
3502 const char **enum_names = NULL;
3503 enum winreg_Type *enum_types = NULL;
3504 DATA_BLOB *enum_data_blobs = NULL;
3506 ZERO_STRUCT(hive_hnd);
3507 ZERO_STRUCT(key_hnd);
3508 ZERO_STRUCT(i8);
3510 tmp_ctx = talloc_stackframe();
3511 if (tmp_ctx == NULL) {
3512 return WERR_NOMEM;
3515 if (driver_version == DRIVER_ANY_VERSION) {
3516 /* look for Win2k first and then for NT4 */
3517 result = winreg_printer_opendriver(tmp_ctx,
3518 winreg_handle,
3519 driver_name,
3520 architecture,
3522 access_mask, false,
3523 &hive_hnd,
3524 &key_hnd);
3525 if (!W_ERROR_IS_OK(result)) {
3526 result = winreg_printer_opendriver(tmp_ctx,
3527 winreg_handle,
3528 driver_name,
3529 architecture,
3531 access_mask, false,
3532 &hive_hnd,
3533 &key_hnd);
3535 } else {
3536 /* ok normal case */
3537 result = winreg_printer_opendriver(tmp_ctx,
3538 winreg_handle,
3539 driver_name,
3540 architecture,
3541 driver_version,
3542 access_mask, false,
3543 &hive_hnd,
3544 &key_hnd);
3546 if (!W_ERROR_IS_OK(result)) {
3547 DEBUG(5, ("winreg_get_driver: "
3548 "Could not open driver key (%s,%s,%d): %s\n",
3549 driver_name, architecture,
3550 driver_version, win_errstr(result)));
3551 goto done;
3554 status = dcerpc_winreg_enumvals(tmp_ctx,
3555 winreg_handle,
3556 &key_hnd,
3557 &num_values,
3558 &enum_names,
3559 &enum_types,
3560 &enum_data_blobs,
3561 &result);
3562 if (!NT_STATUS_IS_OK(status)){
3563 result = ntstatus_to_werror(status);
3566 if (!W_ERROR_IS_OK(result)) {
3567 DEBUG(0, ("winreg_get_driver: "
3568 "Could not enumerate values for (%s,%s,%d): %s\n",
3569 driver_name, architecture,
3570 driver_version, win_errstr(result)));
3571 goto done;
3574 enum_values = talloc_zero_array(tmp_ctx,
3575 struct spoolss_PrinterEnumValues,
3576 num_values);
3577 if (enum_values == NULL){
3578 result = WERR_NOMEM;
3579 goto done;
3582 for (i = 0; i < num_values; i++){
3583 enum_values[i].value_name = enum_names[i];
3584 enum_values[i].value_name_len = strlen_m_term(enum_names[i]) * 2;
3585 enum_values[i].type = enum_types[i];
3586 enum_values[i].data_length = enum_data_blobs[i].length;
3587 enum_values[i].data = NULL;
3588 if (enum_values[i].data_length != 0){
3589 enum_values[i].data = &enum_data_blobs[i];
3593 info8 = talloc_zero(tmp_ctx, struct spoolss_DriverInfo8);
3594 if (info8 == NULL) {
3595 result = WERR_NOMEM;
3596 goto done;
3599 info8->driver_name = talloc_strdup(info8, driver_name);
3600 if (info8->driver_name == NULL) {
3601 result = WERR_NOMEM;
3602 goto done;
3605 info8->architecture = talloc_strdup(info8, architecture);
3606 if (info8->architecture == NULL) {
3607 result = WERR_NOMEM;
3608 goto done;
3611 result = WERR_OK;
3613 for (i = 0; i < num_values; i++) {
3614 const char *tmp_str;
3615 uint32_t tmp = 0;
3617 v = &enum_values[i];
3619 result = winreg_enumval_to_dword(info8, v,
3620 "Version",
3621 &tmp);
3622 if (NT_STATUS_IS_OK(result)) {
3623 info8->version = (enum spoolss_DriverOSVersion) tmp;
3625 CHECK_ERROR(result);
3627 result = winreg_enumval_to_sz(info8, v,
3628 "Driver",
3629 &info8->driver_path);
3630 CHECK_ERROR(result);
3632 result = winreg_enumval_to_sz(info8, v,
3633 "Data File",
3634 &info8->data_file);
3635 CHECK_ERROR(result);
3637 result = winreg_enumval_to_sz(info8, v,
3638 "Configuration File",
3639 &info8->config_file);
3640 CHECK_ERROR(result);
3642 result = winreg_enumval_to_sz(info8, v,
3643 "Help File",
3644 &info8->help_file);
3645 CHECK_ERROR(result);
3647 result = winreg_enumval_to_multi_sz(info8, v,
3648 "Dependent Files",
3649 &info8->dependent_files);
3650 CHECK_ERROR(result);
3652 result = winreg_enumval_to_sz(info8, v,
3653 "Monitor",
3654 &info8->monitor_name);
3655 CHECK_ERROR(result);
3657 result = winreg_enumval_to_sz(info8, v,
3658 "Datatype",
3659 &info8->default_datatype);
3660 CHECK_ERROR(result);
3662 result = winreg_enumval_to_multi_sz(info8, v,
3663 "Previous Names",
3664 &info8->previous_names);
3665 CHECK_ERROR(result);
3667 result = winreg_enumval_to_sz(info8, v,
3668 "DriverDate",
3669 &tmp_str);
3670 if (W_ERROR_IS_OK(result)) {
3671 result = winreg_printer_date_to_NTTIME(tmp_str,
3672 &info8->driver_date);
3674 CHECK_ERROR(result);
3676 result = winreg_enumval_to_sz(info8, v,
3677 "DriverVersion",
3678 &tmp_str);
3679 if (W_ERROR_IS_OK(result)) {
3680 result = winreg_printer_ver_to_dword(tmp_str,
3681 &info8->driver_version);
3683 CHECK_ERROR(result);
3685 result = winreg_enumval_to_sz(info8, v,
3686 "Manufacturer",
3687 &info8->manufacturer_name);
3688 CHECK_ERROR(result);
3690 result = winreg_enumval_to_sz(info8, v,
3691 "OEM URL",
3692 &info8->manufacturer_url);
3693 CHECK_ERROR(result);
3695 result = winreg_enumval_to_sz(info8, v,
3696 "HardwareID",
3697 &info8->hardware_id);
3698 CHECK_ERROR(result);
3700 result = winreg_enumval_to_sz(info8, v,
3701 "Provider",
3702 &info8->provider);
3703 CHECK_ERROR(result);
3705 result = winreg_enumval_to_sz(info8, v,
3706 "Print Processor",
3707 &info8->print_processor);
3708 CHECK_ERROR(result);
3710 result = winreg_enumval_to_sz(info8, v,
3711 "VendorSetup",
3712 &info8->vendor_setup);
3713 CHECK_ERROR(result);
3715 result = winreg_enumval_to_multi_sz(info8, v,
3716 "Color Profiles",
3717 &info8->color_profiles);
3718 CHECK_ERROR(result);
3720 result = winreg_enumval_to_sz(info8, v,
3721 "InfPath",
3722 &info8->inf_path);
3723 CHECK_ERROR(result);
3725 result = winreg_enumval_to_dword(info8, v,
3726 "PrinterDriverAttributes",
3727 &info8->printer_driver_attributes);
3728 CHECK_ERROR(result);
3730 result = winreg_enumval_to_multi_sz(info8, v,
3731 "CoreDependencies",
3732 &info8->core_driver_dependencies);
3733 CHECK_ERROR(result);
3735 result = winreg_enumval_to_sz(info8, v,
3736 "MinInboxDriverVerDate",
3737 &tmp_str);
3738 if (W_ERROR_IS_OK(result)) {
3739 result = winreg_printer_date_to_NTTIME(tmp_str,
3740 &info8->min_inbox_driver_ver_date);
3742 CHECK_ERROR(result);
3744 result = winreg_enumval_to_sz(info8, v,
3745 "MinInboxDriverVerVersion",
3746 &tmp_str);
3747 if (W_ERROR_IS_OK(result)) {
3748 result = winreg_printer_ver_to_dword(tmp_str,
3749 &info8->min_inbox_driver_ver_version);
3751 CHECK_ERROR(result);
3754 if (!W_ERROR_IS_OK(result)) {
3755 DEBUG(0, ("winreg_enumval_to_TYPE() failed "
3756 "for %s: %s\n", v->value_name,
3757 win_errstr(result)));
3758 goto done;
3761 *_info8 = talloc_steal(mem_ctx, info8);
3762 result = WERR_OK;
3763 done:
3764 if (winreg_handle != NULL) {
3765 WERROR ignore;
3767 if (is_valid_policy_hnd(&key_hnd)) {
3768 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
3770 if (is_valid_policy_hnd(&hive_hnd)) {
3771 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
3775 TALLOC_FREE(tmp_ctx);
3776 return result;
3779 WERROR winreg_del_driver(TALLOC_CTX *mem_ctx,
3780 struct dcerpc_binding_handle *winreg_handle,
3781 struct spoolss_DriverInfo8 *info8,
3782 uint32_t version)
3784 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3785 struct policy_handle hive_hnd, key_hnd;
3786 TALLOC_CTX *tmp_ctx;
3787 char *key_name;
3788 WERROR result;
3789 NTSTATUS status;
3791 ZERO_STRUCT(hive_hnd);
3792 ZERO_STRUCT(key_hnd);
3794 tmp_ctx = talloc_stackframe();
3795 if (tmp_ctx == NULL) {
3796 return WERR_NOMEM;
3799 /* test that the key exists */
3800 result = winreg_printer_opendriver(tmp_ctx,
3801 winreg_handle,
3802 info8->driver_name,
3803 info8->architecture,
3804 version,
3805 access_mask, false,
3806 &hive_hnd,
3807 &key_hnd);
3808 if (!W_ERROR_IS_OK(result)) {
3809 /* key doesn't exist */
3810 if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
3811 result = WERR_OK;
3812 goto done;
3815 DEBUG(5, ("winreg_del_driver: "
3816 "Could not open driver (%s,%s,%u): %s\n",
3817 info8->driver_name, info8->architecture,
3818 version, win_errstr(result)));
3819 goto done;
3823 if (is_valid_policy_hnd(&key_hnd)) {
3824 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
3827 key_name = talloc_asprintf(tmp_ctx,
3828 "%s\\Environments\\%s\\Drivers\\Version-%u\\%s",
3829 TOP_LEVEL_CONTROL_KEY,
3830 info8->architecture, version,
3831 info8->driver_name);
3832 if (key_name == NULL) {
3833 result = WERR_NOMEM;
3834 goto done;
3837 status = dcerpc_winreg_delete_subkeys_recursive(tmp_ctx,
3838 winreg_handle,
3839 &hive_hnd,
3840 access_mask,
3841 key_name,
3842 &result);
3844 if (!NT_STATUS_IS_OK(status)){
3845 DEBUG(0, ("winreg_del_driver: "
3846 "Could not open driver (%s,%s,%u): %s\n",
3847 info8->driver_name, info8->architecture,
3848 version, nt_errstr(status)));
3849 goto done;
3852 if (!W_ERROR_IS_OK(result)) {
3853 DEBUG(0, ("winreg_del_driver: "
3854 "Could not open driver (%s,%s,%u): %s\n",
3855 info8->driver_name, info8->architecture,
3856 version, win_errstr(result)));
3857 goto done;
3860 result = WERR_OK;
3861 done:
3862 if (winreg_handle != NULL) {
3863 WERROR ignore;
3865 if (is_valid_policy_hnd(&key_hnd)) {
3866 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
3868 if (is_valid_policy_hnd(&hive_hnd)) {
3869 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
3873 TALLOC_FREE(tmp_ctx);
3874 return result;
3877 WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx,
3878 struct dcerpc_binding_handle *winreg_handle,
3879 const char *architecture,
3880 uint32_t version,
3881 uint32_t *num_drivers,
3882 const char ***drivers_p)
3884 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3885 struct policy_handle hive_hnd, key_hnd;
3886 const char **drivers;
3887 TALLOC_CTX *tmp_ctx;
3888 WERROR result;
3889 NTSTATUS status;
3891 *num_drivers = 0;
3892 *drivers_p = NULL;
3894 ZERO_STRUCT(hive_hnd);
3895 ZERO_STRUCT(key_hnd);
3897 tmp_ctx = talloc_stackframe();
3898 if (tmp_ctx == NULL) {
3899 return WERR_NOMEM;
3902 /* use NULL for the driver name so we open the key that is
3903 * parent of all drivers for this architecture and version */
3904 result = winreg_printer_opendriver(tmp_ctx,
3905 winreg_handle,
3906 NULL,
3907 architecture,
3908 version,
3909 access_mask, false,
3910 &hive_hnd,
3911 &key_hnd);
3912 if (!W_ERROR_IS_OK(result)) {
3913 DEBUG(5, ("winreg_get_driver_list: "
3914 "Could not open key (%s,%u): %s\n",
3915 architecture, version, win_errstr(result)));
3916 result = WERR_OK;
3917 goto done;
3920 status = dcerpc_winreg_enum_keys(tmp_ctx,
3921 winreg_handle,
3922 &key_hnd,
3923 num_drivers,
3924 &drivers,
3925 &result);
3926 if (!NT_STATUS_IS_OK(status)) {
3927 result = ntstatus_to_werror(status);
3929 if (!W_ERROR_IS_OK(result)) {
3930 DEBUG(0, ("winreg_get_driver_list: "
3931 "Could not enumerate drivers for (%s,%u): %s\n",
3932 architecture, version, win_errstr(result)));
3933 goto done;
3936 *drivers_p = talloc_steal(mem_ctx, drivers);
3938 result = WERR_OK;
3939 done:
3940 if (winreg_handle != NULL) {
3941 WERROR ignore;
3943 if (is_valid_policy_hnd(&key_hnd)) {
3944 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
3946 if (is_valid_policy_hnd(&hive_hnd)) {
3947 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
3951 TALLOC_FREE(tmp_ctx);
3952 return result;