3436d2c1c49589b8c34ebd16dec7cda1b758707d
[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         int snum;
2383         NT_PRINTER_INFO_LEVEL_2 info;
2384
2385         ZERO_STRUCT(info);
2386
2387         snum = lp_servicenumber(sharename);
2388
2389         slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
2390         slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s", 
2391                  get_called_name(), sharename);
2392         fstrcpy(info.sharename, sharename);
2393         fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
2394         fstrcpy(info.drivername, lp_printerdriver(snum));
2395
2396         /* by setting the driver name to an empty string, a local NT admin
2397            can now run the **local** APW to install a local printer driver
2398            for a Samba shared printer in 2.2.  Without this, drivers **must** be 
2399            installed on the Samba server for NT clients --jerry */
2400 #if 0   /* JERRY --do not uncomment-- */
2401         if (!*info.drivername)
2402                 fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
2403 #endif
2404
2405
2406         DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info.drivername));
2407
2408         pstrcpy(info.comment, "");
2409         fstrcpy(info.printprocessor, "winprint");
2410         fstrcpy(info.datatype, "RAW");
2411
2412         info.attributes = PRINTER_ATTRIBUTE_SHARED   \
2413                          | PRINTER_ATTRIBUTE_LOCAL  \
2414                          | PRINTER_ATTRIBUTE_RAW_ONLY \
2415                          | PRINTER_ATTRIBUTE_QUEUED ;            /* attributes */
2416
2417         info.starttime = 0; /* Minutes since 12:00am GMT */
2418         info.untiltime = 0; /* Minutes since 12:00am GMT */
2419         info.priority = 1;
2420         info.default_priority = 1;
2421         info.setuptime = (uint32)time(NULL) - 86400;    /* minus 1 day */
2422
2423         /*
2424          * I changed this as I think it is better to have a generic
2425          * DEVMODE than to crash Win2k explorer.exe   --jerry
2426          * See the HP Deskjet 990c Win2k drivers for an example.
2427          */
2428
2429 #if 0 /* JRA - NO NOT CHANGE ! */
2430         info.devmode = NULL;
2431 #else
2432         /*
2433          * We should not return a default devicemode, as this causes
2434          * Win2K to not send the correct one on PCL drivers. It needs to
2435          * see a null devicemode so it can then overwrite the devicemode
2436          * on OpenPrinterEx. Yes this *is* insane :-). JRA.
2437          */
2438         if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
2439                 goto fail;
2440 #endif
2441
2442         /* This will get the current RPC talloc context, but we should be
2443            passing this as a parameter... fixme... JRA ! */
2444
2445         if (!nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf))
2446                 goto fail;
2447
2448         *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
2449         if (! *info_ptr) {
2450                 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
2451                 goto fail;
2452         }
2453
2454         return WERR_OK;
2455
2456   fail:
2457
2458         if (info.devmode)
2459                 free_nt_devicemode(&info.devmode);
2460         return WERR_ACCESS_DENIED;
2461 }
2462
2463 /****************************************************************************
2464 ****************************************************************************/
2465 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2466 {
2467         pstring key;
2468         NT_PRINTER_INFO_LEVEL_2 info;
2469         int             len = 0;
2470         TDB_DATA kbuf, dbuf;
2471         fstring printername;
2472                 
2473         ZERO_STRUCT(info);
2474
2475         slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
2476
2477         kbuf.dptr = key;
2478         kbuf.dsize = strlen(key)+1;
2479
2480         dbuf = tdb_fetch(tdb_printers, kbuf);
2481         if (!dbuf.dptr)
2482                 return get_a_printer_2_default(info_ptr, sharename);
2483
2484         len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
2485                         &info.attributes,
2486                         &info.priority,
2487                         &info.default_priority,
2488                         &info.starttime,
2489                         &info.untiltime,
2490                         &info.status,
2491                         &info.cjobs,
2492                         &info.averageppm,
2493                         &info.changeid,
2494                         &info.c_setprinter,
2495                         &info.setuptime,
2496                         info.servername,
2497                         info.printername,
2498                         info.sharename,
2499                         info.portname,
2500                         info.drivername,
2501                         info.comment,
2502                         info.location,
2503                         info.sepfile,
2504                         info.printprocessor,
2505                         info.datatype,
2506                         info.parameters);
2507
2508         /* Samba has to have shared raw drivers. */
2509         info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
2510
2511         /* Restore the stripped strings. */
2512         slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
2513         slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", get_called_name(),
2514                         info.printername);
2515         fstrcpy(info.printername, printername);
2516
2517         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2518 #if 1
2519         /*
2520          * Some client drivers freak out if there is a NULL devmode
2521          * (probably the driver is not checking before accessing 
2522          * the devmode pointer)   --jerry
2523          */
2524         if (!info.devmode)
2525         {
2526                 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
2527                         printername));
2528                 info.devmode = construct_nt_devicemode(printername);
2529         }
2530 #endif
2531         len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
2532
2533         /* This will get the current RPC talloc context, but we should be
2534        passing this as a parameter... fixme... JRA ! */
2535
2536         nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
2537
2538         /* Fix for OS/2 drivers. */
2539
2540         if (get_remote_arch() == RA_OS2)
2541                 map_to_os2_driver(info.drivername);
2542
2543         SAFE_FREE(dbuf.dptr);
2544         *info_ptr=memdup(&info, sizeof(info));
2545
2546         DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
2547                  sharename, info.printername, info.drivername));
2548
2549         return WERR_OK; 
2550 }
2551
2552 /****************************************************************************
2553 debugging function, dump at level 6 the struct in the logs
2554 ****************************************************************************/
2555 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2556 {
2557         uint32 result;
2558         NT_PRINTER_INFO_LEVEL_2 *info2;
2559         
2560         DEBUG(106,("Dumping printer at level [%d]\n", level));
2561         
2562         switch (level)
2563         {
2564                 case 2:
2565                 {
2566                         if (printer.info_2 == NULL)
2567                                 result=5;
2568                         else
2569                         {
2570                                 info2=printer.info_2;
2571                         
2572                                 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
2573                                 DEBUGADD(106,("priority:[%d]\n", info2->priority));
2574                                 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
2575                                 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
2576                                 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
2577                                 DEBUGADD(106,("status:[%d]\n", info2->status));
2578                                 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
2579                                 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
2580                                 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
2581                                 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
2582                                 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
2583
2584                                 DEBUGADD(106,("servername:[%s]\n", info2->servername));
2585                                 DEBUGADD(106,("printername:[%s]\n", info2->printername));
2586                                 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
2587                                 DEBUGADD(106,("portname:[%s]\n", info2->portname));
2588                                 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
2589                                 DEBUGADD(106,("comment:[%s]\n", info2->comment));
2590                                 DEBUGADD(106,("location:[%s]\n", info2->location));
2591                                 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
2592                                 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
2593                                 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
2594                                 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
2595                                 result=0;
2596                         }
2597                         break;
2598                 }
2599                 default:
2600                         DEBUGADD(1,("Level not implemented\n"));
2601                         result=1;
2602                         break;
2603         }
2604         
2605         return result;
2606 }
2607
2608 /****************************************************************************
2609  Get the parameters we can substitute in an NT print job.
2610 ****************************************************************************/
2611
2612 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
2613 {
2614         NT_PRINTER_INFO_LEVEL *printer = NULL;
2615         
2616         **printername = **sharename = **portname = '\0';
2617
2618         if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
2619                 return;
2620
2621         fstrcpy(*printername, printer->info_2->printername);
2622         fstrcpy(*sharename, printer->info_2->sharename);
2623         fstrcpy(*portname, printer->info_2->portname);
2624
2625         free_a_printer(&printer, 2);
2626 }
2627
2628 /*
2629  * The function below are the high level ones.
2630  * only those ones must be called from the spoolss code.
2631  * JFM.
2632  */
2633
2634 /****************************************************************************
2635  Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
2636 ****************************************************************************/
2637
2638 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2639 {
2640         WERROR result;
2641         
2642         dump_a_printer(printer, level); 
2643         
2644         switch (level)
2645         {
2646                 case 2:
2647                 {
2648                         /*
2649                          * Update the changestamp.  Emperical tests show that the
2650                          * ChangeID is always updated,but c_setprinter is only 
2651                          * incremented on a SetPrinter() call.
2652                          */
2653
2654                         time_t time_unix = time(NULL);
2655
2656                         /* ChangeID **must** be increasing over the lifetime
2657                            of client's spoolss service in order for the 
2658                            client's cache to show updates */
2659
2660                         printer.info_2->changeid = time_unix * 100;
2661
2662                         /*
2663                          * Because one day someone will ask:
2664                          * NT->NT       An admin connection to a remote
2665                          *              printer show changes imeediately in
2666                          *              the properities dialog
2667                          *      
2668                          *              A non-admin connection will only show the
2669                          *              changes after viewing the properites page
2670                          *              2 times.  Seems to be related to a
2671                          *              race condition in the client between the spooler
2672                          *              updating the local cache and the Explorer.exe GUI
2673                          *              actually displaying the properties.
2674                          *
2675                          *              This is fixed in Win2k.  admin/non-admin
2676                          *              connections both display changes immediately.
2677                          *
2678                          * 14/12/01     --jerry
2679                          */
2680
2681                         result=update_a_printer_2(printer.info_2);
2682                         break;
2683                 }
2684                 default:
2685                         result=WERR_UNKNOWN_LEVEL;
2686                         break;
2687         }
2688         
2689         return result;
2690 }
2691
2692 /****************************************************************************
2693  Add a printer. This is called from ADDPRINTER(EX) and also SETPRINTER.
2694  We split this out from mod_a_printer as it updates the id's and timestamps.
2695 ****************************************************************************/
2696
2697 WERROR add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2698 {
2699         WERROR result;
2700         
2701         dump_a_printer(printer, level); 
2702         
2703         switch (level)
2704         {
2705                 case 2:
2706                 {
2707                         /*
2708                          * Update the changestamp.  See comments in mod_a_printer()
2709                          * --jerry
2710                          */
2711
2712                         time_t time_unix = time(NULL);
2713
2714                         printer.info_2->changeid = time_unix * 100;
2715                         printer.info_2->c_setprinter++;
2716
2717                         result=update_a_printer_2(printer.info_2);
2718                         break;
2719                 }
2720                 default:
2721                         result=WERR_UNKNOWN_LEVEL;
2722                         break;
2723         }
2724         
2725         return result;
2726 }
2727
2728 /****************************************************************************
2729  Initialize printer devmode & data with previously saved driver init values.
2730 ****************************************************************************/
2731 static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
2732 {
2733         int                     len = 0;
2734         pstring                 key;
2735         TDB_DATA                kbuf, dbuf;
2736         NT_PRINTER_PARAM        *current;
2737         NT_PRINTER_INFO_LEVEL_2 info;
2738
2739         ZERO_STRUCT(info);
2740
2741         slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
2742
2743         kbuf.dptr = key;
2744         kbuf.dsize = strlen(key)+1;
2745
2746         dbuf = tdb_fetch(tdb_drivers, kbuf);
2747         if (!dbuf.dptr)
2748                 return False;
2749
2750         /*
2751          * Get the saved DEVMODE..
2752          */
2753         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2754
2755         /*
2756          * The saved DEVMODE contains the devicename from the printer used during
2757          * the initialization save. Change it to reflect the new printer.
2758          */
2759         ZERO_STRUCT(info.devmode->devicename);
2760         fstrcpy(info.devmode->devicename, info_ptr->printername);
2761
2762         /* 
2763          *      Bind the saved DEVMODE to the new the printer.
2764          */
2765         free_nt_devicemode(&info_ptr->devmode);
2766         info_ptr->devmode = info.devmode;
2767
2768         DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
2769                         info_ptr->printername, info_ptr->drivername));
2770
2771         /* 
2772          * There should not be any printer data 'specifics' already set during the
2773          * add printer operation, if there are delete them. 
2774          */
2775         while ( (current=info_ptr->specific) != NULL ) {
2776                 info_ptr->specific=current->next;
2777                 SAFE_FREE(current->data);
2778                 SAFE_FREE(current);
2779         }
2780
2781         /* 
2782          * Add the printer data 'specifics' to the new printer
2783          */
2784         len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
2785
2786         SAFE_FREE(dbuf.dptr);
2787
2788         return True;    
2789 }
2790
2791 /****************************************************************************
2792  Initialize printer devmode & data with previously saved driver init values.
2793  When a printer is created using AddPrinter, the drivername bound to the
2794  printer is used to lookup previously saved driver initialization info, which
2795  is bound to the new printer.
2796 ****************************************************************************/
2797
2798 uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
2799 {
2800         uint32 result;
2801         
2802         switch (level)
2803         {
2804                 case 2:
2805                 {
2806                         result=set_driver_init_2(printer->info_2);
2807                         break;
2808                 }
2809                 default:
2810                         result=1;
2811                         break;
2812         }
2813         
2814         return result;
2815 }
2816
2817 /****************************************************************************
2818  Pack up the DEVMODE and specifics for a printer into a 'driver init' entry 
2819  in the tdb. Note: this is different from the driver entry and the printer
2820  entry. There should be a single driver init entry for each driver regardless
2821  of whether it was installed from NT or 2K. Technically, they should be
2822  different, but they work out to the same struct.
2823 ****************************************************************************/
2824 static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
2825 {
2826         pstring key;
2827         char *buf;
2828         int buflen, len, ret;
2829         TDB_DATA kbuf, dbuf;
2830
2831         buf = NULL;
2832         buflen = 0;
2833
2834  again: 
2835         len = 0;
2836         len += pack_devicemode(info->devmode, buf+len, buflen-len);
2837
2838         len += pack_specifics(info->specific, buf+len, buflen-len);
2839
2840         if (buflen != len) {
2841                 char *tb;
2842                 
2843                 tb = (char *)Realloc(buf, len);
2844                 if (!tb) {
2845                         DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
2846                         ret = -1;
2847                         goto done;
2848                 }
2849                 else buf = tb;
2850                 buflen = len;
2851                 goto again;
2852         }
2853
2854         slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername);
2855
2856         kbuf.dptr = key;
2857         kbuf.dsize = strlen(key)+1;
2858         dbuf.dptr = buf;
2859         dbuf.dsize = len;
2860
2861         ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
2862
2863 done:
2864         if (ret == -1)
2865                 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
2866
2867         SAFE_FREE(buf);
2868
2869         DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
2870                  info->sharename, info->drivername));
2871
2872         return ret;
2873 }
2874
2875 /****************************************************************************
2876  Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
2877 ****************************************************************************/
2878
2879 static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2880 {
2881         uint32 result;
2882         
2883         dump_a_printer(printer, level); 
2884         
2885         switch (level)
2886         {
2887                 case 2:
2888                 {
2889                         result=update_driver_init_2(printer.info_2);
2890                         break;
2891                 }
2892                 default:
2893                         result=1;
2894                         break;
2895         }
2896         
2897         return result;
2898 }
2899
2900 /****************************************************************************
2901  Convert the printer data value, a REG_BINARY array, into an initialization 
2902  DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
2903  got to keep the endians happy :).
2904 ****************************************************************************/
2905
2906 static BOOL convert_driver_init(NT_PRINTER_PARAM *param, TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode)
2907 {
2908         BOOL       result = False;
2909         prs_struct ps;
2910         DEVICEMODE devmode;
2911
2912         ZERO_STRUCT(devmode);
2913
2914         prs_init(&ps, 0, ctx, UNMARSHALL);
2915         ps.data_p      = (char *)param->data;
2916         ps.buffer_size = param->data_len;
2917
2918         if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
2919                 result = convert_devicemode("", &devmode, &nt_devmode);
2920         else
2921                 DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
2922
2923         return result;
2924 }
2925
2926 /****************************************************************************
2927  Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
2928
2929  1. Use the driver's config DLL to this UNC printername and:
2930     a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
2931     b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
2932  2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
2933
2934  The last step triggers saving the "driver initialization" information for
2935  this printer into the tdb. Later, new printers that use this driver will
2936  have this initialization information bound to them. This simulates the
2937  driver initialization, as if it had run on the Samba server (as it would
2938  have done on NT).
2939
2940  The Win32 client side code requirement sucks! But until we can run arbitrary
2941  Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
2942  
2943  It would have been easier to use SetPrinter because all the UNMARSHALLING of
2944  the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
2945  about it and you will realize why.  JRR 010720
2946 ****************************************************************************/
2947
2948 static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARAM *param)
2949 {
2950         WERROR        status       = WERR_OK;
2951         TALLOC_CTX    *ctx         = NULL;
2952         NT_DEVICEMODE *nt_devmode  = NULL;
2953         NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
2954         
2955         /*
2956          * Set devmode on printer info, so entire printer initialization can be 
2957          * saved to tdb.
2958          */
2959         if ((ctx = talloc_init()) == NULL)
2960                 return WERR_NOMEM;
2961
2962         if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) {
2963                 status = WERR_NOMEM;
2964                 goto done;
2965         }
2966         
2967         ZERO_STRUCTP(nt_devmode);
2968
2969         /*
2970          * The DEVMODE is held in the 'data' component of the param in raw binary.
2971          * Convert it to to a devmode structure
2972          */
2973         if (!convert_driver_init(param, ctx, nt_devmode)) {
2974                 DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
2975                 status = WERR_INVALID_PARAM;
2976                 goto done;
2977         }
2978
2979         /*
2980          * Pack up and add (or update) the DEVMODE and any current printer data to
2981          * a 'driver init' element in the tdb
2982          * 
2983          */
2984         printer->info_2->devmode = nt_devmode;
2985         if (update_driver_init(*printer, 2)!=0) {
2986                 DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
2987                 status = WERR_NOMEM;
2988                 goto done;
2989         }
2990         
2991         /*
2992          * If driver initialization info was successfully saved, set the current 
2993          * printer to match it. This allows initialization of the current printer 
2994          * as well as the driver.
2995          */
2996         status = mod_a_printer(*printer, 2);
2997         if (!W_ERROR_IS_OK(status)) {
2998                 DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
2999                                   printer->info_2->printername));
3000         }
3001
3002   done:
3003         talloc_destroy(ctx);
3004         if (nt_devmode)
3005                 SAFE_FREE(nt_devmode->private);
3006         SAFE_FREE(nt_devmode);
3007         printer->info_2->devmode = tmp_devmode;
3008
3009         return status;
3010 }
3011
3012 /****************************************************************************
3013  Update the driver init info (DEVMODE and specifics) for a printer
3014 ****************************************************************************/
3015
3016 WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param)
3017 {
3018         WERROR status = WERR_OK;
3019         
3020         switch (level)
3021         {
3022                 case 2:
3023                 {
3024                         status=save_driver_init_2(printer, param);
3025                         break;
3026                 }
3027                 default:
3028                         status=WERR_UNKNOWN_LEVEL;
3029                         break;
3030         }
3031         
3032         return status;
3033 }
3034
3035 /****************************************************************************
3036  Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
3037 ****************************************************************************/
3038
3039 WERROR get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
3040 {
3041         WERROR result;
3042         NT_PRINTER_INFO_LEVEL *printer = NULL;
3043         
3044         *pp_printer = NULL;
3045
3046         DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
3047
3048         switch (level)
3049         {
3050                 case 2:
3051                 {
3052                         if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
3053                                 DEBUG(0,("get_a_printer: malloc fail.\n"));
3054                                 return WERR_NOMEM;
3055                         }
3056                         ZERO_STRUCTP(printer);
3057                         result=get_a_printer_2(&printer->info_2, sharename);
3058                         if (W_ERROR_IS_OK(result)) {
3059                                 dump_a_printer(*printer, level);
3060                                 *pp_printer = printer;
3061                         } else {
3062                                 SAFE_FREE(printer);
3063                         }
3064                         break;
3065                 }
3066                 default:
3067                         result=WERR_UNKNOWN_LEVEL;
3068                         break;
3069         }
3070         
3071         DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", sharename, (unsigned int)level, werror_str(result)));
3072
3073         return result;
3074 }
3075
3076 /****************************************************************************
3077  Deletes a NT_PRINTER_INFO_LEVEL struct.
3078 ****************************************************************************/
3079
3080 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
3081 {
3082         uint32 result;
3083         NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
3084
3085         DEBUG(104,("freeing a printer at level [%d]\n", level));
3086
3087         if (printer == NULL)
3088                 return 0;
3089         
3090         switch (level)
3091         {
3092                 case 2:
3093                 {
3094                         if (printer->info_2 != NULL)
3095                         {
3096                                 free_nt_printer_info_level_2(&printer->info_2);
3097                                 result=0;
3098                         }
3099                         else
3100                         {
3101                                 result=4;
3102                         }
3103                         break;
3104                 }
3105                 default:
3106                         result=1;
3107                         break;
3108         }
3109
3110         SAFE_FREE(*pp_printer);
3111         return result;
3112 }
3113
3114 /****************************************************************************
3115 ****************************************************************************/
3116 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
3117 {
3118         uint32 result;
3119         DEBUG(104,("adding a printer at level [%d]\n", level));
3120         dump_a_printer_driver(driver, level);
3121         
3122         switch (level)
3123         {
3124                 case 3:
3125                 {
3126                         result=add_a_printer_driver_3(driver.info_3);
3127                         break;
3128                 }
3129
3130                 case 6:
3131                 {
3132                         result=add_a_printer_driver_6(driver.info_6);
3133                         break;
3134                 }
3135                 default:
3136                         result=1;
3137                         break;
3138         }
3139         
3140         return result;
3141 }
3142 /****************************************************************************
3143 ****************************************************************************/
3144 WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
3145                             fstring printername, fstring architecture, uint32 version)
3146 {
3147         WERROR result;
3148         
3149         switch (level)
3150         {
3151                 case 3:
3152                 {
3153                         result=get_a_printer_driver_3(&driver->info_3, printername, architecture, version);
3154                         break;
3155                 }
3156                 default:
3157                         result=W_ERROR(1);
3158                         break;
3159         }
3160         
3161         if (W_ERROR_IS_OK(result))
3162                 dump_a_printer_driver(*driver, level);
3163         return result;
3164 }
3165
3166 /****************************************************************************
3167 ****************************************************************************/
3168 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
3169 {
3170         uint32 result;
3171         
3172         switch (level)
3173         {
3174                 case 3:
3175                 {
3176                         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
3177                         if (driver.info_3 != NULL)
3178                         {
3179                                 info3=driver.info_3;
3180                                 SAFE_FREE(info3->dependentfiles);
3181                                 ZERO_STRUCTP(info3);
3182                                 SAFE_FREE(info3);
3183                                 result=0;
3184                         }
3185                         else
3186                         {
3187                                 result=4;
3188                         }
3189                         break;
3190                 }
3191                 case 6:
3192                 {
3193                         NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
3194                         if (driver.info_6 != NULL)
3195                         {
3196                                 info6=driver.info_6;
3197                                 SAFE_FREE(info6->dependentfiles);
3198                                 SAFE_FREE(info6->previousnames);
3199                                 ZERO_STRUCTP(info6);
3200                                 SAFE_FREE(info6);
3201                                 result=0;
3202                         }
3203                         else
3204                         {
3205                                 result=4;
3206                         }
3207                         break;
3208                 }
3209                 default:
3210                         result=1;
3211                         break;
3212         }
3213         return result;
3214 }
3215
3216
3217 /****************************************************************************
3218   Determine whether or not a particular driver is currently assigned
3219   to a printer
3220 ****************************************************************************/
3221 BOOL printer_driver_in_use (char *arch, char *driver)
3222 {
3223         TDB_DATA kbuf, newkey, dbuf;
3224         NT_PRINTER_INFO_LEVEL_2 info;
3225         int ret;
3226
3227         if (!tdb_printers)
3228                 if (!nt_printing_init())
3229                         return False;
3230
3231         DEBUG(5,("printer_driver_in_use: Beginning search through printers.tdb...\n"));
3232         
3233         /* loop through the printers.tdb and check for the drivername */
3234         for (kbuf = tdb_firstkey(tdb_printers); kbuf.dptr;
3235              newkey = tdb_nextkey(tdb_printers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) 
3236         {
3237
3238                 dbuf = tdb_fetch(tdb_printers, kbuf);
3239                 if (!dbuf.dptr) 
3240                         continue;
3241
3242                 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) != 0) 
3243                         continue;
3244
3245                 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddddddfffffPfffff",
3246                         &info.attributes,
3247                         &info.priority,
3248                         &info.default_priority,
3249                         &info.starttime,
3250                         &info.untiltime,
3251                         &info.status,
3252                         &info.cjobs,
3253                         &info.averageppm,
3254                         &info.changeid,
3255                         &info.c_setprinter,
3256                         &info.setuptime,
3257                         info.servername,
3258                         info.printername,
3259                         info.sharename,
3260                         info.portname,
3261                         info.drivername,
3262                         info.comment,
3263                         info.location,
3264                         info.sepfile,
3265                         info.printprocessor,
3266                         info.datatype,
3267                         info.parameters);
3268
3269                 SAFE_FREE(dbuf.dptr);
3270
3271                 if (ret == -1) {
3272                         DEBUG (0,("printer_driver_in_use: tdb_unpack failed for printer %s\n",
3273                                         info.printername));
3274                         continue;
3275                 }
3276                 
3277                 DEBUG (10,("printer_driver_in_use: Printer - %s (%s)\n",
3278                         info.printername, info.drivername));
3279                         
3280                 if (strcmp(info.drivername, driver) == 0) 
3281                 {
3282                         DEBUG(5,("printer_driver_in_use: Printer %s using %s\n",
3283                                 info.printername, driver));
3284                         return True;
3285                 }       
3286         }
3287         DEBUG(5,("printer_driver_in_use: Completed search through printers.tdb...\n"));
3288         
3289         
3290         
3291         /* report that the driver is in use by default */
3292         return False;
3293 }
3294
3295 /****************************************************************************
3296  Remove a printer driver from the TDB.  This assumes that the the driver was
3297  previously looked up.
3298  ***************************************************************************/
3299 WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i)
3300 {
3301         pstring         key;
3302         fstring         arch;
3303         TDB_DATA        kbuf;
3304
3305
3306         get_short_archi(arch, i->environment);
3307         slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
3308                 arch, i->cversion, i->name); 
3309         DEBUG(5,("delete_printer_driver: key = [%s]\n", key));
3310
3311         kbuf.dptr=key;
3312         kbuf.dsize=strlen(key)+1;
3313
3314         if (tdb_delete(tdb_drivers, kbuf) == -1) {
3315                 DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
3316                 return WERR_ACCESS_DENIED;
3317         }
3318         
3319         DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
3320                 i->name));
3321         
3322         return WERR_OK;
3323 }
3324 /****************************************************************************
3325 ****************************************************************************/
3326 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
3327                                  fstring value, uint8 **data, uint32 *type, uint32 *len)
3328 {
3329         /* right now that's enough ! */ 
3330         NT_PRINTER_PARAM *param;
3331         int i=0;
3332         
3333         param=printer.info_2->specific;
3334         
3335         while (param != NULL && i < param_index) {
3336                 param=param->next;
3337                 i++;
3338         }
3339         
3340         if (param == NULL)
3341                 return False;
3342
3343         /* exited because it exist */
3344         *type=param->type;              
3345         StrnCpy(value, param->value, sizeof(fstring)-1);
3346         *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
3347         if(*data == NULL)
3348                 return False;
3349         ZERO_STRUCTP(*data);
3350         memcpy(*data, param->data, param->data_len);
3351         *len=param->data_len;
3352         return True;
3353 }
3354
3355 /****************************************************************************
3356 ****************************************************************************/
3357 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
3358                         fstring value, uint8 **data, uint32 *type, uint32 *len)
3359 {
3360         /* right now that's enough ! */ 
3361         NT_PRINTER_PARAM *param;
3362         
3363         DEBUG(10, ("get_specific_param\n"));
3364         
3365         param=printer.info_2->specific;
3366                 
3367         while (param != NULL)
3368         {
3369 #if 1 /* JRA - I think this should be case insensitive.... */
3370                 if ( strequal(value, param->value)
3371 #else
3372                 if ( !strcmp(value, param->value)
3373 #endif
3374                     && strlen(value)==strlen(param->value))
3375                         break;
3376                         
3377                 param=param->next;
3378         }
3379         
3380         if (param != NULL)
3381         {
3382         DEBUGADD(10, ("get_specific_param: found one param\n"));
3383                 /* exited because it exist */
3384                 *type=param->type;      
3385                 
3386                 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
3387                 if(*data == NULL)
3388                         return False;
3389                 memcpy(*data, param->data, param->data_len);
3390                 *len=param->data_len;
3391
3392                 DEBUGADD(10, ("get_specific_param: exit true\n"));
3393                 return (True);
3394         }
3395         DEBUGADD(10, ("get_specific_param: exit false\n"));
3396         return (False);
3397 }
3398
3399 /****************************************************************************
3400  Store a security desc for a printer.
3401 ****************************************************************************/
3402
3403 WERROR nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
3404 {
3405         SEC_DESC_BUF *new_secdesc_ctr = NULL;
3406         SEC_DESC_BUF *old_secdesc_ctr = NULL;
3407         prs_struct ps;
3408         TALLOC_CTX *mem_ctx = NULL;
3409         fstring key;
3410         WERROR status;
3411
3412         mem_ctx = talloc_init();
3413         if (mem_ctx == NULL)
3414                 return WERR_NOMEM;
3415
3416         /* The old owner and group sids of the security descriptor are not
3417            present when new ACEs are added or removed by changing printer
3418            permissions through NT.  If they are NULL in the new security
3419            descriptor then copy them over from the old one. */
3420
3421         if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
3422                 DOM_SID *owner_sid, *group_sid;
3423                 SEC_ACL *dacl, *sacl;
3424                 SEC_DESC *psd = NULL;
3425                 size_t size;
3426
3427                 nt_printing_getsec(mem_ctx, printername, &old_secdesc_ctr);
3428
3429                 /* Pick out correct owner and group sids */
3430
3431                 owner_sid = secdesc_ctr->sec->owner_sid ?
3432                         secdesc_ctr->sec->owner_sid :
3433                         old_secdesc_ctr->sec->owner_sid;
3434
3435                 group_sid = secdesc_ctr->sec->grp_sid ?
3436                         secdesc_ctr->sec->grp_sid :
3437                         old_secdesc_ctr->sec->grp_sid;
3438
3439                 dacl = secdesc_ctr->sec->dacl ?
3440                         secdesc_ctr->sec->dacl :
3441                         old_secdesc_ctr->sec->dacl;
3442
3443                 sacl = secdesc_ctr->sec->sacl ?
3444                         secdesc_ctr->sec->sacl :
3445                         old_secdesc_ctr->sec->sacl;
3446
3447                 /* Make a deep copy of the security descriptor */
3448
3449                 psd = make_sec_desc(mem_ctx, secdesc_ctr->sec->revision,
3450                                     owner_sid, group_sid,
3451                                     sacl,
3452                                     dacl,
3453                                     &size);
3454
3455                 new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);
3456         }
3457
3458         if (!new_secdesc_ctr) {
3459                 new_secdesc_ctr = secdesc_ctr;
3460         }
3461
3462         /* Store the security descriptor in a tdb */
3463
3464         prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
3465                  sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
3466
3467         if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
3468                              &ps, 1)) {
3469                 status = WERR_BADFUNC;
3470                 goto out;
3471         }
3472
3473         slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
3474
3475         if (tdb_prs_store(tdb_printers, key, &ps)==0) {
3476                 status = WERR_OK;
3477         } else {
3478                 DEBUG(1,("Failed to store secdesc for %s\n", printername));
3479                 status = WERR_BADFUNC;
3480         }
3481
3482         /* Free malloc'ed memory */
3483
3484  out:
3485
3486         prs_mem_free(&ps);
3487         if (mem_ctx)
3488                 talloc_destroy(mem_ctx);
3489         return status;
3490 }
3491
3492 /****************************************************************************
3493  Construct a default security descriptor buffer for a printer.
3494 ****************************************************************************/
3495
3496 static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
3497 {
3498         SEC_ACE ace[3];
3499         SEC_ACCESS sa;
3500         SEC_ACL *psa = NULL;
3501         SEC_DESC_BUF *sdb = NULL;
3502         SEC_DESC *psd = NULL;
3503         DOM_SID owner_sid;
3504         size_t sd_size;
3505         enum SID_NAME_USE name_type;
3506
3507         /* Create an ACE where Everyone is allowed to print */
3508
3509         init_sec_access(&sa, PRINTER_ACE_PRINT);
3510         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
3511                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
3512
3513         /* Make the security descriptor owned by the Administrators group
3514            on the PDC of the domain. */
3515
3516         if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
3517                 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
3518         } else {
3519                 uint32 owner_rid;
3520
3521                 /* Backup plan - make printer owned by admins or root.
3522                    This should emulate a lanman printer as security
3523                    settings can't be changed. */
3524
3525                 sid_peek_rid(&owner_sid, &owner_rid);
3526
3527                 if (owner_rid != BUILTIN_ALIAS_RID_PRINT_OPS &&
3528                     owner_rid != BUILTIN_ALIAS_RID_ADMINS &&
3529                     owner_rid != DOMAIN_USER_RID_ADMIN &&
3530                     !lookup_name("root", &owner_sid, &name_type)) {
3531                         sid_copy(&owner_sid, &global_sid_World);
3532                 }
3533         }
3534
3535         init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
3536         init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
3537                      sa, SEC_ACE_FLAG_OBJECT_INHERIT |
3538                      SEC_ACE_FLAG_INHERIT_ONLY);
3539
3540         init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
3541         init_sec_ace(&ace[2], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
3542                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
3543
3544         /* The ACL revision number in rpc_secdesc.h differs from the one
3545            created by NT when setting ACE entries in printer
3546            descriptors.  NT4 complains about the property being edited by a
3547            NT5 machine. */
3548
3549         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) != NULL) {
3550                 psd = make_sec_desc(ctx, SEC_DESC_REVISION,
3551                                     &owner_sid,&nb