Merge of print server permission handling fixes from HEAD.
[sfrench/samba-autobuild/.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  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #include "includes.h"
23
24 extern DOM_SID global_sid_World;
25
26 static TDB_CONTEXT *tdb_forms; /* used for forms files */
27 static TDB_CONTEXT *tdb_drivers; /* used for driver files */
28 static TDB_CONTEXT *tdb_printers; /* used for printers files */
29
30 #define FORMS_PREFIX "FORMS/"
31 #define DRIVERS_PREFIX "DRIVERS/"
32 #define DRIVER_INIT_PREFIX "DRIVER_INIT/"
33 #define PRINTERS_PREFIX "PRINTERS/"
34 #define SECDESC_PREFIX "SECDESC/"
35 #define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter"
36  
37 #define NTDRIVERS_DATABASE_VERSION_1 1
38 #define NTDRIVERS_DATABASE_VERSION_2 2
39 #define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */
40  
41 #define NTDRIVERS_DATABASE_VERSION NTDRIVERS_DATABASE_VERSION_3
42
43 /* Map generic permissions to printer object specific permissions */
44
45 GENERIC_MAPPING printer_generic_mapping = {
46         PRINTER_READ,
47         PRINTER_WRITE,
48         PRINTER_EXECUTE,
49         PRINTER_ALL_ACCESS
50 };
51
52 STANDARD_MAPPING printer_std_mapping = {
53         PRINTER_READ,
54         PRINTER_WRITE,
55         PRINTER_EXECUTE,
56         PRINTER_ALL_ACCESS
57 };
58
59 /* Map generic permissions to print server object specific permissions */
60
61 GENERIC_MAPPING printserver_generic_mapping = {
62         SERVER_READ,
63         SERVER_WRITE,
64         SERVER_EXECUTE,
65         SERVER_ALL_ACCESS
66 };
67
68 STANDARD_MAPPING printserver_std_mapping = {
69         SERVER_READ,
70         SERVER_WRITE,
71         SERVER_EXECUTE,
72         SERVER_ALL_ACCESS
73 };
74
75 /* We need one default form to support our default printer. Msoft adds the
76 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
77 array index). Letter is always first, so (for the current code) additions
78 always put things in the correct order. */
79 static nt_forms_struct default_forms[] = {
80         {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
81         {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
82         {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
83         {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
84         {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
85         {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
86         {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
87         {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
88         {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
89         {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
90         {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
91         {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
92         {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
93         {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
94         {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
95         {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
96         {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
97         {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
98         {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
99         {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
100         {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
101         {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
102         {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
103         {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
104         {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
105         {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
106         {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
107         {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
108         {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
109         {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
110         {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
111         {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
112         {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
113         {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
114         {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
115         {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
116         {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
117         {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
118         {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
119         {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
120         {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
121         {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
122         {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
123         {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
124         {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
125         {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
126         {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
127         {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
128         {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
129         {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
130         {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
131         {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
132         {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
133         {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
134         {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
135         {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
136         {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
137         {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
138         {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
139         {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
140         {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
141         {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
142         {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
143         {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
144         {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
145         {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
146         {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
147         {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
148         {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
149         {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
150         {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
151         {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
152         {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
153         {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
154         {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
155         {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
156         {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
157         {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
158         {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
159         {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
160         {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
161         {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
162         {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
163         {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
164         {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
165         {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
166         {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
167         {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
168         {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
169         {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
170         {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
171         {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
172         {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
173         {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
174         {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
175         {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
176         {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
177         {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
178         {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
179         {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
180         {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
181         {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
182         {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
183         {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
184         {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
185         {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
186         {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
187         {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
188         {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
189         {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
190         {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
191         {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
192         {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
193         {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
194         {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
195         {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
196         {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
197         {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
198 };
199
200 static BOOL upgrade_to_version_3(void)
201 {
202         TDB_DATA kbuf, newkey, dbuf;
203  
204         DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
205  
206         for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
207                         newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
208
209                 dbuf = tdb_fetch(tdb_drivers, kbuf);
210
211                 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
212                         DEBUG(0,("upgrade_to_version_3:moving form\n"));
213                         if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
214                                 DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
215                                 return False;
216                         }
217                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
218                                 DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
219                                 return False;
220                         }
221                 }
222  
223                 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
224                         DEBUG(0,("upgrade_to_version_3:moving printer\n"));
225                         if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
226                                 DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
227                                 return False;
228                         }
229                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
230                                 DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
231                                 return False;
232                         }
233                 }
234  
235                 if (strncmp(kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
236                         DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
237                         if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
238                                 DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
239                                 return False;
240                         }
241                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
242                                 DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
243                                 return False;
244                         }
245                 }
246  
247                 SAFE_FREE(dbuf.dptr);
248         }
249
250         return True;
251 }
252
253 /****************************************************************************
254  Open the NT printing tdb.
255 ****************************************************************************/
256
257 BOOL nt_printing_init(void)
258 {
259         static pid_t local_pid;
260         char *vstring = "INFO/version";
261
262         if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
263                 return True;
264  
265         tdb_drivers = tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
266         if (!tdb_drivers) {
267                 DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
268                         lock_path("ntdrivers.tdb"), strerror(errno) ));
269                 return False;
270         }
271  
272         tdb_printers = tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
273         if (!tdb_printers) {
274                 DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
275                         lock_path("ntprinters.tdb"), strerror(errno) ));
276                 return False;
277         }
278  
279         tdb_forms = tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
280         if (!tdb_forms) {
281                 DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
282                         lock_path("ntforms.tdb"), strerror(errno) ));
283                 return False;
284         }
285  
286         local_pid = sys_getpid();
287  
288         /* handle a Samba upgrade */
289         tdb_lock_bystring(tdb_drivers, vstring);
290         {
291                 int32 vers_id;
292
293                 /* Cope with byte-reversed older versions of the db. */
294                 vers_id = tdb_fetch_int32(tdb_drivers, vstring);
295                 if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) {
296                         /* Written on a bigendian machine with old fetch_int code. Save as le. */
297                         /* The only upgrade between V2 and V3 is to save the version in little-endian. */
298                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
299                         vers_id = NTDRIVERS_DATABASE_VERSION;
300                 }
301
302                 if (vers_id != NTDRIVERS_DATABASE_VERSION) {
303
304                         if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) { 
305                                 if (!upgrade_to_version_3())
306                                         return False;
307                         } else
308                                 tdb_traverse(tdb_drivers, tdb_traverse_delete_fn, NULL);
309                          
310                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
311                 }
312         }
313         tdb_unlock_bystring(tdb_drivers, vstring);
314
315         update_c_setprinter(True);
316
317         return True;
318 }
319
320 /*******************************************************************
321  tdb traversal function for counting printers.
322 ********************************************************************/
323
324 static int traverse_counting_printers(TDB_CONTEXT *t, TDB_DATA key,
325                                       TDB_DATA data, void *context)
326 {
327         int *printer_count = (int*)context;
328  
329         if (memcmp(PRINTERS_PREFIX, key.dptr, sizeof(PRINTERS_PREFIX)-1) == 0) {
330                 (*printer_count)++;
331                 DEBUG(10,("traverse_counting_printers: printer = [%s]  printer_count = %d\n", key.dptr, *printer_count));
332         }
333  
334         return 0;
335 }
336  
337 /*******************************************************************
338  Update the spooler global c_setprinter. This variable is initialized
339  when the parent smbd starts with the number of existing printers. It
340  is monotonically increased by the current number of printers *after*
341  each add or delete printer RPC. Only Microsoft knows why... JRR020119
342 ********************************************************************/
343
344 uint32 update_c_setprinter(BOOL initialize)
345 {
346         int32 c_setprinter;
347         int32 printer_count = 0;
348  
349         tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
350  
351         /* Traverse the tdb, counting the printers */
352         tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);
353  
354         /* If initializing, set c_setprinter to current printers count
355          * otherwise, bump it by the current printer count
356          */
357         if (!initialize)
358                 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER) + printer_count;
359         else
360                 c_setprinter = printer_count;
361  
362         DEBUG(10,("update_c_setprinter: c_setprinter = %u\n", (unsigned int)c_setprinter));
363         tdb_store_int32(tdb_printers, GLOBAL_C_SETPRINTER, c_setprinter);
364  
365         tdb_unlock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
366  
367         return (uint32)c_setprinter;
368 }
369
370 /*******************************************************************
371  Get the spooler global c_setprinter, accounting for initialization.
372 ********************************************************************/
373
374 uint32 get_c_setprinter(void)
375 {
376         int32 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER);
377  
378         if (c_setprinter == (int32)-1)
379                 c_setprinter = update_c_setprinter(True);
380  
381         DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter));
382  
383         return (uint32)c_setprinter;
384 }
385
386 /****************************************************************************
387  Get builtin form struct list.
388 ****************************************************************************/
389
390 int get_builtin_ntforms(nt_forms_struct **list)
391 {
392         *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
393         return sizeof(default_forms) / sizeof(default_forms[0]);
394 }
395
396 /****************************************************************************
397  get a builtin form struct
398 ****************************************************************************/
399
400 BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
401 {
402         int i,count;
403         fstring form_name;
404         unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
405         DEBUGADD(6,("Looking for builtin form %s \n", form_name));
406         count = sizeof(default_forms) / sizeof(default_forms[0]);
407         for (i=0;i<count;i++) {
408                 if (strequal(form_name,default_forms[i].name)) {
409                         DEBUGADD(6,("Found builtin form %s \n", form_name));
410                         memcpy(form,&default_forms[i],sizeof(*form));
411                         break;
412                 }
413         }
414
415         return (i !=count);
416 }
417
418 /****************************************************************************
419 get a form struct list
420 ****************************************************************************/
421 int get_ntforms(nt_forms_struct **list)
422 {
423         TDB_DATA kbuf, newkey, dbuf;
424         nt_forms_struct *tl;
425         nt_forms_struct form;
426         int ret;
427         int i;
428         int n = 0;
429
430         for (kbuf = tdb_firstkey(tdb_forms);
431              kbuf.dptr;
432              newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
433                 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
434                 
435                 dbuf = tdb_fetch(tdb_forms, kbuf);
436                 if (!dbuf.dptr) continue;
437
438                 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
439                 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
440                                  &i, &form.flag, &form.width, &form.length, &form.left,
441                                  &form.top, &form.right, &form.bottom);
442                 SAFE_FREE(dbuf.dptr);
443                 if (ret != dbuf.dsize) continue;
444
445                 tl = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
446                 if (!tl) {
447                         DEBUG(0,("get_ntforms: Realloc fail.\n"));
448                         return 0;
449                 }
450         *list = tl;
451                 (*list)[n] = form;
452                 n++;
453         }
454         
455
456         return n;
457 }
458
459 /****************************************************************************
460 write a form struct list
461 ****************************************************************************/
462 int write_ntforms(nt_forms_struct **list, int number)
463 {
464         pstring buf, key;
465         int len;
466         TDB_DATA kbuf,dbuf;
467         int i;
468
469         for (i=0;i<number;i++) {
470                 /* save index, so list is rebuilt in correct order */
471                 len = tdb_pack(buf, sizeof(buf), "dddddddd",
472                                i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
473                                (*list)[i].left, (*list)[i].top, (*list)[i].right,
474                                (*list)[i].bottom);
475                 if (len > sizeof(buf)) break;
476                 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name);
477                 kbuf.dsize = strlen(key)+1;
478                 kbuf.dptr = key;
479                 dbuf.dsize = len;
480                 dbuf.dptr = buf;
481                 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) break;
482        }
483
484        return i;
485 }
486
487 /****************************************************************************
488 add a form struct at the end of the list
489 ****************************************************************************/
490 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
491 {
492         int n=0;
493         BOOL update;
494         fstring form_name;
495         nt_forms_struct *tl;
496
497         /*
498          * NT tries to add forms even when
499          * they are already in the base
500          * only update the values if already present
501          */
502
503         update=False;
504         
505         unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
506         for (n=0; n<*count; n++) {
507                 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
508                         DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
509                         update=True;
510                         break;
511                 }
512         }
513
514         if (update==False) {
515                 if((tl=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL) {
516                         DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
517                         return False;
518                 }
519                 *list = tl;
520                 unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
521                 (*count)++;
522         }
523         
524         (*list)[n].flag=form->flags;
525         (*list)[n].width=form->size_x;
526         (*list)[n].length=form->size_y;
527         (*list)[n].left=form->left;
528         (*list)[n].top=form->top;
529         (*list)[n].right=form->right;
530         (*list)[n].bottom=form->bottom;
531
532         return True;
533 }
534
535 /****************************************************************************
536  delete a named form struct
537 ****************************************************************************/
538 BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
539 {
540         pstring key;
541         TDB_DATA kbuf;
542         int n=0;
543         fstring form_name;
544
545         *ret = WERR_OK;
546
547         unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
548
549         for (n=0; n<*count; n++) {
550                 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
551                         DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
552                         break;
553                 }
554         }
555
556         if (n == *count) {
557                 DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
558                 *ret = WERR_INVALID_PARAM;
559                 return False;
560         }
561
562         slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);
563         kbuf.dsize = strlen(key)+1;
564         kbuf.dptr = key;
565         if (tdb_delete(tdb_forms, kbuf) != 0) {
566                 *ret = WERR_NOMEM;
567                 return False;
568         }
569
570         return True;
571 }
572
573 /****************************************************************************
574 update a form struct
575 ****************************************************************************/
576 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
577 {
578         int n=0;
579         fstring form_name;
580         unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
581
582         DEBUG(106, ("[%s]\n", form_name));
583         for (n=0; n<count; n++)
584         {
585                 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
586                 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
587                         break;
588         }
589
590         if (n==count) return;
591
592         (*list)[n].flag=form->flags;
593         (*list)[n].width=form->size_x;
594         (*list)[n].length=form->size_y;
595         (*list)[n].left=form->left;
596         (*list)[n].top=form->top;
597         (*list)[n].right=form->right;
598         (*list)[n].bottom=form->bottom;
599 }
600
601 /****************************************************************************
602 get the nt drivers list
603
604 traverse the database and look-up the matching names
605 ****************************************************************************/
606 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
607 {
608         int total=0;
609         fstring short_archi;
610         fstring *fl;
611         pstring key;
612         TDB_DATA kbuf, newkey;
613
614         get_short_archi(short_archi, architecture);
615         slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
616
617         for (kbuf = tdb_firstkey(tdb_drivers);
618              kbuf.dptr;
619              newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
620                 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
621                 
622                 if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
623                         DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
624                         return -1;
625                 }
626                 else *list = fl;
627
628                 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
629                 total++;
630         }
631
632         return(total);
633 }
634
635 /****************************************************************************
636 function to do the mapping between the long architecture name and
637 the short one.
638 ****************************************************************************/
639 BOOL get_short_archi(char *short_archi, char *long_archi)
640 {
641         struct table {
642                 char *long_archi;
643                 char *short_archi;
644         };
645         
646         struct table archi_table[]=
647         {
648                 {"Windows 4.0",          "WIN40"    },
649                 {"Windows NT x86",       "W32X86"   },
650                 {"Windows NT R4000",     "W32MIPS"  },
651                 {"Windows NT Alpha_AXP", "W32ALPHA" },
652                 {"Windows NT PowerPC",   "W32PPC"   },
653                 {NULL,                   ""         }
654         };
655         
656         int i=-1;
657
658         DEBUG(107,("Getting architecture dependant directory\n"));
659         do {
660                 i++;
661         } while ( (archi_table[i].long_archi!=NULL ) &&
662                   StrCaseCmp(long_archi, archi_table[i].long_archi) );
663
664         if (archi_table[i].long_archi==NULL) {
665                 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
666                 return False;
667         }
668
669         StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
670
671         DEBUGADD(108,("index: [%d]\n", i));
672         DEBUGADD(108,("long architecture: [%s]\n", long_archi));
673         DEBUGADD(108,("short architecture: [%s]\n", short_archi));
674         
675         return True;
676 }
677
678 /****************************************************************************
679  Version information in Microsoft files is held in a VS_VERSION_INFO structure.
680  There are two case to be covered here: PE (Portable Executable) and NE (New
681  Executable) files. Both files support the same INFO structure, but PE files
682  store the signature in unicode, and NE files store it as !unicode.
683  returns -1 on error, 1 on version info found, and 0 on no version info found.
684 ****************************************************************************/
685
686 static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
687 {
688         int     i;
689         char    *buf;
690         ssize_t byte_count;
691
692         if ((buf=malloc(PE_HEADER_SIZE)) == NULL) {
693                 DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
694                                 fname, PE_HEADER_SIZE));
695                 goto error_exit;
696         }
697
698         /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
699         if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
700                 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
701                                 fname, byte_count));
702                 goto no_version_info;
703         }
704
705         /* Is this really a DOS header? */
706         if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
707                 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
708                                 fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
709                 goto no_version_info;
710         }
711
712         /* Skip OEM header (if any) and the DOS stub to start of Windows header */
713         if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
714                 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
715                                 fname, errno));
716                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
717                 goto no_version_info;
718         }
719
720         if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
721                 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
722                                 fname, byte_count));
723                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
724                 goto no_version_info;
725         }
726
727         /* The header may be a PE (Portable Executable) or an NE (New Executable) */
728         if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
729                 int num_sections;
730                 int section_table_bytes;
731                 
732                 if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {
733                         DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
734                                         fname, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
735                         /* At this point, we assume the file is in error. It still could be somthing
736                          * else besides a PE file, but it unlikely at this point.
737                          */
738                         goto error_exit;
739                 }
740
741                 /* get the section table */
742                 num_sections        = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
743                 section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
744                 SAFE_FREE(buf);
745                 if ((buf=malloc(section_table_bytes)) == NULL) {
746                         DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
747                                         fname, section_table_bytes));
748                         goto error_exit;
749                 }
750
751                 if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
752                         DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
753                                         fname, byte_count));
754                         goto error_exit;
755                 }
756
757                 /* Iterate the section table looking for the resource section ".rsrc" */
758                 for (i = 0; i < num_sections; i++) {
759                         int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
760
761                         if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
762                                 int section_pos   = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
763                                 int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
764
765                                 SAFE_FREE(buf);
766                                 if ((buf=malloc(section_bytes)) == NULL) {
767                                         DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
768                                                         fname, section_bytes));
769                                         goto error_exit;
770                                 }
771
772                                 /* Seek to the start of the .rsrc section info */
773                                 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
774                                         DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
775                                                         fname, errno));
776                                         goto error_exit;
777                                 }
778
779                                 if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
780                                         DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
781                                                         fname, byte_count));
782                                         goto error_exit;
783                                 }
784
785                                 for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
786                                         /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
787                                         if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
788                                                 /* Align to next long address */
789                                                 int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;
790
791                                                 if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
792                                                         *major = IVAL(buf,pos+VS_MAJOR_OFFSET);
793                                                         *minor = IVAL(buf,pos+VS_MINOR_OFFSET);
794                                                         
795                                                         DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
796                                                                           fname, *major, *minor,
797                                                                           (*major>>16)&0xffff, *major&0xffff,
798                                                                           (*minor>>16)&0xffff, *minor&0xffff));
799                                                         SAFE_FREE(buf);
800                                                         return 1;
801                                                 }
802                                         }
803                                 }
804                         }
805                 }
806
807                 /* Version info not found, fall back to origin date/time */
808                 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
809                 SAFE_FREE(buf);
810                 return 0;
811
812         } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
813                 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
814                         DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
815                                         fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
816                         /* At this point, we assume the file is in error. It still could be somthing
817                          * else besides a NE file, but it unlikely at this point. */
818                         goto error_exit;
819                 }
820
821                 /* Allocate a bit more space to speed up things */
822                 SAFE_FREE(buf);
823                 if ((buf=malloc(VS_NE_BUF_SIZE)) == NULL) {
824                         DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes  = %d\n",
825                                         fname, PE_HEADER_SIZE));
826                         goto error_exit;
827                 }
828
829                 /* This is a HACK! I got tired of trying to sort through the messy
830                  * 'NE' file format. If anyone wants to clean this up please have at
831                  * it, but this works. 'NE' files will eventually fade away. JRR */
832                 while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {
833                         /* Cover case that should not occur in a well formed 'NE' .dll file */
834                         if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;
835
836                         for(i=0; i<byte_count; i++) {
837                                 /* Fast skip past data that can't possibly match */
838                                 if (buf[i] != 'V') continue;
839
840                                 /* Potential match data crosses buf boundry, move it to beginning
841                                  * of buf, and fill the buf with as much as it will hold. */
842                                 if (i>byte_count-VS_VERSION_INFO_SIZE) {
843                                         int bc;
844
845                                         memcpy(buf, &buf[i], byte_count-i);
846                                         if ((bc = vfs_read_data(fsp, &buf[byte_count-i], VS_NE_BUF_SIZE-
847                                                                    (byte_count-i))) < 0) {
848
849                                                 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
850                                                                  fname, errno));
851                                                 goto error_exit;
852                                         }
853
854                                         byte_count = bc + (byte_count - i);
855                                         if (byte_count<VS_VERSION_INFO_SIZE) break;
856
857                                         i = 0;
858                                 }
859
860                                 /* Check that the full signature string and the magic number that
861                                  * follows exist (not a perfect solution, but the chances that this
862                                  * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
863                                  * twice, as it is simpler to read the code. */
864                                 if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
865                                         /* Compute skip alignment to next long address */
866                                         int skip = -(fsp->conn->vfs_ops.lseek(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
867                                                                  sizeof(VS_SIGNATURE)) & 3;
868                                         if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
869
870                                         *major = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MAJOR_OFFSET);
871                                         *minor = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MINOR_OFFSET);
872                                         DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
873                                                           fname, *major, *minor,
874                                                           (*major>>16)&0xffff, *major&0xffff,
875                                                           (*minor>>16)&0xffff, *minor&0xffff));
876                                         SAFE_FREE(buf);
877                                         return 1;
878                                 }
879                         }
880                 }
881
882                 /* Version info not found, fall back to origin date/time */
883                 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
884                 SAFE_FREE(buf);
885                 return 0;
886
887         } else
888                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
889                 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
890                                 fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
891
892         no_version_info:
893                 SAFE_FREE(buf);
894                 return 0;
895
896         error_exit:
897                 SAFE_FREE(buf);
898                 return -1;
899 }
900
901 /****************************************************************************
902 Drivers for Microsoft systems contain multiple files. Often, multiple drivers
903 share one or more files. During the MS installation process files are checked
904 to insure that only a newer version of a shared file is installed over an
905 older version. There are several possibilities for this comparison. If there
906 is no previous version, the new one is newer (obviously). If either file is
907 missing the version info structure, compare the creation date (on Unix use
908 the modification date). Otherwise chose the numerically larger version number.
909 ****************************************************************************/
910 static int file_version_is_newer(connection_struct *conn, fstring new_file,
911                                                                 fstring old_file)
912 {
913         BOOL   use_version = True;
914         pstring filepath;
915
916         uint32 new_major;
917         uint32 new_minor;
918         time_t new_create_time;
919
920         uint32 old_major;
921         uint32 old_minor;
922         time_t old_create_time;
923
924         int access_mode;
925         int action;
926         files_struct    *fsp = NULL;
927         SMB_STRUCT_STAT st;
928         SMB_STRUCT_STAT stat_buf;
929         BOOL bad_path;
930
931         ZERO_STRUCT(st);
932         ZERO_STRUCT(stat_buf);
933         new_create_time = (time_t)0;
934         old_create_time = (time_t)0;
935
936         /* Get file version info (if available) for previous file (if it exists) */
937         pstrcpy(filepath, old_file);
938
939         unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
940
941         fsp = open_file_shared(conn, filepath, &stat_buf,
942                                                    SET_OPEN_MODE(DOS_OPEN_RDONLY),
943                                                    (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
944                                                    0, 0, &access_mode, &action);
945         if (!fsp) {
946                 /* Old file not found, so by definition new file is in fact newer */
947                 DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
948                                 filepath, errno));
949                 return True;
950
951         } else {
952                 int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
953                 if (ret == -1) goto error_exit;
954
955                 if (!ret) {
956                         DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
957                                          old_file));
958                         use_version = False;
959                         if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
960                         old_create_time = st.st_mtime;
961                         DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
962                 }
963         }
964         close_file(fsp, True);
965
966         /* Get file version info (if available) for new file */
967         pstrcpy(filepath, new_file);
968         unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
969
970         fsp = open_file_shared(conn, filepath, &stat_buf,
971                                                    SET_OPEN_MODE(DOS_OPEN_RDONLY),
972                                                    (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
973                                                    0, 0, &access_mode, &action);
974         if (!fsp) {
975                 /* New file not found, this shouldn't occur if the caller did its job */
976                 DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
977                                 filepath, errno));
978                 goto error_exit;
979
980         } else {
981                 int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
982                 if (ret == -1) goto error_exit;
983
984                 if (!ret) {
985                         DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
986                                          new_file));
987                         use_version = False;
988                         if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
989                         new_create_time = st.st_mtime;
990                         DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
991                 }
992         }
993         close_file(fsp, True);
994
995         if (use_version) {
996                 /* Compare versions and choose the larger version number */
997                 if (new_major > old_major ||
998                         (new_major == old_major && new_minor > old_minor)) {
999                         
1000                         DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
1001                         return True;
1002                 }
1003                 else {
1004                         DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
1005                         return False;
1006                 }
1007
1008         } else {
1009                 /* Compare modification time/dates and choose the newest time/date */
1010                 if (new_create_time > old_create_time) {
1011                         DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
1012                         return True;
1013                 }
1014                 else {
1015                         DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
1016                         return False;
1017                 }
1018         }
1019
1020         error_exit:
1021                 if(fsp)
1022                         close_file(fsp, True);
1023                 return -1;
1024 }
1025
1026 /****************************************************************************
1027 Determine the correct cVersion associated with an architecture and driver
1028 ****************************************************************************/
1029 static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
1030                                    struct current_user *user, WERROR *perr)
1031 {
1032         int               cversion;
1033         int               access_mode;
1034         int               action;
1035         NTSTATUS          nt_status;
1036         pstring           driverpath;
1037         DATA_BLOB         null_pw;
1038         files_struct      *fsp = NULL;
1039         BOOL              bad_path;
1040         SMB_STRUCT_STAT   st;
1041         connection_struct *conn;
1042
1043         ZERO_STRUCT(st);
1044
1045         *perr = WERR_INVALID_PARAM;
1046
1047         /* If architecture is Windows 95/98/ME, the version is always 0. */
1048         if (strcmp(architecture, "WIN40") == 0) {
1049                 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
1050                 *perr = WERR_OK;
1051                 return 0;
1052         }
1053
1054         /*
1055          * Connect to the print$ share under the same account as the user connected
1056          * to the rpc pipe. Note we must still be root to do this.
1057          */
1058
1059         /* Null password is ok - we are already an authenticated user... */
1060         null_pw = data_blob(NULL, 0);
1061         become_root();
1062         conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
1063         unbecome_root();
1064
1065         if (conn == NULL) {
1066                 DEBUG(0,("get_correct_cversion: Unable to connect\n"));
1067                 *perr = ntstatus_to_werror(nt_status);
1068                 return -1;
1069         }
1070
1071         /* We are temporarily becoming the connection user. */
1072         if (!become_user(conn, conn->vuid)) {
1073                 DEBUG(0,("get_correct_cversion: Can't become user!\n"));
1074                 *perr = WERR_ACCESS_DENIED;
1075                 return -1;
1076         }
1077
1078         /* Open the driver file (Portable Executable format) and determine the
1079          * deriver the cversion. */
1080         slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
1081
1082         unix_convert(driverpath,conn,NULL,&bad_path,&st);
1083
1084         fsp = open_file_shared(conn, driverpath, &st,
1085                                                    SET_OPEN_MODE(DOS_OPEN_RDONLY),
1086                                                    (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
1087                                                    0, 0, &access_mode, &action);
1088         if (!fsp) {
1089                 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
1090                                 driverpath, errno));
1091                 *perr = WERR_ACCESS_DENIED;
1092                 goto error_exit;
1093         }
1094         else {
1095                 uint32 major;
1096                 uint32 minor;
1097                 int    ret = get_file_version(fsp, driverpath, &major, &minor);
1098                 if (ret == -1) goto error_exit;
1099
1100                 if (!ret) {
1101                         DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath));
1102                         goto error_exit;
1103                 }
1104
1105                 /*
1106                  * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
1107                  * for more details. Version in this case is not just the version of the 
1108                  * file, but the version in the sense of kernal mode (2) vs. user mode
1109                  * (3) drivers. Other bits of the version fields are the version info. 
1110                  * JRR 010716
1111                 */
1112                 cversion = major & 0x0000ffff;
1113                 switch (cversion) {
1114                         case 2: /* WinNT drivers */
1115                         case 3: /* Win2K drivers */
1116                                 break;
1117                         
1118                         default:
1119                                 DEBUG(6,("get_correct_cversion: cversion invalid [%s]  cversion = %d\n", 
1120                                         driverpath, cversion));
1121                                 goto error_exit;
1122                 }
1123
1124                 DEBUG(10,("get_correct_cversion: Version info found [%s]  major = 0x%x  minor = 0x%x\n",
1125                                   driverpath, major, minor));
1126         }
1127
1128     DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
1129                         driverpath, cversion));
1130
1131         close_file(fsp, True);
1132         close_cnum(conn, user->vuid);
1133         unbecome_user();
1134         *perr = WERR_OK;
1135         return cversion;
1136
1137
1138   error_exit:
1139
1140         if(fsp)
1141                 close_file(fsp, True);
1142
1143         close_cnum(conn, user->vuid);
1144         unbecome_user();
1145         return -1;
1146 }
1147
1148 /****************************************************************************
1149 ****************************************************************************/
1150 static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
1151                                                                                          struct current_user *user)
1152 {
1153         fstring architecture;
1154         fstring new_name;
1155         char *p;
1156         int i;
1157         WERROR err;
1158
1159         /* clean up the driver name.
1160          * we can get .\driver.dll
1161          * or worse c:\windows\system\driver.dll !
1162          */
1163         /* using an intermediate string to not have overlaping memcpy()'s */
1164         if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1165                 fstrcpy(new_name, p+1);
1166                 fstrcpy(driver->driverpath, new_name);
1167         }
1168
1169         if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1170                 fstrcpy(new_name, p+1);
1171                 fstrcpy(driver->datafile, new_name);
1172         }
1173
1174         if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1175                 fstrcpy(new_name, p+1);
1176                 fstrcpy(driver->configfile, new_name);
1177         }
1178
1179         if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1180                 fstrcpy(new_name, p+1);
1181                 fstrcpy(driver->helpfile, new_name);
1182         }
1183
1184         if (driver->dependentfiles) {
1185                 for (i=0; *driver->dependentfiles[i]; i++) {
1186                         if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1187                                 fstrcpy(new_name, p+1);
1188                                 fstrcpy(driver->dependentfiles[i], new_name);
1189                         }
1190                 }
1191         }
1192
1193         get_short_archi(architecture, driver->environment);
1194         
1195         /* jfm:7/16/2000 the client always sends the cversion=0.
1196          * The server should check which version the driver is by reading
1197          * the PE header of driver->driverpath.
1198          *
1199          * For Windows 95/98 the version is 0 (so the value sent is correct)
1200          * For Windows NT (the architecture doesn't matter)
1201          *      NT 3.1: cversion=0
1202          *      NT 3.5/3.51: cversion=1
1203          *      NT 4: cversion=2
1204          *      NT2K: cversion=3
1205          */
1206         if ((driver->cversion = get_correct_cversion( architecture,
1207                                                                         driver->driverpath, user, &err)) == -1)
1208                 return err;
1209
1210         return WERR_OK;
1211 }
1212         
1213 /****************************************************************************
1214 ****************************************************************************/
1215 static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
1216                                                                                          struct current_user *user)
1217 {
1218         fstring architecture;
1219         fstring new_name;
1220         char *p;
1221         int i;
1222         WERROR err;
1223
1224         /* clean up the driver name.
1225          * we can get .\driver.dll
1226          * or worse c:\windows\system\driver.dll !
1227          */
1228         /* using an intermediate string to not have overlaping memcpy()'s */
1229         if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1230                 fstrcpy(new_name, p+1);
1231                 fstrcpy(driver->driverpath, new_name);
1232         }
1233
1234         if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1235                 fstrcpy(new_name, p+1);
1236                 fstrcpy(driver->datafile, new_name);
1237         }
1238
1239         if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1240                 fstrcpy(new_name, p+1);
1241                 fstrcpy(driver->configfile, new_name);
1242         }
1243
1244         if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1245                 fstrcpy(new_name, p+1);
1246                 fstrcpy(driver->helpfile, new_name);
1247         }
1248
1249         if (driver->dependentfiles) {
1250                 for (i=0; *driver->dependentfiles[i]; i++) {
1251                         if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1252                                 fstrcpy(new_name, p+1);
1253                                 fstrcpy(driver->dependentfiles[i], new_name);
1254                         }
1255                 }
1256         }
1257
1258         get_short_archi(architecture, driver->environment);
1259
1260         /* jfm:7/16/2000 the client always sends the cversion=0.
1261          * The server should check which version the driver is by reading
1262          * the PE header of driver->driverpath.
1263          *
1264          * For Windows 95/98 the version is 0 (so the value sent is correct)
1265          * For Windows NT (the architecture doesn't matter)
1266          *      NT 3.1: cversion=0
1267          *      NT 3.5/3.51: cversion=1
1268          *      NT 4: cversion=2
1269          *      NT2K: cversion=3
1270          */
1271         if ((driver->version = get_correct_cversion(architecture,
1272                                                                         driver->driverpath, user, &err)) == -1)
1273                 return err;
1274
1275         return WERR_OK;
1276 }
1277
1278 /****************************************************************************
1279 ****************************************************************************/
1280 WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
1281                                                           uint32 level, struct current_user *user)
1282 {
1283         switch (level) {
1284                 case 3:
1285                 {
1286                         NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1287                         driver=driver_abstract.info_3;
1288                         return clean_up_driver_struct_level_3(driver, user);
1289                 }
1290                 case 6:
1291                 {
1292                         NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
1293                         driver=driver_abstract.info_6;
1294                         return clean_up_driver_struct_level_6(driver, user);
1295                 }
1296                 default:
1297                         return WERR_INVALID_PARAM;
1298         }
1299 }
1300
1301 /****************************************************************************
1302  This function sucks and should be replaced. JRA.
1303 ****************************************************************************/
1304
1305 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
1306 {
1307     dst->cversion  = src->version;
1308
1309     fstrcpy( dst->name, src->name);
1310     fstrcpy( dst->environment, src->environment);
1311     fstrcpy( dst->driverpath, src->driverpath);
1312     fstrcpy( dst->datafile, src->datafile);
1313     fstrcpy( dst->configfile, src->configfile);
1314     fstrcpy( dst->helpfile, src->helpfile);
1315     fstrcpy( dst->monitorname, src->monitorname);
1316     fstrcpy( dst->defaultdatatype, src->defaultdatatype);
1317     dst->dependentfiles = src->dependentfiles;
1318 }
1319
1320 #if 0 /* Debugging function */
1321
1322 static char* ffmt(unsigned char *c){
1323         int i;
1324         static char ffmt_str[17];
1325
1326         for (i=0; i<16; i++) {
1327                 if ((c[i] < ' ') || (c[i] > '~'))
1328                         ffmt_str[i]='.';
1329                 else
1330                         ffmt_str[i]=c[i];
1331         }
1332     ffmt_str[16]='\0';
1333         return ffmt_str;
1334 }
1335
1336 #endif
1337
1338 /****************************************************************************
1339 ****************************************************************************/
1340 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, 
1341                                   struct current_user *user, WERROR *perr)
1342 {
1343         NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1344         NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
1345         fstring architecture;
1346         pstring new_dir;
1347         pstring old_name;
1348         pstring new_name;
1349         DATA_BLOB null_pw;
1350         connection_struct *conn;
1351         NTSTATUS nt_status;
1352         pstring inbuf;
1353         pstring outbuf;
1354         int ver = 0;
1355         int i;
1356
1357         memset(inbuf, '\0', sizeof(inbuf));
1358         memset(outbuf, '\0', sizeof(outbuf));
1359         *perr = WERR_OK;
1360
1361         if (level==3)
1362                 driver=driver_abstract.info_3;
1363         else if (level==6) {
1364                 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
1365                 driver = &converted_driver;
1366         } else {
1367                 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
1368                 return False;
1369         }
1370
1371         get_short_archi(architecture, driver->environment);
1372
1373         /*
1374          * Connect to the print$ share under the same account as the user connected to the rpc pipe.
1375          * Note we must be root to do this.
1376          */
1377
1378         become_root();
1379         null_pw = data_blob(NULL, 0);
1380         conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
1381         unbecome_root();
1382
1383         if (conn == NULL) {
1384                 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
1385                 *perr = ntstatus_to_werror(nt_status);
1386                 return False;
1387         }
1388
1389         /*
1390          * Save who we are - we are temporarily becoming the connection user.
1391          */
1392
1393         if (!become_user(conn, conn->vuid)) {
1394                 DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
1395                 return False;
1396         }
1397
1398         /*
1399          * make the directories version and version\driver_name
1400          * under the architecture directory.
1401          */
1402         DEBUG(5,("Creating first directory\n"));
1403         slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
1404         mkdir_internal(conn, new_dir);
1405
1406         /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
1407          * listed for this driver which has already been moved, skip it (note:
1408          * drivers may list the same file name several times. Then check if the
1409          * file already exists in archi\cversion\, if so, check that the version
1410          * info (or time stamps if version info is unavailable) is newer (or the
1411          * date is later). If it is, move it to archi\cversion\filexxx.yyy.
1412          * Otherwise, delete the file.
1413          *
1414          * If a file is not moved to archi\cversion\ because of an error, all the
1415          * rest of the 'unmoved' driver files are removed from archi\. If one or
1416          * more of the driver's files was already moved to archi\cversion\, it
1417          * potentially leaves the driver in a partially updated state. Version
1418          * trauma will most likely occur if an client attempts to use any printer
1419          * bound to the driver. Perhaps a rewrite to make sure the moves can be
1420          * done is appropriate... later JRR
1421          */
1422
1423         DEBUG(5,("Moving files now !\n"));
1424
1425         if (driver->driverpath && strlen(driver->driverpath)) {
1426                 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);      
1427                 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);   
1428                 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1429                         NTSTATUS status;
1430                         status = rename_internals(conn, new_name, old_name, True);
1431                         if (!NT_STATUS_IS_OK(status)) {
1432                                 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1433                                                 new_name, old_name));
1434                                 *perr = ntstatus_to_werror(status);
1435                                 unlink_internals(conn, 0, new_name);
1436                                 ver = -1;
1437                         }
1438                 }
1439                 else
1440                         unlink_internals(conn, 0, new_name);
1441         }
1442
1443         if (driver->datafile && strlen(driver->datafile)) {
1444                 if (!strequal(driver->datafile, driver->driverpath)) {
1445                         slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);        
1446                         slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);     
1447                         if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1448                                 NTSTATUS status;
1449                                 status = rename_internals(conn, new_name, old_name, True);
1450                                 if (!NT_STATUS_IS_OK(status)) {
1451                                         DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1452                                                         new_name, old_name));
1453                                         *perr = ntstatus_to_werror(status);
1454                                         unlink_internals(conn, 0, new_name);
1455                                         ver = -1;
1456                                 }
1457                         }
1458                         else
1459                                 unlink_internals(conn, 0, new_name);
1460                 }
1461         }
1462
1463         if (driver->configfile && strlen(driver->configfile)) {
1464                 if (!strequal(driver->configfile, driver->driverpath) &&
1465                         !strequal(driver->configfile, driver->datafile)) {
1466                         slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);      
1467                         slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);   
1468                         if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1469                                 NTSTATUS status;
1470                                 status = rename_internals(conn, new_name, old_name, True);
1471                                 if (!NT_STATUS_IS_OK(status)) {
1472                                         DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1473                                                         new_name, old_name));
1474                                         *perr = ntstatus_to_werror(status);
1475                                         unlink_internals(conn, 0, new_name);
1476                                         ver = -1;
1477                                 }
1478                         }
1479                         else
1480                                 unlink_internals(conn, 0, new_name);
1481                 }
1482         }
1483
1484         if (driver->helpfile && strlen(driver->helpfile)) {
1485                 if (!strequal(driver->helpfile, driver->driverpath) &&
1486                         !strequal(driver->helpfile, driver->datafile) &&
1487                         !strequal(driver->helpfile, driver->configfile)) {
1488                         slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);        
1489                         slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);     
1490                         if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1491                                 NTSTATUS status;
1492                                 status = rename_internals(conn, new_name, old_name, True);
1493                                 if (!NT_STATUS_IS_OK(status)) {
1494                                         DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1495                                                         new_name, old_name));
1496                                         *perr = ntstatus_to_werror(status);
1497                                         unlink_internals(conn, 0, new_name);
1498                                         ver = -1;
1499                                 }
1500                         }
1501                         else
1502                                 unlink_internals(conn, 0, new_name);
1503                 }
1504         }
1505
1506         if (driver->dependentfiles) {
1507                 for (i=0; *driver->dependentfiles[i]; i++) {
1508                         if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
1509                                 !strequal(driver->dependentfiles[i], driver->datafile) &&
1510                                 !strequal(driver->dependentfiles[i], driver->configfile) &&
1511                                 !strequal(driver->dependentfiles[i], driver->helpfile)) {
1512                                 int j;
1513                                 for (j=0; j < i; j++) {
1514                                         if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
1515                                                 goto NextDriver;
1516                                         }
1517                                 }
1518
1519                                 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);       
1520                                 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);    
1521                                 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1522                                         NTSTATUS status;
1523                                         status = rename_internals(conn, new_name, old_name, True);
1524                                         if (!NT_STATUS_IS_OK(status)) {
1525                                                 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1526                                                                 new_name, old_name));
1527                                                 *perr = ntstatus_to_werror(status);
1528                                                 unlink_internals(conn, 0, new_name);
1529                                                 ver = -1;
1530                                         }
1531                                 }
1532                                 else
1533                                         unlink_internals(conn, 0, new_name);
1534                         }
1535                 NextDriver: ;
1536                 }
1537         }
1538
1539         close_cnum(conn, user->vuid);
1540         unbecome_user();
1541
1542         return ver == -1 ? False : True;
1543 }
1544
1545 /****************************************************************************
1546 ****************************************************************************/
1547 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
1548 {
1549         int len, buflen;
1550         fstring architecture;
1551         pstring directory;
1552         pstring temp_name;
1553         pstring key;
1554         char *buf;
1555         int i, ret;
1556         TDB_DATA kbuf, dbuf;
1557
1558         get_short_archi(architecture, driver->environment);
1559
1560         /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
1561          * \\server is added in the rpc server layer.
1562          * It does make sense to NOT store the server's name in the printer TDB.
1563          */
1564
1565         slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion);
1566
1567         /* .inf files do not always list a file for each of the four standard files. 
1568          * Don't prepend a path to a null filename, or client claims:
1569          *   "The server on which the printer resides does not have a suitable 
1570          *   <printer driver name> printer driver installed. Click OK if you 
1571          *   wish to install the driver on your local machine."
1572          */
1573         if (strlen(driver->driverpath)) {
1574                 fstrcpy(temp_name, driver->driverpath);
1575                 slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name);
1576         }
1577
1578         if (strlen(driver->datafile)) {
1579                 fstrcpy(temp_name, driver->datafile);
1580                 slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name);
1581         }
1582
1583         if (strlen(driver->configfile)) {
1584                 fstrcpy(temp_name, driver->configfile);
1585                 slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name);
1586         }
1587
1588         if (strlen(driver->helpfile)) {
1589                 fstrcpy(temp_name, driver->helpfile);
1590                 slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name);
1591         }
1592
1593         if (driver->dependentfiles) {
1594                 for (i=0; *driver->dependentfiles[i]; i++) {
1595                         fstrcpy(temp_name, driver->dependentfiles[i]);
1596                         slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", directory, temp_name);
1597                 }
1598         }
1599
1600         slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
1601
1602         DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
1603
1604         buf = NULL;
1605         len = buflen = 0;
1606
1607  again:
1608         len = 0;
1609         len += tdb_pack(buf+len, buflen-len, "dffffffff",
1610                         driver->cversion,
1611                         driver->name,
1612                         driver->environment,
1613                         driver->driverpath,
1614                         driver->datafile,
1615                         driver->configfile,
1616                         driver->helpfile,
1617                         driver->monitorname,
1618                         driver->defaultdatatype);
1619
1620         if (driver->dependentfiles) {
1621                 for (i=0; *driver->dependentfiles[i]; i++) {
1622                         len += tdb_pack(buf+len, buflen-len, "f",
1623                                         driver->dependentfiles[i]);
1624                 }
1625         }
1626
1627         if (len != buflen) {
1628                 char *tb;
1629
1630                 tb = (char *)Realloc(buf, len);
1631                 if (!tb) {
1632                         DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
1633                         ret = -1;
1634                         goto done;
1635                 }
1636                 else buf = tb;
1637                 buflen = len;
1638                 goto again;
1639         }
1640
1641
1642         kbuf.dptr = key;
1643         kbuf.dsize = strlen(key)+1;
1644         dbuf.dptr = buf;
1645         dbuf.dsize = len;
1646         
1647         ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
1648
1649 done:
1650         if (ret)
1651                 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
1652
1653         SAFE_FREE(buf);
1654         return ret;
1655 }
1656
1657 /****************************************************************************
1658 ****************************************************************************/
1659 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
1660 {
1661         NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
1662
1663         ZERO_STRUCT(info3);
1664         info3.cversion = driver->version;
1665         fstrcpy(info3.name,driver->name);
1666         fstrcpy(info3.environment,driver->environment);
1667         fstrcpy(info3.driverpath,driver->driverpath);
1668         fstrcpy(info3.datafile,driver->datafile);
1669         fstrcpy(info3.configfile,driver->configfile);
1670         fstrcpy(info3.helpfile,driver->helpfile);
1671         fstrcpy(info3.monitorname,driver->monitorname);
1672         fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
1673         info3.dependentfiles = driver->dependentfiles;
1674
1675         return add_a_printer_driver_3(&info3);
1676 }
1677
1678
1679 /****************************************************************************
1680 ****************************************************************************/
1681 static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
1682 {
1683         NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
1684
1685         ZERO_STRUCT(info);
1686
1687         fstrcpy(info.name, in_prt);
1688         fstrcpy(info.defaultdatatype, "RAW");
1689         
1690         fstrcpy(info.driverpath, "");
1691         fstrcpy(info.datafile, "");
1692         fstrcpy(info.configfile, "");
1693         fstrcpy(info.helpfile, "");
1694
1695         if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
1696                 return WERR_NOMEM;
1697
1698         memset(info.dependentfiles, '\0', 2*sizeof(fstring));
1699         fstrcpy(info.dependentfiles[0], "");
1700
1701         *info_ptr = memdup(&info, sizeof(info));
1702         
1703         return WERR_OK;
1704 }
1705
1706 /****************************************************************************
1707 ****************************************************************************/
1708 static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
1709 {
1710         NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
1711         TDB_DATA kbuf, dbuf;
1712         fstring architecture;
1713         int len = 0;
1714         int i;
1715         pstring key;
1716
1717         ZERO_STRUCT(driver);
1718
1719         get_short_archi(architecture, in_arch);
1720
1721         DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
1722
1723         slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
1724
1725         kbuf.dptr = key;
1726         kbuf.dsize = strlen(key)+1;
1727         
1728         dbuf = tdb_fetch(tdb_drivers, kbuf);
1729 #if 0
1730         if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1731 #else
1732         if (!dbuf.dptr) return WERR_ACCESS_DENIED;
1733 #endif
1734         len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
1735                           &driver.cversion,
1736                           driver.name,
1737                           driver.environment,
1738                           driver.driverpath,
1739                           driver.datafile,
1740                           driver.configfile,
1741                           driver.helpfile,
1742                           driver.monitorname,
1743                           driver.defaultdatatype);
1744
1745         i=0;
1746         while (len < dbuf.dsize) {
1747                 fstring *tddfs;
1748
1749                 tddfs = (fstring *)Realloc(driver.dependentfiles,
1750                                                          sizeof(fstring)*(i+2));
1751                 if (tddfs == NULL) {
1752                         DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
1753                         break;
1754                 }
1755                 else driver.dependentfiles = tddfs;
1756
1757                 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
1758                                   &driver.dependentfiles[i]);
1759                 i++;
1760         }
1761         if (driver.dependentfiles != NULL)
1762                 fstrcpy(driver.dependentfiles[i], "");
1763
1764         SAFE_FREE(dbuf.dptr);
1765
1766         if (len != dbuf.dsize) {
1767                         SAFE_FREE(driver.dependentfiles);
1768
1769                 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1770         }
1771
1772         *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
1773
1774         return WERR_OK;
1775 }
1776
1777 /****************************************************************************
1778 ****************************************************************************/
1779 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
1780 {
1781         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1782         TDB_DATA kbuf;
1783         pstring key;
1784         int i;
1785         line[0] = '\0';
1786
1787         slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
1788         DEBUG(10,("driver key: [%s]\n", key));
1789         
1790         kbuf.dptr = key;
1791         kbuf.dsize = strlen(key)+1;
1792         if (!tdb_exists(tdb_drivers, kbuf))
1793                 return False;
1794
1795         ZERO_STRUCT(info3);
1796         get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
1797         
1798         DEBUGADD(10,("info3->name            [%s]\n", info3->name));
1799         DEBUGADD(10,("info3->datafile        [%s]\n", info3->datafile));
1800         DEBUGADD(10,("info3->helpfile        [%s]\n", info3->helpfile));
1801         DEBUGADD(10,("info3->monitorname     [%s]\n", info3->monitorname));
1802         DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
1803         for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1804                 DEBUGADD(10,("info3->dependentfiles  [%s]\n", info3->dependentfiles[i]));
1805         }
1806         DEBUGADD(10,("info3->environment     [%s]\n", info3->environment));
1807         DEBUGADD(10,("info3->driverpath      [%s]\n", info3->driverpath));
1808         DEBUGADD(10,("info3->configfile      [%s]\n", info3->configfile));
1809
1810         /*pstrcat(line, info3->name);             pstrcat(line, ":");*/
1811         trim_string(info3->driverpath, "\\print$\\WIN40\\0\\", 0);
1812         pstrcat(line, info3->driverpath);
1813         pstrcat(line, ":");
1814         trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
1815         pstrcat(line, info3->datafile);
1816         pstrcat(line, ":");
1817         trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
1818         pstrcat(line, info3->helpfile);
1819         pstrcat(line, ":");
1820         trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
1821         pstrcat(line, info3->monitorname);
1822         pstrcat(line, ":");
1823         pstrcat(line, "RAW");                /*info3->defaultdatatype);*/
1824         pstrcat(line, ":");
1825
1826         for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1827                 if (i)
1828                         pstrcat(line, ",");               /* don't end in a "," */
1829                 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
1830                 pstrcat(line, info3->dependentfiles[i]);
1831         }
1832         
1833         SAFE_FREE(info3);
1834
1835         return True;    
1836 }
1837
1838 /****************************************************************************
1839  Debugging function, dump at level 6 the struct in the logs.
1840 ****************************************************************************/
1841
1842 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1843 {
1844         uint32 result;
1845         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1846         int i;
1847         
1848         DEBUG(106,("Dumping printer driver at level [%d]\n", level));
1849         
1850         switch (level)
1851         {
1852                 case 3:
1853                 {
1854                         if (driver.info_3 == NULL)
1855                                 result=5;
1856                         else {
1857                                 info3=driver.info_3;
1858                         
1859                                 DEBUGADD(106,("version:[%d]\n",         info3->cversion));
1860                                 DEBUGADD(106,("name:[%s]\n",            info3->name));
1861                                 DEBUGADD(106,("environment:[%s]\n",     info3->environment));
1862                                 DEBUGADD(106,("driverpath:[%s]\n",      info3->driverpath));
1863                                 DEBUGADD(106,("datafile:[%s]\n",        info3->datafile));
1864                                 DEBUGADD(106,("configfile:[%s]\n",      info3->configfile));
1865                                 DEBUGADD(106,("helpfile:[%s]\n",        info3->helpfile));
1866                                 DEBUGADD(106,("monitorname:[%s]\n",     info3->monitorname));
1867                                 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
1868                                 
1869                                 for (i=0; info3->dependentfiles &&
1870                                           *info3->dependentfiles[i]; i++) {
1871                                         DEBUGADD(106,("dependentfile:[%s]\n",
1872                                                       info3->dependentfiles[i]));
1873                                 }
1874                                 result=0;
1875                         }
1876                         break;
1877                 }
1878                 default:
1879                         DEBUGADD(106,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level));
1880                         result=1;
1881                         break;
1882         }
1883         
1884         return result;
1885 }
1886
1887 /****************************************************************************
1888 ****************************************************************************/
1889 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
1890 {
1891         int len = 0;
1892
1893         len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
1894
1895         if (!nt_devmode) return len;
1896
1897         len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1898                         nt_devmode->devicename,
1899                         nt_devmode->formname,
1900
1901                         nt_devmode->specversion,
1902                         nt_devmode->driverversion,
1903                         nt_devmode->size,
1904                         nt_devmode->driverextra,
1905                         nt_devmode->orientation,
1906                         nt_devmode->papersize,
1907                         nt_devmode->paperlength,
1908                         nt_devmode->paperwidth,
1909                         nt_devmode->scale,
1910                         nt_devmode->copies,
1911                         nt_devmode->defaultsource,
1912                         nt_devmode->printquality,
1913                         nt_devmode->color,
1914                         nt_devmode->duplex,
1915                         nt_devmode->yresolution,
1916                         nt_devmode->ttoption,
1917                         nt_devmode->collate,
1918                         nt_devmode->logpixels,
1919                         
1920                         nt_devmode->fields,
1921                         nt_devmode->bitsperpel,
1922                         nt_devmode->pelswidth,
1923                         nt_devmode->pelsheight,
1924                         nt_devmode->displayflags,
1925                         nt_devmode->displayfrequency,
1926                         nt_devmode->icmmethod,
1927                         nt_devmode->icmintent,
1928                         nt_devmode->mediatype,
1929                         nt_devmode->dithertype,
1930                         nt_devmode->reserved1,
1931                         nt_devmode->reserved2,
1932                         nt_devmode->panningwidth,
1933                         nt_devmode->panningheight,
1934                         nt_devmode->private);
1935
1936         
1937         if (nt_devmode->private) {
1938                 len += tdb_pack(buf+len, buflen-len, "B",
1939                                 nt_devmode->driverextra,
1940                                 nt_devmode->private);
1941         }
1942
1943         DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
1944
1945         return len;
1946 }
1947
1948 /****************************************************************************
1949 ****************************************************************************/
1950 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
1951 {
1952         int len = 0;
1953
1954         while (param != NULL) {
1955                 len += tdb_pack(buf+len, buflen-len, "pfdB",
1956                                 param,
1957                                 param->value,
1958                                 param->type,
1959                                 param->data_len,
1960                                 param->data);
1961                 param=param->next;      
1962         }
1963
1964         len += tdb_pack(buf+len, buflen-len, "p", param);
1965
1966         return len;
1967 }
1968
1969
1970 /****************************************************************************
1971  Delete a printer - this just deletes the printer info file, any open
1972  handles are not affected.
1973 ****************************************************************************/
1974
1975 uint32 del_a_printer(char *sharename)
1976 {
1977         pstring key;
1978         TDB_DATA kbuf;
1979
1980         slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
1981
1982         kbuf.dptr=key;
1983         kbuf.dsize=strlen(key)+1;
1984
1985         tdb_delete(tdb_printers, kbuf);
1986         return 0;
1987 }
1988
1989 /* FIXME!!!  Reorder so this forward declaration is not necessary --jerry */
1990 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring);
1991 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
1992 /****************************************************************************
1993 ****************************************************************************/
1994 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
1995 {
1996         pstring key;
1997         char *buf;
1998         int buflen, len;
1999         WERROR ret;
2000         TDB_DATA kbuf, dbuf;
2001         
2002         /*
2003          * in addprinter: no servername and the printer is the name
2004          * in setprinter: servername is \\server
2005          *                and printer is \\server\\printer
2006          *
2007          * Samba manages only local printers.
2008          * we currently don't support things like path=\\other_server\printer
2009          */
2010
2011         if (info->servername[0]!='\0') {
2012                 trim_string(info->printername, info->servername, NULL);
2013                 trim_string(info->printername, "\\", NULL);
2014                 info->servername[0]='\0';
2015         }
2016
2017         /*
2018          * JFM: one day I'll forget.
2019          * below that's info->portname because that's the SAMBA sharename
2020          * and I made NT 'thinks' it's the portname
2021          * the info->sharename is the thing you can name when you add a printer
2022          * that's the short-name when you create shared printer for 95/98
2023          * So I've made a limitation in SAMBA: you can only have 1 printer model
2024          * behind a SAMBA share.
2025          */
2026
2027         buf = NULL;
2028         buflen = 0;
2029
2030  again: 
2031         len = 0;
2032         len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
2033                         info->attributes,
2034                         info->priority,
2035                         info->default_priority,
2036                         info->starttime,
2037                         info->untiltime,
2038                         info->status,
2039                         info->cjobs,
2040                         info->averageppm,
2041                         info->changeid,
2042                         info->c_setprinter,
2043                         info->setuptime,
2044                         info->servername,
2045                         info->printername,
2046                         info->sharename,
2047                         info->portname,
2048                         info->drivername,
2049                         info->comment,
2050                         info->location,
2051                         info->sepfile,
2052                         info->printprocessor,
2053                         info->datatype,
2054                         info->parameters);
2055
2056         len += pack_devicemode(info->devmode, buf+len, buflen-len);
2057         
2058         len += pack_specifics(info->specific, buf+len, buflen-len);
2059
2060         if (buflen != len) {
2061                 char *tb;
2062
2063                 tb = (char *)Realloc(buf, len);
2064                 if (!tb) {
2065                         DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
2066                         ret = WERR_NOMEM;
2067                         goto done;
2068                 }
2069                 else buf = tb;
2070                 buflen = len;
2071                 goto again;
2072         }
2073         
2074
2075         slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, info->sharename);
2076
2077         kbuf.dptr = key;
2078         kbuf.dsize = strlen(key)+1;
2079         dbuf.dptr = buf;
2080         dbuf.dsize = len;
2081
2082         ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
2083
2084 done:
2085         if (!W_ERROR_IS_OK(ret))
2086                 DEBUG(8, ("error updating printer to tdb on disk\n"));
2087
2088         SAFE_FREE(buf);
2089
2090         DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
2091                  info->sharename, info->drivername, info->portname, len));
2092
2093         return ret;
2094 }
2095
2096
2097 /****************************************************************************
2098 ****************************************************************************/
2099 void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM **param)
2100 {
2101         NT_PRINTER_PARAM *current;
2102         
2103         DEBUG(108,("add_a_specific_param\n"));  
2104
2105         (*param)->next=NULL;
2106         
2107         if (info_2->specific == NULL)
2108         {
2109                 info_2->specific=*param;
2110         }
2111         else
2112         {
2113                 current=info_2->specific;               
2114                 while (current->next != NULL) {
2115                         current=current->next;
2116                 }               
2117                 current->next=*param;
2118         }
2119
2120         *param = NULL;
2121 }
2122
2123 /****************************************************************************
2124 ****************************************************************************/
2125 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
2126 {
2127         NT_PRINTER_PARAM *current;
2128         NT_PRINTER_PARAM *previous;
2129         
2130         current=info_2->specific;
2131         previous=current;
2132         
2133         if (current==NULL) return (False);
2134         
2135         if ( !strcmp(current->value, param->value) &&
2136             (strlen(current->value)==strlen(param->value)) ) {
2137                 DEBUG(109,("deleting first value\n"));
2138                 info_2->specific=current->next;
2139                 SAFE_FREE(current->data);
2140                 SAFE_FREE(current);
2141                 DEBUG(109,("deleted first value\n"));
2142                 return (True);
2143         }
2144
2145         current=previous->next;
2146                 
2147         while ( current!=NULL ) {
2148                 if (!strcmp(current->value, param->value) &&
2149                     strlen(current->value)==strlen(param->value) ) {
2150                         DEBUG(109,("deleting current value\n"));
2151                         previous->next=current->next;
2152                         SAFE_FREE(current->data);
2153                         SAFE_FREE(current);
2154                         DEBUG(109,("deleted current value\n"));
2155                         return(True);
2156                 }
2157                 
2158                 previous=previous->next;
2159                 current=current->next;
2160         }
2161         return (False);
2162 }
2163
2164 /****************************************************************************
2165  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
2166 ****************************************************************************/
2167 void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
2168 {
2169         NT_PRINTER_PARAM *param = *param_ptr;
2170
2171         if(param == NULL)
2172                 return;
2173
2174         DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
2175
2176                 SAFE_FREE(param->data);
2177         SAFE_FREE(*param_ptr);
2178 }
2179
2180 /****************************************************************************
2181  Malloc and return an NT devicemode.
2182 ****************************************************************************/
2183
2184 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
2185 {
2186
2187         char adevice[32];
2188         NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
2189
2190         if (nt_devmode == NULL) {
2191                 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
2192                 return NULL;
2193         }
2194
2195         ZERO_STRUCTP(nt_devmode);
2196
2197         safe_strcpy(adevice, default_devicename, sizeof(adevice));
2198         fstrcpy(nt_devmode->devicename, adevice);       
2199         
2200         fstrcpy(nt_devmode->formname, "Letter");
2201
2202         nt_devmode->specversion      = 0x0401;
2203         nt_devmode->driverversion    = 0x0400;
2204         nt_devmode->size             = 0x00DC;
2205         nt_devmode->driverextra      = 0x0000;
2206         nt_devmode->fields           = FORMNAME | TTOPTION | PRINTQUALITY |
2207                                        DEFAULTSOURCE | COPIES | SCALE |
2208                                        PAPERSIZE | ORIENTATION;
2209         nt_devmode->orientation      = 1;
2210         nt_devmode->papersize        = PAPER_LETTER;
2211         nt_devmode->paperlength      = 0;
2212         nt_devmode->paperwidth       = 0;
2213         nt_devmode->scale            = 0x64;
2214         nt_devmode->copies           = 1;
2215         nt_devmode->defaultsource    = BIN_FORMSOURCE;
2216         nt_devmode->printquality     = RES_HIGH;           /* 0x0258 */
2217         nt_devmode->color            = COLOR_MONOCHROME;
2218         nt_devmode->duplex           = DUP_SIMPLEX;
2219         nt_devmode->yresolution      = 0;
2220         nt_devmode->ttoption         = TT_SUBDEV;
2221         nt_devmode->collate          = COLLATE_FALSE;
2222         nt_devmode->icmmethod        = 0;
2223         nt_devmode->icmintent        = 0;
2224         nt_devmode->mediatype        = 0;
2225         nt_devmode->dithertype       = 0;
2226
2227         /* non utilisés par un driver d'imprimante */
2228         nt_devmode->logpixels        = 0;
2229         nt_devmode->bitsperpel       = 0;
2230         nt_devmode->pelswidth        = 0;
2231         nt_devmode->pelsheight       = 0;
2232         nt_devmode->displayflags     = 0;
2233         nt_devmode->displayfrequency = 0;
2234         nt_devmode->reserved1        = 0;
2235         nt_devmode->reserved2        = 0;
2236         nt_devmode->panningwidth     = 0;
2237         nt_devmode->panningheight    = 0;
2238         
2239         nt_devmode->private = NULL;
2240         return nt_devmode;
2241 }
2242
2243 /****************************************************************************
2244  Deepcopy an NT devicemode.
2245 ****************************************************************************/
2246
2247 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
2248 {
2249         NT_DEVICEMODE *new_nt_devicemode = NULL;
2250
2251         if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
2252                 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2253                 return NULL;
2254         }
2255
2256         new_nt_devicemode->private = NULL;
2257         if (nt_devicemode->private != NULL) {
2258                 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
2259                         SAFE_FREE(new_nt_devicemode);
2260                         DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2261                         return NULL;
2262         }
2263         }
2264
2265         return new_nt_devicemode;
2266 }
2267
2268 /****************************************************************************
2269  Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
2270 ****************************************************************************/
2271
2272 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
2273 {
2274         NT_DEVICEMODE *nt_devmode = *devmode_ptr;
2275
2276         if(nt_devmode == NULL)
2277                 return;
2278
2279         DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
2280
2281                 SAFE_FREE(nt_devmode->private);
2282         SAFE_FREE(*devmode_ptr);
2283 }
2284
2285 /****************************************************************************
2286  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
2287 ****************************************************************************/
2288 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
2289 {
2290         NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
2291         NT_PRINTER_PARAM *param_ptr;
2292
2293         if(info == NULL)
2294                 return;
2295
2296         DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
2297
2298         free_nt_devicemode(&info->devmode);
2299
2300         for(param_ptr = info->specific; param_ptr; ) {
2301                 NT_PRINTER_PARAM *tofree = param_ptr;
2302
2303                 param_ptr = param_ptr->next;
2304                 free_nt_printer_param(&tofree);
2305         }
2306
2307         SAFE_FREE(*info_ptr);
2308 }
2309
2310
2311 /****************************************************************************
2312 ****************************************************************************/
2313 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
2314 {
2315         int len = 0;
2316         int extra_len = 0;
2317         NT_DEVICEMODE devmode;
2318
2319         ZERO_STRUCT(devmode);
2320
2321         len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
2322
2323         if (!*nt_devmode) return len;
2324
2325         len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
2326                           devmode.devicename,
2327                           devmode.formname,
2328
2329                           &devmode.specversion,
2330                           &devmode.driverversion,
2331                           &devmode.size,
2332                           &devmode.driverextra,
2333                           &devmode.orientation,
2334                           &devmode.papersize,
2335                           &devmode.paperlength,
2336                           &devmode.paperwidth,
2337                           &devmode.scale,
2338                           &devmode.copies,
2339                           &devmode.defaultsource,
2340                           &devmode.printquality,
2341                           &devmode.color,
2342                           &devmode.duplex,
2343                           &devmode.yresolution,
2344                           &devmode.ttoption,
2345                           &devmode.collate,
2346                           &devmode.logpixels,
2347                         
2348                           &devmode.fields,
2349                           &devmode.bitsperpel,
2350                           &devmode.pelswidth,
2351                           &devmode.pelsheight,
2352                           &devmode.displayflags,
2353                           &devmode.displayfrequency,
2354                           &devmode.icmmethod,
2355                           &devmode.icmintent,
2356                           &devmode.mediatype,
2357                           &devmode.dithertype,
2358                           &devmode.reserved1,
2359                           &devmode.reserved2,
2360                           &devmode.panningwidth,
2361                           &devmode.panningheight,
2362                           &devmode.private);
2363         
2364         if (devmode.private) {
2365                 /* the len in tdb_unpack is an int value and
2366                  * devmode.driverextra is only a short
2367                  */
2368                 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
2369                 devmode.driverextra=(uint16)extra_len;
2370                 
2371                 /* check to catch an invalid TDB entry so we don't segfault */
2372                 if (devmode.driverextra == 0) {
2373                         devmode.private = NULL;
2374                 }
2375         }
2376
2377         *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
2378
2379         DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
2380         if (devmode.private)
2381                 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
2382
2383         return len;
2384 }
2385
2386 /****************************************************************************
2387 ****************************************************************************/
2388 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
2389 {
2390         int len = 0;
2391         NT_PRINTER_PARAM param, *p;
2392
2393         *list = NULL;
2394
2395         while (1) {
2396                 len += tdb_unpack(buf+len, buflen-len, "p", &p);
2397                 if (!p) break;
2398
2399                 len += tdb_unpack(buf+len, buflen-len, "fdB",
2400                                   param.value,
2401                                   &param.type,
2402                                   &param.data_len,
2403                                   &param.data);
2404                 param.next = *list;
2405                 *list = memdup(&param, sizeof(param));
2406
2407                 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
2408         }
2409
2410         return len;
2411 }
2412
2413 static void map_to_os2_driver(fstring drivername)
2414 {
2415         static BOOL initialised=False;
2416         static fstring last_from,last_to;
2417         char *mapfile = lp_os2_driver_map();
2418         char **lines = NULL;
2419         int numlines = 0;
2420         int i;
2421
2422         if (!strlen(drivername))
2423                 return;
2424
2425         if (!*mapfile)
2426                 return;
2427
2428         if (!initialised) {
2429                 *last_from = *last_to = 0;
2430                 initialised = True;
2431         }
2432
2433         if (strequal(drivername,last_from)) {
2434                 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,last_to));
2435                 fstrcpy(drivername,last_to);
2436                 return;
2437         }
2438
2439         lines = file_lines_load(mapfile, &numlines);
2440         if (numlines == 0) {
2441                 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
2442                 return;
2443         }
2444
2445         DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
2446
2447         for( i = 0; i < numlines; i++) {
2448                 char *nt_name = lines[i];
2449                 char *os2_name = strchr(nt_name,'=');
2450
2451                 if (!os2_name)
2452                         continue;
2453
2454                 *os2_name++ = 0;
2455
2456                 while (isspace(*nt_name))
2457                         nt_name++;
2458
2459                 if (!*nt_name || strchr("#;",*nt_name))
2460                         continue;
2461
2462                 {
2463                         int l = strlen(nt_name);
2464                         while (l && isspace(nt_name[l-1])) {
2465                                 nt_name[l-1] = 0;
2466                                 l--;
2467                         }
2468                 }
2469
2470                 while (isspace(*os2_name))
2471                         os2_name++;
2472
2473                 {
2474                         int l = strlen(os2_name);
2475                         while (l && isspace(os2_name[l-1])) {
2476                                 os2_name[l-1] = 0;
2477                                 l--;
2478                         }
2479                 }
2480
2481                 if (strequal(nt_name,drivername)) {
2482                         DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
2483                         fstrcpy(last_from,drivername);
2484                         fstrcpy(last_to,os2_name);
2485                         fstrcpy(drivername,os2_name);
2486                         file_lines_free(lines);
2487                         return;
2488                 }
2489         }
2490
2491         file_lines_free(lines);
2492 }
2493
2494 /****************************************************************************
2495 get a default printer info 2 struct
2496 ****************************************************************************/
2497 static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2498 {
2499         int snum;
2500         NT_PRINTER_INFO_LEVEL_2 info;
2501
2502         ZERO_STRUCT(info);
2503
2504         snum = lp_servicenumber(sharename);
2505
2506         slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
2507         slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s", 
2508                  get_called_name(), sharename);
2509         fstrcpy(info.sharename, sharename);
2510         fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
2511         fstrcpy(info.drivername, lp_printerdriver(snum));
2512
2513         /* by setting the driver name to an empty string, a local NT admin
2514            can now run the **local** APW to install a local printer driver
2515            for a Samba shared printer in 2.2.  Without this, drivers **must** be 
2516            installed on the Samba server for NT clients --jerry */
2517 #if 0   /* JERRY --do not uncomment-- */
2518         if (!*info.drivername)
2519                 fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
2520 #endif
2521
2522
2523         DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info.drivername));
2524
2525         pstrcpy(info.comment, "");
2526         fstrcpy(info.printprocessor, "winprint");
2527         fstrcpy(info.datatype, "RAW");
2528
2529         info.attributes = PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK;      /* attributes */
2530
2531         info.starttime = 0; /* Minutes since 12:00am GMT */
2532         info.untiltime = 0; /* Minutes since 12:00am GMT */
2533         info.priority = 1;
2534         info.default_priority = 1;
2535         info.setuptime = (uint32)time(NULL);
2536
2537         /*
2538          * I changed this as I think it is better to have a generic
2539          * DEVMODE than to crash Win2k explorer.exe   --jerry
2540          * See the HP Deskjet 990c Win2k drivers for an example.
2541          *
2542          * However the default devmode appears to cause problems
2543          * with the HP CLJ 8500 PCL driver.  Hence the addition of
2544          * the "default devmode" parameter   --jerry 22/01/2002
2545          */
2546
2547         if (lp_default_devmode(snum)) {
2548                 if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
2549                         goto fail;
2550         }
2551         else {
2552                 info.devmode = NULL;
2553         }
2554
2555         /* This will get the current RPC talloc context, but we should be
2556            passing this as a parameter... fixme... JRA ! */
2557
2558         if (!nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf))
2559                 goto fail;
2560
2561         *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
2562         if (! *info_ptr) {
2563                 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
2564                 goto fail;
2565         }
2566
2567         return WERR_OK;
2568
2569   fail:
2570         if (info.devmode)
2571                 free_nt_devicemode(&info.devmode);
2572         return WERR_ACCESS_DENIED;
2573 }
2574
2575 /****************************************************************************
2576 ****************************************************************************/
2577 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2578 {
2579         pstring key;
2580         NT_PRINTER_INFO_LEVEL_2 info;
2581         int             len = 0;
2582         TDB_DATA kbuf, dbuf;
2583         fstring printername;
2584                 
2585         ZERO_STRUCT(info);
2586
2587         slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
2588
2589         kbuf.dptr = key;
2590         kbuf.dsize = strlen(key)+1;
2591
2592         dbuf = tdb_fetch(tdb_printers, kbuf);
2593         if (!dbuf.dptr)
2594                 return get_a_printer_2_default(info_ptr, sharename);
2595
2596         len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
2597                         &info.attributes,
2598                         &info.priority,
2599                         &info.default_priority,
2600                         &info.starttime,
2601                         &info.untiltime,
2602                         &info.status,
2603                         &info.cjobs,
2604                         &info.averageppm,
2605                         &info.changeid,
2606                         &info.c_setprinter,
2607                         &info.setuptime,
2608                         info.servername,
2609                         info.printername,
2610                         info.sharename,
2611                         info.portname,
2612                         info.drivername,
2613                         info.comment,
2614                         info.location,
2615                         info.sepfile,
2616                         info.printprocessor,
2617                         info.datatype,
2618                         info.parameters);
2619
2620         /* Samba has to have shared raw drivers. */
2621         info.attributes |= (PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK); 
2622
2623         /* Restore the stripped strings. */
2624         slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
2625         slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", get_called_name(),
2626                         info.printername);
2627         fstrcpy(info.printername, printername);
2628
2629         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2630
2631         /*
2632          * Some client drivers freak out if there is a NULL devmode
2633          * (probably the driver is not checking before accessing 
2634          * the devmode pointer)   --jerry
2635          *
2636          * See comments in get_a_printer_2_default()
2637          */
2638
2639         if (lp_default_devmode(lp_servicenumber(sharename)) && !info.devmode)
2640         {
2641                 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
2642                         printername));
2643                 info.devmode = construct_nt_devicemode(printername);
2644         }
2645
2646         len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
2647
2648         /* This will get the current RPC talloc context, but we should be
2649        passing this as a parameter... fixme... JRA ! */
2650
2651         nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
2652
2653         /* Fix for OS/2 drivers. */
2654
2655         if (get_remote_arch() == RA_OS2)
2656                 map_to_os2_driver(info.drivername);
2657
2658         SAFE_FREE(dbuf.dptr);
2659         *info_ptr=memdup(&info, sizeof(info));
2660
2661         DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
2662                  sharename, info.printername, info.drivername));
2663
2664         return WERR_OK; 
2665 }
2666
2667 /****************************************************************************
2668 debugging function, dump at level 6 the struct in the logs
2669 ****************************************************************************/
2670 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2671 {
2672         uint32 result;
2673         NT_PRINTER_INFO_LEVEL_2 *info2;
2674         
2675         DEBUG(106,("Dumping printer at level [%d]\n", level));
2676         
2677         switch (level)
2678         {
2679                 case 2:
2680                 {
2681                         if (printer.info_2 == NULL)
2682                                 result=5;
2683                         else
2684                         {
2685                                 info2=printer.info_2;
2686                         
2687                                 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
2688                                 DEBUGADD(106,("priority:[%d]\n", info2->priority));
2689                                 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
2690                                 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
2691                                 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
2692                                 DEBUGADD(106,("status:[%d]\n", info2->status));
2693                                 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
2694                                 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
2695                                 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
2696                                 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
2697                                 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
2698
2699                                 DEBUGADD(106,("servername:[%s]\n", info2->servername));
2700                                 DEBUGADD(106,("printername:[%s]\n", info2->printername));
2701                                 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
2702                                 DEBUGADD(106,("portname:[%s]\n", info2->portname));
2703                                 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
2704                                 DEBUGADD(106,("comment:[%s]\n", info2->comment));
2705                                 DEBUGADD(106,("location:[%s]\n", info2->location));
2706                                 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
2707                                 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
2708                                 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
2709                                 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
2710                                 result=0;
2711                         }
2712                         break;
2713                 }
2714                 default:
2715                         DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level ));
2716                         result=1;
2717                         break;
2718         }
2719         
2720         return result;
2721 }
2722
2723 /****************************************************************************
2724  Get the parameters we can substitute in an NT print job.
2725 ****************************************************************************/
2726
2727 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
2728 {
2729         NT_PRINTER_INFO_LEVEL *printer = NULL;
2730
2731         **printername = **sharename = **portname = '\0';
2732
2733         if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
2734                 return;
2735
2736         fstrcpy(*printername, printer->info_2->printername);
2737         fstrcpy(*sharename, printer->info_2->sharename);
2738         fstrcpy(*portname, printer->info_2->portname);
2739
2740         free_a_printer(&printer, 2);
2741 }
2742
2743 /****************************************************************************
2744  Update the changeid time.
2745  This is SO NASTY as some drivers need this to change, others need it
2746  static. This value will change every second, and I must hope that this
2747  is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
2748  UTAH ! JRA.
2749 ****************************************************************************/
2750
2751 static uint32 rev_changeid(void)
2752 {
2753         struct timeval tv;
2754
2755         get_process_uptime(&tv);
2756
2757 #if 1   /* JERRY */
2758         /* Return changeid as msec since spooler restart */
2759         return tv.tv_sec * 1000 + tv.tv_usec / 1000;
2760 #else
2761         /*
2762          * This setting seems to work well but is too untested
2763          * to replace the above calculation.  Left in for experiementation
2764          * of the reader            --jerry (Tue Mar 12 09:15:05 CST 2002)
2765          */
2766         return tv.tv_sec * 10 + tv.tv_usec / 100000;
2767 #endif
2768 }
2769
2770 /*
2771  * The function below are the high level ones.
2772  * only those ones must be called from the spoolss code.
2773  * JFM.
2774  */
2775
2776 /****************************************************************************
2777  Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
2778 ****************************************************************************/
2779
2780 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2781 {
2782         WERROR result;
2783         
2784         dump_a_printer(printer, level); 
2785         
2786         switch (level)
2787         {
2788                 case 2:
2789                 {
2790                         /*
2791                          * Update the changestamp.  Emperical tests show that the
2792                          * ChangeID is always updated,but c_setprinter is  
2793                          *  global spooler variable (not per printer).
2794                          */
2795
2796                         /* ChangeID **must** be increasing over the lifetime
2797                            of client's spoolss service in order for the
2798                            client's cache to show updates */
2799
2800                         printer.info_2->changeid = rev_changeid();
2801
2802                         /*
2803                          * Because one day someone will ask:
2804                          * NT->NT       An admin connection to a remote
2805                          *              printer show changes imeediately in
2806                          *              the properities dialog
2807                          *      
2808                          *              A non-admin connection will only show the
2809                          *              changes after viewing the properites page
2810                          *              2 times.  Seems to be related to a
2811                          *              race condition in the client between the spooler
2812                          *              updating the local cache and the Explorer.exe GUI
2813                          *              actually displaying the properties.
2814                          *
2815                          *              This is fixed in Win2k.  admin/non-admin
2816                          *              connections both display changes immediately.
2817                          *
2818                          * 14/12/01     --jerry
2819                          */
2820
2821                         result=update_a_printer_2(printer.info_2);
2822                         break;
2823                 }
2824                 default:
2825                         result=WERR_UNKNOWN_LEVEL;
2826                         break;
2827         }
2828         
2829         return result;
2830 }
2831
2832 /****************************************************************************
2833  Initialize printer devmode & data with previously saved driver init values.
2834 ****************************************************************************/
2835
2836 static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
2837 {
2838         int                     len = 0;
2839         pstring                 key;
2840         TDB_DATA                kbuf, dbuf;
2841         NT_PRINTER_PARAM        *current;
2842         NT_PRINTER_INFO_LEVEL_2 info;
2843
2844         /*
2845          * Delete any printer data 'specifics' already set. When called for driver
2846          * replace, there will generally be some, but during an add printer, there
2847          * should not be any (if there are delete them).
2848          */
2849         while ( (current=info_ptr->specific) != NULL ) {
2850                 info_ptr->specific=current->next;
2851                 SAFE_FREE(current->data);
2852                 SAFE_FREE(current);
2853         }
2854
2855         ZERO_STRUCT(info);
2856
2857         slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
2858
2859         kbuf.dptr = key;
2860         kbuf.dsize = strlen(key)+1;
2861
2862         dbuf = tdb_fetch(tdb_drivers, kbuf);
2863     if (!dbuf.dptr) {
2864                 /*
2865                  * When changing to a driver that has no init info in the tdb, remove
2866                  * the previous drivers init info and leave the new on blank.
2867                  */
2868                 free_nt_devicemode(&info_ptr->devmode);
2869                 return False;
2870         }
2871
2872         /*
2873          * Get the saved DEVMODE..
2874          */
2875         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2876
2877         /*
2878          * The saved DEVMODE contains the devicename from the printer used during
2879          * the initialization save. Change it to reflect the new printer.
2880          */
2881         ZERO_STRUCT(info.devmode->devicename);
2882         fstrcpy(info.devmode->devicename, info_ptr->printername);
2883
2884
2885         /*
2886          * NT/2k does not change out the entire DeviceMode of a printer
2887          * when changing the driver.  Only the driverextra, private, & 
2888          * driverversion fields.   --jerry  (Thu Mar 14 08:58:43 CST 2002)
2889          */
2890
2891 #if 0   /* JERRY */
2892
2893         /* 
2894          *      Bind the saved DEVMODE to the new the printer.
2895          */
2896         free_nt_devicemode(&info_ptr->devmode);
2897         info_ptr->devmode = info.devmode;
2898 #else
2899         /* copy the entire devmode if we currently don't have one */
2900
2901         if (!info_ptr->devmode) {
2902                 DEBUG(10,("set_driver_init_2: Current Devmode is NULL.  Copying entire Device Mode\n"));
2903                 info_ptr->devmode = info.devmode;
2904         }
2905         else {
2906                 /* only set the necessary fields */
2907
2908                 DEBUG(10,("set_driver_init_2: Setting driverversion [0x%x] and private data [0x%x]\n",
2909                         info.devmode->driverversion, info.devmode->driverextra));
2910
2911                 info_ptr->devmode->driverversion = info.devmode->driverversion;
2912
2913                 SAFE_FREE(info_ptr->devmode->private);
2914                 info_ptr->devmode->private = NULL;
2915
2916                 if (info.devmode->driverversion)
2917                         info_ptr->devmode->private = memdup(info.devmode->private, info.devmode->driverversion);
2918
2919                 free_nt_devicemode(&info.devmode);
2920         }
2921 #endif
2922
2923         DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
2924                         info_ptr->printername, info_ptr->drivername));
2925
2926         /* 
2927          * Add the printer data 'specifics' to the new printer
2928          */
2929         len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
2930
2931         SAFE_FREE(dbuf.dptr);
2932
2933         return True;    
2934 }
2935
2936 /****************************************************************************
2937  Initialize printer devmode & data with previously saved driver init values.
2938  When a printer is created using AddPrinter, the drivername bound to the
2939  printer is used to lookup previously saved driver initialization info, which
2940  is bound to the new printer.
2941 ****************************************************************************/
2942
2943 uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
2944 {
2945         uint32 result;
2946         
2947         switch (level)
2948         {
2949                 case 2:
2950                 {
2951                         result=set_driver_init_2(printer->info_2);
2952                         break;
2953                 }
2954                 default:
2955                         result=1;
2956                         break;
2957         }
2958         
2959         return result;
2960 }
2961
2962 /****************************************************************************
2963  Pack up the DEVMODE and specifics for a printer into a 'driver init' entry 
2964  in the tdb. Note: this is different from the driver entry and the printer
2965  entry. There should be a single driver init entry for each driver regardless
2966  of whether it was installed from NT or 2K. Technically, they should be
2967  different, but they work out to the same struct.
2968 ****************************************************************************/
2969
2970 static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
2971 {
2972         pstring key;
2973         char *buf;
2974         int buflen, len, ret;
2975         TDB_DATA kbuf, dbuf;
2976
2977         buf = NULL;
2978         buflen = 0;
2979
2980  again: 
2981         len = 0;
2982         len += pack_devicemode(info->devmode, buf+len, buflen-len);
2983
2984         len += pack_specifics(info->specific, buf+len, buflen-len);
2985
2986         if (buflen != len) {
2987                 char *tb;
2988
2989                 tb = (char *)Realloc(buf, len);
2990                 if (!tb) {
2991                         DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
2992                         ret = -1;
2993                         goto done;
2994                 }
2995                 else buf = tb;
2996                 buflen = len;
2997                 goto again;
2998         }
2999
3000         slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername);
3001
3002         kbuf.dptr = key;
3003         kbuf.dsize = strlen(key)+1;
3004         dbuf.dptr = buf;
3005         dbuf.dsize = len;
3006
3007         ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
3008
3009 done:
3010         if (ret == -1)
3011                 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
3012
3013         SAFE_FREE(buf);
3014
3015         DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
3016                  info->sharename, info->drivername));
3017
3018         return ret;
3019 }
3020
3021 /****************************************************************************
3022  Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
3023 ****************************************************************************/
3024
3025 uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
3026 {
3027         uint32 result;
3028         
3029         dump_a_printer(printer, level); 
3030         
3031         switch (level)
3032         {
3033                 case 2:
3034                 {
3035                         result=update_driver_init_2(printer.info_2);
3036                         break;
3037                 }
3038                 default:
3039                         result=1;
3040                         break;
3041         }
3042         
3043         return result;
3044 }
3045
3046 /****************************************************************************
3047  Convert the printer data value, a REG_BINARY array, into an initialization 
3048  DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
3049  got to keep the endians happy :).
3050 ****************************************************************************/
3051
3052 static BOOL convert_driver_init(NT_PRINTER_PARAM *param, TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode)
3053 {
3054         BOOL       result = False;
3055         prs_struct ps;
3056         DEVICEMODE devmode;
3057
3058         ZERO_STRUCT(devmode);
3059
3060         prs_init(&ps, 0, ctx, UNMARSHALL);
3061         ps.data_p      = (char *)param->data;
3062         ps.buffer_size = param->data_len;
3063
3064         if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
3065                 result = convert_devicemode("", &devmode, &nt_devmode);
3066         else
3067                 DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
3068
3069         return result;
3070 }
3071
3072 /****************************************************************************
3073  Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
3074
3075  1. Use the driver's config DLL to this UNC printername and:
3076     a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
3077     b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
3078  2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
3079
3080  The last step triggers saving the "driver initialization" information for
3081  this printer into the tdb. Later, new printers that use this driver will
3082  have this initialization information bound to them. This simulates the
3083  driver initialization, as if it had run on the Samba server (as it would
3084  have done on NT).
3085
3086  The Win32 client side code requirement sucks! But until we can run arbitrary
3087  Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
3088  
3089  It would have been easier to use SetPrinter because all the UNMARSHALLING of
3090  the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
3091  about it and you will realize why.  JRR 010720
3092 ****************************************************************************/
3093
3094 static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARAM *param)
3095 {
3096         WERROR        status       = WERR_OK;
3097         TALLOC_CTX    *ctx         = NULL;
3098         NT_DEVICEMODE *nt_devmode  = NULL;
3099         NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
3100         
3101         /*
3102          * When the DEVMODE is already set on the printer, don't try to unpack it.
3103          */
3104
3105         if (!printer->info_2->devmode && param->data_len) {
3106                 /*
3107                  * Set devmode on printer info, so entire printer initialization can be
3108                  * saved to tdb.
3109                  */
3110
3111                 if ((ctx = talloc_init()) == NULL)
3112                         return WERR_NOMEM;
3113
3114                 if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) {
3115                         status = WERR_NOMEM;
3116                         goto done;
3117                 }
3118         
3119                 ZERO_STRUCTP(nt_devmode);
3120
3121                 /*
3122                  * The DEVMODE is held in the 'data' component of the param in raw binary.
3123                  * Convert it to to a devmode structure
3124                  */
3125                 if (!convert_driver_init(param, ctx, nt_devmode)) {
3126                         DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
3127                         status = WERR_INVALID_PARAM;
3128                         goto done;
3129                 }
3130
3131                 printer->info_2->devmode = nt_devmode;
3132         }
3133
3134         /*
3135          * Pack up and add (or update) the DEVMODE and any current printer data to
3136          * a 'driver init' element in the tdb
3137          * 
3138          */
3139
3140         if (update_driver_init(*printer, 2)!=0) {
3141                 DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
3142                 status = WERR_NOMEM;
3143                 goto done;
3144         }
3145         
3146         /*
3147          * If driver initialization info was successfully saved, set the current 
3148          * printer to match it. This allows initialization of the current printer 
3149          * as well as the driver.
3150          */
3151         status = mod_a_printer(*printer, 2);
3152         if (!W_ERROR_IS_OK(status)) {
3153                 DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
3154                                   printer->info_2->printername));
3155         }
3156         
3157 #if 0   /* JERRY */
3158         srv_spoolss_sendnotify(p, handle);
3159 #endif
3160
3161   done:
3162         talloc_destroy(ctx);
3163         if (nt_devmode)
3164                 SAFE_FREE(nt_devmode->private);
3165         SAFE_FREE(nt_devmode);
3166         printer->info_2->devmode = tmp_devmode;
3167
3168         return status;
3169 }
3170
3171 /****************************************************************************
3172  Update the driver init info (DEVMODE and specifics) for a printer
3173 ****************************************************************************/
3174
3175 WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param)
3176 {
3177         WERROR status = WERR_OK;
3178         
3179         switch (level)
3180         {
3181                 case 2:
3182                 {
3183                         status=save_driver_init_2(printer, param);
3184                         break;
3185                 }
3186                 default:
3187                         status=WERR_UNKNOWN_LEVEL;
3188                         break;
3189         }
3190         
3191         return status;
3192 }
3193
3194 /****************************************************************************
3195  Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
3196 ****************************************************************************/
3197
3198 WERROR get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
3199 {
3200         WERROR result;
3201         NT_PRINTER_INFO_LEVEL *printer = NULL;
3202         
3203         *pp_printer = NULL;
3204
3205         DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
3206
3207         switch (level)
3208         {
3209                 case 2:
3210                 {
3211                         if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
3212                                 DEBUG(0,("get_a_printer: malloc fail.\n"));
3213                                 return WERR_NOMEM;
3214                         }
3215                         ZERO_STRUCTP(printer);
3216                         result=get_a_printer_2(&printer->info_2, sharename);
3217                         if (W_ERROR_IS_OK(result)) {
3218                                 dump_a_printer(*printer, level);
3219                                 *pp_printer = printer;
3220                         } else {
3221                                 SAFE_FREE(printer);
3222                         }
3223                         break;
3224                 }
3225                 default:
3226                         result=WERR_UNKNOWN_LEVEL;
3227                         break;
3228         }
3229         
3230         DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", sharename, (unsigned int)level, dos_errstr(result)));
3231
3232         return result;
3233 }
3234
3235 /****************************************************************************
3236  Deletes a NT_PRINTER_INFO_LEVEL struct.
3237 ****************************************************************************/
3238
3239 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
3240 {
3241         uint32 result;
3242         NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
3243
3244         DEBUG(104,("freeing a printer at level [%d]\n", level));
3245
3246         if (printer == NULL)
3247                 return 0;
3248         
3249         switch (level)
3250         {
3251                 case 2:
3252                 {
3253                         if (printer->info_2 != NULL)
3254                         {
3255                                 free_nt_printer_info_level_2(&printer->info_2);
3256                                 result=0;
3257                         }
3258                         else
3259                         {
3260                                 result=4;
3261                         }
3262                         break;
3263                 }
3264                 default:
3265                         result=1;
3266                         break;
3267         }
3268
3269         SAFE_FREE(*pp_printer);
3270         return result;
3271 }
3272
3273 /****************************************************************************
3274 ****************************************************************************/
3275 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
3276 {
3277         uint32 result;
3278         DEBUG(104,("adding a printer at level [%d]\n", level));
3279         dump_a_printer_driver(driver, level);
3280         
3281         switch (level)
3282         {
3283                 case 3:
3284                 {
3285                         result=add_a_printer_driver_3(driver.info_3);
3286                         break;
3287                 }
3288
3289                 case 6:
3290                 {
3291                         result=add_a_printer_driver_6(driver.info_6);
3292                         break;
3293                 }
3294                 default:
3295                         result=1;
3296                         break;
3297         }
3298         
3299         return result;
3300 }
3301 /****************************************************************************
3302 ****************************************************************************/
3303 WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
3304                             fstring printername, fstring architecture, uint32 version)
3305 {
3306         WERROR result;
3307         
3308         switch (level)
3309         {
3310                 case 3:
3311                 {
3312                         result=get_a_printer_driver_3(&driver->info_3, printername, architecture, version);
3313                         break;
3314                 }
3315                 default:
3316                         result=W_ERROR(1);
3317                         break;
3318         }
3319         
3320         if (W_ERROR_IS_OK(result))
3321                 dump_a_printer_driver(*driver, level);
3322         return result;
3323 }
3324
3325 /****************************************************************************
3326 ****************************************************************************/
3327 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
3328 {
3329         uint32 result;
3330         
3331         switch (level)
3332         {
3333                 case 3:
3334                 {
3335                         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
3336                         if (driver.info_3 != NULL)
3337                         {
3338                                 info3=driver.info_3;
3339                                 SAFE_FREE(info3->dependentfiles);
3340                                 ZERO_STRUCTP(info3);
3341                                 SAFE_FREE(info3);
3342                                 result=0;
3343                         }
3344                         else
3345                         {
3346                                 result=4;
3347                         }
3348                         break;
3349                 }
3350                 case 6:
3351                 {
3352                         NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
3353                         if (driver.info_6 != NULL)
3354                         {
3355                                 info6=driver.info_6;
3356                                 SAFE_FREE(info6->dependentfiles);
3357                                 SAFE_FREE(info6->previousnames);
3358                                 ZERO_STRUCTP(info6);
3359                                 SAFE_FREE(info6);
3360                                 result=0;
3361                         }
3362                         else
3363                         {
3364                                 result=4;
3365                         }
3366                         break;
3367                 }
3368                 default:
3369                         result=1;
3370                         break;
3371         }
3372         return result;
3373 }
3374
3375
3376 /****************************************************************************
3377   Determine whether or not a particular driver is currently assigned
3378   to a printer
3379 ****************************************************************************/
3380 BOOL printer_driver_in_use (char *arch, char *driver)
3381 {
3382         TDB_DATA kbuf, newkey, dbuf;
3383         NT_PRINTER_INFO_LEVEL_2 info;
3384         int ret;
3385
3386         if (!tdb_printers)
3387                 if (!nt_printing_init())
3388                         return False;
3389
3390         DEBUG(5,("printer_driver_in_use: Beginning search through printers.tdb...\n"));
3391         
3392         /* loop through the printers.tdb and check for the drivername */
3393         for (kbuf = tdb_firstkey(tdb_printers); kbuf.dptr;
3394              newkey = tdb_nextkey(tdb_printers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) 
3395         {
3396
3397                 dbuf = tdb_fetch(tdb_printers, kbuf);
3398                 if (!dbuf.dptr) 
3399                         continue;
3400
3401                 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) != 0) 
3402                         continue;
3403
3404                 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddddddfffffPfffff",
3405                         &info.attributes,
3406                         &info.priority,
3407                         &info.default_priority,
3408                         &info.starttime,
3409                         &info.untiltime,
3410                         &info.status,
3411                         &info.cjobs,
3412                         &info.averageppm,
3413                         &info.changeid,
3414                         &info.c_setprinter,
3415                         &info.setuptime,
3416                         info.servername,
3417                         info.printername,
3418                         info.sharename,
3419                         info.portname,
3420                         info.drivername,
3421                         info.comment,
3422                         info.location,
3423                         info.sepfile,
3424                         info.printprocessor,
3425                         info.datatype,
3426                         info.parameters);
3427
3428                 SAFE_FREE(dbuf.dptr);
3429
3430                 if (ret == -1) {
3431                         DEBUG (0,("printer_driver_in_use: tdb_unpack failed for printer %s\n",
3432                                         info.printername));
3433                         continue;
3434                 }
3435                 
3436                 DEBUG (10,("printer_driver_in_use: Printer - %s (%s)\n",
3437                         info.printername, info.drivername));
3438                         
3439                 if (strcmp(info.drivername, driver) == 0) 
3440                 {
3441                         DEBUG(5,("printer_driver_in_use: Printer %s using %s\n",
3442                                 info.printername, driver));
3443                         return True;
3444                 }       
3445         }
3446         DEBUG(5,("printer_driver_in_use: Completed search through printers.tdb...\n"));
3447         
3448         
3449         
3450         /* report that the driver is in use by default */
3451         return False;
3452 }
3453
3454 /****************************************************************************
3455  Remove a printer driver from the TDB.  This assumes that the the driver was
3456  previously looked up.
3457  ***************************************************************************/
3458 WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i)
3459 {
3460         pstring         key;
3461         fstring         arch;
3462         TDB_DATA        kbuf;
3463
3464
3465         get_short_archi(arch, i->environment);
3466         slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
3467                 arch, i->cversion, i->name); 
3468         DEBUG(5,("delete_printer_driver: key = [%s]\n", key));
3469
3470         kbuf.dptr=key;
3471         kbuf.dsize=strlen(key)+1;
3472
3473         if (tdb_delete(tdb_drivers, kbuf) == -1) {
3474                 DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
3475                 return WERR_ACCESS_DENIED;
3476         }
3477         
3478         DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
3479                 i->name));
3480         
3481         return WERR_OK;
3482 }
3483 /****************************************************************************
3484 ****************************************************************************/
3485 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
3486                                  fstring value, uint8 **data, uint32 *type, uint32 *len)
3487 {
3488         /* right now that's enough ! */ 
3489         NT_PRINTER_PARAM *param;
3490         int i=0;
3491         
3492         param=printer.info_2->specific;
3493         
3494         while (param != NULL && i < param_index) {
3495                 param=param->next;
3496                 i++;
3497         }
3498         
3499         if (param == NULL)
3500                 return False;
3501
3502         /* exited because it exist */
3503         *type=param->type;              
3504         StrnCpy(value, param->value, sizeof(fstring)-1);
3505         *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
3506         if(*data == NULL)
3507                 return False;
3508         ZERO_STRUCTP(*data);
3509         memcpy(*data, param->data, param->data_len);
3510         *len=param->data_len;
3511         return True;
3512 }
3513
3514 /****************************************************************************
3515 ****************************************************************************/
3516 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
3517                         fstring value, uint8 **data, uint32 *type, uint32 *len)
3518 {
3519         /* right now that's enough ! */ 
3520         NT_PRINTER_PARAM *param;
3521         
3522         DEBUG(10, ("get_specific_param\n"));
3523         
3524         param=printer.info_2->specific;
3525                 
3526         while (param != NULL)
3527         {
3528 #if 1 /* JRA - I think this should be case insensitive.... */
3529                 if ( strequal(value, param->value)
3530 #else
3531                 if ( !strcmp(value, param->value)
3532 #endif
3533                     && strlen(value)==strlen(param->value))
3534                         break;
3535                         
3536                 param=param->next;
3537         }
3538         
3539         if (param != NULL)
3540         {
3541         DEBUGADD(10, ("get_specific_param: found one param\n"));
3542                 /* exited because it exist */
3543                 *type=param->type;      
3544                 
3545                 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
3546                 if(*data == NULL)
3547                         return False;
3548                 memcpy(*data, param->data, param->data_len);
3549                 *len=param->data_len;
3550
3551                 DEBUGADD(10, ("get_specific_param: exit true\n"));
3552                 return (True);
3553         }
3554         DEBUGADD(10, ("get_specific_param: exit false\n"));
3555         return (False);
3556 }
3557
3558 /****************************************************************************
3559  Store a security desc for a printer.
3560 ****************************************************************************/
3561
3562 WERROR nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
3563 {
3564         SEC_DESC_BUF *new_secdesc_ctr = NULL;
3565         SEC_DESC_BUF *old_secdesc_ctr = NULL;
3566         prs_struct ps;
3567         TALLOC_CTX *mem_ctx = NULL;
3568         fstring key;
3569         WERROR status;
3570
3571         mem_ctx = talloc_init();
3572         if (mem_ctx == NULL)
3573                 return WERR_NOMEM;
3574
3575         /* The old owner and group sids of the security descriptor are not
3576            present when new ACEs are added or removed by changing printer
3577            permissions through NT.  If they are NULL in the new security
3578            descriptor then copy them over from the old one. */
3579
3580         if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
3581                 DOM_SID *owner_sid, *group_sid;
3582                 SEC_ACL *dacl, *sacl;
3583                 SEC_DESC *psd = NULL;
3584                 size_t size;
3585
3586                 nt_printing_getsec(mem_ctx, printername, &old_secdesc_ctr);
3587
3588                 /* Pick out correct owner and group sids */
3589
3590                 owner_sid = secdesc_ctr->sec->owner_sid ?
3591                         secdesc_ctr->sec->owner_sid :
3592                         old_secdesc_ctr->sec->owner_sid;
3593
3594                 group_sid = secdesc_ctr->sec->grp_sid ?
3595                         secdesc_ctr->sec->grp_sid :
3596                         old_secdesc_ctr->sec->grp_sid;
3597
3598                 dacl = secdesc_ctr->sec->dacl ?
3599                         secdesc_ctr->sec->dacl :
3600                         old_secdesc_ctr->sec->dacl;
3601
3602                 sacl = secdesc_ctr->sec->sacl ?
3603                         secdesc_ctr->sec->sacl :
3604                         old_secdesc_ctr->sec->sacl;
3605
3606                 /* Make a deep copy of the security descriptor */
3607
3608                 psd = make_sec_desc(mem_ctx, secdesc_ctr->sec->revision,
3609                                     owner_sid, group_sid,
3610                                     sacl,
3611                                     dacl,
3612                                     &size);
3613
3614                 new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);
3615         }
3616
3617         if (!new_secdesc_ctr) {
3618                 new_secdesc_ctr = secdesc_ctr;
3619         }
3620
3621         /* Store the security descriptor in a tdb */
3622
3623         prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
3624                  sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
3625
3626         if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
3627                              &ps, 1)) {
3628                 status = WERR_BADFUNC;
3629                 goto out;
3630         }
3631
3632         slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
3633
3634         if (tdb_prs_store(tdb_printers, key, &ps)==0) {
3635                 status = WERR_OK;
3636         } else {
3637                 DEBUG(1,("Failed to store secdesc for %s\n", printername));
3638                 status = WERR_BADFUNC;
3639         }
3640
3641         /* Free malloc'ed memory */
3642
3643  out:
3644
3645         prs_mem_free(&ps);
3646         if (mem_ctx)
3647                 talloc_destroy(mem_ctx);
3648         return status;
3649 }
3650
3651 /****************************************************************************
3652  Construct a default security descriptor buffer for a printer.
3653 ****************************************************************************/
3654
3655 static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
3656 {
3657         extern DOM_SID global_sam_sid;
3658         SEC_ACE ace[3];
3659         SEC_ACCESS sa;
3660         SEC_ACL *psa = NULL;
3661         SEC_DESC_BUF *sdb = NULL;
3662         SEC_DESC *psd = NULL;
3663         DOM_SID owner_sid;
3664         size_t sd_size;
3665
3666         /* Create an ACE where Everyone is allowed to print */
3667
3668         init_sec_access(&sa, PRINTER_ACE_PRINT);
3669         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
3670                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
3671
3672         /* Make the security descriptor owned by the Administrators group
3673            on the PDC of the domain. */
3674
3675         if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
3676                 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
3677         } else {
3678
3679                 /* Backup plan - make printer owned by admins.
3680                    This should emulate a lanman printer as security
3681                    settings can't be changed. */
3682
3683                 sid_copy(&owner_sid, &global_sam_sid);
3684                 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
3685         }
3686
3687         init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
3688         init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
3689                      sa, SEC_ACE_FLAG_OBJECT_INHERIT |
3690                      SEC_ACE_FLAG_INHERIT_ONLY);
3691
3692         init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
3693         init_sec_ace(&ace[2], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
3694                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
3695
3696         /* The ACL revision number in rpc_secdesc.h differs from the one
3697            created by NT when setting ACE entries in printer
3698            descriptors.  NT4 complains about the property being edited by a
3699            NT5 machine. */
3700
3701         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) != NULL) {
3702                 psd = make_sec_desc(ctx, SEC_DESC_REVISION,
3703                                     &owner_sid, NULL,
3704                                     NULL, psa, &sd_size);
3705         }
3706
3707         if (!psd) {
3708                 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
3709                 return NULL;
3710         }
3711
3712         sdb = make_sec_desc_buf(ctx, sd_size, psd);
3713
3714         DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
3715                  (unsigned int)sd_size));
3716
3717         return sdb;
3718 }
3719
3720 /****************************************************************************
3721  Get a security desc for a printer.
3722 ****************************************************************************/
3723
3724 BOOL nt_printing_getsec(TALLOC_CTX *ctx, char *printername, SEC_DESC_BUF **secdesc_ctr)
3725 {
3726         prs_struct ps;
3727         fstring key;
3728         char *temp;
3729
3730         if ((temp = strchr(printername + 2, '\\'))) {
3731                 printername = temp + 1;
3732         }
3733
3734         /* Fetch security descriptor from tdb */
3735
3736         slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
3737
3738         if (tdb_prs_fetch(tdb_printers, key, &ps, ctx)!=0 ||
3739             !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
3740
3741                 DEBUG(4,("using default secdesc for %s\n", printername));
3742
3743                 if (!(*secdesc_ctr = construct_default_printer_sdb(ctx))) {
3744                         return False;
3745                 }
3746
3747                 /* Save default security descriptor for later */
3748
3749                 prs_init(&ps, (uint32)sec_desc_size((*secdesc_ctr)->sec) +
3750                                 sizeof(SEC_DESC_BUF), ctx, MARSHALL);
3751
3752                 if (sec_io_desc_buf("nt_printing_setsec", secdesc_ctr, &ps, 1))
3753                         tdb_prs_store(tdb_printers, key, &ps);
3754
3755                 prs_mem_free(&ps);
3756
3757                 return True;
3758         }
3759
3760         /* If security descriptor is owned by S-1-1-0 and winbindd is up,
3761            this security descriptor has been created when winbindd was
3762            down.  Take ownership of security descriptor. */
3763
3764         if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
3765                 DOM_SID owner_sid;
3766
3767                 /* Change sd owner to workgroup administrator */
3768
3769                 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
3770                         SEC_DESC_BUF *new_secdesc_ctr = NULL;
3771                         SEC_DESC *psd = NULL;
3772                         size_t size;
3773
3774                         /* Create new sd */
3775
3776                         sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
3777
3778                         psd = make_sec_desc(ctx, (*secdesc_ctr)->sec->revision,
3779                                             &owner_sid,
3780                                             (*secdesc_ctr)->sec->grp_sid,
3781                                             (*secdesc_ctr)->sec->sacl,
3782                                             (*secdesc_ctr)->sec->dacl,
3783                                             &size);
3784
3785                         new_secdesc_ctr = make_sec_desc_buf(ctx, size, psd);
3786
3787                         /* Swap with other one */
3788
3789                         *secdesc_ctr = new_secdesc_ctr;
3790
3791                         /* Set it */
3792
3793                         nt_printing_setsec(printername, *secdesc_ctr);
3794                 }
3795         }
3796
3797         if (DEBUGLEVEL >= 10) {
3798                 SEC_ACL *the_acl = (*secdesc_ctr)->sec->dacl;
3799                 int i;
3800
3801                 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n", 
3802                            printername, the_acl->num_aces));
3803
3804                 for (i = 0; i < the_acl->num_aces; i++) {
3805                         fstring sid_str;
3806
3807                         sid_to_string(sid_str, &the_acl->ace[i].trustee);
3808
3809                         DEBUG(10, ("%s %d %d 0x%08x\n", sid_str,
3810                                    the_acl->ace[i].type, the_acl->ace[i].flags, 
3811                                    the_acl->ace[i].info.mask)); 
3812                 }
3813         }
3814
3815         prs_mem_free(&ps);
3816         return True;
3817 }
3818
3819 /* error code:
3820         0: everything OK
3821         1: level not implemented
3822         2: file doesn't exist
3823         3: can't allocate memory
3824         4: can't free memory
3825         5: non existant struct
3826 */
3827
3828 /*
3829         A printer and a printer driver are 2 different things.
3830         NT manages them separatelly, Samba does the same.
3831         Why ? Simply because it's easier and it makes sense !
3832         
3833         Now explanation: You have 3 printers behind your samba server,
3834         2 of them are the same make and model (laser A and B). But laser B
3835         has an 3000 sheet feeder and laser A doesn't such an option.
3836         Your third printer is an old dot-matrix model for the accounting :-).
3837         
3838         If the /usr/local/samba/lib directory (default dir), you will have
3839         5 files to describe all of this.
3840         
3841         3 files for the printers (1 by printer):
3842                 NTprinter_laser A
3843                 NTprinter_laser B
3844                 NTprinter_accounting
3845         2 files for the drivers (1 for the laser and 1 for the dot matrix)
3846                 NTdriver_printer model X
3847                 NTdriver_printer model Y
3848
3849 jfm: I should use this comment for the text file to explain
3850         same thing for the forms BTW.
3851         Je devrais mettre mes commentaires en francais, ca serait mieux :-)
3852
3853 */
3854
3855 /* Convert generic access rights to printer object specific access rights.
3856    It turns out that NT4 security descriptors use generic access rights and
3857    NT5 the object specific ones. */
3858
3859 void map_printer_permissions(SEC_DESC *sd)
3860 {
3861         int i;
3862
3863         for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
3864                 se_map_generic(&sd->dacl->ace[i].info.mask,
3865                                &printer_generic_mapping);
3866         }
3867 }
3868
3869 /****************************************************************************
3870  Check a user has permissions to perform the given operation.  We use the
3871  permission constants defined in include/rpc_spoolss.h to check the various
3872  actions we perform when checking printer access.
3873
3874    PRINTER_ACCESS_ADMINISTER:
3875        print_queue_pause, print_queue_resume, update_printer_sec,
3876        update_printer, spoolss_addprinterex_level_2,
3877        _spoolss_setprinterdata
3878
3879    PRINTER_ACCESS_USE:
3880        print_job_start
3881
3882    JOB_ACCESS_ADMINISTER:
3883        print_job_delete, print_job_pause, print_job_resume,
3884        print_queue_purge
3885
3886  ****************************************************************************/
3887 BOOL print_access_check(struct current_user *user, int snum, int access_type)
3888 {
3889         SEC_DESC_BUF *secdesc = NULL;
3890         uint32 access_granted;
3891         NTSTATUS status;
3892         BOOL result;
3893         char *pname;
3894         TALLOC_CTX *mem_ctx = NULL;
3895         extern struct current_user current_user;
3896         
3897         /* If user is NULL then use the current_user structure */
3898
3899         if (!user)
3900                 user = &current_user;
3901
3902         /* Always allow root or printer admins to do anything */
3903
3904         if (user->uid == 0 ||
3905             user_in_list(uidtoname(user->uid), lp_printer_admin(snum))) {
3906                 return True;
3907         }
3908
3909         /* Get printer name */
3910
3911         pname = PRINTERNAME(snum);
3912
3913         if (!pname || !*pname) {
3914                 errno = EACCES;
3915                 return False;
3916         }
3917
3918         /* Get printer security descriptor */
3919
3920         if(!(mem_ctx = talloc_init())) {
3921                 errno = ENOMEM;
3922                 return False;
3923         }
3924
3925         nt_printing_getsec(mem_ctx, pname, &secdesc);
3926
3927         if (access_type == JOB_ACCESS_ADMINISTER) {
3928                 SEC_DESC_BUF *parent_secdesc = secdesc;
3929
3930                 /* Create a child security descriptor to check permissions
3931                    against.  This is because print jobs are child objects
3932                    objects of a printer. */
3933
3934                 secdesc = se_create_child_secdesc(mem_ctx, parent_secdesc->sec, False);
3935
3936                 /* Now this is the bit that really confuses me.  The access
3937                    type needs to be changed from JOB_ACCESS_ADMINISTER to
3938                    PRINTER_ACCESS_ADMINISTER for this to work.  Something
3939                    to do with the child (job) object becoming like a
3940                    printer??  -tpot */
3941
3942                 access_type = PRINTER_ACCESS_ADMINISTER;
3943         }
3944         
3945         /* Check access */
3946         
3947         map_printer_permissions(secdesc->sec);
3948
3949         result = se_access_check(secdesc->sec, user->nt_user_token, access_type,
3950                                  &access_granted, &status);
3951
3952         DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
3953
3954         talloc_destroy(mem_ctx);
3955         
3956         if (!result)
3957                 errno = EACCES;
3958
3959         return result;
3960 }
3961
3962 /****************************************************************************
3963  Check the time parameters allow a print operation.
3964 *****************************************************************************/
3965
3966 BOOL print_time_access_check(int snum)
3967 {
3968         NT_PRINTER_INFO_LEVEL *printer = NULL;
3969         BOOL ok = False;
3970         time_t now = time(NULL);
3971         struct tm *t;
3972         uint32 mins;
3973
3974         if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
3975                 return False;
3976
3977         if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
3978                 ok = True;
3979
3980         t = gmtime(&now);
3981         mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
3982
3983         if (mins >= printer->info_2->starttime && mins <= printer->info_2->untiltime)
3984                 ok = True;
3985
3986         free_a_printer(&printer, 2);
3987
3988         if (!ok)
3989                 errno = EACCES;
3990
3991         return ok;
3992 }
3993
3994 #if 0   /* JERRY - not used */
3995 /****************************************************************************
3996  Attempt to write a default device.
3997 *****************************************************************************/
3998
3999 WERROR printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_default)
4000 {
4001         NT_PRINTER_INFO_LEVEL *printer = NULL;
4002         WERROR result;
4003
4004         /*
4005          * Don't bother if no default devicemode was sent.
4006          */
4007
4008         if (printer_default->devmode_cont.devmode == NULL)
4009                 return WERR_OK;
4010
4011         result = get_a_printer(&printer, 2, lp_servicename(snum));
4012         if (!W_ERROR_IS_OK(result)) return result;
4013
4014         /*
4015          * Just ignore it if we already have a devmode.
4016          */
4017 #if 0
4018         if (printer->info_2->devmode != NULL)
4019                 goto done;
4020 #endif
4021         /*
4022          * We don't have a devicemode and we're trying to write
4023          * one. Check we have the access needed.
4024          */
4025         DEBUG(5,("printer_write_default_dev: access: %x\n", printer_default->access_required));
4026
4027         if ( (printer_default->access_required & PRINTER_ACCESS_ADMINISTER) != 
4028               PRINTER_ACCESS_ADMINISTER) {
4029                 DEBUG(5,("printer_write_default_dev: invalid request access to update: %x\n", printer_default->access_required));
4030                 result = WERR_ACCESS_DENIED;
4031                 goto done;
4032         }
4033
4034         if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
4035                 DEBUG(5,("printer_write_default_dev: Access denied for printer %s\n",
4036                         lp_servicename(snum) ));
4037                 result = WERR_ACCESS_DENIED;
4038                 /*result = NT_STATUS_NO_PROBLEMO;*/
4039                 goto done;
4040         }
4041
4042         DEBUG(5,("printer_write_default_dev: updating, check OK.\n"));
4043
4044         /*
4045          * Convert the on the wire devicemode format to the internal one.
4046          */
4047
4048         if (!convert_devicemode(printer->info_2->printername,
4049                                 printer_default->devmode_cont.devmode,
4050                                 &printer->info_2->devmode)) {
4051                 result = WERR_NOMEM;
4052                 goto done;
4053         }
4054
4055         /*
4056          * Finally write back to the tdb.
4057          */
4058
4059         result = mod_a_printer(*printer, 2);
4060
4061   done:
4062
4063         free_a_printer(&printer, 2);
4064         return result;
4065 }
4066 #endif  /* JERRY */