s3-printing: Removed unused get_a_printer functions.
[abartlet/samba.git/.git] / source3 / printing / nt_printing.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-2000,
5  *  Copyright (C) Jean François Micouleau      1998-2000.
6  *  Copyright (C) Gerald Carter                2002-2005.
7  *
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.
12  *
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.
17  *
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/>.
20  */
21
22 #include "includes.h"
23 #include "librpc/gen_ndr/messaging.h"
24 #include "printing/pcap.h"
25 #include "registry.h"
26 #include "registry/reg_objects.h"
27 #include "../librpc/gen_ndr/ndr_security.h"
28 #include "rpc_server/srv_spoolss_util.h"
29
30 #include "../rpc_server/srv_spoolss_util.h"
31
32 static TDB_CONTEXT *tdb_forms; /* used for forms files */
33 static TDB_CONTEXT *tdb_drivers; /* used for driver files */
34 static TDB_CONTEXT *tdb_printers; /* used for printers files */
35
36 #define FORMS_PREFIX "FORMS/"
37 #define DRIVERS_PREFIX "DRIVERS/"
38 #define PRINTERS_PREFIX "PRINTERS/"
39 #define SECDESC_PREFIX "SECDESC/"
40 #define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter"
41
42 #define NTDRIVERS_DATABASE_VERSION_1 1
43 #define NTDRIVERS_DATABASE_VERSION_2 2
44 #define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */
45 #define NTDRIVERS_DATABASE_VERSION_4 4 /* fix generic bits in security descriptors */
46 #define NTDRIVERS_DATABASE_VERSION_5 5 /* normalize keys in ntprinters.tdb */
47
48 /* Map generic permissions to printer object specific permissions */
49
50 const struct generic_mapping printer_generic_mapping = {
51         PRINTER_READ,
52         PRINTER_WRITE,
53         PRINTER_EXECUTE,
54         PRINTER_ALL_ACCESS
55 };
56
57 const struct standard_mapping printer_std_mapping = {
58         PRINTER_READ,
59         PRINTER_WRITE,
60         PRINTER_EXECUTE,
61         PRINTER_ALL_ACCESS
62 };
63
64 /* Map generic permissions to print server object specific permissions */
65
66 const struct generic_mapping printserver_generic_mapping = {
67         SERVER_READ,
68         SERVER_WRITE,
69         SERVER_EXECUTE,
70         SERVER_ALL_ACCESS
71 };
72
73 const struct generic_mapping printserver_std_mapping = {
74         SERVER_READ,
75         SERVER_WRITE,
76         SERVER_EXECUTE,
77         SERVER_ALL_ACCESS
78 };
79
80 /* Map generic permissions to job object specific permissions */
81
82 const struct generic_mapping job_generic_mapping = {
83         JOB_READ,
84         JOB_WRITE,
85         JOB_EXECUTE,
86         JOB_ALL_ACCESS
87 };
88
89 /* We need one default form to support our default printer. Msoft adds the
90 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
91 array index). Letter is always first, so (for the current code) additions
92 always put things in the correct order. */
93 static const nt_forms_struct default_forms[] = {
94         {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
95         {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
96         {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
97         {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
98         {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
99         {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
100         {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
101         {"A0",0x1,0xcd528,0x122488,0x0,0x0,0xcd528,0x122488},
102         {"A1",0x1,0x91050,0xcd528,0x0,0x0,0x91050,0xcd528},
103         {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
104         {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
105         {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
106         {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
107         {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
108         {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
109         {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
110         {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
111         {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
112         {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
113         {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
114         {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
115         {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
116         {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
117         {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
118         {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
119         {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
120         {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
121         {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
122         {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
123         {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
124         {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
125         {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
126         {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
127         {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
128         {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
129         {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
130         {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
131         {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
132         {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
133         {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
134         {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
135         {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
136         {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
137         {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
138         {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
139         {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
140         {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
141         {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
142         {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
143         {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
144         {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
145         {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
146         {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
147         {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
148         {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
149         {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
150         {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
151         {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
152         {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
153         {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
154         {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
155         {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
156         {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
157         {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
158         {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
159         {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
160         {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
161         {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
162         {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
163         {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
164         {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
165         {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
166         {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
167         {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
168         {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
169         {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
170         {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
171         {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
172         {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
173         {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
174         {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
175         {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
176         {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
177         {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
178         {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
179         {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
180         {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
181         {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
182         {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
183         {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
184         {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
185         {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
186         {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
187         {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
188         {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
189         {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
190         {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
191         {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
192         {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
193         {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
194         {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
195         {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
196         {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
197         {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
198         {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
199         {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
200         {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
201         {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
202         {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
203         {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
204         {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
205         {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
206         {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
207         {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
208         {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
209         {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
210         {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
211         {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
212         {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
213         {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
214 };
215
216 static const struct print_architecture_table_node archi_table[]= {
217
218         {"Windows 4.0",          SPL_ARCH_WIN40,        0 },
219         {"Windows NT x86",       SPL_ARCH_W32X86,       2 },
220         {"Windows NT R4000",     SPL_ARCH_W32MIPS,      2 },
221         {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA,     2 },
222         {"Windows NT PowerPC",   SPL_ARCH_W32PPC,       2 },
223         {"Windows IA64",         SPL_ARCH_IA64,         3 },
224         {"Windows x64",          SPL_ARCH_X64,          3 },
225         {NULL,                   "",            -1 }
226 };
227
228
229 /****************************************************************************
230  generate a new TDB_DATA key for storing a printer
231 ****************************************************************************/
232
233 static TDB_DATA make_printer_tdbkey(TALLOC_CTX *ctx, const char *sharename )
234 {
235         fstring share;
236         char *keystr = NULL;
237         TDB_DATA key;
238
239         fstrcpy(share, sharename);
240         strlower_m(share);
241
242         keystr = talloc_asprintf(ctx, "%s%s", PRINTERS_PREFIX, share);
243         key = string_term_tdb_data(keystr ? keystr : "");
244
245         return key;
246 }
247
248 /****************************************************************************
249  generate a new TDB_DATA key for storing a printer security descriptor
250 ****************************************************************************/
251
252 static TDB_DATA make_printers_secdesc_tdbkey(TALLOC_CTX *ctx,
253                                         const char* sharename  )
254 {
255         fstring share;
256         char *keystr = NULL;
257         TDB_DATA key;
258
259         fstrcpy(share, sharename );
260         strlower_m(share);
261
262         keystr = talloc_asprintf(ctx, "%s%s", SECDESC_PREFIX, share);
263         key = string_term_tdb_data(keystr ? keystr : "");
264
265         return key;
266 }
267
268 /****************************************************************************
269 ****************************************************************************/
270
271 static bool upgrade_to_version_3(void)
272 {
273         TDB_DATA kbuf, newkey, dbuf;
274
275         DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
276
277         for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
278                         newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {
279
280                 dbuf = tdb_fetch(tdb_drivers, kbuf);
281
282                 if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
283                         DEBUG(0,("upgrade_to_version_3:moving form\n"));
284                         if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
285                                 SAFE_FREE(dbuf.dptr);
286                                 DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
287                                 return False;
288                         }
289                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
290                                 SAFE_FREE(dbuf.dptr);
291                                 DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
292                                 return False;
293                         }
294                 }
295
296                 if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
297                         DEBUG(0,("upgrade_to_version_3:moving printer\n"));
298                         if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
299                                 SAFE_FREE(dbuf.dptr);
300                                 DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
301                                 return False;
302                         }
303                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
304                                 SAFE_FREE(dbuf.dptr);
305                                 DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
306                                 return False;
307                         }
308                 }
309
310                 if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
311                         DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
312                         if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
313                                 SAFE_FREE(dbuf.dptr);
314                                 DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
315                                 return False;
316                         }
317                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
318                                 SAFE_FREE(dbuf.dptr);
319                                 DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
320                                 return False;
321                         }
322                 }
323
324                 SAFE_FREE(dbuf.dptr);
325         }
326
327         return True;
328 }
329
330 /*******************************************************************
331  Fix an issue with security descriptors.  Printer sec_desc must
332  use more than the generic bits that were previously used
333  in <= 3.0.14a.  They must also have a owner and group SID assigned.
334  Otherwise, any printers than have been migrated to a Windows
335  host using printmig.exe will not be accessible.
336 *******************************************************************/
337
338 static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
339                             TDB_DATA data, void *state )
340 {
341         NTSTATUS status;
342         struct sec_desc_buf *sd_orig = NULL;
343         struct sec_desc_buf *sd_new, *sd_store;
344         struct security_descriptor *sec, *new_sec;
345         TALLOC_CTX *ctx = state;
346         int result, i;
347         uint32 sd_size;
348         size_t size_new_sec;
349
350         if (!data.dptr || data.dsize == 0) {
351                 return 0;
352         }
353
354         if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) != 0 ) {
355                 return 0;
356         }
357
358         /* upgrade the security descriptor */
359
360         status = unmarshall_sec_desc_buf(ctx, data.dptr, data.dsize, &sd_orig);
361         if (!NT_STATUS_IS_OK(status)) {
362                 /* delete bad entries */
363                 DEBUG(0,("sec_desc_upg_fn: Failed to parse original sec_desc for %si.  Deleting....\n",
364                         (const char *)key.dptr ));
365                 tdb_delete( tdb_printers, key );
366                 return 0;
367         }
368
369         if (!sd_orig) {
370                 return 0;
371         }
372         sec = sd_orig->sd;
373
374         /* is this even valid? */
375
376         if ( !sec->dacl ) {
377                 return 0;
378         }
379
380         /* update access masks */
381
382         for ( i=0; i<sec->dacl->num_aces; i++ ) {
383                 switch ( sec->dacl->aces[i].access_mask ) {
384                         case (GENERIC_READ_ACCESS | GENERIC_WRITE_ACCESS | GENERIC_EXECUTE_ACCESS):
385                                 sec->dacl->aces[i].access_mask = PRINTER_ACE_PRINT;
386                                 break;
387
388                         case GENERIC_ALL_ACCESS:
389                                 sec->dacl->aces[i].access_mask = PRINTER_ACE_FULL_CONTROL;
390                                 break;
391
392                         case READ_CONTROL_ACCESS:
393                                 sec->dacl->aces[i].access_mask = PRINTER_ACE_MANAGE_DOCUMENTS;
394
395                         default:        /* no change */
396                                 break;
397                 }
398         }
399
400         /* create a new struct security_descriptor with the appropriate owner and group SIDs */
401
402         new_sec = make_sec_desc( ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
403                                  &global_sid_Builtin_Administrators,
404                                  &global_sid_Builtin_Administrators,
405                                  NULL, NULL, &size_new_sec );
406         if (!new_sec) {
407                 return 0;
408         }
409         sd_new = make_sec_desc_buf( ctx, size_new_sec, new_sec );
410         if (!sd_new) {
411                 return 0;
412         }
413
414         if ( !(sd_store = sec_desc_merge_buf( ctx, sd_new, sd_orig )) ) {
415                 DEBUG(0,("sec_desc_upg_fn: Failed to update sec_desc for %s\n", key.dptr ));
416                 return 0;
417         }
418
419         /* store it back */
420
421         sd_size = ndr_size_security_descriptor(sd_store->sd, 0)
422                 + sizeof(struct sec_desc_buf);
423
424         status = marshall_sec_desc_buf(ctx, sd_store, &data.dptr, &data.dsize);
425         if (!NT_STATUS_IS_OK(status)) {
426                 DEBUG(0,("sec_desc_upg_fn: Failed to parse new sec_desc for %s\n", key.dptr ));
427                 return 0;
428         }
429
430         result = tdb_store( tdb_printers, key, data, TDB_REPLACE );
431
432         /* 0 to continue and non-zero to stop traversal */
433
434         return (result == -1);
435 }
436
437 /*******************************************************************
438 *******************************************************************/
439
440 static bool upgrade_to_version_4(void)
441 {
442         TALLOC_CTX *ctx;
443         int result;
444
445         DEBUG(0,("upgrade_to_version_4: upgrading printer security descriptors\n"));
446
447         if ( !(ctx = talloc_init( "upgrade_to_version_4" )) )
448                 return False;
449
450         result = tdb_traverse( tdb_printers, sec_desc_upg_fn, ctx );
451
452         talloc_destroy( ctx );
453
454         return ( result != -1 );
455 }
456
457 /*******************************************************************
458  Fix an issue with security descriptors.  Printer sec_desc must
459  use more than the generic bits that were previously used
460  in <= 3.0.14a.  They must also have a owner and group SID assigned.
461  Otherwise, any printers than have been migrated to a Windows
462  host using printmig.exe will not be accessible.
463 *******************************************************************/
464
465 static int normalize_printers_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
466                                   TDB_DATA data, void *state )
467 {
468         TALLOC_CTX *ctx = talloc_tos();
469         TDB_DATA new_key;
470
471         if (!data.dptr || data.dsize == 0)
472                 return 0;
473
474         /* upgrade printer records and security descriptors */
475
476         if ( strncmp((const char *) key.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX) ) == 0 ) {
477                 new_key = make_printer_tdbkey(ctx, (const char *)key.dptr+strlen(PRINTERS_PREFIX) );
478         }
479         else if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) == 0 ) {
480                 new_key = make_printers_secdesc_tdbkey(ctx, (const char *)key.dptr+strlen(SECDESC_PREFIX) );
481         }
482         else {
483                 /* ignore this record */
484                 return 0;
485         }
486
487         /* delete the original record and store under the normalized key */
488
489         if ( tdb_delete( the_tdb, key ) != 0 ) {
490                 DEBUG(0,("normalize_printers_fn: tdb_delete for [%s] failed!\n",
491                         key.dptr));
492                 return 1;
493         }
494
495         if ( tdb_store( the_tdb, new_key, data, TDB_REPLACE) != 0 ) {
496                 DEBUG(0,("normalize_printers_fn: failed to store new record for [%s]!\n",
497                         key.dptr));
498                 return 1;
499         }
500
501         return 0;
502 }
503
504 /*******************************************************************
505 *******************************************************************/
506
507 static bool upgrade_to_version_5(void)
508 {
509         TALLOC_CTX *ctx;
510         int result;
511
512         DEBUG(0,("upgrade_to_version_5: normalizing printer keys\n"));
513
514         if ( !(ctx = talloc_init( "upgrade_to_version_5" )) )
515                 return False;
516
517         result = tdb_traverse( tdb_printers, normalize_printers_fn, NULL );
518
519         talloc_destroy( ctx );
520
521         return ( result != -1 );
522 }
523
524 /****************************************************************************
525  Open the NT printing tdbs. Done once before fork().
526 ****************************************************************************/
527
528 bool nt_printing_init(struct messaging_context *msg_ctx)
529 {
530         const char *vstring = "INFO/version";
531         WERROR win_rc;
532         int32 vers_id;
533
534         if ( tdb_drivers && tdb_printers && tdb_forms )
535                 return True;
536
537         if (tdb_drivers)
538                 tdb_close(tdb_drivers);
539         tdb_drivers = tdb_open_log(state_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
540         if (!tdb_drivers) {
541                 DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
542                         state_path("ntdrivers.tdb"), strerror(errno) ));
543                 return False;
544         }
545
546         if (tdb_printers)
547                 tdb_close(tdb_printers);
548         tdb_printers = tdb_open_log(state_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
549         if (!tdb_printers) {
550                 DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
551                         state_path("ntprinters.tdb"), strerror(errno) ));
552                 return False;
553         }
554
555         if (tdb_forms)
556                 tdb_close(tdb_forms);
557         tdb_forms = tdb_open_log(state_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
558         if (!tdb_forms) {
559                 DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
560                         state_path("ntforms.tdb"), strerror(errno) ));
561                 return False;
562         }
563
564         /* handle a Samba upgrade */
565
566         vers_id = tdb_fetch_int32(tdb_drivers, vstring);
567         if (vers_id == -1) {
568                 DEBUG(10, ("Fresh database\n"));
569                 tdb_store_int32( tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5 );
570                 vers_id = NTDRIVERS_DATABASE_VERSION_5;
571         }
572
573         if ( vers_id != NTDRIVERS_DATABASE_VERSION_5 ) {
574
575                 if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) {
576                         if (!upgrade_to_version_3())
577                                 return False;
578                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3);
579                         vers_id = NTDRIVERS_DATABASE_VERSION_3;
580                 }
581
582                 if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) {
583                         /* Written on a bigendian machine with old fetch_int code. Save as le. */
584                         /* The only upgrade between V2 and V3 is to save the version in little-endian. */
585                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3);
586                         vers_id = NTDRIVERS_DATABASE_VERSION_3;
587                 }
588
589                 if (vers_id == NTDRIVERS_DATABASE_VERSION_3 ) {
590                         if ( !upgrade_to_version_4() )
591                                 return False;
592                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_4);
593                         vers_id = NTDRIVERS_DATABASE_VERSION_4;
594                 }
595
596                 if (vers_id == NTDRIVERS_DATABASE_VERSION_4 ) {
597                         if ( !upgrade_to_version_5() )
598                                 return False;
599                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5);
600                         vers_id = NTDRIVERS_DATABASE_VERSION_5;
601                 }
602
603
604                 if ( vers_id != NTDRIVERS_DATABASE_VERSION_5 ) {
605                         DEBUG(0,("nt_printing_init: Unknown printer database version [%d]\n", vers_id));
606                         return False;
607                 }
608         }
609
610         /*
611          * register callback to handle updating printers as new
612          * drivers are installed
613          */
614
615         messaging_register(msg_ctx, NULL, MSG_PRINTER_DRVUPGRADE,
616                            do_drv_upgrade_printer);
617
618         /* of course, none of the message callbacks matter if you don't
619            tell messages.c that you interested in receiving PRINT_GENERAL
620            msgs.  This is done in serverid_register() */
621
622
623         if ( lp_security() == SEC_ADS ) {
624                 win_rc = check_published_printers();
625                 if (!W_ERROR_IS_OK(win_rc))
626                         DEBUG(0, ("nt_printing_init: error checking published printers: %s\n", win_errstr(win_rc)));
627         }
628
629         return True;
630 }
631
632 /*******************************************************************
633  Function to allow filename parsing "the old way".
634 ********************************************************************/
635
636 static NTSTATUS driver_unix_convert(connection_struct *conn,
637                                     const char *old_name,
638                                     struct smb_filename **smb_fname)
639 {
640         NTSTATUS status;
641         TALLOC_CTX *ctx = talloc_tos();
642         char *name = talloc_strdup(ctx, old_name);
643
644         if (!name) {
645                 return NT_STATUS_NO_MEMORY;
646         }
647         unix_format(name);
648         name = unix_clean_name(ctx, name);
649         if (!name) {
650                 return NT_STATUS_NO_MEMORY;
651         }
652         trim_string(name,"/","/");
653
654         status = unix_convert(ctx, conn, name, smb_fname, 0);
655         if (!NT_STATUS_IS_OK(status)) {
656                 return NT_STATUS_NO_MEMORY;
657         }
658
659         return NT_STATUS_OK;
660 }
661
662 /*******************************************************************
663  tdb traversal function for counting printers.
664 ********************************************************************/
665
666 static int traverse_counting_printers(TDB_CONTEXT *t, TDB_DATA key,
667                                       TDB_DATA data, void *context)
668 {
669         int *printer_count = (int*)context;
670
671         if (memcmp(PRINTERS_PREFIX, key.dptr, sizeof(PRINTERS_PREFIX)-1) == 0) {
672                 (*printer_count)++;
673                 DEBUG(10,("traverse_counting_printers: printer = [%s]  printer_count = %d\n", key.dptr, *printer_count));
674         }
675
676         return 0;
677 }
678
679 /*******************************************************************
680  Update the spooler global c_setprinter. This variable is initialized
681  when the parent smbd starts with the number of existing printers. It
682  is monotonically increased by the current number of printers *after*
683  each add or delete printer RPC. Only Microsoft knows why... JRR020119
684 ********************************************************************/
685
686 uint32 update_c_setprinter(bool initialize)
687 {
688         int32 c_setprinter;
689         int32 printer_count = 0;
690
691         tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
692
693         /* Traverse the tdb, counting the printers */
694         tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);
695
696         /* If initializing, set c_setprinter to current printers count
697          * otherwise, bump it by the current printer count
698          */
699         if (!initialize)
700                 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER) + printer_count;
701         else
702                 c_setprinter = printer_count;
703
704         DEBUG(10,("update_c_setprinter: c_setprinter = %u\n", (unsigned int)c_setprinter));
705         tdb_store_int32(tdb_printers, GLOBAL_C_SETPRINTER, c_setprinter);
706
707         tdb_unlock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
708
709         return (uint32)c_setprinter;
710 }
711
712 /*******************************************************************
713  Get the spooler global c_setprinter, accounting for initialization.
714 ********************************************************************/
715
716 uint32 get_c_setprinter(void)
717 {
718         int32 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER);
719
720         if (c_setprinter == (int32)-1)
721                 c_setprinter = update_c_setprinter(True);
722
723         DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter));
724
725         return (uint32)c_setprinter;
726 }
727
728 /****************************************************************************
729  Get builtin form struct list.
730 ****************************************************************************/
731
732 int get_builtin_ntforms(nt_forms_struct **list)
733 {
734         *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
735         if (!*list) {
736                 return 0;
737         }
738         return ARRAY_SIZE(default_forms);
739 }
740
741 /****************************************************************************
742  get a builtin form struct
743 ****************************************************************************/
744
745 bool get_a_builtin_ntform_by_string(const char *form_name, nt_forms_struct *form)
746 {
747         int i;
748         DEBUGADD(6,("Looking for builtin form %s \n", form_name));
749         for (i=0; i<ARRAY_SIZE(default_forms); i++) {
750                 if (strequal(form_name,default_forms[i].name)) {
751                         DEBUGADD(6,("Found builtin form %s \n", form_name));
752                         memcpy(form,&default_forms[i],sizeof(*form));
753                         return true;
754                 }
755         }
756
757         return false;
758 }
759
760 /****************************************************************************
761  get a form struct list.
762 ****************************************************************************/
763
764 int get_ntforms(nt_forms_struct **list)
765 {
766         TDB_DATA kbuf, newkey, dbuf;
767         nt_forms_struct form;
768         int ret;
769         int i;
770         int n = 0;
771
772         *list = NULL;
773
774         for (kbuf = tdb_firstkey(tdb_forms);
775              kbuf.dptr;
776              newkey = tdb_nextkey(tdb_forms, kbuf), free(kbuf.dptr), kbuf=newkey)
777         {
778                 if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0)
779                         continue;
780
781                 dbuf = tdb_fetch(tdb_forms, kbuf);
782                 if (!dbuf.dptr)
783                         continue;
784
785                 fstrcpy(form.name, (const char *)kbuf.dptr+strlen(FORMS_PREFIX));
786                 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
787                                  &i, &form.flag, &form.width, &form.length, &form.left,
788                                  &form.top, &form.right, &form.bottom);
789                 SAFE_FREE(dbuf.dptr);
790                 if (ret != dbuf.dsize)
791                         continue;
792
793                 *list = SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1);
794                 if (!*list) {
795                         DEBUG(0,("get_ntforms: Realloc fail.\n"));
796                         return 0;
797                 }
798                 (*list)[n] = form;
799                 n++;
800         }
801
802
803         return n;
804 }
805
806 /****************************************************************************
807 write a form struct list
808 ****************************************************************************/
809
810 int write_ntforms(nt_forms_struct **list, int number)
811 {
812         TALLOC_CTX *ctx = talloc_tos();
813         char *buf = NULL;
814         char *key = NULL;
815         int len;
816         TDB_DATA dbuf;
817         int i;
818
819         for (i=0;i<number;i++) {
820                 /* save index, so list is rebuilt in correct order */
821                 len = tdb_pack(NULL, 0, "dddddddd",
822                                i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
823                                (*list)[i].left, (*list)[i].top, (*list)[i].right,
824                                (*list)[i].bottom);
825                 if (!len) {
826                         continue;
827                 }
828                 buf = TALLOC_ARRAY(ctx, char, len);
829                 if (!buf) {
830                         return 0;
831                 }
832                 len = tdb_pack((uint8 *)buf, len, "dddddddd",
833                                i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
834                                (*list)[i].left, (*list)[i].top, (*list)[i].right,
835                                (*list)[i].bottom);
836                 key = talloc_asprintf(ctx, "%s%s", FORMS_PREFIX, (*list)[i].name);
837                 if (!key) {
838                         return 0;
839                 }
840                 dbuf.dsize = len;
841                 dbuf.dptr = (uint8 *)buf;
842                 if (tdb_store_bystring(tdb_forms, key, dbuf, TDB_REPLACE) != 0) {
843                         TALLOC_FREE(key);
844                         TALLOC_FREE(buf);
845                         break;
846                 }
847                 TALLOC_FREE(key);
848                 TALLOC_FREE(buf);
849        }
850
851        return i;
852 }
853
854 /****************************************************************************
855 add a form struct at the end of the list
856 ****************************************************************************/
857 bool add_a_form(nt_forms_struct **list, struct spoolss_AddFormInfo1 *form, int *count)
858 {
859         int n=0;
860         bool update;
861
862         /*
863          * NT tries to add forms even when
864          * they are already in the base
865          * only update the values if already present
866          */
867
868         update=False;
869
870         for (n=0; n<*count; n++) {
871                 if ( strequal((*list)[n].name, form->form_name) ) {
872                         update=True;
873                         break;
874                 }
875         }
876
877         if (update==False) {
878                 if((*list=SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1)) == NULL) {
879                         DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
880                         return False;
881                 }
882                 fstrcpy((*list)[n].name, form->form_name);
883                 (*count)++;
884         }
885
886         (*list)[n].flag         = form->flags;
887         (*list)[n].width        = form->size.width;
888         (*list)[n].length       = form->size.height;
889         (*list)[n].left         = form->area.left;
890         (*list)[n].top          = form->area.top;
891         (*list)[n].right        = form->area.right;
892         (*list)[n].bottom       = form->area.bottom;
893
894         DEBUG(6,("add_a_form: Successfully %s form [%s]\n",
895                 update ? "updated" : "added", form->form_name));
896
897         return True;
898 }
899
900 /****************************************************************************
901  Delete a named form struct.
902 ****************************************************************************/
903
904 bool delete_a_form(nt_forms_struct **list, const char *del_name, int *count, WERROR *ret)
905 {
906         char *key = NULL;
907         int n=0;
908
909         *ret = WERR_OK;
910
911         for (n=0; n<*count; n++) {
912                 if (!strncmp((*list)[n].name, del_name, strlen(del_name))) {
913                         DEBUG(103, ("delete_a_form, [%s] in list\n", del_name));
914                         break;
915                 }
916         }
917
918         if (n == *count) {
919                 DEBUG(10,("delete_a_form, [%s] not found\n", del_name));
920                 *ret = WERR_INVALID_FORM_NAME;
921                 return False;
922         }
923
924         if (asprintf(&key, "%s%s", FORMS_PREFIX, (*list)[n].name) < 0) {
925                 *ret = WERR_NOMEM;
926                 return false;
927         }
928         if (tdb_delete_bystring(tdb_forms, key) != 0) {
929                 SAFE_FREE(key);
930                 *ret = WERR_NOMEM;
931                 return False;
932         }
933         SAFE_FREE(key);
934         return true;
935 }
936
937 /****************************************************************************
938  Update a form struct.
939 ****************************************************************************/
940
941 void update_a_form(nt_forms_struct **list, struct spoolss_AddFormInfo1 *form, int count)
942 {
943         int n=0;
944
945         DEBUG(106, ("[%s]\n", form->form_name));
946         for (n=0; n<count; n++) {
947                 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
948                 if (!strncmp((*list)[n].name, form->form_name, strlen(form->form_name)))
949                         break;
950         }
951
952         if (n==count) return;
953
954         (*list)[n].flag         = form->flags;
955         (*list)[n].width        = form->size.width;
956         (*list)[n].length       = form->size.height;
957         (*list)[n].left         = form->area.left;
958         (*list)[n].top          = form->area.top;
959         (*list)[n].right        = form->area.right;
960         (*list)[n].bottom       = form->area.bottom;
961 }
962
963 /****************************************************************************
964  Function to do the mapping between the long architecture name and
965  the short one.
966 ****************************************************************************/
967
968 const char *get_short_archi(const char *long_archi)
969 {
970         int i=-1;
971
972         DEBUG(107,("Getting architecture dependant directory\n"));
973         do {
974                 i++;
975         } while ( (archi_table[i].long_archi!=NULL ) &&
976                   StrCaseCmp(long_archi, archi_table[i].long_archi) );
977
978         if (archi_table[i].long_archi==NULL) {
979                 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
980                 return NULL;
981         }
982
983         /* this might be client code - but shouldn't this be an fstrcpy etc? */
984
985         DEBUGADD(108,("index: [%d]\n", i));
986         DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
987         DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
988
989         return archi_table[i].short_archi;
990 }
991
992 /****************************************************************************
993  Version information in Microsoft files is held in a VS_VERSION_INFO structure.
994  There are two case to be covered here: PE (Portable Executable) and NE (New
995  Executable) files. Both files support the same INFO structure, but PE files
996  store the signature in unicode, and NE files store it as !unicode.
997  returns -1 on error, 1 on version info found, and 0 on no version info found.
998 ****************************************************************************/
999
1000 static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
1001 {
1002         int     i;
1003         char    *buf = NULL;
1004         ssize_t byte_count;
1005
1006         if ((buf=(char *)SMB_MALLOC(DOS_HEADER_SIZE)) == NULL) {
1007                 DEBUG(0,("get_file_version: PE file [%s] DOS Header malloc failed bytes = %d\n",
1008                                 fname, DOS_HEADER_SIZE));
1009                 goto error_exit;
1010         }
1011
1012         if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
1013                 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %lu\n",
1014                          fname, (unsigned long)byte_count));
1015                 goto no_version_info;
1016         }
1017
1018         /* Is this really a DOS header? */
1019         if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
1020                 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
1021                                 fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
1022                 goto no_version_info;
1023         }
1024
1025         /* Skip OEM header (if any) and the DOS stub to start of Windows header */
1026         if (SMB_VFS_LSEEK(fsp, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
1027                 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
1028                                 fname, errno));
1029                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
1030                 goto no_version_info;
1031         }
1032
1033         /* Note: DOS_HEADER_SIZE and NE_HEADER_SIZE are incidentally same */
1034         if ((byte_count = vfs_read_data(fsp, buf, NE_HEADER_SIZE)) < NE_HEADER_SIZE) {
1035                 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %lu\n",
1036                          fname, (unsigned long)byte_count));
1037                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
1038                 goto no_version_info;
1039         }
1040
1041         /* The header may be a PE (Portable Executable) or an NE (New Executable) */
1042         if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
1043                 unsigned int num_sections;
1044                 unsigned int section_table_bytes;
1045
1046                 /* Just skip over optional header to get to section table */
1047                 if (SMB_VFS_LSEEK(fsp,
1048                                 SVAL(buf,PE_HEADER_OPTIONAL_HEADER_SIZE)-(NE_HEADER_SIZE-PE_HEADER_SIZE),
1049                                 SEEK_CUR) == (SMB_OFF_T)-1) {
1050                         DEBUG(3,("get_file_version: File [%s] Windows optional header too short, errno = %d\n",
1051                                 fname, errno));
1052                         goto error_exit;
1053                 }
1054
1055                 /* get the section table */
1056                 num_sections        = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
1057                 section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
1058                 if (section_table_bytes == 0)
1059                         goto error_exit;
1060
1061                 SAFE_FREE(buf);
1062                 if ((buf=(char *)SMB_MALLOC(section_table_bytes)) == NULL) {
1063                         DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
1064                                         fname, section_table_bytes));
1065                         goto error_exit;
1066                 }
1067
1068                 if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
1069                         DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %lu\n",
1070                                  fname, (unsigned long)byte_count));
1071                         goto error_exit;
1072                 }
1073
1074                 /* Iterate the section table looking for the resource section ".rsrc" */
1075                 for (i = 0; i < num_sections; i++) {
1076                         int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
1077
1078                         if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
1079                                 unsigned int section_pos   = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
1080                                 unsigned int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
1081
1082                                 if (section_bytes == 0)
1083                                         goto error_exit;
1084
1085                                 SAFE_FREE(buf);
1086                                 if ((buf=(char *)SMB_MALLOC(section_bytes)) == NULL) {
1087                                         DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
1088                                                         fname, section_bytes));
1089                                         goto error_exit;
1090                                 }
1091
1092                                 /* Seek to the start of the .rsrc section info */
1093                                 if (SMB_VFS_LSEEK(fsp, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
1094                                         DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
1095                                                         fname, errno));
1096                                         goto error_exit;
1097                                 }
1098
1099                                 if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
1100                                         DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %lu\n",
1101                                                  fname, (unsigned long)byte_count));
1102                                         goto error_exit;
1103                                 }
1104
1105                                 if (section_bytes < VS_VERSION_INFO_UNICODE_SIZE)
1106                                         goto error_exit;
1107
1108                                 for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
1109                                         /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
1110                                         if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
1111                                                 /* Align to next long address */
1112                                                 int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;
1113
1114                                                 if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
1115                                                         *major = IVAL(buf,pos+VS_MAJOR_OFFSET);
1116                                                         *minor = IVAL(buf,pos+VS_MINOR_OFFSET);
1117
1118                                                         DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
1119                                                                           fname, *major, *minor,
1120                                                                           (*major>>16)&0xffff, *major&0xffff,
1121                                                                           (*minor>>16)&0xffff, *minor&0xffff));
1122                                                         SAFE_FREE(buf);
1123                                                         return 1;
1124                                                 }
1125                                         }
1126                                 }
1127                         }
1128                 }
1129
1130                 /* Version info not found, fall back to origin date/time */
1131                 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
1132                 SAFE_FREE(buf);
1133                 return 0;
1134
1135         } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
1136                 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
1137                         DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
1138                                         fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
1139                         /* At this point, we assume the file is in error. It still could be somthing
1140                          * else besides a NE file, but it unlikely at this point. */
1141                         goto error_exit;
1142                 }
1143
1144                 /* Allocate a bit more space to speed up things */
1145                 SAFE_FREE(buf);
1146                 if ((buf=(char *)SMB_MALLOC(VS_NE_BUF_SIZE)) == NULL) {
1147                         DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes  = %d\n",
1148                                         fname, PE_HEADER_SIZE));
1149                         goto error_exit;
1150                 }
1151
1152                 /* This is a HACK! I got tired of trying to sort through the messy
1153                  * 'NE' file format. If anyone wants to clean this up please have at
1154                  * it, but this works. 'NE' files will eventually fade away. JRR */
1155                 while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {
1156                         /* Cover case that should not occur in a well formed 'NE' .dll file */
1157                         if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;
1158
1159                         for(i=0; i<byte_count; i++) {
1160                                 /* Fast skip past data that can't possibly match */
1161                                 if (buf[i] != 'V') continue;
1162
1163                                 /* Potential match data crosses buf boundry, move it to beginning
1164                                  * of buf, and fill the buf with as much as it will hold. */
1165                                 if (i>byte_count-VS_VERSION_INFO_SIZE) {
1166                                         int bc;
1167
1168                                         memcpy(buf, &buf[i], byte_count-i);
1169                                         if ((bc = vfs_read_data(fsp, &buf[byte_count-i], VS_NE_BUF_SIZE-
1170                                                                    (byte_count-i))) < 0) {
1171
1172                                                 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
1173                                                                  fname, errno));
1174                                                 goto error_exit;
1175                                         }
1176
1177                                         byte_count = bc + (byte_count - i);
1178                                         if (byte_count<VS_VERSION_INFO_SIZE) break;
1179
1180                                         i = 0;
1181                                 }
1182
1183                                 /* Check that the full signature string and the magic number that
1184                                  * follows exist (not a perfect solution, but the chances that this
1185                                  * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
1186                                  * twice, as it is simpler to read the code. */
1187                                 if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
1188                                         /* Compute skip alignment to next long address */
1189                                         int skip = -(SMB_VFS_LSEEK(fsp, 0, SEEK_CUR) - (byte_count - i) +
1190                                                                  sizeof(VS_SIGNATURE)) & 3;
1191                                         if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
1192
1193                                         *major = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MAJOR_OFFSET);
1194                                         *minor = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MINOR_OFFSET);
1195                                         DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
1196                                                           fname, *major, *minor,
1197                                                           (*major>>16)&0xffff, *major&0xffff,
1198                                                           (*minor>>16)&0xffff, *minor&0xffff));
1199                                         SAFE_FREE(buf);
1200                                         return 1;
1201                                 }
1202                         }
1203                 }
1204
1205                 /* Version info not found, fall back to origin date/time */
1206                 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
1207                 SAFE_FREE(buf);
1208                 return 0;
1209
1210         } else
1211                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
1212                 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
1213                                 fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
1214
1215         no_version_info:
1216                 SAFE_FREE(buf);
1217                 return 0;
1218
1219         error_exit:
1220                 SAFE_FREE(buf);
1221                 return -1;
1222 }
1223
1224 /****************************************************************************
1225 Drivers for Microsoft systems contain multiple files. Often, multiple drivers
1226 share one or more files. During the MS installation process files are checked
1227 to insure that only a newer version of a shared file is installed over an
1228 older version. There are several possibilities for this comparison. If there
1229 is no previous version, the new one is newer (obviously). If either file is
1230 missing the version info structure, compare the creation date (on Unix use
1231 the modification date). Otherwise chose the numerically larger version number.
1232 ****************************************************************************/
1233
1234 static int file_version_is_newer(connection_struct *conn, fstring new_file, fstring old_file)
1235 {
1236         bool use_version = true;
1237
1238         uint32 new_major;
1239         uint32 new_minor;
1240         time_t new_create_time;
1241
1242         uint32 old_major;
1243         uint32 old_minor;
1244         time_t old_create_time;
1245
1246         struct smb_filename *smb_fname = NULL;
1247         files_struct    *fsp = NULL;
1248         SMB_STRUCT_STAT st;
1249
1250         NTSTATUS status;
1251         int ret;
1252
1253         SET_STAT_INVALID(st);
1254         new_create_time = (time_t)0;
1255         old_create_time = (time_t)0;
1256
1257         /* Get file version info (if available) for previous file (if it exists) */
1258         status = driver_unix_convert(conn, old_file, &smb_fname);
1259         if (!NT_STATUS_IS_OK(status)) {
1260                 goto error_exit;
1261         }
1262
1263         status = SMB_VFS_CREATE_FILE(
1264                 conn,                                   /* conn */
1265                 NULL,                                   /* req */
1266                 0,                                      /* root_dir_fid */
1267                 smb_fname,                              /* fname */
1268                 FILE_GENERIC_READ,                      /* access_mask */
1269                 FILE_SHARE_READ | FILE_SHARE_WRITE,     /* share_access */
1270                 FILE_OPEN,                              /* create_disposition*/
1271                 0,                                      /* create_options */
1272                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
1273                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
1274                 0,                                      /* allocation_size */
1275                 0,                                      /* private_flags */
1276                 NULL,                                   /* sd */
1277                 NULL,                                   /* ea_list */
1278                 &fsp,                                   /* result */
1279                 NULL);                                  /* pinfo */
1280
1281         if (!NT_STATUS_IS_OK(status)) {
1282                 /* Old file not found, so by definition new file is in fact newer */
1283                 DEBUG(10,("file_version_is_newer: Can't open old file [%s], "
1284                           "errno = %d\n", smb_fname_str_dbg(smb_fname),
1285                           errno));
1286                 ret = 1;
1287                 goto done;
1288
1289         } else {
1290                 ret = get_file_version(fsp, old_file, &old_major, &old_minor);
1291                 if (ret == -1) {
1292                         goto error_exit;
1293                 }
1294
1295                 if (!ret) {
1296                         DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
1297                                          old_file));
1298                         use_version = false;
1299                         if (SMB_VFS_FSTAT(fsp, &st) == -1) {
1300                                  goto error_exit;
1301                         }
1302                         old_create_time = convert_timespec_to_time_t(st.st_ex_mtime);
1303                         DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n",
1304                                 (long)old_create_time));
1305                 }
1306         }
1307         close_file(NULL, fsp, NORMAL_CLOSE);
1308         fsp = NULL;
1309
1310         /* Get file version info (if available) for new file */
1311         status = driver_unix_convert(conn, new_file, &smb_fname);
1312         if (!NT_STATUS_IS_OK(status)) {
1313                 goto error_exit;
1314         }
1315
1316         status = SMB_VFS_CREATE_FILE(
1317                 conn,                                   /* conn */
1318                 NULL,                                   /* req */
1319                 0,                                      /* root_dir_fid */
1320                 smb_fname,                              /* fname */
1321                 FILE_GENERIC_READ,                      /* access_mask */
1322                 FILE_SHARE_READ | FILE_SHARE_WRITE,     /* share_access */
1323                 FILE_OPEN,                              /* create_disposition*/
1324                 0,                                      /* create_options */
1325                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
1326                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
1327                 0,                                      /* allocation_size */
1328                 0,                                      /* private_flags */
1329                 NULL,                                   /* sd */
1330                 NULL,                                   /* ea_list */
1331                 &fsp,                                   /* result */
1332                 NULL);                                  /* pinfo */
1333
1334         if (!NT_STATUS_IS_OK(status)) {
1335                 /* New file not found, this shouldn't occur if the caller did its job */
1336                 DEBUG(3,("file_version_is_newer: Can't open new file [%s], "
1337                          "errno = %d\n", smb_fname_str_dbg(smb_fname), errno));
1338                 goto error_exit;
1339
1340         } else {
1341                 ret = get_file_version(fsp, new_file, &new_major, &new_minor);
1342                 if (ret == -1) {
1343                         goto error_exit;
1344                 }
1345
1346                 if (!ret) {
1347                         DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
1348                                          new_file));
1349                         use_version = false;
1350                         if (SMB_VFS_FSTAT(fsp, &st) == -1) {
1351                                 goto error_exit;
1352                         }
1353                         new_create_time = convert_timespec_to_time_t(st.st_ex_mtime);
1354                         DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n",
1355                                 (long)new_create_time));
1356                 }
1357         }
1358         close_file(NULL, fsp, NORMAL_CLOSE);
1359         fsp = NULL;
1360
1361         if (use_version && (new_major != old_major || new_minor != old_minor)) {
1362                 /* Compare versions and choose the larger version number */
1363                 if (new_major > old_major ||
1364                         (new_major == old_major && new_minor > old_minor)) {
1365
1366                         DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
1367                         ret = 1;
1368                         goto done;
1369                 }
1370                 else {
1371                         DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
1372                         ret = 0;
1373                         goto done;
1374                 }
1375
1376         } else {
1377                 /* Compare modification time/dates and choose the newest time/date */
1378                 if (new_create_time > old_create_time) {
1379                         DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
1380                         ret = 1;
1381                         goto done;
1382                 }
1383                 else {
1384                         DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
1385                         ret = 0;
1386                         goto done;
1387                 }
1388         }
1389
1390  error_exit:
1391         if(fsp)
1392                 close_file(NULL, fsp, NORMAL_CLOSE);
1393         ret = -1;
1394  done:
1395         TALLOC_FREE(smb_fname);
1396         return ret;
1397 }
1398
1399 /****************************************************************************
1400 Determine the correct cVersion associated with an architecture and driver
1401 ****************************************************************************/
1402 static uint32 get_correct_cversion(struct pipes_struct *p,
1403                                    const char *architecture,
1404                                    const char *driverpath_in,
1405                                    WERROR *perr)
1406 {
1407         int               cversion;
1408         NTSTATUS          nt_status;
1409         struct smb_filename *smb_fname = NULL;
1410         char *driverpath = NULL;
1411         files_struct      *fsp = NULL;
1412         connection_struct *conn = NULL;
1413         NTSTATUS status;
1414         char *oldcwd;
1415         fstring printdollar;
1416         int printdollar_snum;
1417
1418         *perr = WERR_INVALID_PARAM;
1419
1420         /* If architecture is Windows 95/98/ME, the version is always 0. */
1421         if (strcmp(architecture, SPL_ARCH_WIN40) == 0) {
1422                 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
1423                 *perr = WERR_OK;
1424                 return 0;
1425         }
1426
1427         /* If architecture is Windows x64, the version is always 3. */
1428         if (strcmp(architecture, SPL_ARCH_X64) == 0) {
1429                 DEBUG(10,("get_correct_cversion: Driver is x64, cversion = 3\n"));
1430                 *perr = WERR_OK;
1431                 return 3;
1432         }
1433
1434         fstrcpy(printdollar, "print$");
1435
1436         printdollar_snum = find_service(printdollar);
1437         if (printdollar_snum == -1) {
1438                 *perr = WERR_NO_SUCH_SHARE;
1439                 return -1;
1440         }
1441
1442         nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
1443                                        lp_pathname(printdollar_snum),
1444                                        p->server_info, &oldcwd);
1445         if (!NT_STATUS_IS_OK(nt_status)) {
1446                 DEBUG(0,("get_correct_cversion: create_conn_struct "
1447                          "returned %s\n", nt_errstr(nt_status)));
1448                 *perr = ntstatus_to_werror(nt_status);
1449                 return -1;
1450         }
1451
1452         /* Open the driver file (Portable Executable format) and determine the
1453          * deriver the cversion. */
1454         driverpath = talloc_asprintf(talloc_tos(),
1455                                         "%s/%s",
1456                                         architecture,
1457                                         driverpath_in);
1458         if (!driverpath) {
1459                 *perr = WERR_NOMEM;
1460                 goto error_exit;
1461         }
1462
1463         nt_status = driver_unix_convert(conn, driverpath, &smb_fname);
1464         if (!NT_STATUS_IS_OK(nt_status)) {
1465                 *perr = ntstatus_to_werror(nt_status);
1466                 goto error_exit;
1467         }
1468
1469         nt_status = vfs_file_exist(conn, smb_fname);
1470         if (!NT_STATUS_IS_OK(nt_status)) {
1471                 *perr = WERR_BADFILE;
1472                 goto error_exit;
1473         }
1474
1475         status = SMB_VFS_CREATE_FILE(
1476                 conn,                                   /* conn */
1477                 NULL,                                   /* req */
1478                 0,                                      /* root_dir_fid */
1479                 smb_fname,                              /* fname */
1480                 FILE_GENERIC_READ,                      /* access_mask */
1481                 FILE_SHARE_READ | FILE_SHARE_WRITE,     /* share_access */
1482                 FILE_OPEN,                              /* create_disposition*/
1483                 0,                                      /* create_options */
1484                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
1485                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
1486                 0,                                      /* private_flags */
1487                 0,                                      /* allocation_size */
1488                 NULL,                                   /* sd */
1489                 NULL,                                   /* ea_list */
1490                 &fsp,                                   /* result */
1491                 NULL);                                  /* pinfo */
1492
1493         if (!NT_STATUS_IS_OK(status)) {
1494                 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = "
1495                          "%d\n", smb_fname_str_dbg(smb_fname), errno));
1496                 *perr = WERR_ACCESS_DENIED;
1497                 goto error_exit;
1498         } else {
1499                 uint32 major;
1500                 uint32 minor;
1501                 int    ret;
1502
1503                 ret = get_file_version(fsp, smb_fname->base_name, &major, &minor);
1504                 if (ret == -1) goto error_exit;
1505
1506                 if (!ret) {
1507                         DEBUG(6,("get_correct_cversion: Version info not "
1508                                  "found [%s]\n",
1509                                  smb_fname_str_dbg(smb_fname)));
1510                         goto error_exit;
1511                 }
1512
1513                 /*
1514                  * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
1515                  * for more details. Version in this case is not just the version of the
1516                  * file, but the version in the sense of kernal mode (2) vs. user mode
1517                  * (3) drivers. Other bits of the version fields are the version info.
1518                  * JRR 010716
1519                 */
1520                 cversion = major & 0x0000ffff;
1521                 switch (cversion) {
1522                         case 2: /* WinNT drivers */
1523                         case 3: /* Win2K drivers */
1524                                 break;
1525
1526                         default:
1527                                 DEBUG(6,("get_correct_cversion: cversion "
1528                                          "invalid [%s]  cversion = %d\n",
1529                                          smb_fname_str_dbg(smb_fname),
1530                                          cversion));
1531                                 goto error_exit;
1532                 }
1533
1534                 DEBUG(10,("get_correct_cversion: Version info found [%s] major"
1535                           " = 0x%x  minor = 0x%x\n",
1536                           smb_fname_str_dbg(smb_fname), major, minor));
1537         }
1538
1539         DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
1540                   smb_fname_str_dbg(smb_fname), cversion));
1541
1542         goto done;
1543
1544  error_exit:
1545         cversion = -1;
1546  done:
1547         TALLOC_FREE(smb_fname);
1548         if (fsp != NULL) {
1549                 close_file(NULL, fsp, NORMAL_CLOSE);
1550         }
1551         if (conn != NULL) {
1552                 vfs_ChDir(conn, oldcwd);
1553                 conn_free(conn);
1554         }
1555         if (cversion != -1) {
1556                 *perr = WERR_OK;
1557         }
1558         return cversion;
1559 }
1560
1561 /****************************************************************************
1562 ****************************************************************************/
1563
1564 #define strip_driver_path(_mem_ctx, _element) do { \
1565         if (_element && ((_p = strrchr((_element), '\\')) != NULL)) { \
1566                 (_element) = talloc_asprintf((_mem_ctx), "%s", _p+1); \
1567                 W_ERROR_HAVE_NO_MEMORY((_element)); \
1568         } \
1569 } while (0);
1570
1571 static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
1572                                            struct pipes_struct *rpc_pipe,
1573                                            const char *architecture,
1574                                            const char **driver_path,
1575                                            const char **data_file,
1576                                            const char **config_file,
1577                                            const char **help_file,
1578                                            struct spoolss_StringArray *dependent_files,
1579                                            uint32_t *version)
1580 {
1581         const char *short_architecture;
1582         int i;
1583         WERROR err;
1584         char *_p;
1585
1586         if (!*driver_path || !*data_file || !*config_file) {
1587                 return WERR_INVALID_PARAM;
1588         }
1589
1590         /* clean up the driver name.
1591          * we can get .\driver.dll
1592          * or worse c:\windows\system\driver.dll !
1593          */
1594         /* using an intermediate string to not have overlaping memcpy()'s */
1595
1596         strip_driver_path(mem_ctx, *driver_path);
1597         strip_driver_path(mem_ctx, *data_file);
1598         strip_driver_path(mem_ctx, *config_file);
1599         if (help_file) {
1600                 strip_driver_path(mem_ctx, *help_file);
1601         }
1602
1603         if (dependent_files && dependent_files->string) {
1604                 for (i=0; dependent_files->string[i]; i++) {
1605                         strip_driver_path(mem_ctx, dependent_files->string[i]);
1606                 }
1607         }
1608
1609         short_architecture = get_short_archi(architecture);
1610         if (!short_architecture) {
1611                 return WERR_UNKNOWN_PRINTER_DRIVER;
1612         }
1613
1614         /* jfm:7/16/2000 the client always sends the cversion=0.
1615          * The server should check which version the driver is by reading
1616          * the PE header of driver->driverpath.
1617          *
1618          * For Windows 95/98 the version is 0 (so the value sent is correct)
1619          * For Windows NT (the architecture doesn't matter)
1620          *      NT 3.1: cversion=0
1621          *      NT 3.5/3.51: cversion=1
1622          *      NT 4: cversion=2
1623          *      NT2K: cversion=3
1624          */
1625
1626         *version = get_correct_cversion(rpc_pipe, short_architecture,
1627                                         *driver_path, &err);
1628         if (*version == -1) {
1629                 return err;
1630         }
1631
1632         return WERR_OK;
1633 }
1634
1635 /****************************************************************************
1636 ****************************************************************************/
1637
1638 WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx,
1639                               struct pipes_struct *rpc_pipe,
1640                               struct spoolss_AddDriverInfoCtr *r)
1641 {
1642         switch (r->level) {
1643         case 3:
1644                 return clean_up_driver_struct_level(mem_ctx, rpc_pipe,
1645                                                     r->info.info3->architecture,
1646                                                     &r->info.info3->driver_path,
1647                                                     &r->info.info3->data_file,
1648                                                     &r->info.info3->config_file,
1649                                                     &r->info.info3->help_file,
1650                                                     r->info.info3->dependent_files,
1651                                                     &r->info.info3->version);
1652         case 6:
1653                 return clean_up_driver_struct_level(mem_ctx, rpc_pipe,
1654                                                     r->info.info6->architecture,
1655                                                     &r->info.info6->driver_path,
1656                                                     &r->info.info6->data_file,
1657                                                     &r->info.info6->config_file,
1658                                                     &r->info.info6->help_file,
1659                                                     r->info.info6->dependent_files,
1660                                                     &r->info.info6->version);
1661         default:
1662                 return WERR_NOT_SUPPORTED;
1663         }
1664 }
1665
1666 /****************************************************************************
1667  This function sucks and should be replaced. JRA.
1668 ****************************************************************************/
1669
1670 static void convert_level_6_to_level3(struct spoolss_AddDriverInfo3 *dst,
1671                                       const struct spoolss_AddDriverInfo6 *src)
1672 {
1673         dst->version            = src->version;
1674
1675         dst->driver_name        = src->driver_name;
1676         dst->architecture       = src->architecture;
1677         dst->driver_path        = src->driver_path;
1678         dst->data_file          = src->data_file;
1679         dst->config_file        = src->config_file;
1680         dst->help_file          = src->help_file;
1681         dst->monitor_name       = src->monitor_name;
1682         dst->default_datatype   = src->default_datatype;
1683         dst->_ndr_size_dependent_files = src->_ndr_size_dependent_files;
1684         dst->dependent_files    = src->dependent_files;
1685 }
1686
1687 /****************************************************************************
1688 ****************************************************************************/
1689
1690 static WERROR move_driver_file_to_download_area(TALLOC_CTX *mem_ctx,
1691                                                 connection_struct *conn,
1692                                                 const char *driver_file,
1693                                                 const char *short_architecture,
1694                                                 uint32_t driver_version,
1695                                                 uint32_t version)
1696 {
1697         struct smb_filename *smb_fname_old = NULL;
1698         struct smb_filename *smb_fname_new = NULL;
1699         char *old_name = NULL;
1700         char *new_name = NULL;
1701         NTSTATUS status;
1702         WERROR ret;
1703
1704         old_name = talloc_asprintf(mem_ctx, "%s/%s",
1705                                    short_architecture, driver_file);
1706         W_ERROR_HAVE_NO_MEMORY(old_name);
1707
1708         new_name = talloc_asprintf(mem_ctx, "%s/%d/%s",
1709                                    short_architecture, driver_version, driver_file);
1710         if (new_name == NULL) {
1711                 TALLOC_FREE(old_name);
1712                 return WERR_NOMEM;
1713         }
1714
1715         if (version != -1 && (version = file_version_is_newer(conn, old_name, new_name)) > 0) {
1716
1717                 status = driver_unix_convert(conn, old_name, &smb_fname_old);
1718                 if (!NT_STATUS_IS_OK(status)) {
1719                         ret = WERR_NOMEM;
1720                         goto out;
1721                 }
1722
1723                 /* Setup a synthetic smb_filename struct */
1724                 smb_fname_new = TALLOC_ZERO_P(mem_ctx, struct smb_filename);
1725                 if (!smb_fname_new) {
1726                         ret = WERR_NOMEM;
1727                         goto out;
1728                 }
1729
1730                 smb_fname_new->base_name = new_name;
1731
1732                 DEBUG(10,("move_driver_file_to_download_area: copying '%s' to "
1733                           "'%s'\n", smb_fname_old->base_name,
1734                           smb_fname_new->base_name));
1735
1736                 status = copy_file(mem_ctx, conn, smb_fname_old, smb_fname_new,
1737                                    OPENX_FILE_EXISTS_TRUNCATE |
1738                                    OPENX_FILE_CREATE_IF_NOT_EXIST,
1739                                    0, false);
1740
1741                 if (!NT_STATUS_IS_OK(status)) {
1742                         DEBUG(0,("move_driver_file_to_download_area: Unable "
1743                                  "to rename [%s] to [%s]: %s\n",
1744                                  smb_fname_old->base_name, new_name,
1745                                  nt_errstr(status)));
1746                         ret = WERR_ACCESS_DENIED;
1747                         goto out;
1748                 }
1749         }
1750
1751         ret = WERR_OK;
1752  out:
1753         TALLOC_FREE(smb_fname_old);
1754         TALLOC_FREE(smb_fname_new);
1755         return ret;
1756 }
1757
1758 WERROR move_driver_to_download_area(struct pipes_struct *p,
1759                                     struct spoolss_AddDriverInfoCtr *r,
1760                                     WERROR *perr)
1761 {
1762         struct spoolss_AddDriverInfo3 *driver;
1763         struct spoolss_AddDriverInfo3 converted_driver;
1764         const char *short_architecture;
1765         struct smb_filename *smb_dname = NULL;
1766         char *new_dir = NULL;
1767         connection_struct *conn = NULL;
1768         NTSTATUS nt_status;
1769         int i;
1770         TALLOC_CTX *ctx = talloc_tos();
1771         int ver = 0;
1772         char *oldcwd;
1773         fstring printdollar;
1774         int printdollar_snum;
1775
1776         *perr = WERR_OK;
1777
1778         switch (r->level) {
1779         case 3:
1780                 driver = r->info.info3;
1781                 break;
1782         case 6:
1783                 convert_level_6_to_level3(&converted_driver, r->info.info6);
1784                 driver = &converted_driver;
1785                 break;
1786         default:
1787                 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)r->level));
1788                 return WERR_UNKNOWN_LEVEL;
1789         }
1790
1791         short_architecture = get_short_archi(driver->architecture);
1792         if (!short_architecture) {
1793                 return WERR_UNKNOWN_PRINTER_DRIVER;
1794         }
1795
1796         fstrcpy(printdollar, "print$");
1797
1798         printdollar_snum = find_service(printdollar);
1799         if (printdollar_snum == -1) {
1800                 *perr = WERR_NO_SUCH_SHARE;
1801                 return WERR_NO_SUCH_SHARE;
1802         }
1803
1804         nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
1805                                        lp_pathname(printdollar_snum),
1806                                        p->server_info, &oldcwd);
1807         if (!NT_STATUS_IS_OK(nt_status)) {
1808                 DEBUG(0,("move_driver_to_download_area: create_conn_struct "
1809                          "returned %s\n", nt_errstr(nt_status)));
1810                 *perr = ntstatus_to_werror(nt_status);
1811                 return *perr;
1812         }
1813
1814         new_dir = talloc_asprintf(ctx,
1815                                 "%s/%d",
1816                                 short_architecture,
1817                                 driver->version);
1818         if (!new_dir) {
1819                 *perr = WERR_NOMEM;
1820                 goto err_exit;
1821         }
1822         nt_status = driver_unix_convert(conn, new_dir, &smb_dname);
1823         if (!NT_STATUS_IS_OK(nt_status)) {
1824                 *perr = WERR_NOMEM;
1825                 goto err_exit;
1826         }
1827
1828         DEBUG(5,("Creating first directory: %s\n", smb_dname->base_name));
1829
1830         create_directory(conn, NULL, smb_dname);
1831
1832         /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
1833          * listed for this driver which has already been moved, skip it (note:
1834          * drivers may list the same file name several times. Then check if the
1835          * file already exists in archi\version\, if so, check that the version
1836          * info (or time stamps if version info is unavailable) is newer (or the
1837          * date is later). If it is, move it to archi\version\filexxx.yyy.
1838          * Otherwise, delete the file.
1839          *
1840          * If a file is not moved to archi\version\ because of an error, all the
1841          * rest of the 'unmoved' driver files are removed from archi\. If one or
1842          * more of the driver's files was already moved to archi\version\, it
1843          * potentially leaves the driver in a partially updated state. Version
1844          * trauma will most likely occur if an client attempts to use any printer
1845          * bound to the driver. Perhaps a rewrite to make sure the moves can be
1846          * done is appropriate... later JRR
1847          */
1848
1849         DEBUG(5,("Moving files now !\n"));
1850
1851         if (driver->driver_path && strlen(driver->driver_path)) {
1852
1853                 *perr = move_driver_file_to_download_area(ctx,
1854                                                           conn,
1855                                                           driver->driver_path,
1856                                                           short_architecture,
1857                                                           driver->version,
1858                                                           ver);
1859                 if (!W_ERROR_IS_OK(*perr)) {
1860                         if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
1861                                 ver = -1;
1862                         }
1863                         goto err_exit;
1864                 }
1865         }
1866
1867         if (driver->data_file && strlen(driver->data_file)) {
1868                 if (!strequal(driver->data_file, driver->driver_path)) {
1869
1870                         *perr = move_driver_file_to_download_area(ctx,
1871                                                                   conn,
1872                                                                   driver->data_file,
1873                                                                   short_architecture,
1874                                                                   driver->version,
1875                                                                   ver);
1876                         if (!W_ERROR_IS_OK(*perr)) {
1877                                 if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
1878                                         ver = -1;
1879                                 }
1880                                 goto err_exit;
1881                         }
1882                 }
1883         }
1884
1885         if (driver->config_file && strlen(driver->config_file)) {
1886                 if (!strequal(driver->config_file, driver->driver_path) &&
1887                     !strequal(driver->config_file, driver->data_file)) {
1888
1889                         *perr = move_driver_file_to_download_area(ctx,
1890                                                                   conn,
1891                                                                   driver->config_file,
1892                                                                   short_architecture,
1893                                                                   driver->version,
1894                                                                   ver);
1895                         if (!W_ERROR_IS_OK(*perr)) {
1896                                 if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
1897                                         ver = -1;
1898                                 }
1899                                 goto err_exit;
1900                         }
1901                 }
1902         }
1903
1904         if (driver->help_file && strlen(driver->help_file)) {
1905                 if (!strequal(driver->help_file, driver->driver_path) &&
1906                     !strequal(driver->help_file, driver->data_file) &&
1907                     !strequal(driver->help_file, driver->config_file)) {
1908
1909                         *perr = move_driver_file_to_download_area(ctx,
1910                                                                   conn,
1911                                                                   driver->help_file,
1912                                                                   short_architecture,
1913                                                                   driver->version,
1914                                                                   ver);
1915                         if (!W_ERROR_IS_OK(*perr)) {
1916                                 if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
1917                                         ver = -1;
1918                                 }
1919                                 goto err_exit;
1920                         }
1921                 }
1922         }
1923
1924         if (driver->dependent_files && driver->dependent_files->string) {
1925                 for (i=0; driver->dependent_files->string[i]; i++) {
1926                         if (!strequal(driver->dependent_files->string[i], driver->driver_path) &&
1927                             !strequal(driver->dependent_files->string[i], driver->data_file) &&
1928                             !strequal(driver->dependent_files->string[i], driver->config_file) &&
1929                             !strequal(driver->dependent_files->string[i], driver->help_file)) {
1930                                 int j;
1931                                 for (j=0; j < i; j++) {
1932                                         if (strequal(driver->dependent_files->string[i], driver->dependent_files->string[j])) {
1933                                                 goto NextDriver;
1934                                         }
1935                                 }
1936
1937                                 *perr = move_driver_file_to_download_area(ctx,
1938                                                                           conn,
1939                                                                           driver->dependent_files->string[i],
1940                                                                           short_architecture,
1941                                                                           driver->version,
1942                                                                           ver);
1943                                 if (!W_ERROR_IS_OK(*perr)) {
1944                                         if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
1945                                                 ver = -1;
1946                                         }
1947                                         goto err_exit;
1948                                 }
1949                         }
1950                 NextDriver: ;
1951                 }
1952         }
1953
1954   err_exit:
1955         TALLOC_FREE(smb_dname);
1956
1957         if (conn != NULL) {
1958                 vfs_ChDir(conn, oldcwd);
1959                 conn_free(conn);
1960         }
1961
1962         if (W_ERROR_EQUAL(*perr, WERR_OK)) {
1963                 return WERR_OK;
1964         }
1965         if (ver == -1) {
1966                 return WERR_UNKNOWN_PRINTER_DRIVER;
1967         }
1968         return (*perr);
1969 }
1970
1971 /****************************************************************************
1972 ****************************************************************************/
1973 int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen)
1974 {
1975         enum ndr_err_code ndr_err;
1976         DATA_BLOB blob;
1977         int len = 0;
1978
1979         if (devmode) {
1980                 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(),
1981                                                devmode,
1982                                                (ndr_push_flags_fn_t)
1983                                                ndr_push_spoolss_DeviceMode);
1984                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1985                         DEBUG(10, ("pack_devicemode: "
1986                                    "error encoding spoolss_DeviceMode\n"));
1987                         goto done;
1988                 }
1989         } else {
1990                 ZERO_STRUCT(blob);
1991         }
1992
1993         len = tdb_pack(buf, buflen, "B", blob.length, blob.data);
1994
1995         if (devmode) {
1996                 DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname));
1997         }
1998
1999 done:
2000         return len;
2001 }
2002
2003 /****************************************************************************
2004 ****************************************************************************/
2005 int unpack_devicemode(TALLOC_CTX *mem_ctx,
2006                       const uint8 *buf, int buflen,
2007                       struct spoolss_DeviceMode **devmode)
2008 {
2009         struct spoolss_DeviceMode *dm;
2010         enum ndr_err_code ndr_err;
2011         char *data = NULL;
2012         int data_len = 0;
2013         DATA_BLOB blob;
2014         int len = 0;
2015
2016         *devmode = NULL;
2017
2018         len = tdb_unpack(buf, buflen, "B", &data_len, &data);
2019         if (!data) {
2020                 return len;
2021         }
2022
2023         dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
2024         if (!dm) {
2025                 goto done;
2026         }
2027
2028         blob = data_blob_const(data, data_len);
2029
2030         ndr_err = ndr_pull_struct_blob(&blob, dm, dm,
2031                         (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
2032         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2033                 DEBUG(10, ("unpack_devicemode: "
2034                            "error parsing spoolss_DeviceMode\n"));
2035                 goto done;
2036         }
2037
2038         DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
2039                   dm->devicename, dm->formname));
2040         if (dm->driverextra_data.data) {
2041                 DEBUG(8, ("with a private section of %d bytes\n",
2042                           dm->__driverextra_length));
2043         }
2044
2045         *devmode = dm;
2046
2047 done:
2048         SAFE_FREE(data);
2049         return len;
2050 }
2051
2052 /****************************************************************************
2053  Pack all values in all printer keys
2054  ***************************************************************************/
2055
2056 static int pack_values(NT_PRINTER_DATA *data, uint8 *buf, int buflen)
2057 {
2058         int             len = 0;
2059         int             i, j;
2060         struct regval_blob      *val;
2061         struct regval_ctr       *val_ctr;
2062         char *path = NULL;
2063         int             num_values;
2064
2065         if ( !data )
2066                 return 0;
2067
2068         /* loop over all keys */
2069
2070         for ( i=0; i<data->num_keys; i++ ) {
2071                 val_ctr = data->keys[i].values;
2072                 num_values = regval_ctr_numvals( val_ctr );
2073
2074                 /* pack the keyname followed by a empty value */
2075
2076                 len += tdb_pack(buf+len, buflen-len, "pPdB",
2077                                 &data->keys[i].name,
2078                                 data->keys[i].name,
2079                                 REG_NONE,
2080                                 0,
2081                                 NULL);
2082
2083                 /* now loop over all values */
2084
2085                 for ( j=0; j<num_values; j++ ) {
2086                         /* pathname should be stored as <key>\<value> */
2087
2088                         val = regval_ctr_specific_value( val_ctr, j );
2089                         if (asprintf(&path, "%s\\%s",
2090                                         data->keys[i].name,
2091                                         regval_name(val)) < 0) {
2092                                 return -1;
2093                         }
2094
2095                         len += tdb_pack(buf+len, buflen-len, "pPdB",
2096                                         val,
2097                                         path,
2098                                         regval_type(val),
2099                                         regval_size(val),
2100                                         regval_data_p(val) );
2101
2102                         DEBUG(8,("specific: [%s], len: %d\n", regval_name(val), regval_size(val)));
2103                         SAFE_FREE(path);
2104                 }
2105
2106         }
2107
2108         /* terminator */
2109
2110         len += tdb_pack(buf+len, buflen-len, "p", NULL);
2111
2112         return len;
2113 }
2114
2115
2116 /****************************************************************************
2117 ****************************************************************************/
2118 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
2119 {
2120         uint8 *buf;
2121         int buflen, len;
2122         int retlen;
2123         WERROR ret;
2124         TDB_DATA kbuf, dbuf;
2125
2126         /*
2127          * in addprinter: no servername and the printer is the name
2128          * in setprinter: servername is \\server
2129          *                and printer is \\server\\printer
2130          *
2131          * Samba manages only local printers.
2132          * we currently don't support things like i
2133          * path=\\other_server\printer
2134          *
2135          * We only store the printername, not \\server\printername
2136          */
2137
2138         if ( info->servername[0] != '\0' ) {
2139                 trim_string(info->printername, info->servername, NULL);
2140                 trim_char(info->printername, '\\', '\0');
2141                 info->servername[0]='\0';
2142         }
2143
2144         /*
2145          * JFM: one day I'll forget.
2146          * below that's info->portname because that's the SAMBA sharename
2147          * and I made NT 'thinks' it's the portname
2148          * the info->sharename is the thing you can name when you add a printer
2149          * that's the short-name when you create shared printer for 95/98
2150          * So I've made a limitation in SAMBA: you can only have 1 printer model
2151          * behind a SAMBA share.
2152          */
2153
2154         buf = NULL;
2155         buflen = 0;
2156
2157  again:
2158         len = 0;
2159         len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
2160                         info->attributes,
2161                         info->priority,
2162                         info->default_priority,
2163                         info->starttime,
2164                         info->untiltime,
2165                         info->status,
2166                         info->cjobs,
2167                         info->averageppm,
2168                         info->changeid,
2169                         info->c_setprinter,
2170                         info->setuptime,
2171                         info->servername,
2172                         info->printername,
2173                         info->sharename,
2174                         info->portname,
2175                         info->drivername,
2176                         info->comment,
2177                         info->location,
2178                         info->sepfile,
2179                         info->printprocessor,
2180                         info->datatype,
2181                         info->parameters);
2182
2183         len += pack_devicemode(info->devmode, buf+len, buflen-len);
2184         retlen = pack_values( info->data, buf+len, buflen-len );
2185         if (retlen == -1) {
2186                 ret = WERR_NOMEM;
2187                 goto done;
2188         }
2189         len += retlen;
2190
2191         if (buflen != len) {
2192                 buf = (uint8 *)SMB_REALLOC(buf, len);
2193                 if (!buf) {
2194                         DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
2195                         ret = WERR_NOMEM;
2196                         goto done;
2197                 }
2198                 buflen = len;
2199                 goto again;
2200         }
2201
2202         kbuf = make_printer_tdbkey(talloc_tos(), info->sharename );
2203
2204         dbuf.dptr = buf;
2205         dbuf.dsize = len;
2206
2207         ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
2208
2209 done:
2210         if (!W_ERROR_IS_OK(ret))
2211                 DEBUG(8, ("error updating printer to tdb on disk\n"));
2212
2213         SAFE_FREE(buf);
2214
2215         DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
2216                  info->sharename, info->drivername, info->portname, len));
2217
2218         return ret;
2219 }
2220
2221 /****************************************************************************
2222  Create and allocate a default devicemode.
2223 ****************************************************************************/
2224
2225 WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
2226                                       const char *devicename,
2227                                       struct spoolss_DeviceMode **devmode)
2228 {
2229         struct spoolss_DeviceMode *dm;
2230         char *dname;
2231
2232         dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
2233         if (dm == NULL) {
2234                 return WERR_NOMEM;
2235         }
2236
2237         dname = talloc_asprintf(dm, "%s", devicename);
2238         if (dname == NULL) {
2239                 return WERR_NOMEM;
2240         }
2241         if (strlen(dname) > MAXDEVICENAME) {
2242                 dname[MAXDEVICENAME] = '\0';
2243         }
2244         dm->devicename = dname;
2245
2246         dm->formname = talloc_strdup(dm, "Letter");
2247         if (dm->formname == NULL) {
2248                 return WERR_NOMEM;
2249         }
2250
2251         dm->specversion          = DMSPEC_NT4_AND_ABOVE;
2252         dm->driverversion        = 0x0400;
2253         dm->size                 = 0x00DC;
2254         dm->__driverextra_length = 0;
2255         dm->fields               = DEVMODE_FORMNAME |
2256                                    DEVMODE_TTOPTION |
2257                                    DEVMODE_PRINTQUALITY |
2258                                    DEVMODE_DEFAULTSOURCE |
2259                                    DEVMODE_COPIES |
2260                                    DEVMODE_SCALE |
2261                                    DEVMODE_PAPERSIZE |
2262                                    DEVMODE_ORIENTATION;
2263         dm->orientation          = DMORIENT_PORTRAIT;
2264         dm->papersize            = DMPAPER_LETTER;
2265         dm->paperlength          = 0;
2266         dm->paperwidth           = 0;
2267         dm->scale                = 0x64;
2268         dm->copies               = 1;
2269         dm->defaultsource        = DMBIN_FORMSOURCE;
2270         dm->printquality         = DMRES_HIGH;           /* 0x0258 */
2271         dm->color                = DMRES_MONOCHROME;
2272         dm->duplex               = DMDUP_SIMPLEX;
2273         dm->yresolution          = 0;
2274         dm->ttoption             = DMTT_SUBDEV;
2275         dm->collate              = DMCOLLATE_FALSE;
2276         dm->icmmethod            = 0;
2277         dm->icmintent            = 0;
2278         dm->mediatype            = 0;
2279         dm->dithertype           = 0;
2280
2281         dm->logpixels            = 0;
2282         dm->bitsperpel           = 0;
2283         dm->pelswidth            = 0;
2284         dm->pelsheight           = 0;
2285         dm->displayflags         = 0;
2286         dm->displayfrequency     = 0;
2287         dm->reserved1            = 0;
2288         dm->reserved2            = 0;
2289         dm->panningwidth         = 0;
2290         dm->panningheight        = 0;
2291
2292         dm->driverextra_data.data = NULL;
2293         dm->driverextra_data.length = 0;
2294
2295         *devmode = dm;
2296         return WERR_OK;
2297 }
2298
2299 WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
2300                                       struct spoolss_security_descriptor **secdesc)
2301 {
2302         struct security_ace ace[7];     /* max number of ace entries */
2303         int i = 0;
2304         uint32_t sa;
2305         struct security_acl *psa = NULL;
2306         struct security_descriptor *psd = NULL;
2307         struct dom_sid adm_sid;
2308         size_t sd_size;
2309
2310         /* Create an ACE where Everyone is allowed to print */
2311
2312         sa = PRINTER_ACE_PRINT;
2313         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
2314                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2315
2316         /* Add the domain admins group if we are a DC */
2317
2318         if ( IS_DC ) {
2319                 struct dom_sid domadmins_sid;
2320
2321                 sid_compose(&domadmins_sid, get_global_sam_sid(),
2322                             DOMAIN_RID_ADMINS);
2323
2324                 sa = PRINTER_ACE_FULL_CONTROL;
2325                 init_sec_ace(&ace[i++], &domadmins_sid,
2326                         SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
2327                         SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
2328                 init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
2329                         sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2330         }
2331         else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
2332                 sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
2333
2334                 sa = PRINTER_ACE_FULL_CONTROL;
2335                 init_sec_ace(&ace[i++], &adm_sid,
2336                         SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
2337                         SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
2338                 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
2339                         sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2340         }
2341
2342         /* add BUILTIN\Administrators as FULL CONTROL */
2343
2344         sa = PRINTER_ACE_FULL_CONTROL;
2345         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
2346                 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
2347                 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
2348         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
2349                 SEC_ACE_TYPE_ACCESS_ALLOWED,
2350                 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2351
2352         /* add BUILTIN\Print Operators as FULL CONTROL */
2353
2354         sa = PRINTER_ACE_FULL_CONTROL;
2355         init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
2356                 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
2357                 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
2358         init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
2359                 SEC_ACE_TYPE_ACCESS_ALLOWED,
2360                 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2361
2362         /* Make the security descriptor owned by the BUILTIN\Administrators */
2363
2364         /* The ACL revision number in rpc_secdesc.h differs from the one
2365            created by NT when setting ACE entries in printer
2366            descriptors.  NT4 complains about the property being edited by a
2367            NT5 machine. */
2368
2369         if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
2370                 psd = make_sec_desc(mem_ctx,
2371                                     SD_REVISION,
2372                                     SEC_DESC_SELF_RELATIVE,
2373                                     &global_sid_Builtin_Administrators,
2374                                     &global_sid_Builtin_Administrators,
2375                                     NULL,
2376                                     psa,
2377                                     &sd_size);
2378         }
2379
2380         if (psd == NULL) {
2381                 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
2382                 return WERR_NOMEM;
2383         }
2384
2385         DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
2386                  (unsigned int)sd_size));
2387
2388         *secdesc = psd;
2389
2390         return WERR_OK;
2391 }
2392
2393 /****************************************************************************
2394  Allocate and initialize a new slot.
2395 ***************************************************************************/
2396
2397 int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
2398 {
2399         NT_PRINTER_KEY  *d;
2400         int             key_index;
2401         WERROR werr;
2402
2403         if ( !name || !data )
2404                 return -1;
2405
2406         /* allocate another slot in the NT_PRINTER_KEY array */
2407
2408         if ( !(d = TALLOC_REALLOC_ARRAY( data, data->keys, NT_PRINTER_KEY, data->num_keys+1)) ) {
2409                 DEBUG(0,("add_new_printer_key: Realloc() failed!\n"));
2410                 return -1;
2411         }
2412
2413         data->keys = d;
2414
2415         key_index = data->num_keys;
2416
2417         /* initialze new key */
2418
2419         data->keys[key_index].name = talloc_strdup( data, name );
2420
2421         werr = regval_ctr_init(data, &(data->keys[key_index].values));
2422         if (!W_ERROR_IS_OK(werr)) {
2423                 return -1;
2424         }
2425
2426         data->num_keys++;
2427
2428         DEBUG(10,("add_new_printer_key: Inserted new data key [%s]\n", name ));
2429
2430         return key_index;
2431 }
2432
2433 /****************************************************************************
2434  search for a registry key name in the existing printer data
2435  ***************************************************************************/
2436
2437 int delete_printer_key( NT_PRINTER_DATA *data, const char *name )
2438 {
2439         int i;
2440
2441         for ( i=0; i<data->num_keys; i++ ) {
2442                 if ( strequal( data->keys[i].name, name ) ) {
2443
2444                         /* cleanup memory */
2445
2446                         TALLOC_FREE( data->keys[i].name );
2447                         TALLOC_FREE( data->keys[i].values );
2448
2449                         /* if not the end of the array, move remaining elements down one slot */
2450
2451                         data->num_keys--;
2452                         if ( data->num_keys && (i < data->num_keys) )
2453                                 memmove( &data->keys[i], &data->keys[i+1], sizeof(NT_PRINTER_KEY)*(data->num_keys-i) );
2454
2455                         break;
2456                 }
2457         }
2458
2459
2460         return data->num_keys;
2461 }
2462
2463 /****************************************************************************
2464  search for a registry key name in the existing printer data
2465  ***************************************************************************/
2466
2467 int lookup_printerkey( NT_PRINTER_DATA *data, const char *name )
2468 {
2469         int             key_index = -1;
2470         int             i;
2471
2472         if ( !data || !name )
2473                 return -1;
2474
2475         DEBUG(12,("lookup_printerkey: Looking for [%s]\n", name));
2476
2477         /* loop over all existing keys */
2478
2479         for ( i=0; i<data->num_keys; i++ ) {
2480                 if ( strequal(data->keys[i].name, name) ) {
2481                         DEBUG(12,("lookup_printerkey: Found [%s]!\n", name));
2482                         key_index = i;
2483                         break;
2484
2485                 }
2486         }
2487
2488         return key_index;
2489 }
2490
2491 /****************************************************************************
2492  ***************************************************************************/
2493
2494 int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys )
2495 {
2496         int     i, j;
2497         int     key_len;
2498         int     num_subkeys = 0;
2499         char    *p;
2500         fstring *subkeys_ptr = NULL;
2501         fstring subkeyname;
2502
2503         *subkeys = NULL;
2504
2505         if ( !data )
2506                 return 0;
2507
2508         if ( !key )
2509                 return -1;
2510
2511         /* special case of asking for the top level printer data registry key names */
2512
2513         if ( strlen(key) == 0 ) {
2514                 for ( i=0; i<data->num_keys; i++ ) {
2515
2516                         /* found a match, so allocate space and copy the name */
2517
2518                         if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
2519                                 DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
2520                                         num_subkeys+1));
2521                                 return -1;
2522                         }
2523
2524                         fstrcpy( subkeys_ptr[num_subkeys], data->keys[i].name );
2525                         num_subkeys++;
2526                 }
2527
2528                 goto done;
2529         }
2530
2531         /* asking for the subkeys of some key */
2532         /* subkey paths are stored in the key name using '\' as the delimiter */
2533
2534         for ( i=0; i<data->num_keys; i++ ) {
2535                 if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) {
2536
2537                         /* if we found the exact key, then break */
2538                         key_len = strlen( key );
2539                         if ( strlen(data->keys[i].name) == key_len )
2540                                 break;
2541
2542                         /* get subkey path */
2543
2544                         p = data->keys[i].name + key_len;
2545                         if ( *p == '\\' )
2546                                 p++;
2547                         fstrcpy( subkeyname, p );
2548                         if ( (p = strchr( subkeyname, '\\' )) )
2549                                 *p = '\0';
2550
2551                         /* don't add a key more than once */
2552
2553                         for ( j=0; j<num_subkeys; j++ ) {
2554                                 if ( strequal( subkeys_ptr[j], subkeyname ) )
2555                                         break;
2556                         }
2557
2558                         if ( j != num_subkeys )
2559                                 continue;
2560
2561                         /* found a match, so allocate space and copy the name */
2562
2563                         if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
2564                                 DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
2565                                         num_subkeys+1));
2566                                 return 0;
2567                         }
2568
2569                         fstrcpy( subkeys_ptr[num_subkeys], subkeyname );
2570                         num_subkeys++;
2571                 }
2572
2573         }
2574
2575         /* return error if the key was not found */
2576
2577         if ( i == data->num_keys ) {
2578                 SAFE_FREE(subkeys_ptr);
2579                 return -1;
2580         }
2581
2582 done:
2583         /* tag off the end */
2584
2585         if (num_subkeys)
2586                 fstrcpy(subkeys_ptr[num_subkeys], "" );
2587
2588         *subkeys = subkeys_ptr;
2589
2590         return num_subkeys;
2591 }
2592
2593 #ifdef HAVE_ADS
2594 static void map_sz_into_ctr(struct regval_ctr *ctr, const char *val_name,
2595                             const char *sz)
2596 {
2597         regval_ctr_delvalue(ctr, val_name);
2598         regval_ctr_addvalue_sz(ctr, val_name, sz);
2599 }
2600
2601 static void map_dword_into_ctr(struct regval_ctr *ctr, const char *val_name,
2602                                uint32 dword)
2603 {
2604         regval_ctr_delvalue(ctr, val_name);
2605         regval_ctr_addvalue(ctr, val_name, REG_DWORD,
2606                             (uint8 *) &dword, sizeof(dword));
2607 }
2608
2609 static void map_bool_into_ctr(struct regval_ctr *ctr, const char *val_name,
2610                               bool b)
2611 {
2612         uint8 bin_bool = (b ? 1 : 0);
2613         regval_ctr_delvalue(ctr, val_name);
2614         regval_ctr_addvalue(ctr, val_name, REG_BINARY,
2615                             (uint8 *) &bin_bool, sizeof(bin_bool));
2616 }
2617
2618 static void map_single_multi_sz_into_ctr(struct regval_ctr *ctr, const char *val_name,
2619                                          const char *multi_sz)
2620 {
2621         const char *a[2];
2622
2623         a[0] = multi_sz;
2624         a[1] = NULL;
2625
2626         regval_ctr_delvalue(ctr, val_name);
2627         regval_ctr_addvalue_multi_sz(ctr, val_name, a);
2628 }
2629
2630 /****************************************************************************
2631  * Map spoolss_PrinterInfo2 data into DsSpooler keys for publishing.
2632  *
2633  * @param mem_ctx  allocation context
2634  * @param info2    spoolss_PrinterInfo2 describing printer
2635  * @param pdata    the talloced printer data
2636  * @return bool    indicating success or failure
2637  ***************************************************************************/
2638
2639 static bool map_nt_printer_info2_to_dsspooler(TALLOC_CTX *mem_ctx,
2640                                               struct spoolss_PrinterInfo2 *info2,
2641                                               NT_PRINTER_DATA **pdata)
2642 {
2643         NT_PRINTER_DATA *data;
2644         struct regval_ctr *ctr = NULL;
2645         fstring longname;
2646         const char *dnssuffix;
2647         char *allocated_string = NULL;
2648         const char *ascii_str;
2649         int i;
2650
2651         data = talloc_zero(mem_ctx, NT_PRINTER_DATA);
2652         if (!data) return false;
2653
2654         /* init data */
2655         i = add_new_printer_key(data, SPOOL_DSSPOOLER_KEY);
2656         ctr = data->keys[i].values;
2657
2658         map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename);
2659         map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, global_myname());
2660
2661         /* we make the assumption that the netbios name is the same
2662            as the DNS name sinc ethe former will be what we used to
2663            join the domain */
2664
2665         dnssuffix = get_mydnsdomname(talloc_tos());
2666         if (dnssuffix && *dnssuffix) {
2667                 fstr_sprintf( longname, "%s.%s", global_myname(), dnssuffix );
2668         } else {
2669                 fstrcpy( longname, global_myname() );
2670         }
2671
2672         map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname);
2673
2674         if (asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename) == -1) {
2675                 talloc_free(data);
2676                 return false;
2677         }
2678         map_sz_into_ctr(ctr, SPOOL_REG_UNCNAME, allocated_string);
2679         SAFE_FREE(allocated_string);
2680
2681         map_dword_into_ctr(ctr, SPOOL_REG_VERSIONNUMBER, 4);
2682         map_sz_into_ctr(ctr, SPOOL_REG_DRIVERNAME, info2->drivername);
2683         map_sz_into_ctr(ctr, SPOOL_REG_LOCATION, info2->location);
2684         map_sz_into_ctr(ctr, SPOOL_REG_DESCRIPTION, info2->comment);
2685         map_single_multi_sz_into_ctr(ctr, SPOOL_REG_PORTNAME, info2->portname);
2686         map_sz_into_ctr(ctr, SPOOL_REG_PRINTSEPARATORFILE, info2->sepfile);
2687         map_dword_into_ctr(ctr, SPOOL_REG_PRINTSTARTTIME, info2->starttime);
2688         map_dword_into_ctr(ctr, SPOOL_REG_PRINTENDTIME, info2->untiltime);
2689         map_dword_into_ctr(ctr, SPOOL_REG_PRIORITY, info2->priority);
2690
2691         map_bool_into_ctr(ctr, SPOOL_REG_PRINTKEEPPRINTEDJOBS,
2692                           (info2->attributes &
2693                            PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
2694
2695         switch (info2->attributes & 0x3) {
2696         case 0:
2697                 ascii_str = SPOOL_REGVAL_PRINTWHILESPOOLING;
2698                 break;
2699         case 1:
2700                 ascii_str = SPOOL_REGVAL_PRINTAFTERSPOOLED;
2701                 break;
2702         case 2:
2703                 ascii_str = SPOOL_REGVAL_PRINTDIRECT;
2704                 break;
2705         default:
2706                 ascii_str = "unknown";
2707         }
2708         map_sz_into_ctr(ctr, SPOOL_REG_PRINTSPOOLING, ascii_str);
2709
2710         *pdata = data;
2711         return true;
2712 }
2713
2714 /*****************************************************************
2715  ****************************************************************/
2716
2717 static void store_printer_guid(const char *printer, struct GUID guid)
2718 {
2719         TALLOC_CTX *tmp_ctx;
2720         struct auth_serversupplied_info *server_info = NULL;
2721         const char *guid_str;
2722         DATA_BLOB blob;
2723         NTSTATUS status;
2724         WERROR result;
2725
2726         tmp_ctx = talloc_new(NULL);
2727         if (!tmp_ctx) {
2728                 DEBUG(0, ("store_printer_guid: Out of memory?!\n"));
2729                 return;
2730         }
2731
2732         status = make_server_info_system(tmp_ctx, &server_info);
2733         if (!NT_STATUS_IS_OK(status)) {
2734                 DEBUG(0, ("store_printer_guid: "
2735                           "Could not create system server_info\n"));
2736                 goto done;
2737         }
2738
2739         guid_str = GUID_string(tmp_ctx, &guid);
2740         if (!guid_str) {
2741                 DEBUG(0, ("store_printer_guid: Out of memory?!\n"));
2742                 goto done;
2743         }
2744
2745         /* We used to store this as a REG_BINARY but that causes
2746            Vista to whine */
2747
2748         if (!push_reg_sz(tmp_ctx, &blob, guid_str)) {
2749                 DEBUG(0, ("store_printer_guid: "
2750                           "Could not marshall string %s for objectGUID\n",
2751                           guid_str));
2752                 goto done;
2753         }
2754
2755         result = winreg_set_printer_dataex(tmp_ctx, server_info, printer,
2756                                            SPOOL_DSSPOOLER_KEY, "objectGUID",
2757                                            REG_SZ, blob.data, blob.length);
2758         if (!W_ERROR_IS_OK(result)) {
2759                 DEBUG(0, ("store_printer_guid: "
2760                           "Failed to store GUID for printer %s\n", printer));
2761         }
2762
2763 done:
2764         talloc_free(tmp_ctx);
2765 }
2766
2767 static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
2768                                      struct spoolss_PrinterInfo2 *pinfo2)
2769 {
2770         ADS_STATUS ads_rc;
2771         LDAPMessage *res;
2772         char *prt_dn = NULL, *srv_dn, *srv_cn_0, *srv_cn_escaped, *sharename_escaped;
2773         char *srv_dn_utf8, **srv_cn_utf8;
2774         TALLOC_CTX *ctx;
2775         ADS_MODLIST mods;
2776         const char *attrs[] = {"objectGUID", NULL};
2777         struct GUID guid;
2778         WERROR win_rc = WERR_OK;
2779         size_t converted_size;
2780         NT_PRINTER_DATA *pdata;
2781         const char *printer = pinfo2->sharename;
2782
2783         /* build the ads mods */
2784         ctx = talloc_init("nt_printer_publish_ads");
2785         if (ctx == NULL) {
2786                 return WERR_NOMEM;
2787         }
2788
2789         DEBUG(5, ("publishing printer %s\n", printer));
2790
2791         if (!map_nt_printer_info2_to_dsspooler(ctx, pinfo2, &pdata)) {
2792                 TALLOC_FREE(ctx);
2793                 return WERR_SERVER_UNAVAILABLE;
2794         }
2795
2796         /* figure out where to publish */
2797         ads_find_machine_acct(ads, &res, global_myname());
2798
2799         /* We use ldap_get_dn here as we need the answer
2800          * in utf8 to call ldap_explode_dn(). JRA. */
2801
2802         srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res);
2803         if (!srv_dn_utf8) {
2804                 TALLOC_FREE(ctx);
2805                 return WERR_SERVER_UNAVAILABLE;
2806         }
2807         ads_msgfree(ads, res);
2808         srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1);
2809         if (!srv_cn_utf8) {
2810                 TALLOC_FREE(ctx);
2811                 ldap_memfree(srv_dn_utf8);
2812                 return WERR_SERVER_UNAVAILABLE;
2813         }
2814         /* Now convert to CH_UNIX. */
2815         if (!pull_utf8_talloc(ctx, &srv_dn, srv_dn_utf8, &converted_size)) {
2816                 TALLOC_FREE(ctx);
2817                 ldap_memfree(srv_dn_utf8);
2818                 ldap_memfree(srv_cn_utf8);
2819                 return WERR_SERVER_UNAVAILABLE;
2820         }
2821         if (!pull_utf8_talloc(ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size)) {
2822                 TALLOC_FREE(ctx);
2823                 ldap_memfree(srv_dn_utf8);
2824                 ldap_memfree(srv_cn_utf8);
2825                 TALLOC_FREE(srv_dn);
2826                 return WERR_SERVER_UNAVAILABLE;
2827         }
2828
2829         ldap_memfree(srv_dn_utf8);
2830         ldap_memfree(srv_cn_utf8);
2831
2832         srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0);
2833         if (!srv_cn_escaped) {
2834                 TALLOC_FREE(ctx);
2835                 return WERR_SERVER_UNAVAILABLE;
2836         }
2837         sharename_escaped = escape_rdn_val_string_alloc(printer);
2838         if (!sharename_escaped) {
2839                 SAFE_FREE(srv_cn_escaped);
2840                 TALLOC_FREE(ctx);
2841                 return WERR_SERVER_UNAVAILABLE;
2842         }
2843
2844         prt_dn = talloc_asprintf(ctx, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn);
2845
2846         SAFE_FREE(srv_cn_escaped);
2847         SAFE_FREE(sharename_escaped);
2848
2849         mods = ads_init_mods(ctx);
2850
2851         if (mods == NULL) {
2852                 SAFE_FREE(prt_dn);
2853                 TALLOC_FREE(ctx);
2854                 return WERR_NOMEM;
2855         }
2856
2857         get_local_printer_publishing_data(ctx, &mods, pdata);
2858         ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME, printer);
2859
2860         /* publish it */
2861         ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
2862         if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT) {
2863                 int i;
2864                 for (i=0; mods[i] != 0; i++)
2865                         ;
2866                 mods[i] = (LDAPMod *)-1;
2867                 ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
2868         }
2869
2870         if (!ADS_ERR_OK(ads_rc)) {
2871                 DEBUG(3, ("error publishing %s: %s\n",
2872                           printer, ads_errstr(ads_rc)));
2873         }
2874
2875         /* retreive the guid and store it locally */
2876         if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
2877                 ZERO_STRUCT(guid);
2878                 ads_pull_guid(ads, res, &guid);
2879                 ads_msgfree(ads, res);
2880                 store_printer_guid(printer, guid);
2881         }
2882         TALLOC_FREE(ctx);
2883
2884         return win_rc;
2885 }
2886
2887 static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads,
2888                                        const char *printer)
2889 {
2890         ADS_STATUS ads_rc;
2891         LDAPMessage *res = NULL;
2892         char *prt_dn = NULL;
2893
2894         DEBUG(5, ("unpublishing printer %s\n", printer));
2895
2896         /* remove the printer from the directory */
2897         ads_rc = ads_find_printer_on_server(ads, &res,
2898                                             printer, global_myname());
2899
2900         if (ADS_ERR_OK(ads_rc) && res && ads_count_replies(ads, res)) {
2901                 prt_dn = ads_get_dn(ads, talloc_tos(), res);
2902                 if (!prt_dn) {
2903                         ads_msgfree(ads, res);
2904                         return WERR_NOMEM;
2905                 }
2906                 ads_rc = ads_del_dn(ads, prt_dn);
2907                 TALLOC_FREE(prt_dn);
2908         }
2909
2910         if (res) {
2911                 ads_msgfree(ads, res);
2912         }
2913         return WERR_OK;
2914 }
2915
2916 /****************************************************************************
2917  * Publish a printer in the directory
2918  *
2919  * @param mem_ctx      memory context
2920  * @param server_info  server_info to access winreg pipe
2921  * @param pinfo2       printer information
2922  * @param action       publish/unpublish action
2923  * @return WERROR indicating status of publishing
2924  ***************************************************************************/
2925
2926 WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
2927                           struct auth_serversupplied_info *server_info,
2928                           struct spoolss_PrinterInfo2 *pinfo2,
2929                           int action)
2930 {
2931         uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ATTRIBUTES;
2932         struct spoolss_SetPrinterInfo2 *sinfo2;
2933         ADS_STATUS ads_rc;
2934         ADS_STRUCT *ads = NULL;
2935         WERROR win_rc;
2936
2937         sinfo2 = talloc_zero(mem_ctx, struct spoolss_SetPrinterInfo2);
2938         if (!sinfo2) {
2939                 return WERR_NOMEM;
2940         }
2941
2942         switch (action) {
2943         case DSPRINT_PUBLISH:
2944         case DSPRINT_UPDATE:
2945                 pinfo2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
2946                 break;
2947         case DSPRINT_UNPUBLISH:
2948                 pinfo2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
2949                 break;
2950         default:
2951                 win_rc = WERR_NOT_SUPPORTED;
2952                 goto done;
2953         }
2954
2955         sinfo2->attributes = pinfo2->attributes;
2956
2957         win_rc = winreg_update_printer(mem_ctx, server_info,
2958                                         pinfo2->sharename, info2_mask,
2959                                         sinfo2, NULL, NULL);
2960         if (!W_ERROR_IS_OK(win_rc)) {
2961                 DEBUG(3, ("err %d saving data\n", W_ERROR_V(win_rc)));
2962                 goto done;
2963         }
2964
2965         TALLOC_FREE(sinfo2);
2966
2967         ads = ads_init(lp_realm(), lp_workgroup(), NULL);
2968         if (!ads) {
2969                 DEBUG(3, ("ads_init() failed\n"));
2970                 win_rc = WERR_SERVER_UNAVAILABLE;
2971                 goto done;
2972         }
2973         setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
2974         SAFE_FREE(ads->auth.password);
2975         ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
2976                 NULL, NULL);
2977
2978         /* ads_connect() will find the DC for us */
2979         ads_rc = ads_connect(ads);
2980         if (!ADS_ERR_OK(ads_rc)) {
2981                 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
2982                 win_rc = WERR_ACCESS_DENIED;
2983                 goto done;
2984         }
2985
2986         switch (action) {
2987         case DSPRINT_PUBLISH:
2988         case DSPRINT_UPDATE:
2989                 win_rc = nt_printer_publish_ads(ads, pinfo2);
2990                 break;
2991         case DSPRINT_UNPUBLISH:
2992                 win_rc = nt_printer_unpublish_ads(ads, pinfo2->sharename);
2993                 break;
2994         }
2995
2996 done:
2997         ads_destroy(&ads);
2998         return win_rc;
2999 }
3000
3001 WERROR check_published_printers(void)
3002 {
3003         ADS_STATUS ads_rc;
3004         ADS_STRUCT *ads = NULL;
3005         int snum;
3006         int n_services = lp_numservices();
3007         TALLOC_CTX *tmp_ctx = NULL;
3008         struct auth_serversupplied_info *server_info = NULL;
3009         struct spoolss_PrinterInfo2 *pinfo2;
3010         NTSTATUS status;
3011         WERROR result;
3012
3013         tmp_ctx = talloc_new(NULL);
3014         if (!tmp_ctx) return WERR_NOMEM;
3015
3016         ads = ads_init(lp_realm(), lp_workgroup(), NULL);
3017         if (!ads) {
3018                 DEBUG(3, ("ads_init() failed\n"));
3019                 return WERR_SERVER_UNAVAILABLE;
3020         }
3021         setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
3022         SAFE_FREE(ads->auth.password);
3023         ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
3024                 NULL, NULL);
3025
3026         /* ads_connect() will find the DC for us */
3027         ads_rc = ads_connect(ads);
3028         if (!ADS_ERR_OK(ads_rc)) {
3029                 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
3030                 result = WERR_ACCESS_DENIED;
3031                 goto done;
3032         }
3033
3034         status = make_server_info_system(tmp_ctx, &server_info);
3035         if (!NT_STATUS_IS_OK(status)) {
3036                 DEBUG(0, ("check_published_printers: "
3037                           "Could not create system server_info\n"));
3038                 result = WERR_ACCESS_DENIED;
3039                 goto done;
3040         }
3041
3042         for (snum = 0; snum < n_services; snum++) {
3043                 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
3044                         continue;
3045                 }
3046
3047                 result = winreg_get_printer(tmp_ctx, server_info, NULL,
3048                                             lp_servicename(snum), &pinfo2);
3049                 if (!W_ERROR_IS_OK(result)) {
3050                         continue;
3051                 }
3052
3053                 if (pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) {
3054                         nt_printer_publish_ads(ads, pinfo2);
3055                 }
3056
3057                 TALLOC_FREE(pinfo2);
3058         }
3059
3060         result = WERR_OK;
3061 done:
3062         ads_destroy(&ads);
3063         ads_kdestroy("MEMORY:prtpub_cache");
3064         talloc_free(tmp_ctx);
3065         return result;
3066 }
3067
3068 bool is_printer_published(TALLOC_CTX *mem_ctx,
3069                           struct auth_serversupplied_info *server_info,
3070                           char *servername, char *printer, struct GUID *guid,
3071                           struct spoolss_PrinterInfo2 **info2)
3072 {
3073         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3074         enum winreg_Type type;
3075         uint8_t *data;
3076         uint32_t data_size;
3077         WERROR result;
3078         NTSTATUS status;
3079
3080         result = winreg_get_printer(mem_ctx, server_info,
3081                                     servername, printer, &pinfo2);
3082         if (!W_ERROR_IS_OK(result)) {
3083                 return false;
3084         }
3085
3086         if (!(pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED)) {
3087                 TALLOC_FREE(pinfo2);
3088                 return false;
3089         }
3090
3091         if (!guid) {
3092                 goto done;
3093         }
3094
3095         /* fetching printer guids really ought to be a separate function. */
3096
3097         result = winreg_get_printer_dataex(mem_ctx, server_info, printer,
3098                                            SPOOL_DSSPOOLER_KEY, "objectGUID",
3099                                            &type, &data, &data_size);
3100         if (!W_ERROR_IS_OK(result)) {
3101                 TALLOC_FREE(pinfo2);
3102                 return false;
3103         }
3104
3105         /* We used to store the guid as REG_BINARY, then swapped
3106            to REG_SZ for Vista compatibility so check for both */
3107
3108         switch (type) {
3109         case REG_SZ:
3110                 status = GUID_from_string((char *)data, guid);
3111                 if (!NT_STATUS_IS_OK(status)) {
3112                         TALLOC_FREE(pinfo2);
3113                         return false;
3114                 }
3115                 break;
3116
3117         case REG_BINARY:
3118                 if (data_size != sizeof(struct GUID)) {
3119                         TALLOC_FREE(pinfo2);
3120                         return false;
3121                 }
3122                 memcpy(guid, data, sizeof(struct GUID));
3123                 break;
3124         default:
3125                 DEBUG(0,("is_printer_published: GUID value stored as "
3126                          "invaluid type (%d)\n", type));
3127                 break;
3128         }
3129
3130 done:
3131         if (info2) {
3132                 *info2 = talloc_move(mem_ctx, &pinfo2);
3133         }
3134         talloc_free(pinfo2);
3135         return true;
3136 }
3137 #else
3138 WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
3139                           struct auth_serversupplied_info *server_info,
3140                           struct spoolss_PrinterInfo2 *pinfo2,
3141                           int action)
3142 {
3143         return WERR_OK;
3144 }
3145
3146 WERROR check_published_printers(void)
3147 {
3148         return WERR_OK;
3149 }
3150
3151 bool is_printer_published(TALLOC_CTX *mem_ctx,
3152                           struct auth_serversupplied_info *server_info,
3153                           char *servername, char *printer, struct GUID *guid,
3154                           struct spoolss_PrinterInfo2 **info2)
3155 {
3156         return False;
3157 }
3158 #endif /* HAVE_ADS */
3159
3160 /****************************************************************************
3161  ***************************************************************************/
3162
3163 WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
3164 {
3165         NT_PRINTER_DATA *data;
3166         int             i;
3167         int             removed_keys = 0;
3168         int             empty_slot;
3169
3170         data = p2->data;
3171         empty_slot = data->num_keys;
3172
3173         if ( !key )
3174                 return WERR_INVALID_PARAM;
3175
3176         /* remove all keys */
3177
3178         if ( !strlen(key) ) {
3179
3180                 TALLOC_FREE( data );
3181
3182                 p2->data = NULL;
3183
3184                 DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n",
3185                         p2->printername ));
3186
3187                 return WERR_OK;
3188         }
3189
3190         /* remove a specific key (and all subkeys) */
3191
3192         for ( i=0; i<data->num_keys; i++ ) {
3193                 if ( StrnCaseCmp( data->keys[i].name, key, strlen(key)) == 0 ) {
3194                         DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n",
3195                                 data->keys[i].name));
3196
3197                         TALLOC_FREE( data->keys[i].name );
3198                         TALLOC_FREE( data->keys[i].values );
3199
3200                         /* mark the slot as empty */
3201
3202                         ZERO_STRUCTP( &data->keys[i] );
3203                 }
3204         }
3205
3206         /* find the first empty slot */
3207
3208         for ( i=0; i<data->num_keys; i++ ) {
3209                 if ( !data->keys[i].name ) {
3210                         empty_slot = i;
3211                         removed_keys++;
3212                         break;
3213                 }
3214         }
3215
3216         if ( i == data->num_keys )
3217                 /* nothing was removed */
3218                 return WERR_INVALID_PARAM;
3219
3220         /* move everything down */
3221
3222         for ( i=empty_slot+1; i<data->num_keys; i++ ) {
3223                 if ( data->keys[i].name ) {
3224                         memcpy( &data->keys[empty_slot], &data->keys[i], sizeof(NT_PRINTER_KEY) );
3225                         ZERO_STRUCTP( &data->keys[i] );
3226                         empty_slot++;
3227                         removed_keys++;
3228                 }
3229         }
3230
3231         /* update count */
3232
3233         data->num_keys -= removed_keys;
3234
3235         /* sanity check to see if anything is left */
3236
3237         if ( !data->num_keys ) {
3238                 DEBUG(8,("delete_all_printer_data: No keys left for printer [%s]\n", p2->printername ));
3239
3240                 SAFE_FREE( data->keys );
3241                 ZERO_STRUCTP( data );
3242         }
3243
3244         return WERR_OK;
3245 }
3246
3247 /****************************************************************************
3248  ***************************************************************************/
3249
3250 WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
3251 {
3252         WERROR          result = WERR_OK;
3253         int             key_index;
3254
3255         /* we must have names on non-zero length */
3256
3257         if ( !key || !*key|| !value || !*value )
3258                 return WERR_INVALID_NAME;
3259
3260         /* find the printer key first */
3261
3262         key_index = lookup_printerkey( p2->data, key );
3263         if ( key_index == -1 )
3264                 return WERR_OK;
3265
3266         /* make sure the value exists so we can return the correct error code */
3267
3268         if ( !regval_ctr_getvalue( p2->data->keys[key_index].values, value ) )
3269                 return WERR_BADFILE;
3270
3271         regval_ctr_delvalue( p2->data->keys[key_index].values, value );
3272
3273         DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n",
3274                 key, value ));
3275
3276         return result;
3277 }
3278
3279 /****************************************************************************
3280  ***************************************************************************/
3281
3282 WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value,
3283                            uint32 type, uint8 *data, int real_len )
3284 {
3285         WERROR          result = WERR_OK;
3286         int             key_index;
3287
3288         /* we must have names on non-zero length */
3289
3290         if ( !key || !*key|| !value || !*value )
3291                 return WERR_INVALID_NAME;
3292
3293         /* find the printer key first */
3294
3295         key_index = lookup_printerkey( p2->data, key );
3296         if ( key_index == -1 )
3297                 key_index = add_new_printer_key( p2->data, key );
3298
3299         if ( key_index == -1 )
3300                 return WERR_NOMEM;
3301
3302         regval_ctr_addvalue( p2->data->keys[key_index].values, value,
3303                 type, data, real_len );
3304
3305         DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n",
3306                 key, value, type, real_len  ));
3307
3308         return result;
3309 }
3310
3311 /****************************************************************************
3312  ***************************************************************************/
3313
3314 struct regval_blob* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
3315 {
3316         int             key_index;
3317
3318         if ( (key_index = lookup_printerkey( p2->data, key )) == -1 )
3319                 return NULL;
3320
3321         DEBUG(8,("get_printer_data: Attempting to lookup key => [%s], value => [%s]\n",
3322                 key, value ));
3323
3324         return regval_ctr_getvalue( p2->data->keys[key_index].values, value );
3325 }
3326
3327 /****************************************************************************
3328  ***************************************************************************/
3329
3330 static char *win_driver;
3331 static char *os2_driver;
3332
3333 static const char *get_win_driver(void)
3334 {
3335         if (win_driver == NULL) {
3336                 return "";
3337         }
3338         return win_driver;
3339 }
3340
3341 static const char *get_os2_driver(void)
3342 {
3343         if (os2_driver == NULL) {
3344                 return "";
3345         }
3346         return os2_driver;
3347 }
3348
3349 static bool set_driver_mapping(const char *from, const char *to)
3350 {
3351         SAFE_FREE(win_driver);
3352         SAFE_FREE(os2_driver);
3353
3354         win_driver = SMB_STRDUP(from);
3355         os2_driver = SMB_STRDUP(to);
3356
3357         if (win_driver == NULL || os2_driver == NULL) {
3358                 SAFE_FREE(win_driver);
3359                 SAFE_FREE(os2_driver);
3360                 return false;
3361         }
3362         return true;
3363 }
3364
3365 /**
3366  * @internal
3367  *
3368  * @brief Map a Windows driver to a OS/2 driver.
3369  *
3370  * @param[in]  mem_ctx  The memory context to use.
3371  *
3372  * @param[in,out] pdrivername The drivername of Windows to remap.
3373  *
3374  * @return              WERR_OK on success, a corresponding WERROR on failure.
3375  */
3376 WERROR spoolss_map_to_os2_driver(TALLOC_CTX *mem_ctx, const char **pdrivername)
3377 {
3378         const char *mapfile = lp_os2_driver_map();
3379         char **lines = NULL;
3380         const char *drivername;
3381         int numlines = 0;
3382         int i;
3383
3384         if (pdrivername == NULL || *pdrivername == NULL || *pdrivername[0] == '\0') {
3385                 return WERR_INVALID_PARAMETER;
3386         }
3387
3388         drivername = *pdrivername;
3389
3390         if (mapfile[0] == '\0') {
3391                 return WERR_BADFILE;
3392         }
3393
3394         if (strequal(drivername, get_win_driver())) {
3395                 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",
3396                         drivername, get_os2_driver()));
3397                 drivername = talloc_strdup(mem_ctx, get_os2_driver());
3398                 if (drivername == NULL) {
3399                         return WERR_NOMEM;
3400                 }
3401                 *pdrivername = drivername;
3402                 return WERR_OK;
3403         }
3404
3405         lines = file_lines_load(mapfile, &numlines, 0, NULL);
3406         if (numlines == 0 || lines == NULL) {
3407                 DEBUG(0,("No entries in OS/2 driver map %s\n", mapfile));
3408                 TALLOC_FREE(lines);
3409                 return WERR_EMPTY;
3410         }
3411
3412         DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
3413
3414         for( i = 0; i < numlines; i++) {
3415                 char *nt_name = lines[i];
3416                 char *os2_name = strchr(nt_name, '=');
3417
3418                 if (os2_name == NULL) {
3419                         continue;
3420                 }
3421
3422                 *os2_name++ = '\0';
3423
3424                 while (isspace(*nt_name)) {
3425                         nt_name++;
3426                 }
3427
3428                 if (*nt_name == '\0' || strchr("#;", *nt_name)) {
3429                         continue;
3430                 }
3431
3432                 {
3433                         int l = strlen(nt_name);
3434                         while (l && isspace(nt_name[l - 1])) {
3435                                 nt_name[l - 1] = 0;
3436                                 l--;
3437                         }
3438                 }
3439
3440                 while (isspace(*os2_name)) {
3441                         os2_name++;
3442                 }
3443
3444                 {
3445                         int l = strlen(os2_name);
3446                         while (l && isspace(os2_name[l-1])) {
3447                                 os2_name[l-1] = 0;
3448                                 l--;
3449                         }
3450                 }
3451
3452                 if (strequal(nt_name, drivername)) {
3453                         DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,os2_name));
3454                         set_driver_mapping(drivername, os2_name);
3455                         drivername = talloc_strdup(mem_ctx, os2_name);
3456                         TALLOC_FREE(lines);
3457                         if (drivername == NULL) {
3458                                 return WERR_NOMEM;
3459                         }
3460                         *pdrivername = drivername;
3461                         return WERR_OK;
3462                 }
3463         }
3464
3465         TALLOC_FREE(lines);
3466         return WERR_OK;
3467 }
3468
3469 /****************************************************************************
3470  Debugging function, dump at level 6 the struct in the logs.
3471 ****************************************************************************/
3472 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
3473 {
3474         uint32 result;
3475         NT_PRINTER_INFO_LEVEL_2 *info2;
3476
3477         DEBUG(106,("Dumping printer at level [%d]\n", level));
3478
3479         switch (level) {
3480                 case 2:
3481                 {
3482                         if (printer->info_2 == NULL)
3483                                 result=5;
3484                         else
3485                         {
3486                                 info2=printer->info_2;
3487
3488                                 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
3489                                 DEBUGADD(106,("priority:[%d]\n", info2->priority));
3490                                 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
3491                                 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
3492                                 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
3493                                 DEBUGADD(106,("status:[%d]\n", info2->status));
3494                                 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
3495                                 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
3496                                 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
3497                                 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
3498                                 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
3499
3500                                 DEBUGADD(106,("servername:[%s]\n", info2->servername));
3501                                 DEBUGADD(106,("printername:[%s]\n", info2->printername));
3502                                 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
3503                                 DEBUGADD(106,("portname:[%s]\n", info2->portname));
3504                                 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
3505                                 DEBUGADD(106,("comment:[%s]\n", info2->comment));
3506                                 DEBUGADD(106,("location:[%s]\n", info2->location));
3507                                 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
3508                                 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
3509                                 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
3510                                 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
3511                                 result=0;
3512                         }
3513                         break;
3514                 }
3515                 default:
3516                         DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level ));
3517                         result=1;
3518                         break;
3519         }
3520
3521         return result;
3522 }
3523
3524 /****************************************************************************
3525  Update the changeid time.
3526  This is SO NASTY as some drivers need this to change, others need it
3527  static. This value will change every second, and I must hope that this
3528  is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
3529  UTAH ! JRA.
3530 ****************************************************************************/
3531
3532 static uint32 rev_changeid(void)
3533 {
3534         struct timeval tv;
3535
3536         get_process_uptime(&tv);
3537
3538 #if 1   /* JERRY */
3539         /* Return changeid as msec since spooler restart */
3540         return tv.tv_sec * 1000 + tv.tv_usec / 1000;
3541 #else
3542         /*
3543          * This setting seems to work well but is too untested
3544          * to replace the above calculation.  Left in for experiementation
3545          * of the reader            --jerry (Tue Mar 12 09:15:05 CST 2002)
3546          */
3547         return tv.tv_sec * 10 + tv.tv_usec / 100000;
3548 #endif
3549 }
3550
3551
3552 /*
3553  * The function below are the high level ones.
3554  * only those ones must be called from the spoolss code.
3555  * JFM.
3556  */
3557
3558 /****************************************************************************
3559  Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
3560 ****************************************************************************/
3561
3562 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
3563 {
3564         WERROR result;
3565
3566         dump_a_printer(printer, level);
3567
3568         switch (level) {
3569                 case 2:
3570                 {
3571                         /*
3572                          * Update the changestamp.  Emperical tests show that the
3573                          * ChangeID is always updated,but c_setprinter is
3574                          *  global spooler variable (not per printer).
3575                          */
3576
3577                         /* ChangeID **must** be increasing over the lifetime
3578                            of client's spoolss service in order for the
3579                            client's cache to show updates */
3580
3581                         printer->info_2->changeid = rev_changeid();
3582
3583                         /*
3584                          * Because one day someone will ask:
3585                          * NT->NT       An admin connection to a remote
3586                          *              printer show changes imeediately in
3587                          *              the properities dialog
3588                          *
3589                          *              A non-admin connection will only show the
3590                          *              changes after viewing the properites page
3591                          *              2 times.  Seems to be related to a
3592                          *              race condition in the client between the spooler
3593                          *              updating the local cache and the Explorer.exe GUI
3594                          *              actually displaying the properties.
3595                          *
3596                          *              This is fixed in Win2k.  admin/non-admin
3597                          *              connections both display changes immediately.
3598                          *
3599                          * 14/12/01     --jerry
3600                          */
3601
3602                         result=update_a_printer_2(printer->info_2);
3603                         break;
3604                 }
3605                 default:
3606                         result=WERR_UNKNOWN_LEVEL;
3607                         break;
3608         }
3609
3610         return result;
3611 }
3612
3613 /****************************************************************************
3614  Deletes a NT_PRINTER_INFO_LEVEL struct.
3615 ****************************************************************************/
3616
3617 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
3618 {
3619         NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
3620
3621         if ( !printer )
3622                 return 0;
3623
3624         switch (level) {
3625                 case 2:
3626                         TALLOC_FREE(printer->info_2);
3627                         break;
3628
3629                 default:
3630                         DEBUG(0,("free_a_printer: unknown level! [%d]\n", level ));
3631                         return 1;
3632         }
3633
3634         TALLOC_FREE(*pp_printer);
3635
3636         return 0;
3637 }
3638
3639 /****************************************************************************
3640 ****************************************************************************/
3641
3642 bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
3643                               struct spoolss_DriverInfo8 *_info8)
3644 {
3645         struct spoolss_DriverInfo8 info8;
3646
3647         ZERO_STRUCT(info8);
3648
3649         switch (r->level) {
3650         case 3:
3651                 info8.version           = r->info.info3->version;
3652                 info8.driver_name       = r->info.info3->driver_name;
3653                 info8.architecture      = r->info.info3->architecture;
3654                 info8.driver_path       = r->info.info3->driver_path;
3655                 info8.data_file         = r->info.info3->data_file;
3656                 info8.config_file       = r->info.info3->config_file;
3657                 info8.help_file         = r->info.info3->help_file;
3658                 info8.monitor_name      = r->info.info3->monitor_name;
3659                 info8.default_datatype  = r->info.info3->default_datatype;
3660                 if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) {
3661                         info8.dependent_files   = r->info.info3->dependent_files->string;
3662                 }
3663                 break;
3664         case 6:
3665                 info8.version           = r->info.info6->version;
3666                 info8.driver_name       = r->info.info6->driver_name;
3667                 info8.architecture      = r->info.info6->architecture;
3668                 info8.driver_path       = r->info.info6->driver_path;
3669                 info8.data_file         = r->info.info6->data_file;
3670                 info8.config_file       = r->info.info6->config_file;
3671                 info8.help_file         = r->info.info6->help_file;
3672                 info8.monitor_name      = r->info.info6->monitor_name;
3673                 info8.default_datatype  = r->info.info6->default_datatype;
3674                 if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) {
3675                         info8.dependent_files   = r->info.info6->dependent_files->string;
3676                 }
3677                 info8.driver_date       = r->info.info6->driver_date;
3678                 info8.driver_version    = r->info.info6->driver_version;
3679                 info8.manufacturer_name = r->info.info6->manufacturer_name;
3680                 info8.manufacturer_url  = r->info.info6->manufacturer_url;
3681                 info8.hardware_id       = r->info.info6->hardware_id;
3682                 info8.provider          = r->info.info6->provider;
3683                 break;
3684         case 8:
3685                 info8.version           = r->info.info8->version;
3686                 info8.driver_name       = r->info.info8->driver_name;
3687                 info8.architecture      = r->info.info8->architecture;
3688                 info8.driver_path       = r->info.info8->driver_path;
3689                 info8.data_file         = r->info.info8->data_file;
3690                 info8.config_file       = r->info.info8->config_file;
3691                 info8.help_file         = r->info.info8->help_file;
3692                 info8.monitor_name      = r->info.info8->monitor_name;
3693                 info8.default_datatype  = r->info.info8->default_datatype;
3694                 if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) {
3695                         info8.dependent_files   = r->info.info8->dependent_files->string;
3696                 }
3697                 if (r->info.info8->previous_names && r->info.info8->previous_names->string) {
3698                         info8.previous_names    = r->info.info8->previous_names->string;
3699                 }
3700                 info8.driver_date       = r->info.info8->driver_date;
3701                 info8.driver_version    = r->info.info8->driver_version;
3702                 info8.manufacturer_name = r->info.info8->manufacturer_name;
3703                 info8.manufacturer_url  = r->info.info8->manufacturer_url;
3704                 info8.hardware_id       = r->info.info8->hardware_id;
3705                 info8.provider          = r->info.info8->provider;
3706                 info8.print_processor   = r->info.info8->print_processor;
3707                 info8.vendor_setup      = r->info.info8->vendor_setup;
3708                 if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) {
3709                         info8.color_profiles = r->info.info8->color_profiles->string;
3710                 }
3711                 info8.inf_path          = r->info.info8->inf_path;
3712                 info8.printer_driver_attributes = r->info.info8->printer_driver_attributes;
3713                 if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) {
3714                         info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string;
3715                 }
3716                 info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date;
3717                 info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version;
3718                 break;
3719         default:
3720                 return false;
3721         }
3722
3723         *_info8 = info8;
3724
3725         return true;
3726 }
3727
3728
3729 /****************************************************************************
3730   Determine whether or not a particular driver is currently assigned
3731   to a printer
3732 ****************************************************************************/
3733
3734 bool printer_driver_in_use(TALLOC_CTX *mem_ctx,
3735                            struct auth_serversupplied_info *server_info,
3736                            const struct spoolss_DriverInfo8 *r)
3737 {
3738         int snum;
3739         int n_services = lp_numservices();
3740         bool in_use = False;
3741         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3742         WERROR result;
3743
3744         if (!r) {
3745                 return false;
3746         }
3747
3748         DEBUG(10,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n"));
3749
3750         /* loop through the printers.tdb and check for the drivername */
3751
3752         for (snum=0; snum<n_services && !in_use; snum++) {
3753                 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
3754                         continue;
3755                 }
3756
3757                 result = winreg_get_printer(mem_ctx, server_info, NULL,
3758                                             lp_servicename(snum), &pinfo2);
3759                 if (!W_ERROR_IS_OK(result)) {
3760                         continue; /* skip */
3761                 }
3762
3763                 if (strequal(r->driver_name, pinfo2->drivername)) {
3764                         in_use = True;
3765                 }
3766
3767                 TALLOC_FREE(pinfo2);
3768         }
3769
3770         DEBUG(10,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
3771
3772         if ( in_use ) {
3773                 struct spoolss_DriverInfo8 *driver;
3774                 WERROR werr;
3775
3776                 DEBUG(5,("printer_driver_in_use: driver \"%s\" is currently in use\n", r->driver_name));
3777
3778                 /* we can still remove the driver if there is one of
3779                    "Windows NT x86" version 2 or 3 left */
3780
3781                 if (!strequal("Windows NT x86", r->architecture)) {
3782                         werr = winreg_get_driver(mem_ctx, server_info,
3783                                                  "Windows NT x86",
3784                                                  r->driver_name,
3785                                                  DRIVER_ANY_VERSION,
3786                                                  &driver);
3787                 } else if (r->version == 2) {
3788                         werr = winreg_get_driver(mem_ctx, server_info,
3789                                                  "Windows NT x86",
3790                                                  r->driver_name,
3791                                                  3, &driver);
3792                 } else if (r->version == 3) {
3793                         werr = winreg_get_driver(mem_ctx, server_info,
3794                                                  "Windows NT x86",
3795                                                  r->driver_name,
3796                                                  2, &driver);
3797                 } else {
3798                         DEBUG(0, ("printer_driver_in_use: ERROR!"
3799                                   " unknown driver version (%d)\n",
3800                                   r->version));
3801                         werr = WERR_UNKNOWN_PRINTER_DRIVER;
3802                 }
3803
3804                 /* now check the error code */
3805
3806                 if ( W_ERROR_IS_OK(werr) ) {
3807                         /* it's ok to remove the driver, we have other architctures left */
3808                         in_use = False;
3809                         talloc_free(driver);
3810                 }
3811         }
3812
3813         /* report that the driver is not in use by default */
3814
3815         return in_use;
3816 }
3817
3818
3819 /**********************************************************************
3820  Check to see if a ogiven file is in use by *info
3821  *********************************************************************/
3822
3823 static bool drv_file_in_use(const char *file, const struct spoolss_DriverInfo8 *info)
3824 {
3825         int i = 0;
3826
3827         if ( !info )
3828                 return False;
3829
3830         /* mz: skip files that are in the list but already deleted */
3831         if (!file || !file[0]) {
3832                 return false;
3833         }
3834
3835         if (strequal(file, info->driver_path))
3836                 return True;
3837
3838         if (strequal(file, info->data_file))
3839                 return True;
3840
3841         if (strequal(file, info->config_file))
3842                 return True;
3843
3844         if (strequal(file, info->help_file))
3845                 return True;
3846
3847         /* see of there are any dependent files to examine */
3848
3849         if (!info->dependent_files)
3850                 return False;
3851
3852         while (info->dependent_files[i] && *info->dependent_files[i]) {
3853                 if (strequal(file, info->dependent_files[i]))
3854                         return True;
3855                 i++;
3856         }
3857
3858         return False;
3859
3860 }
3861
3862 /**********************************************************************
3863  Utility function to remove the dependent file pointed to by the
3864  input parameter from the list
3865  *********************************************************************/
3866
3867 static void trim_dependent_file(TALLOC_CTX *mem_ctx, const char **files, int idx)
3868 {
3869
3870         /* bump everything down a slot */
3871
3872         while (files && files[idx+1]) {
3873                 files[idx] = talloc_strdup(mem_ctx, files[idx+1]);
3874                 idx++;
3875         }
3876
3877         files[idx] = NULL;
3878
3879         return;
3880 }
3881
3882 /**********************************************************************
3883  Check if any of the files used by src are also used by drv
3884  *********************************************************************/
3885
3886 static bool trim_overlap_drv_files(TALLOC_CTX *mem_ctx,
3887                                    struct spoolss_DriverInfo8 *src,
3888                                    const struct spoolss_DriverInfo8 *drv)
3889 {
3890         bool    in_use = False;
3891         int     i = 0;
3892
3893         if ( !src || !drv )
3894                 return False;
3895
3896         /* check each file.  Remove it from the src structure if it overlaps */
3897
3898         if (drv_file_in_use(src->driver_path, drv)) {
3899                 in_use = True;
3900                 DEBUG(10,("Removing driverfile [%s] from list\n", src->driver_path));
3901                 src->driver_path = talloc_strdup(mem_ctx, "");
3902                 if (!src->driver_path) { return false; }
3903         }
3904
3905         if (drv_file_in_use(src->data_file, drv)) {
3906                 in_use = True;
3907                 DEBUG(10,("Removing datafile [%s] from list\n", src->data_file));
3908                 src->data_file = talloc_strdup(mem_ctx, "");
3909                 if (!src->data_file) { return false; }
3910         }
3911
3912         if (drv_file_in_use(src->config_file, drv)) {
3913                 in_use = True;
3914                 DEBUG(10,("Removing configfile [%s] from list\n", src->config_file));
3915                 src->config_file = talloc_strdup(mem_ctx, "");
3916                 if (!src->config_file) { return false; }
3917         }
3918
3919         if (drv_file_in_use(src->help_file, drv)) {
3920                 in_use = True;
3921                 DEBUG(10,("Removing helpfile [%s] from list\n", src->help_file));
3922                 src->help_file = talloc_strdup(mem_ctx, "");
3923                 if (!src->help_file) { return false; }
3924         }
3925
3926         /* are there any dependentfiles to examine? */
3927
3928         if (!src->dependent_files)
3929                 return in_use;
3930
3931         while (src->dependent_files[i] && *src->dependent_files[i]) {
3932                 if (drv_file_in_use(src->dependent_files[i], drv)) {
3933                         in_use = True;
3934                         DEBUG(10,("Removing [%s] from dependent file list\n", src->dependent_files[i]));
3935                         trim_dependent_file(mem_ctx, src->dependent_files, i);
3936                 } else
3937                         i++;
3938         }
3939
3940         return in_use;
3941 }
3942
3943 /****************************************************************************
3944   Determine whether or not a particular driver files are currently being
3945   used by any other driver.
3946
3947   Return value is True if any files were in use by other drivers
3948   and False otherwise.
3949
3950   Upon return, *info has been modified to only contain the driver files
3951   which are not in use
3952
3953   Fix from mz:
3954
3955   This needs to check all drivers to ensure that all files in use
3956   have been removed from *info, not just the ones in the first
3957   match.
3958 ****************************************************************************/
3959
3960 bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx,
3961                                  struct auth_serversupplied_info *server_info,
3962                                  struct spoolss_DriverInfo8 *info)
3963 {
3964         int                             i;
3965         uint32                          version;
3966         struct spoolss_DriverInfo8      *driver;
3967         bool in_use = false;
3968         uint32_t num_drivers;
3969         const char **drivers;
3970         WERROR result;
3971
3972         if ( !info )
3973                 return False;
3974
3975         version = info->version;
3976
3977         /* loop over all driver versions */
3978
3979         DEBUG(5,("printer_driver_files_in_use: Beginning search of drivers...\n"));
3980
3981         /* get the list of drivers */
3982
3983         result = winreg_get_driver_list(mem_ctx, server_info,
3984                                         info->architecture, version,
3985                                         &num_drivers, &drivers);
3986         if (!W_ERROR_IS_OK(result)) {
3987                 return true;
3988         }
3989
3990         DEBUGADD(4, ("we have:[%d] drivers in environment [%s] and version [%d]\n",
3991                      num_drivers, info->architecture, version));
3992
3993         /* check each driver for overlap in files */
3994
3995         for (i = 0; i < num_drivers; i++) {
3996                 DEBUGADD(5,("\tdriver: [%s]\n", drivers[i]));
3997
3998                 driver = NULL;
3999
4000                 result = winreg_get_driver(mem_ctx, server_info,
4001                                            info->architecture, drivers[i],
4002                                            version, &driver);
4003                 if (!W_ERROR_IS_OK(result)) {
4004                         talloc_free(drivers);
4005                         return True;
4006                 }
4007
4008                 /* check if d2 uses any files from d1 */
4009                 /* only if this is a different driver than the one being deleted */
4010
4011                 if (!strequal(info->driver_name, driver->driver_name)) {
4012                         if (trim_overlap_drv_files(mem_ctx, info, driver)) {
4013                                 /* mz: Do not instantly return -
4014                                  * we need to ensure this file isn't
4015                                  * also in use by other drivers. */
4016                                 in_use = true;
4017                         }
4018                 }
4019
4020                 talloc_free(driver);
4021         }
4022
4023         talloc_free(drivers);
4024
4025         DEBUG(5,("printer_driver_files_in_use: Completed search of drivers...\n"));
4026
4027         return in_use;
4028 }
4029
4030 static NTSTATUS driver_unlink_internals(connection_struct *conn,
4031                                         const char *name)
4032 {
4033         struct smb_filename *smb_fname = NULL;
4034         NTSTATUS status;
4035
4036         status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
4037             &smb_fname);
4038         if (!NT_STATUS_IS_OK(status)) {
4039                 return status;
4040         }
4041
4042         status = unlink_internals(conn, NULL, 0, smb_fname, false);
4043
4044         TALLOC_FREE(smb_fname);
4045         return status;
4046 }
4047
4048 /****************************************************************************
4049   Actually delete the driver files.  Make sure that
4050   printer_driver_files_in_use() return False before calling
4051   this.
4052 ****************************************************************************/
4053
4054 bool delete_driver_files(struct auth_serversupplied_info *server_info,
4055                          const struct spoolss_DriverInfo8 *r)
4056 {
4057         int i = 0;
4058         char *s;
4059         const char *file;
4060         connection_struct *conn;
4061         NTSTATUS nt_status;
4062         char *oldcwd;
4063         fstring printdollar;
4064         int printdollar_snum;
4065         bool ret = false;
4066
4067         if (!r) {
4068                 return false;
4069         }
4070
4071         DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n",
4072                 r->driver_name, r->version));
4073
4074         fstrcpy(printdollar, "print$");
4075
4076         printdollar_snum = find_service(printdollar);
4077         if (printdollar_snum == -1) {
4078                 return false;
4079         }
4080
4081         nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
4082                                        lp_pathname(printdollar_snum),
4083                                        server_info, &oldcwd);
4084         if (!NT_STATUS_IS_OK(nt_status)) {
4085                 DEBUG(0,("delete_driver_files: create_conn_struct "
4086                          "returned %s\n", nt_errstr(nt_status)));
4087                 return false;
4088         }
4089
4090         if ( !CAN_WRITE(conn) ) {
4091                 DEBUG(3,("delete_driver_files: Cannot delete print driver when [print$] is read-only\n"));
4092                 goto fail;
4093         }
4094
4095         /* now delete the files; must strip the '\print$' string from
4096            fron of path                                                */
4097
4098         if (r->driver_path && r->driver_path[0]) {
4099                 if ((s = strchr(&r->driver_path[1], '\\')) != NULL) {
4100                         file = s;
4101                         DEBUG(10,("deleting driverfile [%s]\n", s));
4102                         driver_unlink_internals(conn, file);
4103                 }
4104         }
4105
4106         if (r->config_file && r->config_file[0]) {
4107                 if ((s = strchr(&r->config_file[1], '\\')) != NULL) {
4108                         file = s;
4109                         DEBUG(10,("deleting configfile [%s]\n", s));
4110                         driver_unlink_internals(conn, file);
4111                 }
4112         }
4113
4114         if (r->data_file && r->data_file[0]) {
4115                 if ((s = strchr(&r->data_file[1], '\\')) != NULL) {
4116                         file = s;
4117                         DEBUG(10,("deleting datafile [%s]\n", s));
4118                         driver_unlink_internals(conn, file);
4119                 }
4120         }
4121
4122         if (r->help_file && r->help_file[0]) {
4123                 if ((s = strchr(&r->help_file[1], '\\')) != NULL) {
4124                         file = s;
4125                         DEBUG(10,("deleting helpfile [%s]\n", s));
4126                         driver_unlink_internals(conn, file);
4127                 }
4128         }
4129
4130         /* check if we are done removing files */
4131
4132         if (r->dependent_files) {
4133                 while (r->dependent_files[i] && r->dependent_files[i][0]) {
4134                         char *p;
4135
4136                         /* bypass the "\print$" portion of the path */
4137
4138                         if ((p = strchr(r->dependent_files[i]+1, '\\')) != NULL) {
4139                                 file = p;
4140                                 DEBUG(10,("deleting dependent file [%s]\n", file));
4141                                 driver_unlink_internals(conn, file);
4142                         }
4143
4144                         i++;
4145                 }
4146         }
4147
4148         goto done;
4149  fail:
4150         ret = false;
4151  done:
4152         if (conn != NULL) {
4153                 vfs_ChDir(conn, oldcwd);
4154                 conn_free(conn);
4155         }
4156         return ret;
4157 }
4158
4159 /****************************************************************************
4160  Store a security desc for a printer.
4161 ****************************************************************************/
4162
4163 WERROR nt_printing_setsec(const char *sharename, struct sec_desc_buf *secdesc_ctr)
4164 {
4165         struct sec_desc_buf *new_secdesc_ctr = NULL;
4166         struct sec_desc_buf *old_secdesc_ctr = NULL;
4167         TALLOC_CTX *mem_ctx = NULL;
4168         TDB_DATA kbuf;
4169         TDB_DATA dbuf;
4170         DATA_BLOB blob;
4171         WERROR status;
4172         NTSTATUS nt_status;
4173
4174         mem_ctx = talloc_init("nt_printing_setsec");
4175         if (mem_ctx == NULL)
4176                 return WERR_NOMEM;
4177
4178         /* The old owner and group sids of the security descriptor are not
4179            present when new ACEs are added or removed by changing printer
4180            permissions through NT.  If they are NULL in the new security
4181            descriptor then copy them over from the old one. */
4182
4183         if (!secdesc_ctr->sd->owner_sid || !secdesc_ctr->sd->group_sid) {
4184                 struct dom_sid *owner_sid, *group_sid;
4185                 struct security_acl *dacl, *sacl;
4186                 struct security_descriptor *psd = NULL;
4187                 size_t size;
4188
4189                 if (!nt_printing_getsec(mem_ctx, sharename, &old_secdesc_ctr)) {
4190                         status = WERR_NOMEM;
4191                         goto out;
4192                 }
4193
4194                 /* Pick out correct owner and group sids */
4195
4196                 owner_sid = secdesc_ctr->sd->owner_sid ?
4197                         secdesc_ctr->sd->owner_sid :
4198                         old_secdesc_ctr->sd->owner_sid;
4199
4200                 group_sid = secdesc_ctr->sd->group_sid ?
4201                         secdesc_ctr->sd->group_sid :
4202                         old_secdesc_ctr->sd->group_sid;
4203
4204                 dacl = secdesc_ctr->sd->dacl ?
4205                         secdesc_ctr->sd->dacl :
4206                         old_secdesc_ctr->sd->dacl;
4207
4208                 sacl = secdesc_ctr->sd->sacl ?
4209                         secdesc_ctr->sd->sacl :
4210                         old_secdesc_ctr->sd->sacl;
4211
4212                 /* Make a deep copy of the security descriptor */
4213
4214                 psd = make_sec_desc(mem_ctx, secdesc_ctr->sd->revision, secdesc_ctr->sd->type,
4215                                     owner_sid, group_sid,
4216                                     sacl,
4217                                     dacl,
4218                                     &size);
4219
4220                 if (!psd) {
4221                         status = WERR_NOMEM;
4222                         goto out;
4223                 }
4224
4225                 new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);
4226         }
4227
4228         if (!new_secdesc_ctr) {
4229                 new_secdesc_ctr = secdesc_ctr;
4230         }
4231
4232         /* Store the security descriptor in a tdb */
4233
4234         nt_status = marshall_sec_desc_buf(mem_ctx, new_secdesc_ctr,
4235                                           &blob.data, &blob.length);
4236         if (!NT_STATUS_IS_OK(nt_status)) {
4237                 status = ntstatus_to_werror(nt_status);
4238                 goto out;
4239         }
4240
4241         kbuf = make_printers_secdesc_tdbkey(mem_ctx, sharename );
4242
4243         dbuf.dptr = (unsigned char *)blob.data;
4244         dbuf.dsize = blob.length;
4245
4246         if (tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE)==0) {
4247                 status = WERR_OK;
4248         } else {
4249                 DEBUG(1,("Failed to store secdesc for %s\n", sharename));
4250                 status = WERR_BADFUNC;
4251         }
4252
4253         /* Free malloc'ed memory */
4254         talloc_free(blob.data);
4255
4256  out:
4257
4258         if (mem_ctx)
4259                 talloc_destroy(mem_ctx);
4260         return status;
4261 }
4262
4263 /****************************************************************************
4264  Construct a default security descriptor buffer for a printer.
4265 ****************************************************************************/
4266
4267 static struct sec_desc_buf *construct_default_printer_sdb(TALLOC_CTX *ctx)
4268 {
4269         struct security_ace ace[7];     /* max number of ace entries */
4270         int i = 0;
4271         uint32_t sa;
4272         struct security_acl *psa = NULL;
4273         struct sec_desc_buf *sdb = NULL;
4274         struct security_descriptor *psd = NULL;
4275         struct dom_sid adm_sid;
4276         size_t sd_size;
4277
4278         /* Create an ACE where Everyone is allowed to print */
4279
4280         sa = PRINTER_ACE_PRINT;
4281         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
4282                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
4283
4284         /* Add the domain admins group if we are a DC */
4285
4286         if ( IS_DC ) {
4287                 struct dom_sid domadmins_sid;
4288
4289                 sid_compose(&domadmins_sid, get_global_sam_sid(),
4290                             DOMAIN_RID_ADMINS);
4291
4292                 sa = PRINTER_ACE_FULL_CONTROL;
4293                 init_sec_ace(&ace[i++], &domadmins_sid,
4294                         SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
4295                         SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
4296                 init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
4297                         sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
4298         }
4299         else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
4300                 sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
4301
4302                 sa = PRINTER_ACE_FULL_CONTROL;
4303                 init_sec_ace(&ace[i++], &adm_sid,
4304                         SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
4305                         SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
4306                 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
4307                         sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
4308         }
4309
4310         /* add BUILTIN\Administrators as FULL CONTROL */
4311
4312         sa = PRINTER_ACE_FULL_CONTROL;
4313         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
4314                 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
4315                 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
4316         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
4317                 SEC_ACE_TYPE_ACCESS_ALLOWED,
4318                 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
4319
4320         /* add BUILTIN\Print Operators as FULL CONTROL */
4321
4322         sa = PRINTER_ACE_FULL_CONTROL;
4323         init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
4324                 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
4325                 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
4326         init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
4327                 SEC_ACE_TYPE_ACCESS_ALLOWED,
4328                 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
4329
4330         /* Make the security descriptor owned by the BUILTIN\Administrators */
4331
4332         /* The ACL revision number in rpc_secdesc.h differs from the one
4333            created by NT when setting ACE entries in printer
4334            descriptors.  NT4 complains about the property being edited by a
4335            NT5 machine. */
4336
4337         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
4338                 psd = make_sec_desc(ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
4339                         &global_sid_Builtin_Administrators,
4340                         &global_sid_Builtin_Administrators,
4341                         NULL, psa, &sd_size);
4342         }
4343
4344         if (!psd) {
4345                 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
4346                 return NULL;
4347         }
4348
4349         sdb = make_sec_desc_buf(ctx, sd_size, psd);
4350
4351         DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
4352                  (unsigned int)sd_size));
4353
4354         return sdb;
4355 }
4356
4357 /****************************************************************************
4358  Get a security desc for a printer.
4359 ****************************************************************************/
4360
4361 bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, struct sec_desc_buf **secdesc_ctr)
4362 {
4363         TDB_DATA kbuf;
4364         TDB_DATA dbuf;
4365         DATA_BLOB blob;
4366         char *temp;
4367         NTSTATUS status;
4368
4369         if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) {
4370                 sharename = temp + 1;
4371         }
4372
4373         /* Fetch security descriptor from tdb */
4374
4375         kbuf = make_printers_secdesc_tdbkey(ctx, sharename);
4376
4377         dbuf = tdb_fetch(tdb_printers, kbuf);
4378         if (dbuf.dptr) {
4379
4380                 status = unmarshall_sec_desc_buf(ctx, dbuf.dptr, dbuf.dsize,
4381                                                  secdesc_ctr);
4382                 SAFE_FREE(dbuf.dptr);
4383
4384                 if (NT_STATUS_IS_OK(status)) {
4385                         return true;
4386                 }
4387         }
4388
4389         *secdesc_ctr = construct_default_printer_sdb(ctx);
4390         if (!*secdesc_ctr) {
4391                 return false;
4392         }
4393
4394         status = marshall_sec_desc_buf(ctx, *secdesc_ctr,
4395                                        &blob.data, &blob.length);
4396         if (NT_STATUS_IS_OK(status)) {
4397                 dbuf.dptr = (unsigned char *)blob.data;
4398                 dbuf.dsize = blob.length;
4399                 tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE);
4400                 talloc_free(blob.data);
4401         }
4402
4403         /* If security descriptor is owned by S-1-1-0 and winbindd is up,
4404            this security descriptor has been created when winbindd was
4405            down.  Take ownership of security descriptor. */
4406
4407         if (sid_equal((*secdesc_ctr)->sd->owner_sid, &global_sid_World)) {
4408                 struct dom_sid owner_sid;
4409
4410                 /* Change sd owner to workgroup administrator */
4411
4412                 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
4413                         struct sec_desc_buf *new_secdesc_ctr = NULL;
4414                         struct security_descriptor *psd = NULL;
4415                         size_t size;
4416
4417                         /* Create new sd */
4418
4419                         sid_append_rid(&owner_sid, DOMAIN_RID_ADMINISTRATOR);
4420
4421                         psd = make_sec_desc(ctx, (*secdesc_ctr)->sd->revision, (*secdesc_ctr)->sd->type,
4422                                             &owner_sid,
4423                                             (*secdesc_ctr)->sd->group_sid,
4424                                             (*secdesc_ctr)->sd->sacl,
4425                                             (*secdesc_ctr)->sd->dacl,
4426                                             &size);
4427
4428                         if (!psd) {
4429                                 return False;
4430                         }
4431
4432                         new_secdesc_ctr = make_sec_desc_buf(ctx, size, psd);
4433                         if (!new_secdesc_ctr) {
4434                                 return False;
4435                         }
4436
4437                         /* Swap with other one */
4438
4439                         *secdesc_ctr = new_secdesc_ctr;
4440
4441                         /* Set it */
4442
4443                         nt_printing_setsec(sharename, *secdesc_ctr);
4444                 }
4445         }
4446
4447         if (DEBUGLEVEL >= 10) {
4448                 struct security_acl *the_acl = (*secdesc_ctr)->sd->dacl;
4449                 int i;
4450
4451                 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
4452                            sharename, the_acl->num_aces));
4453
4454                 for (i = 0; i < the_acl->num_aces; i++) {
4455                         DEBUG(10, ("%s %d %d 0x%08x\n",
4456                                    sid_string_dbg(&the_acl->aces[i].trustee),
4457                                    the_acl->aces[i].type, the_acl->aces[i].flags,
4458                                    the_acl->aces[i].access_mask));
4459                 }
4460         }
4461
4462         return True;
4463 }
4464
4465 /* error code:
4466         0: everything OK
4467         1: level not implemented
4468         2: file doesn't exist
4469         3: can't allocate memory
4470         4: can't free memory
4471         5: non existant struct
4472 */
4473
4474 /*
4475         A printer and a printer driver are 2 different things.
4476         NT manages them separatelly, Samba does the same.
4477         Why ? Simply because it's easier and it makes sense !
4478
4479         Now explanation: You have 3 printers behind your samba server,
4480         2 of them are the same make and model (laser A and B). But laser B
4481         has an 3000 sheet feeder and laser A doesn't such an option.
4482         Your third printer is an old dot-matrix model for the accounting :-).
4483
4484         If the /usr/local/samba/lib directory (default dir), you will have
4485         5 files to describe all of this.
4486
4487         3 files for the printers (1 by printer):
4488                 NTprinter_laser A
4489                 NTprinter_laser B
4490                 NTprinter_accounting
4491         2 files for the drivers (1 for the laser and 1 for the dot matrix)
4492                 NTdriver_printer model X
4493                 NTdriver_printer model Y
4494
4495 jfm: I should use this comment for the text file to explain
4496         same thing for the forms BTW.
4497         Je devrais mettre mes commentaires en francais, ca serait mieux :-)
4498
4499 */
4500
4501 /* Convert generic access rights to printer object specific access rights.
4502    It turns out that NT4 security descriptors use generic access rights and
4503    NT5 the object specific ones. */
4504
4505 void map_printer_permissions(struct security_descriptor *sd)
4506 {
4507         int i;
4508
4509         for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
4510                 se_map_generic(&sd->dacl->aces[i].access_mask,
4511                                &printer_generic_mapping);
4512         }
4513 }
4514
4515 void map_job_permissions(struct security_descriptor *sd)
4516 {
4517         int i;
4518
4519         for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
4520                 se_map_generic(&sd->dacl->aces[i].access_mask,
4521                                &job_generic_mapping);
4522         }
4523 }
4524
4525
4526 /****************************************************************************
4527  Check a user has permissions to perform the given operation.  We use the
4528  permission constants defined in include/rpc_spoolss.h to check the various
4529  actions we perform when checking printer access.
4530
4531    PRINTER_ACCESS_ADMINISTER:
4532        print_queue_pause, print_queue_resume, update_printer_sec,
4533        update_printer, spoolss_addprinterex_level_2,
4534        _spoolss_setprinterdata
4535
4536    PRINTER_ACCESS_USE:
4537        print_job_start
4538
4539    JOB_ACCESS_ADMINISTER:
4540        print_job_delete, print_job_pause, print_job_resume,
4541        print_queue_purge
4542
4543   Try access control in the following order (for performance reasons):
4544     1)  root and SE_PRINT_OPERATOR can do anything (easy check)
4545     2)  check security descriptor (bit comparisons in memory)
4546     3)  "printer admins" (may result in numerous calls to winbind)
4547
4548  ****************************************************************************/
4549 bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
4550                         int access_type)
4551 {
4552         struct spoolss_security_descriptor *secdesc = NULL;
4553         uint32 access_granted;
4554         size_t sd_size;
4555         NTSTATUS status;
4556         WERROR result;
4557         const char *pname;
4558         TALLOC_CTX *mem_ctx = NULL;
4559         SE_PRIV se_printop = SE_PRINT_OPERATOR;
4560
4561         /* If user is NULL then use the current_user structure */
4562
4563         /* Always allow root or SE_PRINT_OPERATROR to do anything */
4564
4565         if (server_info->utok.uid == sec_initial_uid()
4566             || user_has_privileges(server_info->ptok, &se_printop ) ) {
4567                 return True;
4568         }
4569
4570         /* Get printer name */
4571
4572         pname = lp_printername(snum);
4573
4574         if (!pname || !*pname) {
4575                 errno = EACCES;
4576                 return False;
4577         }
4578
4579         /* Get printer security descriptor */
4580
4581         if(!(mem_ctx = talloc_init("print_access_check"))) {
4582                 errno = ENOMEM;
4583                 return False;
4584         }
4585
4586         result = winreg_get_printer_secdesc(mem_ctx,
4587                                             server_info,
4588                                             pname,
4589                                             &secdesc);
4590         if (!W_ERROR_IS_OK(result)) {
4591                 talloc_destroy(mem_ctx);
4592                 errno = ENOMEM;
4593                 return False;
4594         }
4595
4596         if (access_type == JOB_ACCESS_ADMINISTER) {
4597                 struct spoolss_security_descriptor *parent_secdesc = secdesc;
4598
4599                 /* Create a child security descriptor to check permissions
4600                    against.  This is because print jobs are child objects
4601                    objects of a printer. */
4602                 status = se_create_child_secdesc(mem_ctx,
4603                                                  &secdesc,
4604                                                  &sd_size,
4605                                                  parent_secdesc,
4606                                                  parent_secdesc->owner_sid,
4607                                                  parent_secdesc->group_sid,
4608                                                  false);
4609                 if (!NT_STATUS_IS_OK(status)) {
4610                         talloc_destroy(mem_ctx);
4611                         errno = map_errno_from_nt_status(status);
4612                         return False;
4613                 }
4614
4615                 map_job_permissions(secdesc);
4616         } else {
4617                 map_printer_permissions(secdesc);
4618         }
4619
4620         /* Check access */
4621         status = se_access_check(secdesc, server_info->ptok, access_type,
4622                                  &access_granted);
4623
4624         DEBUG(4, ("access check was %s\n", NT_STATUS_IS_OK(status) ? "SUCCESS" : "FAILURE"));
4625
4626         /* see if we need to try the printer admin list */
4627
4628         if (!NT_STATUS_IS_OK(status) &&
4629             (token_contains_name_in_list(uidtoname(server_info->utok.uid),
4630                                          server_info->info3->base.domain.string,
4631                                          NULL, server_info->ptok,
4632                                          lp_printer_admin(snum)))) {
4633                 talloc_destroy(mem_ctx);
4634                 return True;
4635         }
4636
4637         talloc_destroy(mem_ctx);
4638
4639         if (!NT_STATUS_IS_OK(status)) {
4640                 errno = EACCES;
4641         }
4642
4643         return NT_STATUS_IS_OK(status);
4644 }
4645
4646 /****************************************************************************
4647  Check the time parameters allow a print operation.
4648 *****************************************************************************/
4649
4650 bool print_time_access_check(struct auth_serversupplied_info *server_info,
4651                              const char *servicename)
4652 {
4653         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
4654         WERROR result;
4655         bool ok = False;
4656         time_t now = time(NULL);
4657         struct tm *t;
4658         uint32 mins;
4659
4660         result = winreg_get_printer(NULL, server_info,
4661                                     NULL, servicename, &pinfo2);
4662         if (!W_ERROR_IS_OK(result)) {
4663                 return False;
4664         }
4665
4666         if (pinfo2->starttime == 0 && pinfo2->untiltime == 0) {
4667                 ok = True;
4668         }
4669
4670         t = gmtime(&now);
4671         mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
4672
4673         if (mins >= pinfo2->starttime && mins <= pinfo2->untiltime) {
4674                 ok = True;
4675         }
4676
4677         TALLOC_FREE(pinfo2);
4678
4679         if (!ok) {
4680                 errno = EACCES;
4681         }
4682
4683         return ok;
4684 }
4685
4686 void nt_printer_remove(TALLOC_CTX *mem_ctx,
4687                         struct auth_serversupplied_info *server_info,
4688                         const char *printer)
4689 {
4690         WERROR result;
4691
4692         result = winreg_delete_printer_key(mem_ctx, server_info, printer, "");
4693         if (!W_ERROR_IS_OK(result)) {
4694                 DEBUG(0, ("nt_printer_remove: failed to remove rpinter %s",
4695                           printer));
4696         }
4697 }