Return called NetBIOS name if present in preference to global_myname.
[ira/wip.git] / source3 / printing / nt_printing.c
1 /*
2  *  Unix SMB/Netbios implementation.
3  *  Version 1.9.
4  *  RPC Pipe client / server routines
5  *  Copyright (C) Andrew Tridgell              1992-2000,
6  *  Copyright (C) Jean François Micouleau      1998-2000.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #include "includes.h"
24
25 extern DOM_SID global_sid_World;
26
27 static TDB_CONTEXT *tdb_forms; /* used for forms files */
28 static TDB_CONTEXT *tdb_drivers; /* used for driver files */
29 static TDB_CONTEXT *tdb_printers; /* used for printers files */
30
31 #define FORMS_PREFIX "FORMS/"
32 #define DRIVERS_PREFIX "DRIVERS/"
33 #define DRIVER_INIT_PREFIX "DRIVER_INIT/"
34 #define PRINTERS_PREFIX "PRINTERS/"
35 #define SECDESC_PREFIX "SECDESC/"
36  
37 #define NTDRIVERS_DATABASE_VERSION_1 1
38 #define NTDRIVERS_DATABASE_VERSION_2 2
39  
40 #define NTDRIVERS_DATABASE_VERSION NTDRIVERS_DATABASE_VERSION_2
41
42 /* Map generic permissions to printer object specific permissions */
43
44 struct generic_mapping printer_generic_mapping = {
45         PRINTER_READ,
46         PRINTER_WRITE,
47         PRINTER_EXECUTE,
48         PRINTER_ALL_ACCESS
49 };
50
51 /* We need one default form to support our default printer. Msoft adds the
52 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
53 array index). Letter is always first, so (for the current code) additions
54 always put things in the correct order. */
55 static nt_forms_struct default_forms[] = {
56         {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
57         {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
58         {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
59         {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
60         {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
61         {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
62         {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
63         {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
64         {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
65         {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
66         {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
67         {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
68         {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
69         {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
70         {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
71         {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
72         {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
73         {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
74         {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
75         {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
76         {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
77         {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
78         {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
79         {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
80         {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
81         {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
82         {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
83         {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
84         {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
85         {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
86         {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
87         {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
88         {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
89         {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
90         {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
91         {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
92         {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
93         {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
94         {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
95         {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
96         {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
97         {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
98         {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
99         {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
100         {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
101         {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
102         {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
103         {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
104         {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
105         {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
106         {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
107         {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
108         {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
109         {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
110         {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
111         {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
112         {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
113         {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
114         {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
115         {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
116         {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
117         {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
118         {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
119         {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
120         {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
121         {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
122         {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
123         {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
124         {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
125         {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
126         {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
127         {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
128         {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
129         {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
130         {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
131         {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
132         {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
133         {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
134         {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
135         {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
136         {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
137         {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
138         {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
139         {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
140         {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
141         {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
142         {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
143         {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
144         {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
145         {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
146         {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
147         {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
148         {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
149         {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
150         {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
151         {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
152         {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
153         {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
154         {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
155         {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
156         {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
157         {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
158         {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
159         {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
160         {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
161         {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
162         {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
163         {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
164         {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
165         {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
166         {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
167         {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
168         {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
169         {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
170         {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
171         {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
172         {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
173         {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
174 };
175
176 static BOOL upgrade_to_version_2(void)
177 {
178         TDB_DATA kbuf, newkey, dbuf;
179  
180         DEBUG(0,("upgrade_to_version_2: upgrading print tdb's to version 2\n"));
181  
182         for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
183                         newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
184
185                 dbuf = tdb_fetch(tdb_drivers, kbuf);
186
187                 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
188                         DEBUG(0,("upgrade_to_version_2:moving form\n"));
189                         if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
190                                 DEBUG(0,("upgrade_to_version_2: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
191                                 return False;
192                         }
193                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
194                                 DEBUG(0,("upgrade_to_version_2: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
195                                 return False;
196                         }
197                 }
198  
199                 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
200                         DEBUG(0,("upgrade_to_version_2:moving printer\n"));
201                         if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
202                                 DEBUG(0,("upgrade_to_version_2: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
203                                 return False;
204                         }
205                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
206                                 DEBUG(0,("upgrade_to_version_2: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
207                                 return False;
208                         }
209                 }
210  
211                 if (strncmp(kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
212                         DEBUG(0,("upgrade_to_version_2:moving secdesc\n"));
213                         if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
214                                 DEBUG(0,("upgrade_to_version_2: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
215                                 return False;
216                         }
217                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
218                                 DEBUG(0,("upgrade_to_version_2: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
219                                 return False;
220                         }
221                 }
222  
223                 SAFE_FREE(dbuf.dptr);
224         }
225
226         return True;
227 }
228
229 /****************************************************************************
230 open the NT printing tdb
231 ****************************************************************************/
232 BOOL nt_printing_init(void)
233 {
234         static pid_t local_pid;
235         char *vstring = "INFO/version";
236
237         if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
238                 return True;
239  
240         tdb_drivers = tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
241         if (!tdb_drivers) {
242                 DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
243                         lock_path("ntdrivers.tdb"), strerror(errno) ));
244                 return False;
245         }
246  
247         tdb_printers = tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
248         if (!tdb_printers) {
249                 DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
250                         lock_path("ntprinters.tdb"), strerror(errno) ));
251                 return False;
252         }
253  
254         tdb_forms = tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
255         if (!tdb_forms) {
256                 DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
257                         lock_path("ntforms.tdb"), strerror(errno) ));
258                 return False;
259         }
260  
261         local_pid = sys_getpid();
262  
263         /* handle a Samba upgrade */
264         tdb_lock_bystring(tdb_drivers, vstring);
265         if (tdb_fetch_int(tdb_drivers, vstring) != NTDRIVERS_DATABASE_VERSION) {
266  
267                 if (tdb_fetch_int(tdb_drivers, vstring) == NTDRIVERS_DATABASE_VERSION_1) {
268                         if (!upgrade_to_version_2())
269                                 return False;
270                 } else
271                         tdb_traverse(tdb_drivers, tdb_traverse_delete_fn, NULL);
272  
273                 tdb_store_int(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
274         }
275         tdb_unlock_bystring(tdb_drivers, vstring);
276
277         return True;
278 }
279
280 /****************************************************************************
281  get builtin form struct list
282 ****************************************************************************/
283 int get_builtin_ntforms(nt_forms_struct **list)
284 {
285         *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
286         return sizeof(default_forms) / sizeof(default_forms[0]);
287 }
288
289 /****************************************************************************
290  get a builtin form struct
291 ****************************************************************************/
292
293 BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
294 {
295         int i,count;
296         fstring form_name;
297         unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
298         DEBUGADD(6,("Looking for builtin form %s \n", form_name));
299         count = sizeof(default_forms) / sizeof(default_forms[0]);
300         for (i=0;i<count;i++) {
301                 if (strequal(form_name,default_forms[i].name)) {
302                         DEBUGADD(6,("Found builtin form %s \n", form_name));
303                         memcpy(form,&default_forms[i],sizeof(*form));
304                         break;
305                 }
306         }
307
308         return (i !=count);
309 }
310
311 /****************************************************************************
312 get a form struct list
313 ****************************************************************************/
314 int get_ntforms(nt_forms_struct **list)
315 {
316         TDB_DATA kbuf, newkey, dbuf;
317         nt_forms_struct *tl;
318         nt_forms_struct form;
319         int ret;
320         int i;
321         int n = 0;
322
323         for (kbuf = tdb_firstkey(tdb_forms);
324              kbuf.dptr;
325              newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
326                 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
327                 
328                 dbuf = tdb_fetch(tdb_forms, kbuf);
329                 if (!dbuf.dptr) continue;
330
331                 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
332                 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
333                                  &i, &form.flag, &form.width, &form.length, &form.left,
334                                  &form.top, &form.right, &form.bottom);
335                 SAFE_FREE(dbuf.dptr);
336                 if (ret != dbuf.dsize) continue;
337
338                 tl = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
339                 if (!tl) {
340                         DEBUG(0,("get_ntforms: Realloc fail.\n"));
341                         return 0;
342                 }
343                 *list = tl;
344                 (*list)[n] = form;
345                 n++;
346         }
347         
348
349         return n;
350 }
351
352 /****************************************************************************
353 write a form struct list
354 ****************************************************************************/
355 int write_ntforms(nt_forms_struct **list, int number)
356 {
357         pstring buf, key;
358         int len;
359         TDB_DATA kbuf,dbuf;
360         int i;
361
362         for (i=0;i<number;i++) {
363                 /* save index, so list is rebuilt in correct order */
364                 len = tdb_pack(buf, sizeof(buf), "dddddddd",
365                                i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
366                                (*list)[i].left, (*list)[i].top, (*list)[i].right,
367                                (*list)[i].bottom);
368                 if (len > sizeof(buf)) break;
369                 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name);
370                 kbuf.dsize = strlen(key)+1;
371                 kbuf.dptr = key;
372                 dbuf.dsize = len;
373                 dbuf.dptr = buf;
374                 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) break;
375        }
376
377        return i;
378 }
379
380 /****************************************************************************
381 add a form struct at the end of the list
382 ****************************************************************************/
383 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
384 {
385         int n=0;
386         BOOL update;
387         fstring form_name;
388         nt_forms_struct *tl;
389
390         /*
391          * NT tries to add forms even when
392          * they are already in the base
393          * only update the values if already present
394          */
395
396         update=False;
397         
398         unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
399         for (n=0; n<*count; n++) {
400                 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
401                         DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
402                         update=True;
403                         break;
404                 }
405         }
406
407         if (update==False) {
408                 if((tl=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL) {
409                         DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
410                         return False;
411                 }
412                 *list = tl;
413                 unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
414                 (*count)++;
415         }
416         
417         (*list)[n].flag=form->flags;
418         (*list)[n].width=form->size_x;
419         (*list)[n].length=form->size_y;
420         (*list)[n].left=form->left;
421         (*list)[n].top=form->top;
422         (*list)[n].right=form->right;
423         (*list)[n].bottom=form->bottom;
424
425         return True;
426 }
427
428 /****************************************************************************
429  delete a named form struct
430 ****************************************************************************/
431 BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
432 {
433         pstring key;
434         TDB_DATA kbuf;
435         int n=0;
436         fstring form_name;
437
438         *ret = WERR_OK;
439
440         unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
441
442         for (n=0; n<*count; n++) {
443                 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
444                         DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
445                         break;
446                 }
447         }
448
449         if (n == *count) {
450                 DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
451                 *ret = WERR_INVALID_PARAM;
452                 return False;
453         }
454
455         slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);
456         kbuf.dsize = strlen(key)+1;
457         kbuf.dptr = key;
458         if (tdb_delete(tdb_forms, kbuf) != 0) {
459                 *ret = WERR_NOMEM;
460                 return False;
461         }
462
463         return True;
464 }
465
466 /****************************************************************************
467 update a form struct
468 ****************************************************************************/
469 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
470 {
471         int n=0;
472         fstring form_name;
473         unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
474
475         DEBUG(106, ("[%s]\n", form_name));
476         for (n=0; n<count; n++)
477         {
478                 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
479                 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
480                         break;
481         }
482
483         if (n==count) return;
484
485         (*list)[n].flag=form->flags;
486         (*list)[n].width=form->size_x;
487         (*list)[n].length=form->size_y;
488         (*list)[n].left=form->left;
489         (*list)[n].top=form->top;
490         (*list)[n].right=form->right;
491         (*list)[n].bottom=form->bottom;
492 }
493
494 /****************************************************************************
495 get the nt drivers list
496
497 traverse the database and look-up the matching names
498 ****************************************************************************/
499 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
500 {
501         int total=0;
502         fstring short_archi;
503         fstring *fl;
504         pstring key;
505         TDB_DATA kbuf, newkey;
506
507         get_short_archi(short_archi, architecture);
508         slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
509
510         for (kbuf = tdb_firstkey(tdb_drivers);
511              kbuf.dptr;
512              newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
513                 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
514                 
515                 if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
516                         DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
517                         return -1;
518                 }
519                 else *list = fl;
520
521                 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
522                 total++;
523         }
524
525         return(total);
526 }
527
528 /****************************************************************************
529 function to do the mapping between the long architecture name and
530 the short one.
531 ****************************************************************************/
532 BOOL get_short_archi(char *short_archi, char *long_archi)
533 {
534         struct table {
535                 char *long_archi;
536                 char *short_archi;
537         };
538         
539         struct table archi_table[]=
540         {
541                 {"Windows 4.0",          "WIN40"    },
542                 {"Windows NT x86",       "W32X86"   },
543                 {"Windows NT R4000",     "W32MIPS"  },
544                 {"Windows NT Alpha_AXP", "W32ALPHA" },
545                 {"Windows NT PowerPC",   "W32PPC"   },
546                 {NULL,                   ""         }
547         };
548         
549         int i=-1;
550
551         DEBUG(107,("Getting architecture dependant directory\n"));
552         do {
553                 i++;
554         } while ( (archi_table[i].long_archi!=NULL ) &&
555                   StrCaseCmp(long_archi, archi_table[i].long_archi) );
556
557         if (archi_table[i].long_archi==NULL) {
558                 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
559                 return False;
560         }
561
562         StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
563
564         DEBUGADD(108,("index: [%d]\n", i));
565         DEBUGADD(108,("long architecture: [%s]\n", long_archi));
566         DEBUGADD(108,("short architecture: [%s]\n", short_archi));
567         
568         return True;
569 }
570
571 /****************************************************************************
572 Version information in Microsoft files is held in a VS_VERSION_INFO structure.
573 There are two case to be covered here: PE (Portable Executable) and NE (New
574 Executable) files. Both files support the same INFO structure, but PE files
575 store the signature in unicode, and NE files store it as !unicode.
576 ****************************************************************************/
577 static BOOL get_file_version(files_struct *fsp, char *fname,uint32 *major,
578                                                          uint32 *minor)
579 {
580         int     i;
581         char    *buf;
582         ssize_t byte_count;
583
584         if ((buf=malloc(PE_HEADER_SIZE)) == NULL) {
585                 DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
586                                 fname, PE_HEADER_SIZE));
587                 goto error_exit;
588         }
589
590         /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
591         if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
592                 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
593                                 fname, byte_count));
594                 goto no_version_info;
595         }
596
597         /* Is this really a DOS header? */
598         if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
599                 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
600                                 fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
601                 goto no_version_info;
602         }
603
604         /* Skip OEM header (if any) and the DOS stub to start of Windows header */
605         if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
606                 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
607                                 fname, errno));
608                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
609                 goto no_version_info;
610         }
611
612         if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
613                 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
614                                 fname, byte_count));
615                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
616                 goto no_version_info;
617         }
618
619         /* The header may be a PE (Portable Executable) or an NE (New Executable) */
620         if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
621                 int num_sections;
622                 int section_table_bytes;
623                 
624                 if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {
625                         DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
626                                         fname, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
627                         /* At this point, we assume the file is in error. It still could be somthing
628                          * else besides a PE file, but it unlikely at this point.
629                          */
630                         goto error_exit;
631                 }
632
633                 /* get the section table */
634                 num_sections        = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
635                 section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
636                 SAFE_FREE(buf);
637                 if ((buf=malloc(section_table_bytes)) == NULL) {
638                         DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
639                                         fname, section_table_bytes));
640                         goto error_exit;
641                 }
642
643                 if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
644                         DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
645                                         fname, byte_count));
646                         goto error_exit;
647                 }
648
649                 /* Iterate the section table looking for the resource section ".rsrc" */
650                 for (i = 0; i < num_sections; i++) {
651                         int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
652
653                         if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
654                                 int section_pos   = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
655                                 int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
656
657                                 SAFE_FREE(buf);
658                                 if ((buf=malloc(section_bytes)) == NULL) {
659                                         DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
660                                                         fname, section_bytes));
661                                         goto error_exit;
662                                 }
663
664                                 /* Seek to the start of the .rsrc section info */
665                                 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
666                                         DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
667                                                         fname, errno));
668                                         goto error_exit;
669                                 }
670
671                                 if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
672                                         DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
673                                                         fname, byte_count));
674                                         goto error_exit;
675                                 }
676
677                                 for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
678                                         /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
679                                         if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
680                                                 /* Align to next long address */
681                                                 int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;
682
683                                                 if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
684                                                         *major = IVAL(buf,pos+VS_MAJOR_OFFSET);
685                                                         *minor = IVAL(buf,pos+VS_MINOR_OFFSET);
686                                                         
687                                                         DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
688                                                                           fname, *major, *minor,
689                                                                           (*major>>16)&0xffff, *major&0xffff,
690                                                                           (*minor>>16)&0xffff, *minor&0xffff));
691                                                         SAFE_FREE(buf);
692                                                         return True;
693                                                 }
694                                         }
695                                 }
696                         }
697                 }
698
699                 /* Version info not found, fall back to origin date/time */
700                 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
701                 SAFE_FREE(buf);
702                 return False;
703
704         } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
705                 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
706                         DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
707                                         fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
708                         /* At this point, we assume the file is in error. It still could be somthing
709                          * else besides a NE file, but it unlikely at this point. */
710                         goto error_exit;
711                 }
712
713                 /* Allocate a bit more space to speed up things */
714                 SAFE_FREE(buf);
715                 if ((buf=malloc(VS_NE_BUF_SIZE)) == NULL) {
716                         DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes  = %d\n",
717                                         fname, PE_HEADER_SIZE));
718                         goto error_exit;
719                 }
720
721                 /* This is a HACK! I got tired of trying to sort through the messy
722                  * 'NE' file format. If anyone wants to clean this up please have at
723                  * it, but this works. 'NE' files will eventually fade away. JRR */
724                 while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {
725                         /* Cover case that should not occur in a well formed 'NE' .dll file */
726                         if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;
727
728                         for(i=0; i<byte_count; i++) {
729                                 /* Fast skip past data that can't possibly match */
730                                 if (buf[i] != 'V') continue;
731
732                                 /* Potential match data crosses buf boundry, move it to beginning
733                                  * of buf, and fill the buf with as much as it will hold. */
734                                 if (i>byte_count-VS_VERSION_INFO_SIZE) {
735                                         int bc;
736
737                                         memcpy(buf, &buf[i], byte_count-i);
738                                         if ((bc = vfs_read_data(fsp, &buf[byte_count-i], VS_NE_BUF_SIZE-
739                                                                    (byte_count-i))) < 0) {
740
741                                                 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
742                                                                  fname, errno));
743                                                 goto error_exit;
744                                         }
745
746                                         byte_count = bc + (byte_count - i);
747                                         if (byte_count<VS_VERSION_INFO_SIZE) break;
748
749                                         i = 0;
750                                 }
751
752                                 /* Check that the full signature string and the magic number that
753                                  * follows exist (not a perfect solution, but the chances that this
754                                  * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
755                                  * twice, as it is simpler to read the code. */
756                                 if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
757                                         /* Compute skip alignment to next long address */
758                                         int skip = -(fsp->conn->vfs_ops.lseek(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
759                                                                  sizeof(VS_SIGNATURE)) & 3;
760                                         if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
761
762                                         *major = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MAJOR_OFFSET);
763                                         *minor = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MINOR_OFFSET);
764                                         DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
765                                                           fname, *major, *minor,
766                                                           (*major>>16)&0xffff, *major&0xffff,
767                                                           (*minor>>16)&0xffff, *minor&0xffff));
768                                         SAFE_FREE(buf);
769                                         return True;
770                                 }
771                         }
772                 }
773
774                 /* Version info not found, fall back to origin date/time */
775                 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
776                 SAFE_FREE(buf);
777                 return False;
778
779         } else
780                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
781                 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
782                                 fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
783
784         no_version_info:
785                 SAFE_FREE(buf);
786                 return False;
787
788         error_exit:
789                 SAFE_FREE(buf);
790                 return -1;
791 }
792
793 /****************************************************************************
794 Drivers for Microsoft systems contain multiple files. Often, multiple drivers
795 share one or more files. During the MS installation process files are checked
796 to insure that only a newer version of a shared file is installed over an
797 older version. There are several possibilities for this comparison. If there
798 is no previous version, the new one is newer (obviously). If either file is
799 missing the version info structure, compare the creation date (on Unix use
800 the modification date). Otherwise chose the numerically larger version number.
801 ****************************************************************************/
802 static int file_version_is_newer(connection_struct *conn, fstring new_file,
803                                                                 fstring old_file)
804 {
805         BOOL   use_version = True;
806         pstring filepath;
807
808         uint32 new_major;
809         uint32 new_minor;
810         time_t new_create_time;
811
812         uint32 old_major;
813         uint32 old_minor;
814         time_t old_create_time;
815
816         int access_mode;
817         int action;
818         files_struct    *fsp = NULL;
819         SMB_STRUCT_STAT st;
820         SMB_STRUCT_STAT stat_buf;
821         BOOL bad_path;
822
823         ZERO_STRUCT(st);
824         ZERO_STRUCT(stat_buf);
825         new_create_time = (time_t)0;
826         old_create_time = (time_t)0;
827
828         /* Get file version info (if available) for previous file (if it exists) */
829         pstrcpy(filepath, old_file);
830
831         unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
832
833         fsp = open_file_shared(conn, filepath, &stat_buf,
834                                                    SET_OPEN_MODE(DOS_OPEN_RDONLY),
835                                                    (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
836                                                    0, 0, &access_mode, &action);
837         if (!fsp) {
838                 /* Old file not found, so by definition new file is in fact newer */
839                 DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
840                                 filepath, errno));
841                 return True;
842
843         } else {
844                 int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
845                 if (ret == -1) goto error_exit;
846
847                 if (!ret) {
848                         DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
849                                          old_file));
850                         use_version = False;
851                         if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
852                         old_create_time = st.st_mtime;
853                         DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
854                 }
855         }
856         close_file(fsp, True);
857
858         /* Get file version info (if available) for new file */
859         pstrcpy(filepath, new_file);
860         unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
861
862         fsp = open_file_shared(conn, filepath, &stat_buf,
863                                                    SET_OPEN_MODE(DOS_OPEN_RDONLY),
864                                                    (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
865                                                    0, 0, &access_mode, &action);
866         if (!fsp) {
867                 /* New file not found, this shouldn't occur if the caller did its job */
868                 DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
869                                 filepath, errno));
870                 goto error_exit;
871
872         } else {
873                 int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
874                 if (ret == -1) goto error_exit;
875
876                 if (!ret) {
877                         DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
878                                          new_file));
879                         use_version = False;
880                         if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
881                         new_create_time = st.st_mtime;
882                         DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
883                 }
884         }
885         close_file(fsp, True);
886
887         if (use_version) {
888                 /* Compare versions and choose the larger version number */
889                 if (new_major > old_major ||
890                         (new_major == old_major && new_minor > old_minor)) {
891                         
892                         DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
893                         return True;
894                 }
895                 else {
896                         DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
897                         return False;
898                 }
899
900         } else {
901                 /* Compare modification time/dates and choose the newest time/date */
902                 if (new_create_time > old_create_time) {
903                         DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
904                         return True;
905                 }
906                 else {
907                         DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
908                         return False;
909                 }
910         }
911
912         error_exit:
913                 if(fsp)
914                         close_file(fsp, True);
915                 return -1;
916 }
917
918 /****************************************************************************
919 Determine the correct cVersion associated with an architecture and driver
920 ****************************************************************************/
921 static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
922                                    struct current_user *user, WERROR *perr)
923 {
924         int               cversion;
925         int               access_mode;
926         int               action;
927         NTSTATUS          nt_status;
928         pstring           driverpath;
929         DATA_BLOB         null_pw;
930         files_struct      *fsp = NULL;
931         BOOL              bad_path;
932         SMB_STRUCT_STAT   st;
933         connection_struct *conn;
934
935         ZERO_STRUCT(st);
936
937         *perr = WERR_INVALID_PARAM;
938
939         /* If architecture is Windows 95/98/ME, the version is always 0. */
940         if (strcmp(architecture, "WIN40") == 0) {
941                 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
942                 *perr = WERR_OK;
943                 return 0;
944         }
945
946         /* connect to the print$ share under the same account as the user connected to the rpc pipe */  
947         /* Null password is ok - we are already an authenticated user... */
948         null_pw = data_blob(NULL, 0);
949
950         become_root();
951         conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
952         unbecome_root();
953
954         if (conn == NULL) {
955                 DEBUG(0,("get_correct_cversion: Unable to connect\n"));
956                 *perr = ntstatus_to_werror(nt_status);
957                 return -1;
958         }
959
960         /* We are temporarily becoming the connection user. */
961         if (!become_user(conn, conn->vuid)) {
962                 DEBUG(0,("get_correct_cversion: Can't become user!\n"));
963                 *perr = WERR_ACCESS_DENIED;
964                 return -1;
965         }
966
967         /* Open the driver file (Portable Executable format) and determine the
968          * deriver the cversion. */
969         slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
970
971         unix_convert(driverpath,conn,NULL,&bad_path,&st);
972
973         fsp = open_file_shared(conn, driverpath, &st,
974                                                    SET_OPEN_MODE(DOS_OPEN_RDONLY),
975                                                    (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
976                                                    0, 0, &access_mode, &action);
977         if (!fsp) {
978                 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
979                                 driverpath, errno));
980                 *perr = WERR_ACCESS_DENIED;
981                 goto error_exit;
982         }
983         else {
984                 uint32 major;
985                 uint32 minor;
986                 int    ret = get_file_version(fsp, driverpath, &major, &minor);
987                 if (ret == -1) goto error_exit;
988
989                 if (!ret) {
990                         DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath));
991                         goto error_exit;
992                 }
993
994                 /*
995                  * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
996                  * for more details. Version in this case is not just the version of the 
997                  * file, but the version in the sense of kernal mode (2) vs. user mode
998                  * (3) drivers. Other bits of the version fields are the version info. 
999                  * JRR 010716
1000                 */
1001                 cversion = major & 0x0000ffff;
1002                 switch (cversion) {
1003                         case 2: /* WinNT drivers */
1004                         case 3: /* Win2K drivers */
1005                                 break;
1006                         
1007                         default:
1008                                 DEBUG(6,("get_correct_cversion: cversion invalid [%s]  cversion = %d\n", 
1009                                         driverpath, cversion));
1010                                 goto error_exit;
1011                 }
1012
1013                 DEBUG(10,("get_correct_cversion: Version info found [%s]  major = 0x%x  minor = 0x%x\n",
1014                                   driverpath, major, minor));
1015         }
1016
1017         DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
1018                   driverpath, cversion));
1019
1020         close_file(fsp, True);
1021         close_cnum(conn, user->vuid);
1022         unbecome_user();
1023         *perr = WERR_OK;
1024         return cversion;
1025
1026   error_exit:
1027
1028         if(fsp)
1029                 close_file(fsp, True);
1030         
1031         close_cnum(conn, user->vuid);
1032         unbecome_user();
1033         return -1;
1034 }
1035
1036 /****************************************************************************
1037 ****************************************************************************/
1038 static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
1039                                              struct current_user *user)
1040 {
1041         fstring architecture;
1042         fstring new_name;
1043         char *p;
1044         int i;
1045         WERROR err;
1046
1047         /* clean up the driver name.
1048          * we can get .\driver.dll
1049          * or worse c:\windows\system\driver.dll !
1050          */
1051         /* using an intermediate string to not have overlaping memcpy()'s */
1052         if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1053                 fstrcpy(new_name, p+1);
1054                 fstrcpy(driver->driverpath, new_name);
1055         }
1056
1057         if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1058                 fstrcpy(new_name, p+1);
1059                 fstrcpy(driver->datafile, new_name);
1060         }
1061
1062         if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1063                 fstrcpy(new_name, p+1);
1064                 fstrcpy(driver->configfile, new_name);
1065         }
1066
1067         if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1068                 fstrcpy(new_name, p+1);
1069                 fstrcpy(driver->helpfile, new_name);
1070         }
1071
1072         if (driver->dependentfiles) {
1073                 for (i=0; *driver->dependentfiles[i]; i++) {
1074                         if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1075                                 fstrcpy(new_name, p+1);
1076                                 fstrcpy(driver->dependentfiles[i], new_name);
1077                         }
1078                 }
1079         }
1080
1081         get_short_archi(architecture, driver->environment);
1082         
1083         /* jfm:7/16/2000 the client always sends the cversion=0.
1084          * The server should check which version the driver is by reading
1085          * the PE header of driver->driverpath.
1086          *
1087          * For Windows 95/98 the version is 0 (so the value sent is correct)
1088          * For Windows NT (the architecture doesn't matter)
1089          *      NT 3.1: cversion=0
1090          *      NT 3.5/3.51: cversion=1
1091          *      NT 4: cversion=2
1092          *      NT2K: cversion=3
1093          */
1094         if ((driver->cversion = get_correct_cversion( architecture,
1095                                                       driver->driverpath, user, &err)) == -1)
1096                 return err;
1097
1098         return WERR_OK;
1099 }
1100         
1101 /****************************************************************************
1102 ****************************************************************************/
1103 static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
1104                                              struct current_user *user)
1105 {
1106         fstring architecture;
1107         fstring new_name;
1108         char *p;
1109         int i;
1110         WERROR err;
1111
1112         /* clean up the driver name.
1113          * we can get .\driver.dll
1114          * or worse c:\windows\system\driver.dll !
1115          */
1116         /* using an intermediate string to not have overlaping memcpy()'s */
1117         if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1118                 fstrcpy(new_name, p+1);
1119                 fstrcpy(driver->driverpath, new_name);
1120         }
1121
1122         if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1123                 fstrcpy(new_name, p+1);
1124                 fstrcpy(driver->datafile, new_name);
1125         }
1126
1127         if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1128                 fstrcpy(new_name, p+1);
1129                 fstrcpy(driver->configfile, new_name);
1130         }
1131
1132         if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1133                 fstrcpy(new_name, p+1);
1134                 fstrcpy(driver->helpfile, new_name);
1135         }
1136
1137         if (driver->dependentfiles) {
1138                 for (i=0; *driver->dependentfiles[i]; i++) {
1139                         if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1140                                 fstrcpy(new_name, p+1);
1141                                 fstrcpy(driver->dependentfiles[i], new_name);
1142                         }
1143                 }
1144         }
1145
1146         get_short_archi(architecture, driver->environment);
1147
1148         /* jfm:7/16/2000 the client always sends the cversion=0.
1149          * The server should check which version the driver is by reading
1150          * the PE header of driver->driverpath.
1151          *
1152          * For Windows 95/98 the version is 0 (so the value sent is correct)
1153          * For Windows NT (the architecture doesn't matter)
1154          *      NT 3.1: cversion=0
1155          *      NT 3.5/3.51: cversion=1
1156          *      NT 4: cversion=2
1157          *      NT2K: cversion=3
1158          */
1159         if ((driver->version = get_correct_cversion(architecture,
1160                                                     driver->driverpath, user, &err)) == -1)
1161                 return err;
1162
1163         return WERR_OK;
1164 }
1165
1166 /****************************************************************************
1167 ****************************************************************************/
1168 WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
1169                                                           uint32 level, struct current_user *user)
1170 {
1171         switch (level) {
1172                 case 3:
1173                 {
1174                         NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1175                         driver=driver_abstract.info_3;
1176                         return clean_up_driver_struct_level_3(driver, user);
1177                 }
1178                 case 6:
1179                 {
1180                         NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
1181                         driver=driver_abstract.info_6;
1182                         return clean_up_driver_struct_level_6(driver, user);
1183                 }
1184                 default:
1185                         return WERR_INVALID_PARAM;
1186         }
1187 }
1188
1189 /****************************************************************************
1190  This function sucks and should be replaced. JRA.
1191 ****************************************************************************/
1192
1193 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
1194 {
1195     dst->cversion  = src->version;
1196
1197     fstrcpy( dst->name, src->name);
1198     fstrcpy( dst->environment, src->environment);
1199     fstrcpy( dst->driverpath, src->driverpath);
1200     fstrcpy( dst->datafile, src->datafile);
1201     fstrcpy( dst->configfile, src->configfile);
1202     fstrcpy( dst->helpfile, src->helpfile);
1203     fstrcpy( dst->monitorname, src->monitorname);
1204     fstrcpy( dst->defaultdatatype, src->defaultdatatype);
1205     dst->dependentfiles = src->dependentfiles;
1206 }
1207
1208 #if 0 /* Debugging function */
1209
1210 static char* ffmt(unsigned char *c){
1211         int i;
1212         static char ffmt_str[17];
1213
1214         for (i=0; i<16; i++) {
1215                 if ((c[i] < ' ') || (c[i] > '~'))
1216                         ffmt_str[i]='.';
1217                 else
1218                         ffmt_str[i]=c[i];
1219         }
1220     ffmt_str[16]='\0';
1221         return ffmt_str;
1222 }
1223
1224 #endif
1225
1226 /****************************************************************************
1227 ****************************************************************************/
1228 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, 
1229                                   struct current_user *user, WERROR *perr)
1230 {
1231         NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1232         NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
1233         fstring architecture;
1234         pstring new_dir;
1235         pstring old_name;
1236         pstring new_name;
1237         DATA_BLOB null_pw;
1238         connection_struct *conn;
1239         NTSTATUS nt_status;
1240         int ver = 0;
1241         int i;
1242
1243         *perr = WERR_OK;
1244
1245         if (level==3)
1246                 driver=driver_abstract.info_3;
1247         else if (level==6) {
1248                 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
1249                 driver = &converted_driver;
1250         } else {
1251                 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
1252                 return False;
1253         }
1254
1255         get_short_archi(architecture, driver->environment);
1256
1257         /* connect to the print$ share under the same account as the user connected to the rpc pipe */  
1258         /* Null password is ok - we are already an authenticated user... */
1259         null_pw = data_blob(NULL, 0);
1260         conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
1261
1262         if (conn == NULL) {
1263                 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
1264                 *perr = ntstatus_to_werror(nt_status);
1265                 return False;
1266         }
1267
1268         /*
1269          * Save who we are - we are temporarily becoming the connection user.
1270          */
1271
1272         push_sec_ctx();
1273
1274         if (!become_user(conn, conn->vuid)) {
1275                 DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
1276                 pop_sec_ctx();
1277                 return False;
1278         }
1279
1280         /*
1281          * make the directories version and version\driver_name
1282          * under the architecture directory.
1283          */
1284         DEBUG(5,("Creating first directory\n"));
1285         slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
1286         mkdir_internal(conn, new_dir);
1287
1288         /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
1289          * listed for this driver which has already been moved, skip it (note:
1290          * drivers may list the same file name several times. Then check if the
1291          * file already exists in archi\cversion\, if so, check that the version
1292          * info (or time stamps if version info is unavailable) is newer (or the
1293          * date is later). If it is, move it to archi\cversion\filexxx.yyy.
1294          * Otherwise, delete the file.
1295          *
1296          * If a file is not moved to archi\cversion\ because of an error, all the
1297          * rest of the 'unmoved' driver files are removed from archi\. If one or
1298          * more of the driver's files was already moved to archi\cversion\, it
1299          * potentially leaves the driver in a partially updated state. Version
1300          * trauma will most likely occur if an client attempts to use any printer
1301          * bound to the driver. Perhaps a rewrite to make sure the moves can be
1302          * done is appropriate... later JRR
1303          */
1304
1305         DEBUG(5,("Moving files now !\n"));
1306
1307         if (driver->driverpath && strlen(driver->driverpath)) {
1308                 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);      
1309                 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);   
1310                 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1311                         NTSTATUS status;
1312                         status = rename_internals(conn, new_name, old_name, True);
1313                         if (!NT_STATUS_IS_OK(status)) {
1314                                 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1315                                                 new_name, old_name));
1316                                 *perr = ntstatus_to_werror(status);
1317                                 unlink_internals(conn, 0, new_name);
1318                                 ver = -1;
1319                         }
1320                 }
1321                 else
1322                         unlink_internals(conn, 0, new_name);
1323         }
1324
1325         if (driver->datafile && strlen(driver->datafile)) {
1326                 if (!strequal(driver->datafile, driver->driverpath)) {
1327                         slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);        
1328                         slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);     
1329                         if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1330                                 NTSTATUS status;
1331                                 status = rename_internals(conn, new_name, old_name, True);
1332                                 if (!NT_STATUS_IS_OK(status)) {
1333                                         DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1334                                                         new_name, old_name));
1335                                         *perr = ntstatus_to_werror(status);
1336                                         unlink_internals(conn, 0, new_name);
1337                                         ver = -1;
1338                                 }
1339                         }
1340                         else
1341                                 unlink_internals(conn, 0, new_name);
1342                 }
1343         }
1344
1345         if (driver->configfile && strlen(driver->configfile)) {
1346                 if (!strequal(driver->configfile, driver->driverpath) &&
1347                         !strequal(driver->configfile, driver->datafile)) {
1348                         slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);      
1349                         slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);   
1350                         if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1351                                 NTSTATUS status;
1352                                 status = rename_internals(conn, new_name, old_name, True);
1353                                 if (!NT_STATUS_IS_OK(status)) {
1354                                         DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1355                                                         new_name, old_name));
1356                                         *perr = ntstatus_to_werror(status);
1357                                         unlink_internals(conn, 0, new_name);
1358                                         ver = -1;
1359                                 }
1360                         }
1361                         else
1362                                 unlink_internals(conn, 0, new_name);
1363                 }
1364         }
1365
1366         if (driver->helpfile && strlen(driver->helpfile)) {
1367                 if (!strequal(driver->helpfile, driver->driverpath) &&
1368                         !strequal(driver->helpfile, driver->datafile) &&
1369                         !strequal(driver->helpfile, driver->configfile)) {
1370                         slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);        
1371                         slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);     
1372                         if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1373                                 NTSTATUS status;
1374                                 status = rename_internals(conn, new_name, old_name, True);
1375                                 if (!NT_STATUS_IS_OK(status)) {
1376                                         DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1377                                                         new_name, old_name));
1378                                         *perr = ntstatus_to_werror(status);
1379                                         unlink_internals(conn, 0, new_name);
1380                                         ver = -1;
1381                                 }
1382                         }
1383                         else
1384                                 unlink_internals(conn, 0, new_name);
1385                 }
1386         }
1387
1388         if (driver->dependentfiles) {
1389                 for (i=0; *driver->dependentfiles[i]; i++) {
1390                         if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
1391                                 !strequal(driver->dependentfiles[i], driver->datafile) &&
1392                                 !strequal(driver->dependentfiles[i], driver->configfile) &&
1393                                 !strequal(driver->dependentfiles[i], driver->helpfile)) {
1394                                 int j;
1395                                 for (j=0; j < i; j++) {
1396                                         if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
1397                                                 goto NextDriver;
1398                                         }
1399                                 }
1400
1401                                 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);       
1402                                 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);    
1403                                 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1404                                         NTSTATUS status;
1405                                         status = rename_internals(conn, new_name, old_name, True);
1406                                         if (!NT_STATUS_IS_OK(status)) {
1407                                                 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1408                                                                 new_name, old_name));
1409                                                 *perr = ntstatus_to_werror(status);
1410                                                 unlink_internals(conn, 0, new_name);
1411                                                 ver = -1;
1412                                         }
1413                                 }
1414                                 else
1415                                         unlink_internals(conn, 0, new_name);
1416                         }
1417                 NextDriver: ;
1418                 }
1419         }
1420
1421         close_cnum(conn, user->vuid);
1422         pop_sec_ctx();
1423
1424         return ver == -1 ? False : True;
1425 }
1426
1427 /****************************************************************************
1428 ****************************************************************************/
1429 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
1430 {
1431         int len, buflen;
1432         fstring architecture;
1433         pstring directory;
1434         pstring temp_name;
1435         pstring key;
1436         char *buf;
1437         int i, ret;
1438         TDB_DATA kbuf, dbuf;
1439
1440         get_short_archi(architecture, driver->environment);
1441
1442         /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
1443          * \\server is added in the rpc server layer.
1444          * It does make sense to NOT store the server's name in the printer TDB.
1445          */
1446
1447         slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion);
1448
1449     /* .inf files do not always list a file for each of the four standard files. 
1450      * Don't prepend a path to a null filename, or client claims:
1451      *   "The server on which the printer resides does not have a suitable 
1452      *   <printer driver name> printer driver installed. Click OK if you 
1453      *   wish to install the driver on your local machine."
1454      */
1455         if (strlen(driver->driverpath)) {
1456         fstrcpy(temp_name, driver->driverpath);
1457         slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name);
1458     }
1459
1460         if (strlen(driver->datafile)) {
1461         fstrcpy(temp_name, driver->datafile);
1462         slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name);
1463     }
1464
1465         if (strlen(driver->configfile)) {
1466         fstrcpy(temp_name, driver->configfile);
1467         slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name);
1468     }
1469
1470         if (strlen(driver->helpfile)) {
1471         fstrcpy(temp_name, driver->helpfile);
1472         slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name);
1473     }
1474
1475         if (driver->dependentfiles) {
1476                 for (i=0; *driver->dependentfiles[i]; i++) {
1477             fstrcpy(temp_name, driver->dependentfiles[i]);
1478             slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", directory, temp_name);
1479                 }
1480         }
1481
1482         slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
1483
1484         DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
1485
1486         buf = NULL;
1487         len = buflen = 0;
1488
1489  again:
1490         len = 0;
1491         len += tdb_pack(buf+len, buflen-len, "dffffffff",
1492                         driver->cversion,
1493                         driver->name,
1494                         driver->environment,
1495                         driver->driverpath,
1496                         driver->datafile,
1497                         driver->configfile,
1498                         driver->helpfile,
1499                         driver->monitorname,
1500                         driver->defaultdatatype);
1501
1502         if (driver->dependentfiles) {
1503                 for (i=0; *driver->dependentfiles[i]; i++) {
1504                         len += tdb_pack(buf+len, buflen-len, "f",
1505                                         driver->dependentfiles[i]);
1506                 }
1507         }
1508
1509         if (len != buflen) {
1510                 char *tb;
1511                 
1512                 tb = (char *)Realloc(buf, len);
1513                 if (!tb) {
1514                         DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
1515                         ret = -1;
1516                         goto done;
1517                 }
1518                 else buf = tb;
1519                 buflen = len;
1520                 goto again;
1521         }
1522
1523
1524         kbuf.dptr = key;
1525         kbuf.dsize = strlen(key)+1;
1526         dbuf.dptr = buf;
1527         dbuf.dsize = len;
1528         
1529         ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
1530
1531 done:
1532         if (ret)
1533                 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
1534
1535         SAFE_FREE(buf);
1536         return ret;
1537 }
1538
1539 /****************************************************************************
1540 ****************************************************************************/
1541 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
1542 {
1543         NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
1544
1545         ZERO_STRUCT(info3);
1546         info3.cversion = driver->version;
1547         fstrcpy(info3.name,driver->name);
1548         fstrcpy(info3.environment,driver->environment);
1549         fstrcpy(info3.driverpath,driver->driverpath);
1550         fstrcpy(info3.datafile,driver->datafile);
1551         fstrcpy(info3.configfile,driver->configfile);
1552         fstrcpy(info3.helpfile,driver->helpfile);
1553         fstrcpy(info3.monitorname,driver->monitorname);
1554         fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
1555         info3.dependentfiles = driver->dependentfiles;
1556
1557         return add_a_printer_driver_3(&info3);
1558 }
1559
1560
1561 /****************************************************************************
1562 ****************************************************************************/
1563 static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
1564 {
1565         NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
1566
1567         ZERO_STRUCT(info);
1568
1569         fstrcpy(info.name, in_prt);
1570         fstrcpy(info.defaultdatatype, "RAW");
1571         
1572         fstrcpy(info.driverpath, "");
1573         fstrcpy(info.datafile, "");
1574         fstrcpy(info.configfile, "");
1575         fstrcpy(info.helpfile, "");
1576
1577         if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
1578                 return WERR_NOMEM;
1579
1580         memset(info.dependentfiles, '\0', 2*sizeof(fstring));
1581         fstrcpy(info.dependentfiles[0], "");
1582
1583         *info_ptr = memdup(&info, sizeof(info));
1584         
1585         return WERR_OK;
1586 }
1587
1588 /****************************************************************************
1589 ****************************************************************************/
1590 static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
1591 {
1592         NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
1593         TDB_DATA kbuf, dbuf;
1594         fstring architecture;
1595         int len = 0;
1596         int i;
1597         pstring key;
1598
1599         ZERO_STRUCT(driver);
1600
1601         get_short_archi(architecture, in_arch);
1602
1603         DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
1604
1605         slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
1606
1607         kbuf.dptr = key;
1608         kbuf.dsize = strlen(key)+1;
1609         
1610         dbuf = tdb_fetch(tdb_drivers, kbuf);
1611 #if 0
1612         if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1613 #else
1614         if (!dbuf.dptr) return WERR_ACCESS_DENIED;
1615 #endif
1616         len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
1617                           &driver.cversion,
1618                           driver.name,
1619                           driver.environment,
1620                           driver.driverpath,
1621                           driver.datafile,
1622                           driver.configfile,
1623                           driver.helpfile,
1624                           driver.monitorname,
1625                           driver.defaultdatatype);
1626
1627         i=0;
1628         while (len < dbuf.dsize) {
1629                 fstring *tddfs;
1630         
1631                 tddfs = (fstring *)Realloc(driver.dependentfiles,
1632                                                          sizeof(fstring)*(i+2));
1633                 if (tddfs == NULL) {
1634                         DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
1635                         break;
1636                 }
1637                 else driver.dependentfiles = tddfs;
1638
1639                 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
1640                                   &driver.dependentfiles[i]);
1641                 i++;
1642         }
1643         if (driver.dependentfiles != NULL)
1644                 fstrcpy(driver.dependentfiles[i], "");
1645
1646         SAFE_FREE(dbuf.dptr);
1647
1648         if (len != dbuf.dsize) {
1649                 SAFE_FREE(driver.dependentfiles);
1650
1651                 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1652         }
1653
1654         *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
1655
1656         return WERR_OK;
1657 }
1658
1659 /****************************************************************************
1660 ****************************************************************************/
1661 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
1662 {
1663         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1664         TDB_DATA kbuf;
1665         pstring key;
1666         int i;
1667         line[0] = '\0';
1668
1669         slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
1670         DEBUG(10,("driver key: [%s]\n", key));
1671         
1672         kbuf.dptr = key;
1673         kbuf.dsize = strlen(key)+1;
1674         if (!tdb_exists(tdb_drivers, kbuf)) return False;
1675
1676         ZERO_STRUCT(info3);
1677         get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
1678         
1679     DEBUGADD(10,("info3->name            [%s]\n", info3->name));
1680     DEBUGADD(10,("info3->datafile        [%s]\n", info3->datafile));
1681     DEBUGADD(10,("info3->helpfile        [%s]\n", info3->helpfile));
1682     DEBUGADD(10,("info3->monitorname     [%s]\n", info3->monitorname));
1683     DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
1684         for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1685     DEBUGADD(10,("info3->dependentfiles  [%s]\n", info3->dependentfiles[i]));
1686     }
1687     DEBUGADD(10,("info3->environment     [%s]\n", info3->environment));
1688     DEBUGADD(10,("info3->driverpath      [%s]\n", info3->driverpath));
1689     DEBUGADD(10,("info3->configfile      [%s]\n", info3->configfile));
1690
1691         /*pstrcat(line, info3->name);             pstrcat(line, ":");*/
1692         trim_string(info3->configfile, "\\print$\\WIN40\\0\\", 0);
1693         pstrcat(line, info3->configfile);
1694     pstrcat(line, ":");
1695         trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
1696         pstrcat(line, info3->datafile);
1697     pstrcat(line, ":");
1698         trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
1699         pstrcat(line, info3->helpfile);
1700     pstrcat(line, ":");
1701         trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
1702         pstrcat(line, info3->monitorname);
1703     pstrcat(line, ":");
1704         pstrcat(line, "RAW");                /*info3->defaultdatatype);*/
1705     pstrcat(line, ":");
1706
1707         for (i=0; info3->dependentfiles &&
1708                  *info3->dependentfiles[i]; i++) {
1709                 if (i) pstrcat(line, ",");               /* don't end in a "," */
1710                 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
1711                 pstrcat(line, info3->dependentfiles[i]);
1712         }
1713         
1714         SAFE_FREE(info3);
1715
1716         return True;    
1717 }
1718
1719 /****************************************************************************
1720 debugging function, dump at level 6 the struct in the logs
1721 ****************************************************************************/
1722 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1723 {
1724         uint32 result;
1725         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1726         int i;
1727         
1728         DEBUG(106,("Dumping printer driver at level [%d]\n", level));
1729         
1730         switch (level)
1731         {
1732                 case 3:
1733                 {
1734                         if (driver.info_3 == NULL)
1735                                 result=5;
1736                         else {
1737                                 info3=driver.info_3;
1738                         
1739                                 DEBUGADD(106,("version:[%d]\n",         info3->cversion));
1740                                 DEBUGADD(106,("name:[%s]\n",            info3->name));
1741                                 DEBUGADD(106,("environment:[%s]\n",     info3->environment));
1742                                 DEBUGADD(106,("driverpath:[%s]\n",      info3->driverpath));
1743                                 DEBUGADD(106,("datafile:[%s]\n",        info3->datafile));
1744                                 DEBUGADD(106,("configfile:[%s]\n",      info3->configfile));
1745                                 DEBUGADD(106,("helpfile:[%s]\n",        info3->helpfile));
1746                                 DEBUGADD(106,("monitorname:[%s]\n",     info3->monitorname));
1747                                 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
1748                                 
1749                                 for (i=0; info3->dependentfiles &&
1750                                           *info3->dependentfiles[i]; i++) {
1751                                         DEBUGADD(106,("dependentfile:[%s]\n",
1752                                                       info3->dependentfiles[i]));
1753                                 }
1754                                 result=0;
1755                         }
1756                         break;
1757                 }
1758                 default:
1759                         DEBUGADD(1,("Level not implemented\n"));
1760                         result=1;
1761                         break;
1762         }
1763         
1764         return result;
1765 }
1766
1767 /****************************************************************************
1768 ****************************************************************************/
1769 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
1770 {
1771         int len = 0;
1772
1773         len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
1774
1775         if (!nt_devmode) return len;
1776
1777         len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1778                         nt_devmode->devicename,
1779                         nt_devmode->formname,
1780
1781                         nt_devmode->specversion,
1782                         nt_devmode->driverversion,
1783                         nt_devmode->size,
1784                         nt_devmode->driverextra,
1785                         nt_devmode->orientation,
1786                         nt_devmode->papersize,
1787                         nt_devmode->paperlength,
1788                         nt_devmode->paperwidth,
1789                         nt_devmode->scale,
1790                         nt_devmode->copies,
1791                         nt_devmode->defaultsource,
1792                         nt_devmode->printquality,
1793                         nt_devmode->color,
1794                         nt_devmode->duplex,
1795                         nt_devmode->yresolution,
1796                         nt_devmode->ttoption,
1797                         nt_devmode->collate,
1798                         nt_devmode->logpixels,
1799                         
1800                         nt_devmode->fields,
1801                         nt_devmode->bitsperpel,
1802                         nt_devmode->pelswidth,
1803                         nt_devmode->pelsheight,
1804                         nt_devmode->displayflags,
1805                         nt_devmode->displayfrequency,
1806                         nt_devmode->icmmethod,
1807                         nt_devmode->icmintent,
1808                         nt_devmode->mediatype,
1809                         nt_devmode->dithertype,
1810                         nt_devmode->reserved1,
1811                         nt_devmode->reserved2,
1812                         nt_devmode->panningwidth,
1813                         nt_devmode->panningheight,
1814                         nt_devmode->private);
1815
1816         
1817         if (nt_devmode->private) {
1818                 len += tdb_pack(buf+len, buflen-len, "B",
1819                                 nt_devmode->driverextra,
1820                                 nt_devmode->private);
1821         }
1822
1823         DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
1824
1825         return len;
1826 }
1827
1828 /****************************************************************************
1829 ****************************************************************************/
1830 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
1831 {
1832         int len = 0;
1833
1834         while (param != NULL) {
1835                 len += tdb_pack(buf+len, buflen-len, "pfdB",
1836                                 param,
1837                                 param->value,
1838                                 param->type,
1839                                 param->data_len,
1840                                 param->data);
1841                 param=param->next;      
1842         }
1843
1844         len += tdb_pack(buf+len, buflen-len, "p", param);
1845
1846         return len;
1847 }
1848
1849
1850 /****************************************************************************
1851 delete a printer - this just deletes the printer info file, any open
1852 handles are not affected
1853 ****************************************************************************/
1854 uint32 del_a_printer(char *sharename)
1855 {
1856         pstring key;
1857         TDB_DATA kbuf;
1858
1859         slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
1860
1861         kbuf.dptr=key;
1862         kbuf.dsize=strlen(key)+1;
1863
1864         tdb_delete(tdb_printers, kbuf);
1865         return 0;
1866 }
1867
1868 /* FIXME!!!  Reorder so this forward declaration is not necessary --jerry */
1869 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring);
1870 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
1871 /****************************************************************************
1872 ****************************************************************************/
1873 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
1874 {
1875         pstring key;
1876         char *buf;
1877         int buflen, len;
1878         WERROR ret;
1879         TDB_DATA kbuf, dbuf;
1880         
1881         /*
1882          * in addprinter: no servername and the printer is the name
1883          * in setprinter: servername is \\server
1884          *                and printer is \\server\\printer
1885          *
1886          * Samba manages only local printers.
1887          * we currently don't support things like path=\\other_server\printer
1888          */
1889
1890         if (info->servername[0]!='\0') {
1891                 trim_string(info->printername, info->servername, NULL);
1892                 trim_string(info->printername, "\\", NULL);
1893                 info->servername[0]='\0';
1894         }
1895
1896         /*
1897          * JFM: one day I'll forget.
1898          * below that's info->portname because that's the SAMBA sharename
1899          * and I made NT 'thinks' it's the portname
1900          * the info->sharename is the thing you can name when you add a printer
1901          * that's the short-name when you create shared printer for 95/98
1902          * So I've made a limitation in SAMBA: you can only have 1 printer model
1903          * behind a SAMBA share.
1904          */
1905
1906         buf = NULL;
1907         buflen = 0;
1908
1909  again: 
1910         len = 0;
1911         len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
1912                         info->attributes,
1913                         info->priority,
1914                         info->default_priority,
1915                         info->starttime,
1916                         info->untiltime,
1917                         info->status,
1918                         info->cjobs,
1919                         info->averageppm,
1920                         info->changeid,
1921                         info->c_setprinter,
1922                         info->setuptime,
1923                         info->servername,
1924                         info->printername,
1925                         info->sharename,
1926                         info->portname,
1927                         info->drivername,
1928                         info->comment,
1929                         info->location,
1930                         info->sepfile,
1931                         info->printprocessor,
1932                         info->datatype,
1933                         info->parameters);
1934
1935         len += pack_devicemode(info->devmode, buf+len, buflen-len);
1936         
1937         len += pack_specifics(info->specific, buf+len, buflen-len);
1938
1939         if (buflen != len) {
1940                 char *tb;
1941                 
1942                 tb = (char *)Realloc(buf, len);
1943                 if (!tb) {
1944                         DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
1945                         ret = WERR_NOMEM;
1946                         goto done;
1947                 }
1948                 else buf = tb;
1949                 buflen = len;
1950                 goto again;
1951         }
1952         
1953
1954         slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, info->sharename);
1955
1956         kbuf.dptr = key;
1957         kbuf.dsize = strlen(key)+1;
1958         dbuf.dptr = buf;
1959         dbuf.dsize = len;
1960
1961         ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
1962
1963 done:
1964         if (!W_ERROR_IS_OK(ret))
1965                 DEBUG(8, ("error updating printer to tdb on disk\n"));
1966
1967         SAFE_FREE(buf);
1968
1969         DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
1970                  info->sharename, info->drivername, info->portname, len));
1971
1972         return ret;
1973 }
1974
1975
1976 /****************************************************************************
1977 ****************************************************************************/
1978 void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM **param)
1979 {
1980         NT_PRINTER_PARAM *current;
1981         
1982         DEBUG(108,("add_a_specific_param\n"));  
1983
1984         (*param)->next=NULL;
1985         
1986         if (info_2->specific == NULL)
1987         {
1988                 info_2->specific=*param;
1989         }
1990         else
1991         {
1992                 current=info_2->specific;               
1993                 while (current->next != NULL) {
1994                         current=current->next;
1995                 }               
1996                 current->next=*param;
1997         }
1998
1999         *param = NULL;
2000 }
2001
2002 /****************************************************************************
2003 ****************************************************************************/
2004 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
2005 {
2006         NT_PRINTER_PARAM *current;
2007         NT_PRINTER_PARAM *previous;
2008         
2009         current=info_2->specific;
2010         previous=current;
2011         
2012         if (current==NULL) return (False);
2013         
2014         if ( !strcmp(current->value, param->value) &&
2015             (strlen(current->value)==strlen(param->value)) ) {
2016                 DEBUG(109,("deleting first value\n"));
2017                 info_2->specific=current->next;
2018                 SAFE_FREE(current->data);
2019                 SAFE_FREE(current);
2020                 DEBUG(109,("deleted first value\n"));
2021                 return (True);
2022         }
2023
2024         current=previous->next;
2025                 
2026         while ( current!=NULL ) {
2027                 if (!strcmp(current->value, param->value) &&
2028                     strlen(current->value)==strlen(param->value) ) {
2029                         DEBUG(109,("deleting current value\n"));
2030                         previous->next=current->next;
2031                         SAFE_FREE(current->data);
2032                         SAFE_FREE(current);
2033                         DEBUG(109,("deleted current value\n"));
2034                         return(True);
2035                 }
2036                 
2037                 previous=previous->next;
2038                 current=current->next;
2039         }
2040         return (False);
2041 }
2042
2043 /****************************************************************************
2044  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
2045 ****************************************************************************/
2046 void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
2047 {
2048         NT_PRINTER_PARAM *param = *param_ptr;
2049
2050         if(param == NULL)
2051                 return;
2052
2053         DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
2054
2055         SAFE_FREE(param->data);
2056         SAFE_FREE(*param_ptr);
2057 }
2058
2059 /****************************************************************************
2060  Malloc and return an NT devicemode.
2061 ****************************************************************************/
2062
2063 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
2064 {
2065 /*
2066  * should I init this ones ???
2067         nt_devmode->devicename
2068 */
2069
2070         char adevice[32];
2071         NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
2072
2073         if (nt_devmode == NULL) {
2074                 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
2075                 return NULL;
2076         }
2077
2078         ZERO_STRUCTP(nt_devmode);
2079
2080         safe_strcpy(adevice, default_devicename, sizeof(adevice));
2081         fstrcpy(nt_devmode->devicename, adevice);       
2082         
2083         fstrcpy(nt_devmode->formname, "Letter");
2084
2085         nt_devmode->specversion      = 0x0401;
2086         nt_devmode->driverversion    = 0x0400;
2087         nt_devmode->size             = 0x00DC;
2088         nt_devmode->driverextra      = 0x0000;
2089         nt_devmode->fields           = FORMNAME | TTOPTION | PRINTQUALITY |
2090                                        DEFAULTSOURCE | COPIES | SCALE |
2091                                        PAPERSIZE | ORIENTATION;
2092         nt_devmode->orientation      = 1;
2093         nt_devmode->papersize        = PAPER_LETTER;
2094         nt_devmode->paperlength      = 0;
2095         nt_devmode->paperwidth       = 0;
2096         nt_devmode->scale            = 0x64;
2097         nt_devmode->copies           = 1;
2098         nt_devmode->defaultsource    = BIN_FORMSOURCE;
2099         nt_devmode->printquality     = RES_HIGH;           /* 0x0258 */
2100         nt_devmode->color            = COLOR_MONOCHROME;
2101         nt_devmode->duplex           = DUP_SIMPLEX;
2102         nt_devmode->yresolution      = 0;
2103         nt_devmode->ttoption         = TT_SUBDEV;
2104         nt_devmode->collate          = COLLATE_FALSE;
2105         nt_devmode->icmmethod        = 0;
2106         nt_devmode->icmintent        = 0;
2107         nt_devmode->mediatype        = 0;
2108         nt_devmode->dithertype       = 0;
2109
2110         /* non utilisés par un driver d'imprimante */
2111         nt_devmode->logpixels        = 0;
2112         nt_devmode->bitsperpel       = 0;
2113         nt_devmode->pelswidth        = 0;
2114         nt_devmode->pelsheight       = 0;
2115         nt_devmode->displayflags     = 0;
2116         nt_devmode->displayfrequency = 0;
2117         nt_devmode->reserved1        = 0;
2118         nt_devmode->reserved2        = 0;
2119         nt_devmode->panningwidth     = 0;
2120         nt_devmode->panningheight    = 0;
2121         
2122         nt_devmode->private = NULL;
2123         return nt_devmode;
2124 }
2125
2126 /****************************************************************************
2127  Deepcopy an NT devicemode.
2128 ****************************************************************************/
2129
2130 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
2131 {
2132         NT_DEVICEMODE *new_nt_devicemode = NULL;
2133
2134         if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
2135                 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2136                 return NULL;
2137         }
2138
2139         new_nt_devicemode->private = NULL;
2140         if (nt_devicemode->private != NULL) {
2141                 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
2142                         SAFE_FREE(new_nt_devicemode);
2143                         DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2144                         return NULL;
2145         }
2146         }
2147
2148         return new_nt_devicemode;
2149 }
2150
2151 /****************************************************************************
2152  Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
2153 ****************************************************************************/
2154
2155 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
2156 {
2157         NT_DEVICEMODE *nt_devmode = *devmode_ptr;
2158
2159         if(nt_devmode == NULL)
2160                 return;
2161
2162         DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
2163
2164         SAFE_FREE(nt_devmode->private);
2165         SAFE_FREE(*devmode_ptr);
2166 }
2167
2168 /****************************************************************************
2169  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
2170 ****************************************************************************/
2171 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
2172 {
2173         NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
2174         NT_PRINTER_PARAM *param_ptr;
2175
2176         if(info == NULL)
2177                 return;
2178
2179         DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
2180
2181         free_nt_devicemode(&info->devmode);
2182
2183         for(param_ptr = info->specific; param_ptr; ) {
2184                 NT_PRINTER_PARAM *tofree = param_ptr;
2185
2186                 param_ptr = param_ptr->next;
2187                 free_nt_printer_param(&tofree);
2188         }
2189
2190         SAFE_FREE(*info_ptr);
2191 }
2192
2193
2194 /****************************************************************************
2195 ****************************************************************************/
2196 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
2197 {
2198         int len = 0;
2199         int extra_len = 0;
2200         NT_DEVICEMODE devmode;
2201
2202         ZERO_STRUCT(devmode);
2203
2204         len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
2205
2206         if (!*nt_devmode) return len;
2207
2208         len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
2209                           devmode.devicename,
2210                           devmode.formname,
2211
2212                           &devmode.specversion,
2213                           &devmode.driverversion,
2214                           &devmode.size,
2215                           &devmode.driverextra,
2216                           &devmode.orientation,
2217                           &devmode.papersize,
2218                           &devmode.paperlength,
2219                           &devmode.paperwidth,
2220                           &devmode.scale,
2221                           &devmode.copies,
2222                           &devmode.defaultsource,
2223                           &devmode.printquality,
2224                           &devmode.color,
2225                           &devmode.duplex,
2226                           &devmode.yresolution,
2227                           &devmode.ttoption,
2228                           &devmode.collate,
2229                           &devmode.logpixels,
2230                         
2231                           &devmode.fields,
2232                           &devmode.bitsperpel,
2233                           &devmode.pelswidth,
2234                           &devmode.pelsheight,
2235                           &devmode.displayflags,
2236                           &devmode.displayfrequency,
2237                           &devmode.icmmethod,
2238                           &devmode.icmintent,
2239                           &devmode.mediatype,
2240                           &devmode.dithertype,
2241                           &devmode.reserved1,
2242                           &devmode.reserved2,
2243                           &devmode.panningwidth,
2244                           &devmode.panningheight,
2245                           &devmode.private);
2246         
2247         if (devmode.private) {
2248                 /* the len in tdb_unpack is an int value and
2249                  * devmode.driverextra is only a short
2250                  */
2251                 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
2252                 devmode.driverextra=(uint16)extra_len;
2253                 
2254                 /* check to catch an invalid TDB entry so we don't segfault */
2255                 if (devmode.driverextra == 0) {
2256                         devmode.private = NULL;
2257                 }
2258         }
2259
2260         *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
2261
2262         DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
2263         if (devmode.private)
2264                 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
2265
2266         return len;
2267 }
2268
2269 /****************************************************************************
2270 ****************************************************************************/
2271 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
2272 {
2273         int len = 0;
2274         NT_PRINTER_PARAM param, *p;
2275
2276         *list = NULL;
2277
2278         while (1) {
2279                 len += tdb_unpack(buf+len, buflen-len, "p", &p);
2280                 if (!p) break;
2281
2282                 len += tdb_unpack(buf+len, buflen-len, "fdB",
2283                                   param.value,
2284                                   &param.type,
2285                                   &param.data_len,
2286                                   &param.data);
2287                 param.next = *list;
2288                 *list = memdup(&param, sizeof(param));
2289
2290                 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
2291         }
2292
2293         return len;
2294 }
2295
2296 static void map_to_os2_driver(fstring drivername)
2297 {
2298         static BOOL initialised=False;
2299         static fstring last_from,last_to;
2300         char *mapfile = lp_os2_driver_map();
2301         char **lines = NULL;
2302         int numlines = 0;
2303         int i;
2304
2305         if (!strlen(drivername))
2306                 return;
2307
2308         if (!*mapfile)
2309                 return;
2310
2311         if (!initialised) {
2312                 *last_from = *last_to = 0;
2313                 initialised = True;
2314         }
2315
2316         if (strequal(drivername,last_from)) {
2317                 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,last_to));
2318                 fstrcpy(drivername,last_to);
2319                 return;
2320         }
2321
2322         lines = file_lines_load(mapfile, &numlines);
2323         if (numlines == 0) {
2324                 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
2325                 return;
2326         }
2327
2328         DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
2329
2330         for( i = 0; i < numlines; i++) {
2331                 char *nt_name = lines[i];
2332                 char *os2_name = strchr(nt_name,'=');
2333
2334                 if (!os2_name)
2335                         continue;
2336
2337                 *os2_name++ = 0;
2338
2339                 while (isspace(*nt_name))
2340                         nt_name++;
2341
2342                 if (!*nt_name || strchr("#;",*nt_name))
2343                         continue;
2344
2345                 {
2346                         int l = strlen(nt_name);
2347                         while (l && isspace(nt_name[l-1])) {
2348                                 nt_name[l-1] = 0;
2349                                 l--;
2350                         }
2351                 }
2352
2353                 while (isspace(*os2_name))
2354                         os2_name++;
2355
2356                 {
2357                         int l = strlen(os2_name);
2358                         while (l && isspace(os2_name[l-1])) {
2359                                 os2_name[l-1] = 0;
2360                                 l--;
2361                         }
2362                 }
2363
2364                 if (strequal(nt_name,drivername)) {
2365                         DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
2366                         fstrcpy(last_from,drivername);
2367                         fstrcpy(last_to,os2_name);
2368                         fstrcpy(drivername,os2_name);
2369                         file_lines_free(lines);
2370                         return;
2371                 }
2372         }
2373
2374         file_lines_free(lines);
2375 }
2376
2377 /****************************************************************************
2378 get a default printer info 2 struct
2379 ****************************************************************************/
2380 static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2381 {
2382         extern pstring global_myname;
2383         extern fstring local_machine;
2384         int snum;
2385         NT_PRINTER_INFO_LEVEL_2 info;
2386         char *sub_name = *local_machine ? local_machine : global_myname;
2387
2388         ZERO_STRUCT(info);
2389
2390         snum = lp_servicenumber(sharename);
2391
2392         slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", sub_name);
2393         slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s", 
2394                  sub_name, sharename);
2395         fstrcpy(info.sharename, sharename);
2396         fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
2397         fstrcpy(info.drivername, lp_printerdriver(snum));
2398
2399         /* by setting the driver name to an empty string, a local NT admin
2400            can now run the **local** APW to install a local printer driver
2401            for a Samba shared printer in 2.2.  Without this, drivers **must** be 
2402            installed on the Samba server for NT clients --jerry */
2403 #if 0   /* JERRY --do not uncomment-- */
2404         if (!*info.drivername)
2405                 fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
2406 #endif
2407
2408
2409         DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info.drivername));
2410
2411         pstrcpy(info.comment, "");
2412         fstrcpy(info.printprocessor, "winprint");
2413         fstrcpy(info.datatype, "RAW");
2414
2415         info.attributes = PRINTER_ATTRIBUTE_SHARED   \
2416                          | PRINTER_ATTRIBUTE_LOCAL  \
2417                          | PRINTER_ATTRIBUTE_RAW_ONLY \
2418                          | PRINTER_ATTRIBUTE_QUEUED ;            /* attributes */
2419
2420         info.starttime = 0; /* Minutes since 12:00am GMT */
2421         info.untiltime = 0; /* Minutes since 12:00am GMT */
2422         info.priority = 1;
2423         info.default_priority = 1;
2424         info.setuptime = (uint32)time(NULL) - 86400;    /* minus 1 day */
2425
2426         /*
2427          * I changed this as I think it is better to have a generic
2428          * DEVMODE than to crash Win2k explorer.exe   --jerry
2429          * See the HP Deskjet 990c Win2k drivers for an example.
2430          */
2431
2432 #if 0 /* JRA - NO NOT CHANGE ! */
2433         info.devmode = NULL;
2434 #else
2435         /*
2436          * We should not return a default devicemode, as this causes
2437          * Win2K to not send the correct one on PCL drivers. It needs to
2438          * see a null devicemode so it can then overwrite the devicemode
2439          * on OpenPrinterEx. Yes this *is* insane :-). JRA.
2440          */
2441         if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
2442                 goto fail;
2443 #endif
2444
2445         /* This will get the current RPC talloc context, but we should be
2446            passing this as a parameter... fixme... JRA ! */
2447
2448         if (!nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf))
2449                 goto fail;
2450
2451         *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
2452         if (! *info_ptr) {
2453                 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
2454                 goto fail;
2455         }
2456
2457         return WERR_OK;
2458
2459   fail:
2460
2461         if (info.devmode)
2462                 free_nt_devicemode(&info.devmode);
2463         return WERR_ACCESS_DENIED;
2464 }
2465
2466 /****************************************************************************
2467 ****************************************************************************/
2468 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2469 {
2470         extern pstring global_myname;
2471         extern fstring local_machine;
2472         pstring key;
2473         char *sub_name = *local_machine ? local_machine : global_myname;
2474         NT_PRINTER_INFO_LEVEL_2 info;
2475         int             len = 0;
2476         TDB_DATA kbuf, dbuf;
2477         fstring printername;
2478                 
2479         ZERO_STRUCT(info);
2480
2481         slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
2482
2483         kbuf.dptr = key;
2484         kbuf.dsize = strlen(key)+1;
2485
2486         dbuf = tdb_fetch(tdb_printers, kbuf);
2487         if (!dbuf.dptr)
2488                 return get_a_printer_2_default(info_ptr, sharename);
2489
2490         len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
2491                         &info.attributes,
2492                         &info.priority,
2493                         &info.default_priority,
2494                         &info.starttime,
2495                         &info.untiltime,
2496                         &info.status,
2497                         &info.cjobs,
2498                         &info.averageppm,
2499                         &info.changeid,
2500                         &info.c_setprinter,
2501                         &info.setuptime,
2502                         info.servername,
2503                         info.printername,
2504                         info.sharename,
2505                         info.portname,
2506                         info.drivername,
2507                         info.comment,
2508                         info.location,
2509                         info.sepfile,
2510                         info.printprocessor,
2511                         info.datatype,
2512                         info.parameters);
2513
2514         /* Samba has to have shared raw drivers. */
2515         info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
2516
2517         /* Restore the stripped strings. */
2518         slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", sub_name);
2519         slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", sub_name,
2520                         info.printername);
2521         fstrcpy(info.printername, printername);
2522
2523         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2524 #if 1
2525         /*
2526          * Some client drivers freak out if there is a NULL devmode
2527          * (probably the driver is not checking before accessing 
2528          * the devmode pointer)   --jerry
2529          */
2530         if (!info.devmode)
2531         {
2532                 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
2533                         printername));
2534                 info.devmode = construct_nt_devicemode(printername);
2535         }
2536 #endif
2537         len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
2538
2539         /* This will get the current RPC talloc context, but we should be
2540        passing this as a parameter... fixme... JRA ! */
2541
2542         nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
2543
2544         /* Fix for OS/2 drivers. */
2545
2546         if (get_remote_arch() == RA_OS2)
2547                 map_to_os2_driver(info.drivername);
2548
2549         SAFE_FREE(dbuf.dptr);
2550         *info_ptr=memdup(&info, sizeof(info));
2551
2552         DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
2553                  sharename, info.printername, info.drivername));
2554
2555         return WERR_OK; 
2556 }
2557
2558 /****************************************************************************
2559 debugging function, dump at level 6 the struct in the logs
2560 ****************************************************************************/
2561 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2562 {
2563         uint32 result;
2564         NT_PRINTER_INFO_LEVEL_2 *info2;
2565         
2566         DEBUG(106,("Dumping printer at level [%d]\n", level));
2567         
2568         switch (level)
2569         {
2570                 case 2:
2571                 {
2572                         if (printer.info_2 == NULL)
2573                                 result=5;
2574                         else
2575                         {
2576                                 info2=printer.info_2;
2577                         
2578                                 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
2579                                 DEBUGADD(106,("priority:[%d]\n", info2->priority));
2580                                 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
2581                                 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
2582                                 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
2583                                 DEBUGADD(106,("status:[%d]\n", info2->status));
2584                                 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
2585                                 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
2586                                 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
2587                                 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
2588                                 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
2589
2590                                 DEBUGADD(106,("servername:[%s]\n", info2->servername));
2591                                 DEBUGADD(106,("printername:[%s]\n", info2->printername));
2592                                 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
2593                                 DEBUGADD(106,("portname:[%s]\n", info2->portname));
2594                                 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
2595                                 DEBUGADD(106,("comment:[%s]\n", info2->comment));
2596                                 DEBUGADD(106,("location:[%s]\n", info2->location));
2597                                 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
2598                                 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
2599                                 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
2600                                 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
2601                                 result=0;
2602                         }
2603                         break;
2604                 }
2605                 default:
2606                         DEBUGADD(1,("Level not implemented\n"));
2607                         result=1;
2608                         break;
2609         }
2610         
2611         return result;
2612 }
2613
2614 /****************************************************************************
2615  Get the parameters we can substitute in an NT print job.
2616 ****************************************************************************/
2617
2618 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
2619 {
2620         NT_PRINTER_INFO_LEVEL *printer = NULL;
2621         
2622         **printername = **sharename = **portname = '\0';
2623
2624         if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
2625                 return;
2626
2627         fstrcpy(*printername, printer->info_2->printername);
2628         fstrcpy(*sharename, printer->info_2->sharename);
2629         fstrcpy(*portname, printer->info_2->portname);
2630
2631         free_a_printer(&printer, 2);
2632 }
2633
2634 /*
2635  * The function below are the high level ones.
2636  * only those ones must be called from the spoolss code.
2637  * JFM.
2638  */
2639
2640 /****************************************************************************
2641  Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
2642 ****************************************************************************/
2643
2644 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2645 {
2646         WERROR result;
2647         
2648         dump_a_printer(printer, level); 
2649         
2650         switch (level)
2651         {
2652                 case 2:
2653                 {
2654                         /*
2655                          * Update the changestamp.  Emperical tests show that the
2656                          * ChangeID is always updated,but c_setprinter is only 
2657                          * incremented on a SetPrinter() call.
2658                          */
2659
2660                         time_t time_unix = time(NULL);
2661
2662                         /* ChangeID **must** be increasing over the lifetime
2663                            of client's spoolss service in order for the 
2664                            client's cache to show updates */
2665
2666                         printer.info_2->changeid = time_unix * 100;
2667
2668                         /*
2669                          * Because one day someone will ask:
2670                          * NT->NT       An admin connection to a remote
2671                          *              printer show changes imeediately in
2672                          *              the properities dialog
2673                          *      
2674                          *              A non-admin connection will only show the
2675                          *              changes after viewing the properites page
2676                          *              2 times.  Seems to be related to a
2677                          *              race condition in the client between the spooler
2678                          *              updating the local cache and the Explorer.exe GUI
2679                          *              actually displaying the properties.
2680                          *
2681                          *              This is fixed in Win2k.  admin/non-admin
2682                          *              connections both display changes immediately.
2683                          *
2684                          * 14/12/01     --jerry
2685                          */
2686
2687                         result=update_a_printer_2(printer.info_2);
2688                         break;
2689                 }
2690                 default:
2691                         result=WERR_UNKNOWN_LEVEL;
2692                         break;
2693         }
2694         
2695         return result;
2696 }
2697
2698 /****************************************************************************
2699  Add a printer. This is called from ADDPRINTER(EX) and also SETPRINTER.
2700  We split this out from mod_a_printer as it updates the id's and timestamps.
2701 ****************************************************************************/
2702
2703 WERROR add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2704 {
2705         WERROR result;
2706         
2707         dump_a_printer(printer, level); 
2708         
2709         switch (level)
2710         {
2711                 case 2:
2712                 {
2713                         /*
2714                          * Update the changestamp.  See comments in mod_a_printer()
2715                          * --jerry
2716                          */
2717
2718                         time_t time_unix = time(NULL);
2719
2720                         printer.info_2->changeid = time_unix * 100;
2721                         printer.info_2->c_setprinter++;
2722
2723                         result=update_a_printer_2(printer.info_2);
2724                         break;
2725                 }
2726                 default:
2727                         result=WERR_UNKNOWN_LEVEL;
2728                         break;
2729         }
2730         
2731         return result;
2732 }
2733
2734 /****************************************************************************
2735  Initialize printer devmode & data with previously saved driver init values.
2736 ****************************************************************************/
2737 static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
2738 {
2739         int                     len = 0;
2740         pstring                 key;
2741         TDB_DATA                kbuf, dbuf;
2742         NT_PRINTER_PARAM        *current;
2743         NT_PRINTER_INFO_LEVEL_2 info;
2744
2745         ZERO_STRUCT(info);
2746
2747         slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
2748
2749         kbuf.dptr = key;
2750         kbuf.dsize = strlen(key)+1;
2751
2752         dbuf = tdb_fetch(tdb_drivers, kbuf);
2753         if (!dbuf.dptr)
2754                 return False;
2755
2756         /*
2757          * Get the saved DEVMODE..
2758          */
2759         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2760
2761         /*
2762          * The saved DEVMODE contains the devicename from the printer used during
2763          * the initialization save. Change it to reflect the new printer.
2764          */
2765         ZERO_STRUCT(info.devmode->devicename);
2766         fstrcpy(info.devmode->devicename, info_ptr->printername);
2767
2768         /* 
2769          *      Bind the saved DEVMODE to the new the printer.
2770          */
2771         free_nt_devicemode(&info_ptr->devmode);
2772         info_ptr->devmode = info.devmode;
2773
2774         DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
2775                         info_ptr->printername, info_ptr->drivername));
2776
2777         /* 
2778          * There should not be any printer data 'specifics' already set during the
2779          * add printer operation, if there are delete them. 
2780          */
2781         while ( (current=info_ptr->specific) != NULL ) {
2782                 info_ptr->specific=current->next;
2783                 SAFE_FREE(current->data);
2784                 SAFE_FREE(current);
2785         }
2786
2787         /* 
2788          * Add the printer data 'specifics' to the new printer
2789          */
2790         len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
2791
2792         SAFE_FREE(dbuf.dptr);
2793
2794         return True;    
2795 }
2796
2797 /****************************************************************************
2798  Initialize printer devmode & data with previously saved driver init values.
2799  When a printer is created using AddPrinter, the drivername bound to the
2800  printer is used to lookup previously saved driver initialization info, which
2801  is bound to the new printer.
2802 ****************************************************************************/
2803
2804 uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
2805 {
2806         uint32 result;
2807         
2808         switch (level)
2809         {
2810                 case 2:
2811                 {
2812                         result=set_driver_init_2(printer->info_2);
2813                         break;
2814                 }
2815                 default:
2816                         result=1;
2817                         break;
2818         }
2819         
2820         return result;
2821 }
2822
2823 /****************************************************************************
2824  Pack up the DEVMODE and specifics for a printer into a 'driver init' entry 
2825  in the tdb. Note: this is different from the driver entry and the printer
2826  entry. There should be a single driver init entry for each driver regardless
2827  of whether it was installed from NT or 2K. Technically, they should be
2828  different, but they work out to the same struct.
2829 ****************************************************************************/
2830 static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
2831 {
2832         pstring key;
2833         char *buf;
2834         int buflen, len, ret;
2835         TDB_DATA kbuf, dbuf;
2836
2837         buf = NULL;
2838         buflen = 0;
2839
2840  again: 
2841         len = 0;
2842         len += pack_devicemode(info->devmode, buf+len, buflen-len);
2843
2844         len += pack_specifics(info->specific, buf+len, buflen-len);
2845
2846         if (buflen != len) {
2847                 char *tb;
2848                 
2849                 tb = (char *)Realloc(buf, len);
2850                 if (!tb) {
2851                         DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
2852                         ret = -1;
2853                         goto done;
2854                 }
2855                 else buf = tb;
2856                 buflen = len;
2857                 goto again;
2858         }
2859
2860         slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername);
2861
2862         kbuf.dptr = key;
2863         kbuf.dsize = strlen(key)+1;
2864         dbuf.dptr = buf;
2865         dbuf.dsize = len;
2866
2867         ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
2868
2869 done:
2870         if (ret == -1)
2871                 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
2872
2873         SAFE_FREE(buf);
2874
2875         DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
2876                  info->sharename, info->drivername));
2877
2878         return ret;
2879 }
2880
2881 /****************************************************************************
2882  Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
2883 ****************************************************************************/
2884
2885 static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2886 {
2887         uint32 result;
2888         
2889         dump_a_printer(printer, level); 
2890         
2891         switch (level)
2892         {
2893                 case 2:
2894                 {
2895                         result=update_driver_init_2(printer.info_2);
2896                         break;
2897                 }
2898                 default:
2899                         result=1;
2900                         break;
2901         }
2902         
2903         return result;
2904 }
2905
2906 /****************************************************************************
2907  Convert the printer data value, a REG_BINARY array, into an initialization 
2908  DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
2909  got to keep the endians happy :).
2910 ****************************************************************************/
2911
2912 static BOOL convert_driver_init(NT_PRINTER_PARAM *param, TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode)
2913 {
2914         BOOL       result = False;
2915         prs_struct ps;
2916         DEVICEMODE devmode;
2917
2918         ZERO_STRUCT(devmode);
2919
2920         prs_init(&ps, 0, ctx, UNMARSHALL);
2921         ps.data_p      = (char *)param->data;
2922         ps.buffer_size = param->data_len;
2923
2924         if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
2925                 result = convert_devicemode("", &devmode, &nt_devmode);
2926         else
2927                 DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
2928
2929         return result;
2930 }
2931
2932 /****************************************************************************
2933  Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
2934
2935  1. Use the driver's config DLL to this UNC printername and:
2936     a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
2937     b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
2938  2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
2939
2940  The last step triggers saving the "driver initialization" information for
2941  this printer into the tdb. Later, new printers that use this driver will
2942  have this initialization information bound to them. This simulates the
2943  driver initialization, as if it had run on the Samba server (as it would
2944  have done on NT).
2945
2946  The Win32 client side code requirement sucks! But until we can run arbitrary
2947  Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
2948  
2949  It would have been easier to use SetPrinter because all the UNMARSHALLING of
2950  the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
2951  about it and you will realize why.  JRR 010720
2952 ****************************************************************************/
2953
2954 static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARAM *param)
2955 {
2956         WERROR        status       = WERR_OK;
2957         TALLOC_CTX    *ctx         = NULL;
2958         NT_DEVICEMODE *nt_devmode  = NULL;
2959         NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
2960         
2961         /*
2962          * Set devmode on printer info, so entire printer initialization can be 
2963          * saved to tdb.
2964          */
2965         if ((ctx = talloc_init()) == NULL)
2966                 return WERR_NOMEM;
2967
2968         if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) {
2969                 status = WERR_NOMEM;
2970                 goto done;
2971         }
2972         
2973         ZERO_STRUCTP(nt_devmode);
2974
2975         /*
2976          * The DEVMODE is held in the 'data' component of the param in raw binary.
2977          * Convert it to to a devmode structure
2978          */
2979         if (!convert_driver_init(param, ctx, nt_devmode)) {
2980                 DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
2981                 status = WERR_INVALID_PARAM;
2982                 goto done;
2983         }
2984
2985         /*
2986          * Pack up and add (or update) the DEVMODE and any current printer data to
2987          * a 'driver init' element in the tdb
2988          * 
2989          */
2990         printer->info_2->devmode = nt_devmode;
2991         if (update_driver_init(*printer, 2)!=0) {
2992                 DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
2993                 status = WERR_NOMEM;
2994                 goto done;
2995         }
2996         
2997         /*
2998          * If driver initialization info was successfully saved, set the current 
2999          * printer to match it. This allows initialization of the current printer 
3000          * as well as the driver.
3001          */
3002         status = mod_a_printer(*printer, 2);
3003         if (!W_ERROR_IS_OK(status)) {
3004                 DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
3005                                   printer->info_2->printername));
3006         }
3007
3008   done:
3009         talloc_destroy(ctx);
3010         if (nt_devmode)
3011                 SAFE_FREE(nt_devmode->private);
3012         SAFE_FREE(nt_devmode);
3013         printer->info_2->devmode = tmp_devmode;
3014
3015         return status;
3016 }
3017
3018 /****************************************************************************
3019  Update the driver init info (DEVMODE and specifics) for a printer
3020 ****************************************************************************/
3021
3022 WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param)
3023 {
3024         WERROR status = WERR_OK;
3025         
3026         switch (level)
3027         {
3028                 case 2:
3029                 {
3030                         status=save_driver_init_2(printer, param);
3031                         break;
3032                 }
3033                 default:
3034                         status=WERR_UNKNOWN_LEVEL;
3035                         break;
3036         }
3037         
3038         return status;
3039 }
3040
3041 /****************************************************************************
3042  Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
3043 ****************************************************************************/
3044
3045 WERROR get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
3046 {
3047         WERROR result;
3048         NT_PRINTER_INFO_LEVEL *printer = NULL;
3049         
3050         *pp_printer = NULL;
3051
3052         DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
3053
3054         switch (level)
3055         {
3056                 case 2:
3057                 {
3058                         if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
3059                                 DEBUG(0,("get_a_printer: malloc fail.\n"));
3060                                 return WERR_NOMEM;
3061                         }
3062                         ZERO_STRUCTP(printer);
3063                         result=get_a_printer_2(&printer->info_2, sharename);
3064                         if (W_ERROR_IS_OK(result)) {
3065                                 dump_a_printer(*printer, level);
3066                                 *pp_printer = printer;
3067                         } else {
3068                                 SAFE_FREE(printer);
3069                         }
3070                         break;
3071                 }
3072                 default:
3073                         result=WERR_UNKNOWN_LEVEL;
307