s3-printing: Convert print_driver_in_use.
[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  Delete a printer - this just deletes the printer info file, any open
2118  handles are not affected.
2119 ****************************************************************************/
2120
2121 uint32 del_a_printer(const char *sharename)
2122 {
2123         TDB_DATA kbuf;
2124         char *printdb_path = NULL;
2125         TALLOC_CTX *ctx = talloc_tos();
2126
2127         kbuf = make_printer_tdbkey(ctx, sharename);
2128         tdb_delete(tdb_printers, kbuf);
2129
2130         kbuf= make_printers_secdesc_tdbkey(ctx, sharename);
2131         tdb_delete(tdb_printers, kbuf);
2132
2133         close_all_print_db();
2134
2135         if (geteuid() == sec_initial_uid()) {
2136                 if (asprintf(&printdb_path, "%s%s.tdb",
2137                                 cache_path("printing/"),
2138                                 sharename) < 0) {
2139                         return (uint32)-1;
2140                 }
2141                 unlink(printdb_path);
2142                 SAFE_FREE(printdb_path);
2143         }
2144
2145         return 0;
2146 }
2147
2148 /****************************************************************************
2149 ****************************************************************************/
2150 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
2151 {
2152         uint8 *buf;
2153         int buflen, len;
2154         int retlen;
2155         WERROR ret;
2156         TDB_DATA kbuf, dbuf;
2157
2158         /*
2159          * in addprinter: no servername and the printer is the name
2160          * in setprinter: servername is \\server
2161          *                and printer is \\server\\printer
2162          *
2163          * Samba manages only local printers.
2164          * we currently don't support things like i
2165          * path=\\other_server\printer
2166          *
2167          * We only store the printername, not \\server\printername
2168          */
2169
2170         if ( info->servername[0] != '\0' ) {
2171                 trim_string(info->printername, info->servername, NULL);
2172                 trim_char(info->printername, '\\', '\0');
2173                 info->servername[0]='\0';
2174         }
2175
2176         /*
2177          * JFM: one day I'll forget.
2178          * below that's info->portname because that's the SAMBA sharename
2179          * and I made NT 'thinks' it's the portname
2180          * the info->sharename is the thing you can name when you add a printer
2181          * that's the short-name when you create shared printer for 95/98
2182          * So I've made a limitation in SAMBA: you can only have 1 printer model
2183          * behind a SAMBA share.
2184          */
2185
2186         buf = NULL;
2187         buflen = 0;
2188
2189  again:
2190         len = 0;
2191         len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
2192                         info->attributes,
2193                         info->priority,
2194                         info->default_priority,
2195                         info->starttime,
2196                         info->untiltime,
2197                         info->status,
2198                         info->cjobs,
2199                         info->averageppm,
2200                         info->changeid,
2201                         info->c_setprinter,
2202                         info->setuptime,
2203                         info->servername,
2204                         info->printername,
2205                         info->sharename,
2206                         info->portname,
2207                         info->drivername,
2208                         info->comment,
2209                         info->location,
2210                         info->sepfile,
2211                         info->printprocessor,
2212                         info->datatype,
2213                         info->parameters);
2214
2215         len += pack_devicemode(info->devmode, buf+len, buflen-len);
2216         retlen = pack_values( info->data, buf+len, buflen-len );
2217         if (retlen == -1) {
2218                 ret = WERR_NOMEM;
2219                 goto done;
2220         }
2221         len += retlen;
2222
2223         if (buflen != len) {
2224                 buf = (uint8 *)SMB_REALLOC(buf, len);
2225                 if (!buf) {
2226                         DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
2227                         ret = WERR_NOMEM;
2228                         goto done;
2229                 }
2230                 buflen = len;
2231                 goto again;
2232         }
2233
2234         kbuf = make_printer_tdbkey(talloc_tos(), info->sharename );
2235
2236         dbuf.dptr = buf;
2237         dbuf.dsize = len;
2238
2239         ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
2240
2241 done:
2242         if (!W_ERROR_IS_OK(ret))
2243                 DEBUG(8, ("error updating printer to tdb on disk\n"));
2244
2245         SAFE_FREE(buf);
2246
2247         DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
2248                  info->sharename, info->drivername, info->portname, len));
2249
2250         return ret;
2251 }
2252
2253 /****************************************************************************
2254  Create and allocate a default devicemode.
2255 ****************************************************************************/
2256
2257 WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
2258                                       const char *devicename,
2259                                       struct spoolss_DeviceMode **devmode)
2260 {
2261         struct spoolss_DeviceMode *dm;
2262         char *dname;
2263
2264         dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
2265         if (dm == NULL) {
2266                 return WERR_NOMEM;
2267         }
2268
2269         dname = talloc_asprintf(dm, "%s", devicename);
2270         if (dname == NULL) {
2271                 return WERR_NOMEM;
2272         }
2273         if (strlen(dname) > MAXDEVICENAME) {
2274                 dname[MAXDEVICENAME] = '\0';
2275         }
2276         dm->devicename = dname;
2277
2278         dm->formname = talloc_strdup(dm, "Letter");
2279         if (dm->formname == NULL) {
2280                 return WERR_NOMEM;
2281         }
2282
2283         dm->specversion          = DMSPEC_NT4_AND_ABOVE;
2284         dm->driverversion        = 0x0400;
2285         dm->size                 = 0x00DC;
2286         dm->__driverextra_length = 0;
2287         dm->fields               = DEVMODE_FORMNAME |
2288                                    DEVMODE_TTOPTION |
2289                                    DEVMODE_PRINTQUALITY |
2290                                    DEVMODE_DEFAULTSOURCE |
2291                                    DEVMODE_COPIES |
2292                                    DEVMODE_SCALE |
2293                                    DEVMODE_PAPERSIZE |
2294                                    DEVMODE_ORIENTATION;
2295         dm->orientation          = DMORIENT_PORTRAIT;
2296         dm->papersize            = DMPAPER_LETTER;
2297         dm->paperlength          = 0;
2298         dm->paperwidth           = 0;
2299         dm->scale                = 0x64;
2300         dm->copies               = 1;
2301         dm->defaultsource        = DMBIN_FORMSOURCE;
2302         dm->printquality         = DMRES_HIGH;           /* 0x0258 */
2303         dm->color                = DMRES_MONOCHROME;
2304         dm->duplex               = DMDUP_SIMPLEX;
2305         dm->yresolution          = 0;
2306         dm->ttoption             = DMTT_SUBDEV;
2307         dm->collate              = DMCOLLATE_FALSE;
2308         dm->icmmethod            = 0;
2309         dm->icmintent            = 0;
2310         dm->mediatype            = 0;
2311         dm->dithertype           = 0;
2312
2313         dm->logpixels            = 0;
2314         dm->bitsperpel           = 0;
2315         dm->pelswidth            = 0;
2316         dm->pelsheight           = 0;
2317         dm->displayflags         = 0;
2318         dm->displayfrequency     = 0;
2319         dm->reserved1            = 0;
2320         dm->reserved2            = 0;
2321         dm->panningwidth         = 0;
2322         dm->panningheight        = 0;
2323
2324         dm->driverextra_data.data = NULL;
2325         dm->driverextra_data.length = 0;
2326
2327         *devmode = dm;
2328         return WERR_OK;
2329 }
2330
2331 WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
2332                                       struct spoolss_security_descriptor **secdesc)
2333 {
2334         struct security_ace ace[7];     /* max number of ace entries */
2335         int i = 0;
2336         uint32_t sa;
2337         struct security_acl *psa = NULL;
2338         struct security_descriptor *psd = NULL;
2339         struct dom_sid adm_sid;
2340         size_t sd_size;
2341
2342         /* Create an ACE where Everyone is allowed to print */
2343
2344         sa = PRINTER_ACE_PRINT;
2345         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
2346                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2347
2348         /* Add the domain admins group if we are a DC */
2349
2350         if ( IS_DC ) {
2351                 struct dom_sid domadmins_sid;
2352
2353                 sid_compose(&domadmins_sid, get_global_sam_sid(),
2354                             DOMAIN_RID_ADMINS);
2355
2356                 sa = PRINTER_ACE_FULL_CONTROL;
2357                 init_sec_ace(&ace[i++], &domadmins_sid,
2358                         SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
2359                         SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
2360                 init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
2361                         sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2362         }
2363         else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
2364                 sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
2365
2366                 sa = PRINTER_ACE_FULL_CONTROL;
2367                 init_sec_ace(&ace[i++], &adm_sid,
2368                         SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
2369                         SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
2370                 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
2371                         sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2372         }
2373
2374         /* add BUILTIN\Administrators as FULL CONTROL */
2375
2376         sa = PRINTER_ACE_FULL_CONTROL;
2377         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
2378                 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
2379                 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
2380         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
2381                 SEC_ACE_TYPE_ACCESS_ALLOWED,
2382                 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2383
2384         /* add BUILTIN\Print Operators as FULL CONTROL */
2385
2386         sa = PRINTER_ACE_FULL_CONTROL;
2387         init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
2388                 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
2389                 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
2390         init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
2391                 SEC_ACE_TYPE_ACCESS_ALLOWED,
2392                 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2393
2394         /* Make the security descriptor owned by the BUILTIN\Administrators */
2395
2396         /* The ACL revision number in rpc_secdesc.h differs from the one
2397            created by NT when setting ACE entries in printer
2398            descriptors.  NT4 complains about the property being edited by a
2399            NT5 machine. */
2400
2401         if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
2402                 psd = make_sec_desc(mem_ctx,
2403                                     SD_REVISION,
2404                                     SEC_DESC_SELF_RELATIVE,
2405                                     &global_sid_Builtin_Administrators,
2406                                     &global_sid_Builtin_Administrators,
2407                                     NULL,
2408                                     psa,
2409                                     &sd_size);
2410         }
2411
2412         if (psd == NULL) {
2413                 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
2414                 return WERR_NOMEM;
2415         }
2416
2417         DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
2418                  (unsigned int)sd_size));
2419
2420         *secdesc = psd;
2421
2422         return WERR_OK;
2423 }
2424
2425 /****************************************************************************
2426  Allocate and initialize a new slot.
2427 ***************************************************************************/
2428
2429 int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
2430 {
2431         NT_PRINTER_KEY  *d;
2432         int             key_index;
2433         WERROR werr;
2434
2435         if ( !name || !data )
2436                 return -1;
2437
2438         /* allocate another slot in the NT_PRINTER_KEY array */
2439
2440         if ( !(d = TALLOC_REALLOC_ARRAY( data, data->keys, NT_PRINTER_KEY, data->num_keys+1)) ) {
2441                 DEBUG(0,("add_new_printer_key: Realloc() failed!\n"));
2442                 return -1;
2443         }
2444
2445         data->keys = d;
2446
2447         key_index = data->num_keys;
2448
2449         /* initialze new key */
2450
2451         data->keys[key_index].name = talloc_strdup( data, name );
2452
2453         werr = regval_ctr_init(data, &(data->keys[key_index].values));
2454         if (!W_ERROR_IS_OK(werr)) {
2455                 return -1;
2456         }
2457
2458         data->num_keys++;
2459
2460         DEBUG(10,("add_new_printer_key: Inserted new data key [%s]\n", name ));
2461
2462         return key_index;
2463 }
2464
2465 /****************************************************************************
2466  search for a registry key name in the existing printer data
2467  ***************************************************************************/
2468
2469 int delete_printer_key( NT_PRINTER_DATA *data, const char *name )
2470 {
2471         int i;
2472
2473         for ( i=0; i<data->num_keys; i++ ) {
2474                 if ( strequal( data->keys[i].name, name ) ) {
2475
2476                         /* cleanup memory */
2477
2478                         TALLOC_FREE( data->keys[i].name );
2479                         TALLOC_FREE( data->keys[i].values );
2480
2481                         /* if not the end of the array, move remaining elements down one slot */
2482
2483                         data->num_keys--;
2484                         if ( data->num_keys && (i < data->num_keys) )
2485                                 memmove( &data->keys[i], &data->keys[i+1], sizeof(NT_PRINTER_KEY)*(data->num_keys-i) );
2486
2487                         break;
2488                 }
2489         }
2490
2491
2492         return data->num_keys;
2493 }
2494
2495 /****************************************************************************
2496  search for a registry key name in the existing printer data
2497  ***************************************************************************/
2498
2499 int lookup_printerkey( NT_PRINTER_DATA *data, const char *name )
2500 {
2501         int             key_index = -1;
2502         int             i;
2503
2504         if ( !data || !name )
2505                 return -1;
2506
2507         DEBUG(12,("lookup_printerkey: Looking for [%s]\n", name));
2508
2509         /* loop over all existing keys */
2510
2511         for ( i=0; i<data->num_keys; i++ ) {
2512                 if ( strequal(data->keys[i].name, name) ) {
2513                         DEBUG(12,("lookup_printerkey: Found [%s]!\n", name));
2514                         key_index = i;
2515                         break;
2516
2517                 }
2518         }
2519
2520         return key_index;
2521 }
2522
2523 /****************************************************************************
2524  ***************************************************************************/
2525
2526 int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys )
2527 {
2528         int     i, j;
2529         int     key_len;
2530         int     num_subkeys = 0;
2531         char    *p;
2532         fstring *subkeys_ptr = NULL;
2533         fstring subkeyname;
2534
2535         *subkeys = NULL;
2536
2537         if ( !data )
2538                 return 0;
2539
2540         if ( !key )
2541                 return -1;
2542
2543         /* special case of asking for the top level printer data registry key names */
2544
2545         if ( strlen(key) == 0 ) {
2546                 for ( i=0; i<data->num_keys; i++ ) {
2547
2548                         /* found a match, so allocate space and copy the name */
2549
2550                         if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
2551                                 DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
2552                                         num_subkeys+1));
2553                                 return -1;
2554                         }
2555
2556                         fstrcpy( subkeys_ptr[num_subkeys], data->keys[i].name );
2557                         num_subkeys++;
2558                 }
2559
2560                 goto done;
2561         }
2562
2563         /* asking for the subkeys of some key */
2564         /* subkey paths are stored in the key name using '\' as the delimiter */
2565
2566         for ( i=0; i<data->num_keys; i++ ) {
2567                 if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) {
2568
2569                         /* if we found the exact key, then break */
2570                         key_len = strlen( key );
2571                         if ( strlen(data->keys[i].name) == key_len )
2572                                 break;
2573
2574                         /* get subkey path */
2575
2576                         p = data->keys[i].name + key_len;
2577                         if ( *p == '\\' )
2578                                 p++;
2579                         fstrcpy( subkeyname, p );
2580                         if ( (p = strchr( subkeyname, '\\' )) )
2581                                 *p = '\0';
2582
2583                         /* don't add a key more than once */
2584
2585                         for ( j=0; j<num_subkeys; j++ ) {
2586                                 if ( strequal( subkeys_ptr[j], subkeyname ) )
2587                                         break;
2588                         }
2589
2590                         if ( j != num_subkeys )
2591                                 continue;
2592
2593                         /* found a match, so allocate space and copy the name */
2594
2595                         if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
2596                                 DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
2597                                         num_subkeys+1));
2598                                 return 0;
2599                         }
2600
2601                         fstrcpy( subkeys_ptr[num_subkeys], subkeyname );
2602                         num_subkeys++;
2603                 }
2604
2605         }
2606
2607         /* return error if the key was not found */
2608
2609         if ( i == data->num_keys ) {
2610                 SAFE_FREE(subkeys_ptr);
2611                 return -1;
2612         }
2613
2614 done:
2615         /* tag off the end */
2616
2617         if (num_subkeys)
2618                 fstrcpy(subkeys_ptr[num_subkeys], "" );
2619
2620         *subkeys = subkeys_ptr;
2621
2622         return num_subkeys;
2623 }
2624
2625 #ifdef HAVE_ADS
2626 static void map_sz_into_ctr(struct regval_ctr *ctr, const char *val_name,
2627                             const char *sz)
2628 {
2629         regval_ctr_delvalue(ctr, val_name);
2630         regval_ctr_addvalue_sz(ctr, val_name, sz);
2631 }
2632
2633 static void map_dword_into_ctr(struct regval_ctr *ctr, const char *val_name,
2634                                uint32 dword)
2635 {
2636         regval_ctr_delvalue(ctr, val_name);
2637         regval_ctr_addvalue(ctr, val_name, REG_DWORD,
2638                             (uint8 *) &dword, sizeof(dword));
2639 }
2640
2641 static void map_bool_into_ctr(struct regval_ctr *ctr, const char *val_name,
2642                               bool b)
2643 {
2644         uint8 bin_bool = (b ? 1 : 0);
2645         regval_ctr_delvalue(ctr, val_name);
2646         regval_ctr_addvalue(ctr, val_name, REG_BINARY,
2647                             (uint8 *) &bin_bool, sizeof(bin_bool));
2648 }
2649
2650 static void map_single_multi_sz_into_ctr(struct regval_ctr *ctr, const char *val_name,
2651                                          const char *multi_sz)
2652 {
2653         const char *a[2];
2654
2655         a[0] = multi_sz;
2656         a[1] = NULL;
2657
2658         regval_ctr_delvalue(ctr, val_name);
2659         regval_ctr_addvalue_multi_sz(ctr, val_name, a);
2660 }
2661
2662 /****************************************************************************
2663  * Map the NT_PRINTER_INFO_LEVEL_2 data into DsSpooler keys for publishing.
2664  *
2665  * @param info2 NT_PRINTER_INFO_LEVEL_2 describing printer - gets modified
2666  * @return bool indicating success or failure
2667  ***************************************************************************/
2668
2669 static bool map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
2670 {
2671         struct regval_ctr *ctr = NULL;
2672         fstring longname;
2673         const char *dnssuffix;
2674         char *allocated_string = NULL;
2675         const char *ascii_str;
2676         int i;
2677
2678         if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
2679                 i = add_new_printer_key(info2->data, SPOOL_DSSPOOLER_KEY);
2680         ctr = info2->data->keys[i].values;
2681
2682         map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename);
2683         map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, global_myname());
2684
2685         /* we make the assumption that the netbios name is the same
2686            as the DNS name sinc ethe former will be what we used to
2687            join the domain */
2688
2689         dnssuffix = get_mydnsdomname(talloc_tos());
2690         if (dnssuffix && *dnssuffix) {
2691                 fstr_sprintf( longname, "%s.%s", global_myname(), dnssuffix );
2692         } else {
2693                 fstrcpy( longname, global_myname() );
2694         }
2695
2696         map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname);
2697
2698         if (asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename) == -1) {
2699                 return false;
2700         }
2701         map_sz_into_ctr(ctr, SPOOL_REG_UNCNAME, allocated_string);
2702         SAFE_FREE(allocated_string);
2703
2704         map_dword_into_ctr(ctr, SPOOL_REG_VERSIONNUMBER, 4);
2705         map_sz_into_ctr(ctr, SPOOL_REG_DRIVERNAME, info2->drivername);
2706         map_sz_into_ctr(ctr, SPOOL_REG_LOCATION, info2->location);
2707         map_sz_into_ctr(ctr, SPOOL_REG_DESCRIPTION, info2->comment);
2708         map_single_multi_sz_into_ctr(ctr, SPOOL_REG_PORTNAME, info2->portname);
2709         map_sz_into_ctr(ctr, SPOOL_REG_PRINTSEPARATORFILE, info2->sepfile);
2710         map_dword_into_ctr(ctr, SPOOL_REG_PRINTSTARTTIME, info2->starttime);
2711         map_dword_into_ctr(ctr, SPOOL_REG_PRINTENDTIME, info2->untiltime);
2712         map_dword_into_ctr(ctr, SPOOL_REG_PRIORITY, info2->priority);
2713
2714         map_bool_into_ctr(ctr, SPOOL_REG_PRINTKEEPPRINTEDJOBS,
2715                           (info2->attributes &
2716                            PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
2717
2718         switch (info2->attributes & 0x3) {
2719         case 0:
2720                 ascii_str = SPOOL_REGVAL_PRINTWHILESPOOLING;
2721                 break;
2722         case 1:
2723                 ascii_str = SPOOL_REGVAL_PRINTAFTERSPOOLED;
2724                 break;
2725         case 2:
2726                 ascii_str = SPOOL_REGVAL_PRINTDIRECT;
2727                 break;
2728         default:
2729                 ascii_str = "unknown";
2730         }
2731         map_sz_into_ctr(ctr, SPOOL_REG_PRINTSPOOLING, ascii_str);
2732
2733         return True;
2734 }
2735
2736 /*****************************************************************
2737  ****************************************************************/
2738
2739 static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2,
2740                                struct GUID guid)
2741 {
2742         int i;
2743         struct regval_ctr *ctr=NULL;
2744
2745         /* find the DsSpooler key */
2746         if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
2747                 i = add_new_printer_key(info2->data, SPOOL_DSSPOOLER_KEY);
2748         ctr = info2->data->keys[i].values;
2749
2750         regval_ctr_delvalue(ctr, "objectGUID");
2751
2752         /* We used to store this as a REG_BINARY but that causes
2753            Vista to whine */
2754
2755         regval_ctr_addvalue_sz(ctr, "objectGUID",
2756                                GUID_string(talloc_tos(), &guid));
2757 }
2758
2759 static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
2760                                      NT_PRINTER_INFO_LEVEL *printer)
2761 {
2762         ADS_STATUS ads_rc;
2763         LDAPMessage *res;
2764         char *prt_dn = NULL, *srv_dn, *srv_cn_0, *srv_cn_escaped, *sharename_escaped;
2765         char *srv_dn_utf8, **srv_cn_utf8;
2766         TALLOC_CTX *ctx;
2767         ADS_MODLIST mods;
2768         const char *attrs[] = {"objectGUID", NULL};
2769         struct GUID guid;
2770         WERROR win_rc = WERR_OK;
2771         size_t converted_size;
2772
2773         /* build the ads mods */
2774         ctx = talloc_init("nt_printer_publish_ads");
2775         if (ctx == NULL) {
2776                 return WERR_NOMEM;
2777         }
2778
2779         DEBUG(5, ("publishing printer %s\n", printer->info_2->printername));
2780
2781         /* figure out where to publish */
2782         ads_find_machine_acct(ads, &res, global_myname());
2783
2784         /* We use ldap_get_dn here as we need the answer
2785          * in utf8 to call ldap_explode_dn(). JRA. */
2786
2787         srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res);
2788         if (!srv_dn_utf8) {
2789                 TALLOC_FREE(ctx);
2790                 return WERR_SERVER_UNAVAILABLE;
2791         }
2792         ads_msgfree(ads, res);
2793         srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1);
2794         if (!srv_cn_utf8) {
2795                 TALLOC_FREE(ctx);
2796                 ldap_memfree(srv_dn_utf8);
2797                 return WERR_SERVER_UNAVAILABLE;
2798         }
2799         /* Now convert to CH_UNIX. */
2800         if (!pull_utf8_talloc(ctx, &srv_dn, srv_dn_utf8, &converted_size)) {
2801                 TALLOC_FREE(ctx);
2802                 ldap_memfree(srv_dn_utf8);
2803                 ldap_memfree(srv_cn_utf8);
2804                 return WERR_SERVER_UNAVAILABLE;
2805         }
2806         if (!pull_utf8_talloc(ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size)) {
2807                 TALLOC_FREE(ctx);
2808                 ldap_memfree(srv_dn_utf8);
2809                 ldap_memfree(srv_cn_utf8);
2810                 TALLOC_FREE(srv_dn);
2811                 return WERR_SERVER_UNAVAILABLE;
2812         }
2813
2814         ldap_memfree(srv_dn_utf8);
2815         ldap_memfree(srv_cn_utf8);
2816
2817         srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0);
2818         if (!srv_cn_escaped) {
2819                 TALLOC_FREE(ctx);
2820                 return WERR_SERVER_UNAVAILABLE;
2821         }
2822         sharename_escaped = escape_rdn_val_string_alloc(printer->info_2->sharename);
2823         if (!sharename_escaped) {
2824                 SAFE_FREE(srv_cn_escaped);
2825                 TALLOC_FREE(ctx);
2826                 return WERR_SERVER_UNAVAILABLE;
2827         }
2828
2829         prt_dn = talloc_asprintf(ctx, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn);
2830
2831         SAFE_FREE(srv_cn_escaped);
2832         SAFE_FREE(sharename_escaped);
2833
2834         mods = ads_init_mods(ctx);
2835
2836         if (mods == NULL) {
2837                 SAFE_FREE(prt_dn);
2838                 TALLOC_FREE(ctx);
2839                 return WERR_NOMEM;
2840         }
2841
2842         get_local_printer_publishing_data(ctx, &mods, printer->info_2->data);
2843         ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME,
2844                     printer->info_2->sharename);
2845
2846         /* publish it */
2847         ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
2848         if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT) {
2849                 int i;
2850                 for (i=0; mods[i] != 0; i++)
2851                         ;
2852                 mods[i] = (LDAPMod *)-1;
2853                 ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
2854         }
2855
2856         if (!ADS_ERR_OK(ads_rc))
2857                 DEBUG(3, ("error publishing %s: %s\n", printer->info_2->sharename, ads_errstr(ads_rc)));
2858
2859         /* retreive the guid and store it locally */
2860         if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
2861                 ZERO_STRUCT(guid);
2862                 ads_pull_guid(ads, res, &guid);
2863                 ads_msgfree(ads, res);
2864                 store_printer_guid(printer->info_2, guid);
2865                 win_rc = mod_a_printer(printer, 2);
2866         }
2867         TALLOC_FREE(ctx);
2868
2869         return win_rc;
2870 }
2871
2872 static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads,
2873                                        NT_PRINTER_INFO_LEVEL *printer)
2874 {
2875         ADS_STATUS ads_rc;
2876         LDAPMessage *res = NULL;
2877         char *prt_dn = NULL;
2878
2879         DEBUG(5, ("unpublishing printer %s\n", printer->info_2->printername));
2880
2881         /* remove the printer from the directory */
2882         ads_rc = ads_find_printer_on_server(ads, &res,
2883                             printer->info_2->sharename, global_myname());
2884
2885         if (ADS_ERR_OK(ads_rc) && res && ads_count_replies(ads, res)) {
2886                 prt_dn = ads_get_dn(ads, talloc_tos(), res);
2887                 if (!prt_dn) {
2888                         ads_msgfree(ads, res);
2889                         return WERR_NOMEM;
2890                 }
2891                 ads_rc = ads_del_dn(ads, prt_dn);
2892                 TALLOC_FREE(prt_dn);
2893         }
2894
2895         if (res) {
2896                 ads_msgfree(ads, res);
2897         }
2898         return WERR_OK;
2899 }
2900
2901 /****************************************************************************
2902  * Publish a printer in the directory
2903  *
2904  * @param snum describing printer service
2905  * @return WERROR indicating status of publishing
2906  ***************************************************************************/
2907
2908 WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
2909 {
2910         ADS_STATUS ads_rc;
2911         ADS_STRUCT *ads = NULL;
2912         NT_PRINTER_INFO_LEVEL *printer = NULL;
2913         WERROR win_rc;
2914
2915         win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
2916         if (!W_ERROR_IS_OK(win_rc))
2917                 goto done;
2918
2919         switch (action) {
2920         case DSPRINT_PUBLISH:
2921         case DSPRINT_UPDATE:
2922                 /* set the DsSpooler info and attributes */
2923                 if (!(map_nt_printer_info2_to_dsspooler(printer->info_2))) {
2924                         win_rc = WERR_NOMEM;
2925                         goto done;
2926                 }
2927
2928                 printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
2929                 break;
2930         case DSPRINT_UNPUBLISH:
2931                 printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
2932                 break;
2933         default:
2934                 win_rc = WERR_NOT_SUPPORTED;
2935                 goto done;
2936         }
2937
2938         win_rc = mod_a_printer(printer, 2);
2939         if (!W_ERROR_IS_OK(win_rc)) {
2940                 DEBUG(3, ("err %d saving data\n", W_ERROR_V(win_rc)));
2941                 goto done;
2942         }
2943
2944         ads = ads_init(lp_realm(), lp_workgroup(), NULL);
2945         if (!ads) {
2946                 DEBUG(3, ("ads_init() failed\n"));
2947                 win_rc = WERR_SERVER_UNAVAILABLE;
2948                 goto done;
2949         }
2950         setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
2951         SAFE_FREE(ads->auth.password);
2952         ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
2953                 NULL, NULL);
2954
2955         /* ads_connect() will find the DC for us */
2956         ads_rc = ads_connect(ads);
2957         if (!ADS_ERR_OK(ads_rc)) {
2958                 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
2959                 win_rc = WERR_ACCESS_DENIED;
2960                 goto done;
2961         }
2962
2963         switch (action) {
2964         case DSPRINT_PUBLISH:
2965         case DSPRINT_UPDATE:
2966                 win_rc = nt_printer_publish_ads(ads, printer);
2967                 break;
2968         case DSPRINT_UNPUBLISH:
2969                 win_rc = nt_printer_unpublish_ads(ads, printer);
2970                 break;
2971         }
2972
2973 done:
2974         free_a_printer(&printer, 2);
2975         ads_destroy(&ads);
2976         return win_rc;
2977 }
2978
2979 WERROR check_published_printers(void)
2980 {
2981         ADS_STATUS ads_rc;
2982         ADS_STRUCT *ads = NULL;
2983         int snum;
2984         int n_services = lp_numservices();
2985         NT_PRINTER_INFO_LEVEL *printer = NULL;
2986
2987         ads = ads_init(lp_realm(), lp_workgroup(), NULL);
2988         if (!ads) {
2989                 DEBUG(3, ("ads_init() failed\n"));
2990                 return WERR_SERVER_UNAVAILABLE;
2991         }
2992         setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
2993         SAFE_FREE(ads->auth.password);
2994         ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
2995                 NULL, NULL);
2996
2997         /* ads_connect() will find the DC for us */
2998         ads_rc = ads_connect(ads);
2999         if (!ADS_ERR_OK(ads_rc)) {
3000                 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
3001                 ads_destroy(&ads);
3002                 ads_kdestroy("MEMORY:prtpub_cache");
3003                 return WERR_ACCESS_DENIED;
3004         }
3005
3006         for (snum = 0; snum < n_services; snum++) {
3007                 if (!(lp_snum_ok(snum) && lp_print_ok(snum)))
3008                         continue;
3009
3010                 if (W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2,
3011                                                 lp_servicename(snum))) &&
3012                     (printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED))
3013                         nt_printer_publish_ads(ads, printer);
3014
3015                 free_a_printer(&printer, 2);
3016         }
3017
3018         ads_destroy(&ads);
3019         ads_kdestroy("MEMORY:prtpub_cache");
3020         return WERR_OK;
3021 }
3022
3023 bool is_printer_published(Printer_entry *print_hnd, int snum,
3024                           struct GUID *guid)
3025 {
3026         NT_PRINTER_INFO_LEVEL *printer = NULL;
3027         struct regval_ctr *ctr;
3028         struct regval_blob *guid_val;
3029         WERROR win_rc;
3030         int i;
3031         bool ret = False;
3032         DATA_BLOB blob;
3033
3034         win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
3035
3036         if (!W_ERROR_IS_OK(win_rc) ||
3037             !(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) ||
3038             ((i = lookup_printerkey(printer->info_2->data, SPOOL_DSSPOOLER_KEY)) < 0) ||
3039             !(ctr = printer->info_2->data->keys[i].values) ||
3040             !(guid_val = regval_ctr_getvalue(ctr, "objectGUID")))
3041         {
3042                 free_a_printer(&printer, 2);
3043                 return False;
3044         }
3045
3046         /* fetching printer guids really ought to be a separate function. */
3047
3048         if ( guid ) {
3049                 char *guid_str;
3050
3051                 /* We used to store the guid as REG_BINARY, then swapped
3052                    to REG_SZ for Vista compatibility so check for both */
3053
3054                 switch ( regval_type(guid_val) ){
3055                 case REG_SZ:
3056                         blob = data_blob_const(regval_data_p(guid_val),
3057                                                regval_size(guid_val));
3058                         pull_reg_sz(talloc_tos(), &blob, (const char **)&guid_str);
3059                         ret = NT_STATUS_IS_OK(GUID_from_string( guid_str, guid ));
3060                         talloc_free(guid_str);
3061                         break;
3062                 case REG_BINARY:
3063                         if ( regval_size(guid_val) != sizeof(struct GUID) ) {
3064                                 ret = False;
3065                                 break;
3066                         }
3067                         memcpy(guid, regval_data_p(guid_val), sizeof(struct GUID));
3068                         break;
3069                 default:
3070                         DEBUG(0,("is_printer_published: GUID value stored as "
3071                                  "invaluid type (%d)\n", regval_type(guid_val) ));
3072                         break;
3073                 }
3074         }
3075
3076         free_a_printer(&printer, 2);
3077         return ret;
3078 }
3079 #else
3080 WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
3081 {
3082         return WERR_OK;
3083 }
3084
3085 WERROR check_published_printers(void)
3086 {
3087         return WERR_OK;
3088 }
3089
3090 bool is_printer_published(Printer_entry *print_hnd, int snum,
3091                           struct GUID *guid)
3092 {
3093         return False;
3094 }
3095 #endif /* HAVE_ADS */
3096
3097 /****************************************************************************
3098  ***************************************************************************/
3099
3100 WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
3101 {
3102         NT_PRINTER_DATA *data;
3103         int             i;
3104         int             removed_keys = 0;
3105         int             empty_slot;
3106
3107         data = p2->data;
3108         empty_slot = data->num_keys;
3109
3110         if ( !key )
3111                 return WERR_INVALID_PARAM;
3112
3113         /* remove all keys */
3114
3115         if ( !strlen(key) ) {
3116
3117                 TALLOC_FREE( data );
3118
3119                 p2->data = NULL;
3120
3121                 DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n",
3122                         p2->printername ));
3123
3124                 return WERR_OK;
3125         }
3126
3127         /* remove a specific key (and all subkeys) */
3128
3129         for ( i=0; i<data->num_keys; i++ ) {
3130                 if ( StrnCaseCmp( data->keys[i].name, key, strlen(key)) == 0 ) {
3131                         DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n",
3132                                 data->keys[i].name));
3133
3134                         TALLOC_FREE( data->keys[i].name );
3135                         TALLOC_FREE( data->keys[i].values );
3136
3137                         /* mark the slot as empty */
3138
3139                         ZERO_STRUCTP( &data->keys[i] );
3140                 }
3141         }
3142
3143         /* find the first empty slot */
3144
3145         for ( i=0; i<data->num_keys; i++ ) {
3146                 if ( !data->keys[i].name ) {
3147                         empty_slot = i;
3148                         removed_keys++;
3149                         break;
3150                 }
3151         }
3152
3153         if ( i == data->num_keys )
3154                 /* nothing was removed */
3155                 return WERR_INVALID_PARAM;
3156
3157         /* move everything down */
3158
3159         for ( i=empty_slot+1; i<data->num_keys; i++ ) {
3160                 if ( data->keys[i].name ) {
3161                         memcpy( &data->keys[empty_slot], &data->keys[i], sizeof(NT_PRINTER_KEY) );
3162                         ZERO_STRUCTP( &data->keys[i] );
3163                         empty_slot++;
3164                         removed_keys++;
3165                 }
3166         }
3167
3168         /* update count */
3169
3170         data->num_keys -= removed_keys;
3171
3172         /* sanity check to see if anything is left */
3173
3174         if ( !data->num_keys ) {
3175                 DEBUG(8,("delete_all_printer_data: No keys left for printer [%s]\n", p2->printername ));
3176
3177                 SAFE_FREE( data->keys );
3178                 ZERO_STRUCTP( data );
3179         }
3180
3181         return WERR_OK;
3182 }
3183
3184 /****************************************************************************
3185  ***************************************************************************/
3186
3187 WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
3188 {
3189         WERROR          result = WERR_OK;
3190         int             key_index;
3191
3192         /* we must have names on non-zero length */
3193
3194         if ( !key || !*key|| !value || !*value )
3195                 return WERR_INVALID_NAME;
3196
3197         /* find the printer key first */
3198
3199         key_index = lookup_printerkey( p2->data, key );
3200         if ( key_index == -1 )
3201                 return WERR_OK;
3202
3203         /* make sure the value exists so we can return the correct error code */
3204
3205         if ( !regval_ctr_getvalue( p2->data->keys[key_index].values, value ) )
3206                 return WERR_BADFILE;
3207
3208         regval_ctr_delvalue( p2->data->keys[key_index].values, value );
3209
3210         DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n",
3211                 key, value ));
3212
3213         return result;
3214 }
3215
3216 /****************************************************************************
3217  ***************************************************************************/
3218
3219 WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value,
3220                            uint32 type, uint8 *data, int real_len )
3221 {
3222         WERROR          result = WERR_OK;
3223         int             key_index;
3224
3225         /* we must have names on non-zero length */
3226
3227         if ( !key || !*key|| !value || !*value )
3228                 return WERR_INVALID_NAME;
3229
3230         /* find the printer key first */
3231
3232         key_index = lookup_printerkey( p2->data, key );
3233         if ( key_index == -1 )
3234                 key_index = add_new_printer_key( p2->data, key );
3235
3236         if ( key_index == -1 )
3237                 return WERR_NOMEM;
3238
3239         regval_ctr_addvalue( p2->data->keys[key_index].values, value,
3240                 type, data, real_len );
3241
3242         DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n",
3243                 key, value, type, real_len  ));
3244
3245         return result;
3246 }
3247
3248 /****************************************************************************
3249  ***************************************************************************/
3250
3251 struct regval_blob* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
3252 {
3253         int             key_index;
3254
3255         if ( (key_index = lookup_printerkey( p2->data, key )) == -1 )
3256                 return NULL;
3257
3258         DEBUG(8,("get_printer_data: Attempting to lookup key => [%s], value => [%s]\n",
3259                 key, value ));
3260
3261         return regval_ctr_getvalue( p2->data->keys[key_index].values, value );
3262 }
3263
3264 /****************************************************************************
3265  Unpack a list of registry values frem the TDB
3266  ***************************************************************************/
3267
3268 static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int buflen)
3269 {
3270         int             len = 0;
3271         uint32          type;
3272         fstring string;
3273         const char *valuename = NULL;
3274         const char *keyname = NULL;
3275         char            *str;
3276         int             size;
3277         uint8           *data_p;
3278         struct regval_blob      *regval_p;
3279         int             key_index;
3280
3281         /* add the "PrinterDriverData" key first for performance reasons */
3282
3283         add_new_printer_key( printer_data, SPOOL_PRINTERDATA_KEY );
3284
3285         /* loop and unpack the rest of the registry values */
3286
3287         while ( True ) {
3288
3289                 /* check to see if there are any more registry values */
3290
3291                 regval_p = NULL;
3292                 len += tdb_unpack(buf+len, buflen-len, "p", &regval_p);
3293                 if ( !regval_p )
3294                         break;
3295
3296                 /* unpack the next regval */
3297
3298                 len += tdb_unpack(buf+len, buflen-len, "fdB",
3299                                   string,
3300                                   &type,
3301                                   &size,
3302                                   &data_p);
3303
3304                 /* lookup for subkey names which have a type of REG_NONE */
3305                 /* there's no data with this entry */
3306
3307                 if ( type == REG_NONE ) {
3308                         if ( (key_index=lookup_printerkey( printer_data, string)) == -1 )
3309                                 add_new_printer_key( printer_data, string );
3310                         continue;
3311                 }
3312
3313                 /*
3314                  * break of the keyname from the value name.
3315                  * Valuenames can have embedded '\'s so be careful.
3316                  * only support one level of keys.  See the
3317                  * "Konica Fiery S300 50C-K v1.1. enu" 2k driver.
3318                  * -- jerry
3319                  */
3320
3321                 str = strchr_m( string, '\\');
3322
3323                 /* Put in "PrinterDriverData" is no key specified */
3324
3325                 if ( !str ) {
3326                         keyname = SPOOL_PRINTERDATA_KEY;
3327                         valuename = string;
3328                 }
3329                 else {
3330                         *str = '\0';
3331                         keyname = string;
3332                         valuename = str+1;
3333                 }
3334
3335                 /* see if we need a new key */
3336
3337                 if ( (key_index=lookup_printerkey( printer_data, keyname )) == -1 )
3338                         key_index = add_new_printer_key( printer_data, keyname );
3339
3340                 if ( key_index == -1 ) {
3341                         DEBUG(0,("unpack_values: Failed to allocate a new key [%s]!\n",
3342                                 keyname));
3343                         break;
3344                 }
3345
3346                 DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size));
3347
3348                 /* Vista doesn't like unknown REG_BINARY values in DsSpooler.
3349                    Thanks to Martin Zielinski for the hint. */
3350
3351                 if ( type == REG_BINARY &&
3352                      strequal( keyname, SPOOL_DSSPOOLER_KEY ) &&
3353                      strequal( valuename, "objectGUID" ) )
3354                 {
3355                         struct GUID guid;
3356
3357                         /* convert the GUID to a UNICODE string */
3358
3359                         memcpy( &guid, data_p, sizeof(struct GUID) );
3360
3361                         regval_ctr_addvalue_sz(printer_data->keys[key_index].values,
3362                                                valuename,
3363                                                GUID_string(talloc_tos(), &guid));
3364
3365                 } else {
3366                         /* add the value */
3367
3368                         regval_ctr_addvalue( printer_data->keys[key_index].values,
3369                                              valuename, type, data_p,
3370                                              size );
3371                 }
3372
3373                 SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */
3374
3375         }
3376
3377         return len;
3378 }
3379
3380 /****************************************************************************
3381  ***************************************************************************/
3382
3383 static char *win_driver;
3384 static char *os2_driver;
3385
3386 static const char *get_win_driver(void)
3387 {
3388         if (win_driver == NULL) {
3389                 return "";
3390         }
3391         return win_driver;
3392 }
3393
3394 static const char *get_os2_driver(void)
3395 {
3396         if (os2_driver == NULL) {
3397                 return "";
3398         }
3399         return os2_driver;
3400 }
3401
3402 static bool set_driver_mapping(const char *from, const char *to)
3403 {
3404         SAFE_FREE(win_driver);
3405         SAFE_FREE(os2_driver);
3406
3407         win_driver = SMB_STRDUP(from);
3408         os2_driver = SMB_STRDUP(to);
3409
3410         if (win_driver == NULL || os2_driver == NULL) {
3411                 SAFE_FREE(win_driver);
3412                 SAFE_FREE(os2_driver);
3413                 return false;
3414         }
3415         return true;
3416 }
3417
3418 static void map_to_os2_driver(fstring drivername)
3419 {
3420         char *mapfile = lp_os2_driver_map();
3421         char **lines = NULL;
3422         int numlines = 0;
3423         int i;
3424
3425         if (!strlen(drivername))
3426                 return;
3427
3428         if (!*mapfile)
3429                 return;
3430
3431         if (strequal(drivername, get_win_driver())) {
3432                 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",
3433                         drivername, get_os2_driver()));
3434                 fstrcpy(drivername, get_os2_driver());
3435                 return;
3436         }
3437
3438         lines = file_lines_load(mapfile, &numlines,0,NULL);
3439         if (numlines == 0 || lines == NULL) {
3440                 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
3441                 TALLOC_FREE(lines);
3442                 return;
3443         }
3444
3445         DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
3446
3447         for( i = 0; i < numlines; i++) {
3448                 char *nt_name = lines[i];
3449                 char *os2_name = strchr(nt_name,'=');
3450
3451                 if (!os2_name)
3452                         continue;
3453
3454                 *os2_name++ = 0;
3455
3456                 while (isspace(*nt_name))
3457                         nt_name++;
3458
3459                 if (!*nt_name || strchr("#;",*nt_name))
3460                         continue;
3461
3462                 {
3463                         int l = strlen(nt_name);
3464                         while (l && isspace(nt_name[l-1])) {
3465                                 nt_name[l-1] = 0;
3466                                 l--;
3467                         }
3468                 }
3469
3470                 while (isspace(*os2_name))
3471                         os2_name++;
3472
3473                 {
3474                         int l = strlen(os2_name);
3475                         while (l && isspace(os2_name[l-1])) {
3476                                 os2_name[l-1] = 0;
3477                                 l--;
3478                         }
3479                 }
3480
3481                 if (strequal(nt_name,drivername)) {
3482                         DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
3483                         set_driver_mapping(drivername,os2_name);
3484                         fstrcpy(drivername,os2_name);
3485                         TALLOC_FREE(lines);
3486                         return;
3487                 }
3488         }
3489
3490         TALLOC_FREE(lines);
3491 }
3492
3493 /**
3494  * @internal
3495  *
3496  * @brief Map a Windows driver to a OS/2 driver.
3497  *
3498  * @param[in]  mem_ctx  The memory context to use.
3499  *
3500  * @param[in,out] pdrivername The drivername of Windows to remap.
3501  *
3502  * @return              WERR_OK on success, a corresponding WERROR on failure.
3503  */
3504 WERROR spoolss_map_to_os2_driver(TALLOC_CTX *mem_ctx, const char **pdrivername)
3505 {
3506         const char *mapfile = lp_os2_driver_map();
3507         char **lines = NULL;
3508         const char *drivername;
3509         int numlines = 0;
3510         int i;
3511
3512         if (pdrivername == NULL || *pdrivername == NULL || *pdrivername[0] == '\0') {
3513                 return WERR_INVALID_PARAMETER;
3514         }
3515
3516         drivername = *pdrivername;
3517
3518         if (mapfile[0] == '\0') {
3519                 return WERR_BADFILE;
3520         }
3521
3522         if (strequal(drivername, get_win_driver())) {
3523                 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",
3524                         drivername, get_os2_driver()));
3525                 drivername = talloc_strdup(mem_ctx, get_os2_driver());
3526                 if (drivername == NULL) {
3527                         return WERR_NOMEM;
3528                 }
3529                 *pdrivername = drivername;
3530                 return WERR_OK;
3531         }
3532
3533         lines = file_lines_load(mapfile, &numlines, 0, NULL);
3534         if (numlines == 0 || lines == NULL) {
3535                 DEBUG(0,("No entries in OS/2 driver map %s\n", mapfile));
3536                 TALLOC_FREE(lines);
3537                 return WERR_EMPTY;
3538         }
3539
3540         DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
3541
3542         for( i = 0; i < numlines; i++) {
3543                 char *nt_name = lines[i];
3544                 char *os2_name = strchr(nt_name, '=');
3545
3546                 if (os2_name == NULL) {
3547                         continue;
3548                 }
3549
3550                 *os2_name++ = '\0';
3551
3552                 while (isspace(*nt_name)) {
3553                         nt_name++;
3554                 }
3555
3556                 if (*nt_name == '\0' || strchr("#;", *nt_name)) {
3557                         continue;
3558                 }
3559
3560                 {
3561                         int l = strlen(nt_name);
3562                         while (l && isspace(nt_name[l - 1])) {
3563                                 nt_name[l - 1] = 0;
3564                                 l--;
3565                         }
3566                 }
3567
3568                 while (isspace(*os2_name)) {
3569                         os2_name++;
3570                 }
3571
3572                 {
3573                         int l = strlen(os2_name);
3574                         while (l && isspace(os2_name[l-1])) {
3575                                 os2_name[l-1] = 0;
3576                                 l--;
3577                         }
3578                 }
3579
3580                 if (strequal(nt_name, drivername)) {
3581                         DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,os2_name));
3582                         set_driver_mapping(drivername, os2_name);
3583                         drivername = talloc_strdup(mem_ctx, os2_name);
3584                         TALLOC_FREE(lines);
3585                         if (drivername == NULL) {
3586                                 return WERR_NOMEM;
3587                         }
3588                         *pdrivername = drivername;
3589                         return WERR_OK;
3590                 }
3591         }
3592
3593         TALLOC_FREE(lines);
3594         return WERR_OK;
3595 }
3596
3597 /****************************************************************************
3598  Get a default printer info 2 struct.
3599 ****************************************************************************/
3600
3601 static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info,
3602                                 const char *servername,
3603                                 const char* sharename,
3604                                 bool get_loc_com)
3605 {
3606         int snum = lp_servicenumber(sharename);
3607         WERROR result;
3608
3609         slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername);
3610         slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
3611                 servername, sharename);
3612         fstrcpy(info->sharename, sharename);
3613         fstrcpy(info->portname, SAMBA_PRINTER_PORT_NAME);
3614
3615         /* by setting the driver name to an empty string, a local NT admin
3616            can now run the **local** APW to install a local printer driver
3617            for a Samba shared printer in 2.2.  Without this, drivers **must** be
3618            installed on the Samba server for NT clients --jerry */
3619 #if 0   /* JERRY --do not uncomment-- */
3620         if (!*info->drivername)
3621                 fstrcpy(info->drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
3622 #endif
3623
3624
3625         DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info->drivername));
3626
3627         strlcpy(info->comment, "", sizeof(info->comment));
3628         fstrcpy(info->printprocessor, "winprint");
3629         fstrcpy(info->datatype, "RAW");
3630
3631 #ifdef HAVE_CUPS
3632         if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
3633                 /* Pull the location and comment strings from cups if we don't
3634                    already have one */
3635                 if ( !strlen(info->location) || !strlen(info->comment) ) {
3636                         char *comment = NULL;
3637                         char *location = NULL;
3638                         if (cups_pull_comment_location(info, info->sharename,
3639                                                        &comment, &location)) {
3640                                 strlcpy(info->comment, comment, sizeof(info->comment));
3641                                 fstrcpy(info->location, location);
3642                                 TALLOC_FREE(comment);
3643                                 TALLOC_FREE(location);
3644                         }
3645                 }
3646         }
3647 #endif
3648
3649         info->attributes = PRINTER_ATTRIBUTE_SAMBA;
3650
3651         info->starttime = 0; /* Minutes since 12:00am GMT */
3652         info->untiltime = 0; /* Minutes since 12:00am GMT */
3653         info->priority = 1;
3654         info->default_priority = 1;
3655         info->setuptime = (uint32)time(NULL);
3656
3657         /*
3658          * I changed this as I think it is better to have a generic
3659          * DEVMODE than to crash Win2k explorer.exe   --jerry
3660          * See the HP Deskjet 990c Win2k drivers for an example.
3661          *
3662          * However the default devmode appears to cause problems
3663          * with the HP CLJ 8500 PCL driver.  Hence the addition of
3664          * the "default devmode" parameter   --jerry 22/01/2002
3665          */
3666
3667         if (lp_default_devmode(snum)) {
3668                 result = spoolss_create_default_devmode(info,
3669                                                         info->printername,
3670                                                         &info->devmode);
3671                 if (!W_ERROR_IS_OK(result)) {
3672                         goto fail;
3673                 }
3674         } else {
3675                 info->devmode = NULL;
3676         }
3677
3678         if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) {
3679                 goto fail;
3680         }
3681
3682         info->data = TALLOC_ZERO_P(info, NT_PRINTER_DATA);
3683         if (!info->data) {
3684                 goto fail;
3685         }
3686
3687         add_new_printer_key(info->data, SPOOL_PRINTERDATA_KEY);
3688
3689         return WERR_OK;
3690
3691 fail:
3692         TALLOC_FREE(info->devmode);
3693
3694         return WERR_ACCESS_DENIED;
3695 }
3696
3697 /****************************************************************************
3698 ****************************************************************************/
3699
3700 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info,
3701                                 const char *servername,
3702                                 const char *sharename,
3703                                 bool get_loc_com)
3704 {
3705         int len = 0;
3706         int snum = lp_servicenumber(sharename);
3707         TDB_DATA kbuf, dbuf;
3708         fstring printername;
3709         char *comment = NULL;
3710         WERROR result;
3711
3712         kbuf = make_printer_tdbkey(talloc_tos(), sharename);
3713
3714         dbuf = tdb_fetch(tdb_printers, kbuf);
3715         if (!dbuf.dptr) {
3716                 return get_a_printer_2_default(info, servername,
3717                                         sharename, get_loc_com);
3718         }
3719
3720         len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
3721                         &info->attributes,
3722                         &info->priority,
3723                         &info->default_priority,
3724                         &info->starttime,
3725                         &info->untiltime,
3726                         &info->status,
3727                         &info->cjobs,
3728                         &info->averageppm,
3729                         &info->changeid,
3730                         &info->c_setprinter,
3731                         &info->setuptime,
3732                         info->servername,
3733                         info->printername,
3734                         info->sharename,
3735                         info->portname,
3736                         info->drivername,
3737                         &comment,
3738                         info->location,
3739                         info->sepfile,
3740                         info->printprocessor,
3741                         info->datatype,
3742                         info->parameters);
3743
3744         if (comment) {
3745                 strlcpy(info->comment, comment, sizeof(info->comment));
3746                 SAFE_FREE(comment);
3747         }
3748
3749         /* Samba has to have shared raw drivers. */
3750         info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
3751         info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
3752
3753         /* Restore the stripped strings. */
3754         slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername);
3755
3756         if ( lp_force_printername(snum) ) {
3757                 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, sharename );
3758         } else {
3759                 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, info->printername);
3760         }
3761
3762         fstrcpy(info->printername, printername);
3763
3764 #ifdef HAVE_CUPS
3765         if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
3766                 /* Pull the location and comment strings from cups if we don't
3767                    already have one */
3768                 if ( !strlen(info->location) || !strlen(info->comment) ) {
3769                         char *location = NULL;
3770                         comment = NULL;
3771                         if (cups_pull_comment_location(info, info->sharename,
3772                                                        &comment, &location)) {
3773                                 strlcpy(info->comment, comment, sizeof(info->comment));
3774                                 fstrcpy(info->location, location);
3775                                 TALLOC_FREE(comment);
3776                                 TALLOC_FREE(location);
3777                         }
3778                 }
3779         }
3780 #endif
3781
3782         len += unpack_devicemode(info, dbuf.dptr+len,
3783                                         dbuf.dsize-len,
3784                                         &info->devmode);
3785
3786         /*
3787          * Some client drivers freak out if there is a NULL devmode
3788          * (probably the driver is not checking before accessing
3789          * the devmode pointer)   --jerry
3790          *
3791          * See comments in get_a_printer_2_default()
3792          */
3793
3794         if (lp_default_devmode(snum) && !info->devmode) {
3795                 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
3796                         printername));
3797                 result = spoolss_create_default_devmode(info, printername,
3798                                                         &info->devmode);
3799                 if (!W_ERROR_IS_OK(result)) {
3800                         goto done;
3801                 }
3802         }
3803
3804         if (info->devmode) {
3805                 info->devmode->devicename = talloc_strdup(info->devmode,
3806                                                           info->printername);
3807                 if (!info->devmode->devicename) {
3808                         result = WERR_NOMEM;
3809                         goto done;
3810                 }
3811         }
3812
3813         if ( !(info->data = TALLOC_ZERO_P( info, NT_PRINTER_DATA )) ) {
3814                 DEBUG(0,("unpack_values: talloc() failed!\n"));
3815                 result = WERR_NOMEM;
3816                 goto done;
3817         }
3818         len += unpack_values( info->data, dbuf.dptr+len, dbuf.dsize-len );
3819
3820         /* This will get the current RPC talloc context, but we should be
3821            passing this as a parameter... fixme... JRA ! */
3822
3823         if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) {
3824                 result = WERR_NOMEM;
3825                 goto done;
3826         }
3827
3828         /* Fix for OS/2 drivers. */
3829
3830         if (get_remote_arch() == RA_OS2) {
3831                 map_to_os2_driver(info->drivername);
3832         }
3833
3834         DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
3835                  sharename, info->printername, info->drivername));
3836
3837         result = WERR_OK;
3838
3839 done:
3840         SAFE_FREE(dbuf.dptr);
3841         return result;
3842 }
3843
3844 /****************************************************************************
3845  Debugging function, dump at level 6 the struct in the logs.
3846 ****************************************************************************/
3847 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
3848 {
3849         uint32 result;
3850         NT_PRINTER_INFO_LEVEL_2 *info2;
3851
3852         DEBUG(106,("Dumping printer at level [%d]\n", level));
3853
3854         switch (level) {
3855                 case 2:
3856                 {
3857                         if (printer->info_2 == NULL)
3858                                 result=5;
3859                         else
3860                         {
3861                                 info2=printer->info_2;
3862
3863                                 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
3864                                 DEBUGADD(106,("priority:[%d]\n", info2->priority));
3865                                 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
3866                                 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
3867                                 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
3868                                 DEBUGADD(106,("status:[%d]\n", info2->status));
3869                                 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
3870                                 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
3871                                 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
3872                                 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
3873                                 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
3874
3875                                 DEBUGADD(106,("servername:[%s]\n", info2->servername));
3876                                 DEBUGADD(106,("printername:[%s]\n", info2->printername));
3877                                 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
3878                                 DEBUGADD(106,("portname:[%s]\n", info2->portname));
3879                                 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
3880                                 DEBUGADD(106,("comment:[%s]\n", info2->comment));
3881                                 DEBUGADD(106,("location:[%s]\n", info2->location));
3882                                 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
3883                                 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
3884                                 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
3885                                 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
3886                                 result=0;
3887                         }
3888                         break;
3889                 }
3890                 default:
3891                         DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level ));
3892                         result=1;
3893                         break;
3894         }
3895
3896         return result;
3897 }
3898
3899 /****************************************************************************
3900  Update the changeid time.
3901  This is SO NASTY as some drivers need this to change, others need it
3902  static. This value will change every second, and I must hope that this
3903  is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
3904  UTAH ! JRA.
3905 ****************************************************************************/
3906
3907 static uint32 rev_changeid(void)
3908 {
3909         struct timeval tv;
3910
3911         get_process_uptime(&tv);
3912
3913 #if 1   /* JERRY */
3914         /* Return changeid as msec since spooler restart */
3915         return tv.tv_sec * 1000 + tv.tv_usec / 1000;
3916 #else
3917         /*
3918          * This setting seems to work well but is too untested
3919          * to replace the above calculation.  Left in for experiementation
3920          * of the reader            --jerry (Tue Mar 12 09:15:05 CST 2002)
3921          */
3922         return tv.tv_sec * 10 + tv.tv_usec / 100000;
3923 #endif
3924 }
3925
3926
3927 /*
3928  * The function below are the high level ones.
3929  * only those ones must be called from the spoolss code.
3930  * JFM.
3931  */
3932
3933 /****************************************************************************
3934  Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
3935 ****************************************************************************/
3936
3937 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
3938 {
3939         WERROR result;
3940
3941         dump_a_printer(printer, level);
3942
3943         switch (level) {
3944                 case 2:
3945                 {
3946                         /*
3947                          * Update the changestamp.  Emperical tests show that the
3948                          * ChangeID is always updated,but c_setprinter is
3949                          *  global spooler variable (not per printer).
3950                          */
3951
3952                         /* ChangeID **must** be increasing over the lifetime
3953                            of client's spoolss service in order for the
3954                            client's cache to show updates */
3955
3956                         printer->info_2->changeid = rev_changeid();
3957
3958                         /*
3959                          * Because one day someone will ask:
3960                          * NT->NT       An admin connection to a remote
3961                          *              printer show changes imeediately in
3962                          *              the properities dialog
3963                          *
3964                          *              A non-admin connection will only show the
3965                          *              changes after viewing the properites page
3966                          *              2 times.  Seems to be related to a
3967                          *              race condition in the client between the spooler
3968                          *              updating the local cache and the Explorer.exe GUI
3969                          *              actually displaying the properties.
3970                          *
3971                          *              This is fixed in Win2k.  admin/non-admin
3972                          *              connections both display changes immediately.
3973                          *
3974                          * 14/12/01     --jerry
3975                          */
3976
3977                         result=update_a_printer_2(printer->info_2);
3978                         break;
3979                 }
3980                 default:
3981                         result=WERR_UNKNOWN_LEVEL;
3982                         break;
3983         }
3984
3985         return result;
3986 }
3987
3988 /****************************************************************************
3989  Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
3990
3991  Previously the code had a memory allocation problem because it always
3992  used the TALLOC_CTX from the Printer_entry*.   This context lasts
3993  as a long as the original handle is open.  So if the client made a lot
3994  of getprinter[data]() calls, the memory usage would climb.  Now we use
3995  a short lived TALLOC_CTX for printer_info_2 objects returned.  We
3996  still use the Printer_entry->ctx for maintaining the cache copy though
3997  since that object must live as long as the handle by definition.
3998                                                     --jerry
3999
4000 ****************************************************************************/
4001
4002 static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level,
4003                         const char *sharename, bool get_loc_com)
4004 {
4005         WERROR result;
4006         fstring servername;
4007
4008         DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
4009
4010         if ( !(*pp_printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
4011                 DEBUG(0,("get_a_printer: talloc() fail.\n"));
4012                 return WERR_NOMEM;
4013         }
4014
4015         switch (level) {
4016                 case 2:
4017                         if ( !((*pp_printer)->info_2 = TALLOC_ZERO_P(*pp_printer, NT_PRINTER_INFO_LEVEL_2)) ) {
4018                                 DEBUG(0,("get_a_printer: talloc() fail.\n"));
4019                                 TALLOC_FREE( *pp_printer );
4020                                 return WERR_NOMEM;
4021                         }
4022
4023                         if ( print_hnd )
4024                                 fstrcpy( servername, print_hnd->servername );
4025                         else {
4026                                 fstrcpy( servername, "%L" );
4027                                 standard_sub_basic( "", "", servername,
4028                                                     sizeof(servername)-1 );
4029                         }
4030
4031                         result = get_a_printer_2( (*pp_printer)->info_2,
4032                                         servername, sharename, get_loc_com);
4033
4034                         /* we have a new printer now.  Save it with this handle */
4035
4036                         if ( !W_ERROR_IS_OK(result) ) {
4037                                 TALLOC_FREE( *pp_printer );
4038                                 DEBUG(10,("get_a_printer: [%s] level %u returning %s\n",
4039                                         sharename, (unsigned int)level, win_errstr(result)));
4040                                 return result;
4041                         }
4042
4043                         dump_a_printer( *pp_printer, level);
4044
4045                         break;
4046
4047                 default:
4048                         TALLOC_FREE( *pp_printer );
4049                         return WERR_UNKNOWN_LEVEL;
4050         }
4051
4052         return WERR_OK;
4053 }
4054
4055 WERROR get_a_printer( Printer_entry *print_hnd,
4056                         NT_PRINTER_INFO_LEVEL **pp_printer,
4057                         uint32 level,
4058                         const char *sharename)
4059 {
4060         return get_a_printer_internal(print_hnd, pp_printer, level,
4061                                         sharename, true);
4062 }
4063
4064 WERROR get_a_printer_search( Printer_entry *print_hnd,
4065                         NT_PRINTER_INFO_LEVEL **pp_printer,
4066                         uint32 level,
4067                         const char *sharename)
4068 {
4069         return get_a_printer_internal(print_hnd, pp_printer, level,
4070                                         sharename, false);
4071 }
4072
4073 /****************************************************************************
4074  Deletes a NT_PRINTER_INFO_LEVEL struct.
4075 ****************************************************************************/
4076
4077 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
4078 {
4079         NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
4080
4081         if ( !printer )
4082                 return 0;
4083
4084         switch (level) {
4085                 case 2:
4086                         TALLOC_FREE(printer->info_2);
4087                         break;
4088
4089                 default:
4090                         DEBUG(0,("free_a_printer: unknown level! [%d]\n", level ));
4091                         return 1;
4092         }
4093
4094         TALLOC_FREE(*pp_printer);
4095
4096         return 0;
4097 }
4098
4099 /****************************************************************************
4100 ****************************************************************************/
4101
4102 bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
4103                               struct spoolss_DriverInfo8 *_info8)
4104 {
4105         struct spoolss_DriverInfo8 info8;
4106
4107         ZERO_STRUCT(info8);
4108
4109         switch (r->level) {
4110         case 3:
4111                 info8.version           = r->info.info3->version;
4112                 info8.driver_name       = r->info.info3->driver_name;
4113                 info8.architecture      = r->info.info3->architecture;
4114                 info8.driver_path       = r->info.info3->driver_path;
4115                 info8.data_file         = r->info.info3->data_file;
4116                 info8.config_file       = r->info.info3->config_file;
4117                 info8.help_file         = r->info.info3->help_file;
4118                 info8.monitor_name      = r->info.info3->monitor_name;
4119                 info8.default_datatype  = r->info.info3->default_datatype;
4120                 if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) {
4121                         info8.dependent_files   = r->info.info3->dependent_files->string;
4122                 }
4123                 break;
4124         case 6:
4125                 info8.version           = r->info.info6->version;
4126                 info8.driver_name       = r->info.info6->driver_name;
4127                 info8.architecture      = r->info.info6->architecture;
4128                 info8.driver_path       = r->info.info6->driver_path;
4129                 info8.data_file         = r->info.info6->data_file;
4130                 info8.config_file       = r->info.info6->config_file;
4131                 info8.help_file         = r->info.info6->help_file;
4132                 info8.monitor_name      = r->info.info6->monitor_name;
4133                 info8.default_datatype  = r->info.info6->default_datatype;
4134                 if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) {
4135                         info8.dependent_files   = r->info.info6->dependent_files->string;
4136                 }
4137                 info8.driver_date       = r->info.info6->driver_date;
4138                 info8.driver_version    = r->info.info6->driver_version;
4139                 info8.manufacturer_name = r->info.info6->manufacturer_name;
4140                 info8.manufacturer_url  = r->info.info6->manufacturer_url;
4141                 info8.hardware_id       = r->info.info6->hardware_id;
4142                 info8.provider          = r->info.info6->provider;
4143                 break;
4144         case 8:
4145                 info8.version           = r->info.info8->version;
4146                 info8.driver_name       = r->info.info8->driver_name;
4147                 info8.architecture      = r->info.info8->architecture;
4148                 info8.driver_path       = r->info.info8->driver_path;
4149                 info8.data_file         = r->info.info8->data_file;
4150                 info8.config_file       = r->info.info8->config_file;
4151                 info8.help_file         = r->info.info8->help_file;
4152                 info8.monitor_name      = r->info.info8->monitor_name;
4153                 info8.default_datatype  = r->info.info8->default_datatype;
4154                 if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) {
4155                         info8.dependent_files   = r->info.info8->dependent_files->string;
4156                 }
4157                 if (r->info.info8->previous_names && r->info.info8->previous_names->string) {
4158                         info8.previous_names    = r->info.info8->previous_names->string;
4159                 }
4160                 info8.driver_date       = r->info.info8->driver_date;
4161                 info8.driver_version    = r->info.info8->driver_version;
4162                 info8.manufacturer_name = r->info.info8->manufacturer_name;
4163                 info8.manufacturer_url  = r->info.info8->manufacturer_url;
4164                 info8.hardware_id       = r->info.info8->hardware_id;
4165                 info8.provider          = r->info.info8->provider;
4166                 info8.print_processor   = r->info.info8->print_processor;
4167                 info8.vendor_setup      = r->info.info8->vendor_setup;
4168                 if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) {
4169                         info8.color_profiles = r->info.info8->color_profiles->string;
4170                 }
4171                 info8.inf_path          = r->info.info8->inf_path;
4172                 info8.printer_driver_attributes = r->info.info8->printer_driver_attributes;
4173                 if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) {
4174                         info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string;
4175                 }
4176                 info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date;
4177                 info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version;
4178                 break;
4179         default:
4180                 return false;
4181         }
4182
4183         *_info8 = info8;
4184
4185         return true;
4186 }
4187
4188
4189 /****************************************************************************
4190   Determine whether or not a particular driver is currently assigned
4191   to a printer
4192 ****************************************************************************/
4193
4194 bool printer_driver_in_use(TALLOC_CTX *mem_ctx,
4195                            struct auth_serversupplied_info *server_info,
4196                            const struct spoolss_DriverInfo8 *r)
4197 {
4198         int snum;
4199         int n_services = lp_numservices();
4200         bool in_use = False;
4201         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
4202         WERROR result;
4203
4204         if (!r) {
4205                 return false;
4206         }
4207
4208         DEBUG(10,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n"));
4209
4210         /* loop through the printers.tdb and check for the drivername */
4211
4212         for (snum=0; snum<n_services && !in_use; snum++) {
4213                 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
4214                         continue;
4215                 }
4216
4217                 result = winreg_get_printer(mem_ctx, server_info, NULL,
4218                                             lp_servicename(snum), &pinfo2);
4219                 if (!W_ERROR_IS_OK(result)) {
4220                         continue; /* skip */
4221                 }
4222
4223                 if (strequal(r->driver_name, pinfo2->drivername)) {
4224                         in_use = True;
4225                 }
4226
4227                 TALLOC_FREE(pinfo2);
4228         }
4229
4230         DEBUG(10,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
4231
4232         if ( in_use ) {
4233                 struct spoolss_DriverInfo8 *driver;
4234                 WERROR werr;
4235
4236                 DEBUG(5,("printer_driver_in_use: driver \"%s\" is currently in use\n", r->driver_name));
4237
4238                 /* we can still remove the driver if there is one of
4239                    "Windows NT x86" version 2 or 3 left */
4240
4241                 if (!strequal("Windows NT x86", r->architecture)) {
4242                         werr = winreg_get_driver(mem_ctx, server_info,
4243                                                  "Windows NT x86",
4244                                                  r->driver_name,
4245                                                  DRIVER_ANY_VERSION,
4246                                                  &driver);
4247                 } else if (r->version == 2) {
4248                         werr = winreg_get_driver(mem_ctx, server_info,
4249                                                  "Windows NT x86",
4250                                                  r->driver_name,
4251                                                  3, &driver);
4252                 } else if (r->version == 3) {
4253                         werr = winreg_get_driver(mem_ctx, server_info,
4254                                                  "Windows NT x86",
4255                                                  r->driver_name,
4256                                                  2, &driver);
4257                 } else {
4258                         DEBUG(0, ("printer_driver_in_use: ERROR!"
4259                                   " unknown driver version (%d)\n",
4260                                   r->version));
4261                         werr = WERR_UNKNOWN_PRINTER_DRIVER;
4262                 }
4263
4264                 /* now check the error code */
4265
4266                 if ( W_ERROR_IS_OK(werr) ) {
4267                         /* it's ok to remove the driver, we have other architctures left */
4268                         in_use = False;
4269                         talloc_free(driver);
4270                 }
4271         }
4272
4273         /* report that the driver is not in use by default */
4274
4275         return in_use;
4276 }
4277
4278
4279 /**********************************************************************
4280  Check to see if a ogiven file is in use by *info
4281  *********************************************************************/
4282
4283 static bool drv_file_in_use(const char *file, const struct spoolss_DriverInfo8 *info)
4284 {
4285         int i = 0;
4286
4287         if ( !info )
4288                 return False;
4289
4290         /* mz: skip files that are in the list but already deleted */
4291         if (!file || !file[0]) {
4292                 return false;
4293         }
4294
4295         if (strequal(file, info->driver_path))
4296                 return True;
4297
4298         if (strequal(file, info->data_file))
4299                 return True;
4300
4301         if (strequal(file, info->config_file))
4302                 return True;
4303
4304         if (strequal(file, info->help_file))
4305                 return True;
4306
4307         /* see of there are any dependent files to examine */
4308
4309         if (!info->dependent_files)
4310                 return False;
4311
4312         while (info->dependent_files[i] && *info->dependent_files[i]) {
4313                 if (strequal(file, info->dependent_files[i]))
4314                         return True;
4315                 i++;
4316         }
4317
4318         return False;
4319
4320 }
4321
4322 /**********************************************************************
4323  Utility function to remove the dependent file pointed to by the
4324  input parameter from the list
4325  *********************************************************************/
4326
4327 static void trim_dependent_file(TALLOC_CTX *mem_ctx, const char **files, int idx)
4328 {
4329
4330         /* bump everything down a slot */
4331
4332         while (files && files[idx+1]) {
4333                 files[idx] = talloc_strdup(mem_ctx, files[idx+1]);
4334                 idx++;
4335         }
4336
4337         files[idx] = NULL;
4338
4339         return;
4340 }
4341
4342 /**********************************************************************
4343  Check if any of the files used by src are also used by drv
4344  *********************************************************************/
4345
4346 static bool trim_overlap_drv_files(TALLOC_CTX *mem_ctx,
4347                                    struct spoolss_DriverInfo8 *src,
4348                                    const struct spoolss_DriverInfo8 *drv)
4349 {
4350         bool    in_use = False;
4351         int     i = 0;
4352
4353         if ( !src || !drv )
4354                 return False;
4355
4356         /* check each file.  Remove it from the src structure if it overlaps */
4357
4358         if (drv_file_in_use(src->driver_path, drv)) {
4359                 in_use = True;
4360                 DEBUG(10,("Removing driverfile [%s] from list\n", src->driver_path));
4361                 src->driver_path = talloc_strdup(mem_ctx, "");
4362                 if (!src->driver_path) { return false; }
4363         }
4364
4365         if (drv_file_in_use(src->data_file, drv)) {
4366                 in_use = True;
4367                 DEBUG(10,("Removing datafile [%s] from list\n", src->data_file));
4368                 src->data_file = talloc_strdup(mem_ctx, "");
4369                 if (!src->data_file) { return false; }
4370         }
4371
4372         if (drv_file_in_use(src->config_file, drv)) {
4373                 in_use = True;
4374                 DEBUG(10,("Removing configfile [%s] from list\n", src->config_file));
4375                 src->config_file = talloc_strdup(mem_ctx, "");
4376                 if (!src->config_file) { return false; }
4377         }
4378
4379         if (drv_file_in_use(src->help_file, drv)) {
4380                 in_use = True;
4381                 DEBUG(10,("Removing helpfile [%s] from list\n", src->help_file));
4382                 src->help_file = talloc_strdup(mem_ctx, "");
4383                 if (!src->help_file) { return false; }
4384         }
4385
4386         /* are there any dependentfiles to examine? */
4387
4388         if (!src->dependent_files)
4389                 return in_use;
4390
4391         while (src->dependent_files[i] && *src->dependent_files[i]) {
4392                 if (drv_file_in_use(src->dependent_files[i], drv)) {
4393                         in_use = True;
4394                         DEBUG(10,("Removing [%s] from dependent file list\n", src->dependent_files[i]));
4395                         trim_dependent_file(mem_ctx, src->dependent_files, i);
4396                 } else
4397                         i++;
4398         }
4399
4400         return in_use;
4401 }
4402
4403 /****************************************************************************
4404   Determine whether or not a particular driver files are currently being
4405   used by any other driver.
4406
4407   Return value is True if any files were in use by other drivers
4408   and False otherwise.
4409
4410   Upon return, *info has been modified to only contain the driver files
4411   which are not in use
4412
4413   Fix from mz:
4414
4415   This needs to check all drivers to ensure that all files in use
4416   have been removed from *info, not just the ones in the first
4417   match.
4418 ****************************************************************************/
4419
4420 bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx,
4421                                  struct auth_serversupplied_info *server_info,
4422                                  struct spoolss_DriverInfo8 *info)
4423 {
4424         int                             i;
4425         uint32                          version;
4426         struct spoolss_DriverInfo8      *driver;
4427         bool in_use = false;
4428         uint32_t num_drivers;
4429         const char **drivers;
4430         WERROR result;
4431
4432         if ( !info )
4433                 return False;
4434
4435         version = info->version;
4436
4437         /* loop over all driver versions */
4438
4439         DEBUG(5,("printer_driver_files_in_use: Beginning search of drivers...\n"));
4440
4441         /* get the list of drivers */
4442
4443         result = winreg_get_driver_list(mem_ctx, server_info,
4444                                         info->architecture, version,
4445                                         &num_drivers, &drivers);
4446         if (!W_ERROR_IS_OK(result)) {
4447                 return true;
4448         }
4449
4450         DEBUGADD(4, ("we have:[%d] drivers in environment [%s] and version [%d]\n",
4451                      num_drivers, info->architecture, version));
4452
4453         /* check each driver for overlap in files */
4454
4455         for (i = 0; i < num_drivers; i++) {
4456                 DEBUGADD(5,("\tdriver: [%s]\n", drivers[i]));
4457
4458                 driver = NULL;
4459
4460                 result = winreg_get_driver(mem_ctx, server_info,
4461                                            info->architecture, drivers[i],
4462                                            version, &driver);
4463                 if (!W_ERROR_IS_OK(result)) {
4464                         talloc_free(drivers);
4465                         return True;
4466                 }
4467
4468                 /* check if d2 uses any files from d1 */
4469                 /* only if this is a different driver than the one being deleted */
4470
4471                 if (!strequal(info->driver_name, driver->driver_name)) {
4472                         if (trim_overlap_drv_files(mem_ctx, info, driver)) {
4473                                 /* mz: Do not instantly return -
4474                                  * we need to ensure this file isn't
4475                                  * also in use by other drivers. */
4476                                 in_use = true;
4477                         }
4478                 }
4479
4480                 talloc_free(driver);
4481         }
4482
4483         talloc_free(drivers);
4484
4485         DEBUG(5,("printer_driver_files_in_use: Completed search of drivers...\n"));
4486
4487         return in_use;
4488 }
4489
4490 static NTSTATUS driver_unlink_internals(connection_struct *conn,
4491                                         const char *name)
4492 {
4493         struct smb_filename *smb_fname = NULL;
4494         NTSTATUS status;
4495
4496         status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
4497             &smb_fname);
4498         if (!NT_STATUS_IS_OK(status)) {
4499                 return status;
4500         }
4501
4502         status = unlink_internals(conn, NULL, 0, smb_fname, false);
4503
4504         TALLOC_FREE(smb_fname);
4505         return status;
4506 }
4507
4508 /****************************************************************************
4509   Actually delete the driver files.  Make sure that
4510   printer_driver_files_in_use() return False before calling
4511   this.
4512 ****************************************************************************/
4513
4514 bool delete_driver_files(struct auth_serversupplied_info *server_info,
4515                          const struct spoolss_DriverInfo8 *r)
4516 {
4517         int i = 0;
4518         char *s;
4519         const char *file;
4520         connection_struct *conn;
4521         NTSTATUS nt_status;
4522         char *oldcwd;
4523         fstring printdollar;
4524         int printdollar_snum;
4525         bool ret = false;
4526
4527         if (!r) {
4528                 return false;
4529         }
4530
4531         DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n",
4532                 r->driver_name, r->version));
4533
4534         fstrcpy(printdollar, "print$");
4535
4536         printdollar_snum = find_service(printdollar);
4537         if (printdollar_snum == -1) {
4538                 return false;
4539         }
4540
4541         nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
4542                                        lp_pathname(printdollar_snum),
4543                                        server_info, &oldcwd);
4544         if (!NT_STATUS_IS_OK(nt_status)) {
4545                 DEBUG(0,("delete_driver_files: create_conn_struct "
4546                          "returned %s\n", nt_errstr(nt_status)));
4547                 return false;
4548         }
4549
4550         if ( !CAN_WRITE(conn) ) {
4551                 DEBUG(3,("delete_driver_files: Cannot delete print driver when [print$] is read-only\n"));
4552                 goto fail;
4553         }
4554
4555         /* now delete the files; must strip the '\print$' string from
4556            fron of path                                                */
4557
4558         if (r->driver_path && r->driver_path[0]) {
4559                 if ((s = strchr(&r->driver_path[1], '\\')) != NULL) {
4560                         file = s;
4561                         DEBUG(10,("deleting driverfile [%s]\n", s));
4562                         driver_unlink_internals(conn, file);
4563                 }
4564         }
4565
4566         if (r->config_file && r->config_file[0]) {
4567                 if ((s = strchr(&r->config_file[1], '\\')) != NULL) {
4568                         file = s;
4569                         DEBUG(10,("deleting configfile [%s]\n", s));
4570                         driver_unlink_internals(conn, file);
4571                 }
4572         }
4573
4574         if (r->data_file && r->data_file[0]) {
4575                 if ((s = strchr(&r->data_file[1], '\\')) != NULL) {
4576                         file = s;
4577                         DEBUG(10,("deleting datafile [%s]\n", s));
4578                         driver_unlink_internals(conn, file);
4579                 }
4580         }
4581
4582         if (r->help_file && r->help_file[0]) {
4583                 if ((s = strchr(&r->help_file[1], '\\')) != NULL) {
4584                         file = s;
4585                         DEBUG(10,("deleting helpfile [%s]\n", s));
4586                         driver_unlink_internals(conn, file);
4587                 }
4588         }
4589
4590         /* check if we are done removing files */
4591
4592         if (r->dependent_files) {
4593                 while (r->dependent_files[i] && r->dependent_files[i][0]) {
4594                         char *p;
4595
4596                         /* bypass the "\print$" portion of the path */
4597
4598                         if ((p = strchr(r->dependent_files[i]+1, '\\')) != NULL) {
4599                                 file = p;
4600                                 DEBUG(10,("deleting dependent file [%s]\n", file));
4601                                 driver_unlink_internals(conn, file);
4602                         }
4603
4604                         i++;
4605                 }
4606         }
4607
4608         goto done;
4609  fail:
4610         ret = false;
4611  done:
4612         if (conn != NULL) {
4613                 vfs_ChDir(conn, oldcwd);
4614                 conn_free(conn);
4615         }
4616         return ret;
4617 }
4618
4619 /****************************************************************************
4620  Store a security desc for a printer.
4621 ****************************************************************************/
4622
4623 WERROR nt_printing_setsec(const char *sharename, struct sec_desc_buf *secdesc_ctr)
4624 {
4625         struct sec_desc_buf *new_secdesc_ctr = NULL;
4626         struct sec_desc_buf *old_secdesc_ctr = NULL;
4627         TALLOC_CTX *mem_ctx = NULL;
4628         TDB_DATA kbuf;
4629         TDB_DATA dbuf;
4630         DATA_BLOB blob;
4631         WERROR status;
4632         NTSTATUS nt_status;
4633
4634         mem_ctx = talloc_init("nt_printing_setsec");
4635         if (mem_ctx == NULL)
4636                 return WERR_NOMEM;
4637
4638         /* The old owner and group sids of the security descriptor are not
4639            present when new ACEs are added or removed by changing printer
4640            permissions through NT.  If they are NULL in the new security
4641            descriptor then copy them over from the old one. */
4642
4643         if (!secdesc_ctr->sd->owner_sid || !secdesc_ctr->sd->group_sid) {
4644                 struct dom_sid *owner_sid, *group_sid;
4645                 struct security_acl *dacl, *sacl;
4646                 struct security_descriptor *psd = NULL;
4647                 size_t size;
4648
4649                 if (!nt_printing_getsec(mem_ctx, sharename, &old_secdesc_ctr)) {
4650                         status = WERR_NOMEM;
4651                         goto out;
4652                 }
4653
4654                 /* Pick out correct owner and group sids */
4655
4656                 owner_sid = secdesc_ctr->sd->owner_sid ?
4657                         secdesc_ctr->sd->owner_sid :
4658                         old_secdesc_ctr->sd->owner_sid;
4659
4660                 group_sid = secdesc_ctr->sd->group_sid ?
4661                         secdesc_ctr->sd->group_sid :
4662                         old_secdesc_ctr->sd->group_sid;
4663
4664                 dacl = secdesc_ctr->sd->dacl ?
4665                         secdesc_ctr->sd->dacl :
4666                         old_secdesc_ctr->sd->dacl;
4667
4668                 sacl = secdesc_ctr->sd->sacl ?
4669                         secdesc_ctr->sd->sacl :
4670                         old_secdesc_ctr->sd->sacl;
4671
4672                 /* Make a deep copy of the security descriptor */
4673
4674                 psd = make_sec_desc(mem_ctx, secdesc_ctr->sd->revision, secdesc_ctr->sd->type,
4675                                     owner_sid, group_sid,
4676                                     sacl,
4677                                     dacl,
4678                                     &size);
4679
4680                 if (!psd) {
4681                         status = WERR_NOMEM;
4682                         goto out;
4683                 }
4684
4685                 new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);
4686         }
4687
4688         if (!new_secdesc_ctr) {
4689                 new_secdesc_ctr = secdesc_ctr;
4690         }
4691
4692         /* Store the security descriptor in a tdb */
4693
4694         nt_status = marshall_sec_desc_buf(mem_ctx, new_secdesc_ctr,
4695                                           &blob.data, &blob.length);
4696         if (!NT_STATUS_IS_OK(nt_status)) {
4697                 status = ntstatus_to_werror(nt_status);
4698                 goto out;
4699         }
4700
4701         kbuf = make_printers_secdesc_tdbkey(mem_ctx, sharename );
4702
4703         dbuf.dptr = (unsigned char *)blob.data;
4704         dbuf.dsize = blob.length;
4705
4706         if (tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE)==0) {
4707                 status = WERR_OK;
4708         } else {
4709                 DEBUG(1,("Failed to store secdesc for %s\n", sharename));
4710                 status = WERR_BADFUNC;
4711         }
4712
4713         /* Free malloc'ed memory */
4714         talloc_free(blob.data);
4715
4716  out:
4717
4718         if (mem_ctx)
4719                 talloc_destroy(mem_ctx);
4720         return status;
4721 }
4722
4723 /****************************************************************************
4724  Construct a default security descriptor buffer for a printer.
4725 ****************************************************************************/
4726
4727 static struct sec_desc_buf *construct_default_printer_sdb(TALLOC_CTX *ctx)
4728 {
4729         struct security_ace ace[7];     /* max number of ace entries */
4730         int i = 0;
4731         uint32_t sa;
4732         struct security_acl *psa = NULL;
4733         struct sec_desc_buf *sdb = NULL;
4734         struct security_descriptor *psd = NULL;
4735         struct dom_sid adm_sid;
4736         size_t sd_size;
4737
4738         /* Create an ACE where Everyone is allowed to print */
4739
4740         sa = PRINTER_ACE_PRINT;
4741         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
4742                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
4743
4744         /* Add the domain admins group if we are a DC */
4745
4746         if ( IS_DC ) {
4747                 struct dom_sid domadmins_sid;
4748
4749                 sid_compose(&domadmins_sid, get_global_sam_sid(),
4750                             DOMAIN_RID_ADMINS);
4751
4752                 sa = PRINTER_ACE_FULL_CONTROL;
4753                 init_sec_ace(&ace[i++], &domadmins_sid,
4754                         SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
4755                         SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
4756                 init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
4757                         sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
4758         }
4759         else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
4760                 sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
4761
4762                 sa = PRINTER_ACE_FULL_CONTROL;
4763                 init_sec_ace(&ace[i++], &adm_sid,
4764                         SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
4765                         SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
4766                 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
4767                         sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
4768         }
4769
4770         /* add BUILTIN\Administrators as FULL CONTROL */
4771
4772         sa = PRINTER_ACE_FULL_CONTROL;
4773         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
4774                 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
4775                 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
4776         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
4777                 SEC_ACE_TYPE_ACCESS_ALLOWED,
4778                 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
4779
4780         /* add BUILTIN\Print Operators as FULL CONTROL */
4781
4782         sa = PRINTER_ACE_FULL_CONTROL;
4783         init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
4784                 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
4785                 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
4786         init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
4787                 SEC_ACE_TYPE_ACCESS_ALLOWED,
4788                 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
4789
4790         /* Make the security descriptor owned by the BUILTIN\Administrators */
4791
4792         /* The ACL revision number in rpc_secdesc.h differs from the one
4793            created by NT when setting ACE entries in printer
4794            descriptors.  NT4 complains about the property being edited by a
4795            NT5 machine. */
4796
4797         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
4798                 psd = make_sec_desc(ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
4799                         &global_sid_Builtin_Administrators,
4800                         &global_sid_Builtin_Administrators,
4801                         NULL, psa, &sd_size);
4802         }
4803
4804         if (!psd) {
4805                 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
4806                 return NULL;
4807         }
4808
4809         sdb = make_sec_desc_buf(ctx, sd_size, psd);
4810
4811         DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
4812                  (unsigned int)sd_size));
4813
4814         return sdb;
4815 }
4816
4817 /****************************************************************************
4818  Get a security desc for a printer.
4819 ****************************************************************************/
4820
4821 bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, struct sec_desc_buf **secdesc_ctr)
4822 {
4823         TDB_DATA kbuf;
4824         TDB_DATA dbuf;
4825         DATA_BLOB blob;
4826         char *temp;
4827         NTSTATUS status;
4828
4829         if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) {
4830                 sharename = temp + 1;
4831         }
4832
4833         /* Fetch security descriptor from tdb */
4834
4835         kbuf = make_printers_secdesc_tdbkey(ctx, sharename);
4836
4837         dbuf = tdb_fetch(tdb_printers, kbuf);
4838         if (dbuf.dptr) {
4839
4840                 status = unmarshall_sec_desc_buf(ctx, dbuf.dptr, dbuf.dsize,
4841                                                  secdesc_ctr);
4842                 SAFE_FREE(dbuf.dptr);
4843
4844                 if (NT_STATUS_IS_OK(status)) {
4845                         return true;
4846                 }
4847         }
4848
4849         *secdesc_ctr = construct_default_printer_sdb(ctx);
4850         if (!*secdesc_ctr) {
4851                 return false;
4852         }
4853
4854         status = marshall_sec_desc_buf(ctx, *secdesc_ctr,
4855                                        &blob.data, &blob.length);
4856         if (NT_STATUS_IS_OK(status)) {
4857                 dbuf.dptr = (unsigned char *)blob.data;
4858                 dbuf.dsize = blob.length;
4859                 tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE);
4860                 talloc_free(blob.data);
4861         }
4862
4863         /* If security descriptor is owned by S-1-1-0 and winbindd is up,
4864            this security descriptor has been created when winbindd was
4865            down.  Take ownership of security descriptor. */
4866
4867         if (sid_equal((*secdesc_ctr)->sd->owner_sid, &global_sid_World)) {
4868                 struct dom_sid owner_sid;
4869
4870                 /* Change sd owner to workgroup administrator */
4871
4872                 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
4873                         struct sec_desc_buf *new_secdesc_ctr = NULL;
4874                         struct security_descriptor *psd = NULL;
4875                         size_t size;
4876
4877                         /* Create new sd */
4878
4879                         sid_append_rid(&owner_sid, DOMAIN_RID_ADMINISTRATOR);
4880
4881                         psd = make_sec_desc(ctx, (*secdesc_ctr)->sd->revision, (*secdesc_ctr)->sd->type,
4882                                             &owner_sid,
4883                                             (*secdesc_ctr)->sd->group_sid,
4884                                             (*secdesc_ctr)->sd->sacl,
4885                                             (*secdesc_ctr)->sd->dacl,
4886                                             &size);
4887
4888                         if (!psd) {
4889                                 return False;
4890                         }
4891
4892                         new_secdesc_ctr = make_sec_desc_buf(ctx, size, psd);
4893                         if (!new_secdesc_ctr) {
4894                                 return False;
4895                         }
4896
4897                         /* Swap with other one */
4898
4899                         *secdesc_ctr = new_secdesc_ctr;
4900
4901                         /* Set it */
4902
4903                         nt_printing_setsec(sharename, *secdesc_ctr);
4904                 }
4905         }
4906
4907         if (DEBUGLEVEL >= 10) {
4908                 struct security_acl *the_acl = (*secdesc_ctr)->sd->dacl;
4909                 int i;
4910
4911                 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
4912                            sharename, the_acl->num_aces));
4913
4914                 for (i = 0; i < the_acl->num_aces; i++) {
4915                         DEBUG(10, ("%s %d %d 0x%08x\n",
4916                                    sid_string_dbg(&the_acl->aces[i].trustee),
4917                                    the_acl->aces[i].type, the_acl->aces[i].flags,
4918                                    the_acl->aces[i].access_mask));
4919                 }
4920         }
4921
4922         return True;
4923 }
4924
4925 /* error code:
4926         0: everything OK
4927         1: level not implemented
4928         2: file doesn't exist
4929         3: can't allocate memory
4930         4: can't free memory
4931         5: non existant struct
4932 */
4933
4934 /*
4935         A printer and a printer driver are 2 different things.
4936         NT manages them separatelly, Samba does the same.
4937         Why ? Simply because it's easier and it makes sense !
4938
4939         Now explanation: You have 3 printers behind your samba server,
4940         2 of them are the same make and model (laser A and B). But laser B
4941         has an 3000 sheet feeder and laser A doesn't such an option.
4942         Your third printer is an old dot-matrix model for the accounting :-).
4943
4944         If the /usr/local/samba/lib directory (default dir), you will have
4945         5 files to describe all of this.
4946
4947         3 files for the printers (1 by printer):
4948                 NTprinter_laser A
4949                 NTprinter_laser B
4950                 NTprinter_accounting
4951         2 files for the drivers (1 for the laser and 1 for the dot matrix)
4952                 NTdriver_printer model X
4953                 NTdriver_printer model Y
4954
4955 jfm: I should use this comment for the text file to explain
4956         same thing for the forms BTW.
4957         Je devrais mettre mes commentaires en francais, ca serait mieux :-)
4958
4959 */
4960
4961 /* Convert generic access rights to printer object specific access rights.
4962    It turns out that NT4 security descriptors use generic access rights and
4963    NT5 the object specific ones. */
4964
4965 void map_printer_permissions(struct security_descriptor *sd)
4966 {
4967         int i;
4968
4969         for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
4970                 se_map_generic(&sd->dacl->aces[i].access_mask,
4971                                &printer_generic_mapping);
4972         }
4973 }
4974
4975 void map_job_permissions(struct security_descriptor *sd)
4976 {
4977         int i;
4978
4979         for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
4980                 se_map_generic(&sd->dacl->aces[i].access_mask,
4981                                &job_generic_mapping);
4982         }
4983 }
4984
4985
4986 /****************************************************************************
4987  Check a user has permissions to perform the given operation.  We use the
4988  permission constants defined in include/rpc_spoolss.h to check the various
4989  actions we perform when checking printer access.
4990
4991    PRINTER_ACCESS_ADMINISTER:
4992        print_queue_pause, print_queue_resume, update_printer_sec,
4993        update_printer, spoolss_addprinterex_level_2,
4994        _spoolss_setprinterdata
4995
4996    PRINTER_ACCESS_USE:
4997        print_job_start
4998
4999    JOB_ACCESS_ADMINISTER:
5000        print_job_delete, print_job_pause, print_job_resume,
5001        print_queue_purge
5002
5003   Try access control in the following order (for performance reasons):
5004     1)  root and SE_PRINT_OPERATOR can do anything (easy check)
5005     2)  check security descriptor (bit comparisons in memory)
5006     3)  "printer admins" (may result in numerous calls to winbind)
5007
5008  ****************************************************************************/
5009 bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
5010                         int access_type)
5011 {
5012         struct spoolss_security_descriptor *secdesc = NULL;
5013         uint32 access_granted;
5014         size_t sd_size;
5015         NTSTATUS status;
5016         WERROR result;
5017         const char *pname;
5018         TALLOC_CTX *mem_ctx = NULL;
5019         SE_PRIV se_printop = SE_PRINT_OPERATOR;
5020
5021         /* If user is NULL then use the current_user structure */
5022
5023         /* Always allow root or SE_PRINT_OPERATROR to do anything */
5024
5025         if (server_info->utok.uid == sec_initial_uid()
5026             || user_has_privileges(server_info->ptok, &se_printop ) ) {
5027                 return True;
5028         }
5029
5030         /* Get printer name */
5031
5032         pname = lp_printername(snum);
5033
5034         if (!pname || !*pname) {
5035                 errno = EACCES;
5036                 return False;
5037         }
5038
5039         /* Get printer security descriptor */
5040
5041         if(!(mem_ctx = talloc_init("print_access_check"))) {
5042                 errno = ENOMEM;
5043                 return False;
5044         }
5045
5046         result = winreg_get_printer_secdesc(mem_ctx,
5047                                             server_info,
5048                                             pname,
5049                                             &secdesc);
5050         if (!W_ERROR_IS_OK(result)) {
5051                 talloc_destroy(mem_ctx);
5052                 errno = ENOMEM;
5053                 return False;
5054         }
5055
5056         if (access_type == JOB_ACCESS_ADMINISTER) {
5057                 struct spoolss_security_descriptor *parent_secdesc = secdesc;
5058
5059                 /* Create a child security descriptor to check permissions
5060                    against.  This is because print jobs are child objects
5061                    objects of a printer. */
5062                 status = se_create_child_secdesc(mem_ctx,
5063                                                  &secdesc,
5064                                                  &sd_size,
5065                                                  parent_secdesc,
5066                                                  parent_secdesc->owner_sid,
5067                                                  parent_secdesc->group_sid,
5068                                                  false);
5069                 if (!NT_STATUS_IS_OK(status)) {
5070                         talloc_destroy(mem_ctx);
5071                         errno = map_errno_from_nt_status(status);
5072                         return False;
5073                 }
5074
5075                 map_job_permissions(secdesc);
5076         } else {
5077                 map_printer_permissions(secdesc);
5078         }
5079
5080         /* Check access */
5081         status = se_access_check(secdesc, server_info->ptok, access_type,
5082                                  &access_granted);
5083
5084         DEBUG(4, ("access check was %s\n", NT_STATUS_IS_OK(status) ? "SUCCESS" : "FAILURE"));
5085
5086         /* see if we need to try the printer admin list */
5087
5088         if (!NT_STATUS_IS_OK(status) &&
5089             (token_contains_name_in_list(uidtoname(server_info->utok.uid),
5090                                          server_info->info3->base.domain.string,
5091                                          NULL, server_info->ptok,
5092                                          lp_printer_admin(snum)))) {
5093                 talloc_destroy(mem_ctx);
5094                 return True;
5095         }
5096
5097         talloc_destroy(mem_ctx);
5098
5099         if (!NT_STATUS_IS_OK(status)) {
5100                 errno = EACCES;
5101         }
5102
5103         return NT_STATUS_IS_OK(status);
5104 }
5105
5106 /****************************************************************************
5107  Check the time parameters allow a print operation.
5108 *****************************************************************************/
5109
5110 bool print_time_access_check(struct auth_serversupplied_info *server_info,
5111                              const char *servicename)
5112 {
5113         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
5114         WERROR result;
5115         bool ok = False;
5116         time_t now = time(NULL);
5117         struct tm *t;
5118         uint32 mins;
5119
5120         result = winreg_get_printer(NULL, server_info,
5121                                     NULL, servicename, &pinfo2);
5122         if (!W_ERROR_IS_OK(result)) {
5123                 return False;
5124         }
5125
5126         if (pinfo2->starttime == 0 && pinfo2->untiltime == 0) {
5127                 ok = True;
5128         }
5129
5130         t = gmtime(&now);
5131         mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
5132
5133         if (mins >= pinfo2->starttime && mins <= pinfo2->untiltime) {
5134                 ok = True;
5135         }
5136
5137         TALLOC_FREE(pinfo2);
5138
5139         if (!ok) {
5140                 errno = EACCES;
5141         }
5142
5143         return ok;
5144 }
5145
5146 /****************************************************************************
5147  Fill in the servername sent in the _spoolss_open_printer_ex() call
5148 ****************************************************************************/
5149
5150 char* get_server_name( Printer_entry *printer )
5151 {
5152         return printer->servername;
5153 }
5154
5155