2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000.
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.
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.
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.
25 extern pstring global_myname;
26 extern DOM_SID global_sid_World;
28 static TDB_CONTEXT *tdb_forms; /* used for forms files */
29 static TDB_CONTEXT *tdb_drivers; /* used for driver files */
30 static TDB_CONTEXT *tdb_printers; /* used for printers files */
32 #define FORMS_PREFIX "FORMS/"
33 #define DRIVERS_PREFIX "DRIVERS/"
34 #define DRIVER_INIT_PREFIX "DRIVER_INIT/"
35 #define PRINTERS_PREFIX "PRINTERS/"
36 #define SECDESC_PREFIX "SECDESC/"
38 #define NTDRIVERS_DATABASE_VERSION_1 1
39 #define NTDRIVERS_DATABASE_VERSION_2 2
41 #define NTDRIVERS_DATABASE_VERSION NTDRIVERS_DATABASE_VERSION_2
43 /* Map generic permissions to printer object specific permissions */
45 struct generic_mapping printer_generic_mapping = {
52 /* We need one default form to support our default printer. Msoft adds the
53 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
54 array index). Letter is always first, so (for the current code) additions
55 always put things in the correct order. */
56 static nt_forms_struct default_forms[] = {
57 {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
58 {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
59 {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
60 {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
61 {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
62 {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
63 {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
64 {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
65 {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
66 {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
67 {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
68 {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
69 {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
70 {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
71 {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
72 {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
73 {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
74 {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
75 {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
76 {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
77 {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
78 {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
79 {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
80 {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
81 {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
82 {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
83 {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
84 {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
85 {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
86 {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
87 {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
88 {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
89 {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
90 {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
91 {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
92 {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
93 {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
94 {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
95 {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
96 {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
97 {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
98 {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
99 {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
100 {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
101 {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
102 {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
103 {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
104 {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
105 {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
106 {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
107 {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
108 {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
109 {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
110 {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
111 {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
112 {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
113 {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
114 {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
115 {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
116 {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
117 {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
118 {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
119 {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
120 {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
121 {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
122 {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
123 {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
124 {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
125 {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
126 {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
127 {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
128 {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
129 {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
130 {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
131 {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
132 {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
133 {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
134 {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
135 {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
136 {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
137 {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
138 {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
139 {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
140 {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
141 {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
142 {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
143 {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
144 {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
145 {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
146 {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
147 {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
148 {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
149 {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
150 {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
151 {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
152 {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
153 {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
154 {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
155 {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
156 {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
157 {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
158 {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
159 {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
160 {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
161 {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
162 {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
163 {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
164 {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
165 {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
166 {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
167 {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
168 {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
169 {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
170 {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
171 {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
172 {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
173 {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
174 {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
177 static BOOL upgrade_to_version_2(void)
179 TDB_DATA kbuf, newkey, dbuf;
181 DEBUG(0,("upgrade_to_version_2: upgrading print tdb's to version 2\n"));
183 for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
184 newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
186 dbuf = tdb_fetch(tdb_drivers, kbuf);
188 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
189 DEBUG(0,("upgrade_to_version_2:moving form\n"));
190 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
191 DEBUG(0,("upgrade_to_version_2: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
194 if (tdb_delete(tdb_drivers, kbuf) != 0) {
195 DEBUG(0,("upgrade_to_version_2: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
200 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
201 DEBUG(0,("upgrade_to_version_2:moving printer\n"));
202 if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
203 DEBUG(0,("upgrade_to_version_2: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
206 if (tdb_delete(tdb_drivers, kbuf) != 0) {
207 DEBUG(0,("upgrade_to_version_2: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
212 if (strncmp(kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
213 DEBUG(0,("upgrade_to_version_2:moving secdesc\n"));
214 if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
215 DEBUG(0,("upgrade_to_version_2: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
218 if (tdb_delete(tdb_drivers, kbuf) != 0) {
219 DEBUG(0,("upgrade_to_version_2: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
224 SAFE_FREE(dbuf.dptr);
230 /****************************************************************************
231 open the NT printing tdb
232 ****************************************************************************/
233 BOOL nt_printing_init(void)
235 static pid_t local_pid;
236 char *vstring = "INFO/version";
238 if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
241 tdb_drivers = tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
243 DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
244 lock_path("ntdrivers.tdb"), strerror(errno) ));
248 tdb_printers = tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
250 DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
251 lock_path("ntprinters.tdb"), strerror(errno) ));
255 tdb_forms = tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
257 DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
258 lock_path("ntforms.tdb"), strerror(errno) ));
262 local_pid = sys_getpid();
264 /* handle a Samba upgrade */
265 tdb_lock_bystring(tdb_drivers, vstring);
266 if (tdb_fetch_int(tdb_drivers, vstring) != NTDRIVERS_DATABASE_VERSION) {
268 if (tdb_fetch_int(tdb_drivers, vstring) == NTDRIVERS_DATABASE_VERSION_1) {
269 if (!upgrade_to_version_2())
272 tdb_traverse(tdb_drivers, (tdb_traverse_func)tdb_delete, NULL);
274 tdb_store_int(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
276 tdb_unlock_bystring(tdb_drivers, vstring);
281 /****************************************************************************
282 get builtin form struct list
283 ****************************************************************************/
284 int get_builtin_ntforms(nt_forms_struct **list)
286 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
287 return sizeof(default_forms) / sizeof(default_forms[0]);
290 /****************************************************************************
291 get a builtin form struct
292 ****************************************************************************/
294 BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
298 unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
299 DEBUGADD(6,("Looking for builtin form %s \n", form_name));
300 count = sizeof(default_forms) / sizeof(default_forms[0]);
301 for (i=0;i<count;i++) {
302 if (strequal(form_name,default_forms[i].name)) {
303 DEBUGADD(6,("Found builtin form %s \n", form_name));
304 memcpy(form,&default_forms[i],sizeof(*form));
312 /****************************************************************************
313 get a form struct list
314 ****************************************************************************/
315 int get_ntforms(nt_forms_struct **list)
317 TDB_DATA kbuf, newkey, dbuf;
319 nt_forms_struct form;
324 for (kbuf = tdb_firstkey(tdb_forms);
326 newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
327 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
329 dbuf = tdb_fetch(tdb_forms, kbuf);
330 if (!dbuf.dptr) continue;
332 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
333 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
334 &i, &form.flag, &form.width, &form.length, &form.left,
335 &form.top, &form.right, &form.bottom);
336 SAFE_FREE(dbuf.dptr);
337 if (ret != dbuf.dsize) continue;
339 tl = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
341 DEBUG(0,("get_ntforms: Realloc fail.\n"));
353 /****************************************************************************
354 write a form struct list
355 ****************************************************************************/
356 int write_ntforms(nt_forms_struct **list, int number)
363 for (i=0;i<number;i++) {
364 /* save index, so list is rebuilt in correct order */
365 len = tdb_pack(buf, sizeof(buf), "dddddddd",
366 i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
367 (*list)[i].left, (*list)[i].top, (*list)[i].right,
369 if (len > sizeof(buf)) break;
370 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name);
371 kbuf.dsize = strlen(key)+1;
375 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) break;
381 /****************************************************************************
382 add a form struct at the end of the list
383 ****************************************************************************/
384 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
392 * NT tries to add forms even when
393 * they are already in the base
394 * only update the values if already present
399 unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
400 for (n=0; n<*count; n++) {
401 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
402 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
409 if((tl=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL) {
410 DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
414 unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
418 (*list)[n].flag=form->flags;
419 (*list)[n].width=form->size_x;
420 (*list)[n].length=form->size_y;
421 (*list)[n].left=form->left;
422 (*list)[n].top=form->top;
423 (*list)[n].right=form->right;
424 (*list)[n].bottom=form->bottom;
429 /****************************************************************************
430 delete a named form struct
431 ****************************************************************************/
432 BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
441 unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
443 for (n=0; n<*count; n++) {
444 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
445 DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
451 DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
452 *ret = WERR_INVALID_PARAM;
456 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);
457 kbuf.dsize = strlen(key)+1;
459 if (tdb_delete(tdb_forms, kbuf) != 0) {
467 /****************************************************************************
469 ****************************************************************************/
470 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
474 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
476 DEBUG(106, ("[%s]\n", form_name));
477 for (n=0; n<count; n++)
479 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
480 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
484 if (n==count) return;
486 (*list)[n].flag=form->flags;
487 (*list)[n].width=form->size_x;
488 (*list)[n].length=form->size_y;
489 (*list)[n].left=form->left;
490 (*list)[n].top=form->top;
491 (*list)[n].right=form->right;
492 (*list)[n].bottom=form->bottom;
495 /****************************************************************************
496 get the nt drivers list
498 traverse the database and look-up the matching names
499 ****************************************************************************/
500 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
506 TDB_DATA kbuf, newkey;
508 get_short_archi(short_archi, architecture);
509 slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
511 for (kbuf = tdb_firstkey(tdb_drivers);
513 newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
514 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
516 if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
517 DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
522 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
529 /****************************************************************************
530 function to do the mapping between the long architecture name and
532 ****************************************************************************/
533 BOOL get_short_archi(char *short_archi, char *long_archi)
540 struct table archi_table[]=
542 {"Windows 4.0", "WIN40" },
543 {"Windows NT x86", "W32X86" },
544 {"Windows NT R4000", "W32MIPS" },
545 {"Windows NT Alpha_AXP", "W32ALPHA" },
546 {"Windows NT PowerPC", "W32PPC" },
552 DEBUG(107,("Getting architecture dependant directory\n"));
555 } while ( (archi_table[i].long_archi!=NULL ) &&
556 StrCaseCmp(long_archi, archi_table[i].long_archi) );
558 if (archi_table[i].long_archi==NULL) {
559 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
563 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
565 DEBUGADD(108,("index: [%d]\n", i));
566 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
567 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
572 /****************************************************************************
573 Version information in Microsoft files is held in a VS_VERSION_INFO structure.
574 There are two case to be covered here: PE (Portable Executable) and NE (New
575 Executable) files. Both files support the same INFO structure, but PE files
576 store the signature in unicode, and NE files store it as !unicode.
577 ****************************************************************************/
578 static BOOL get_file_version(files_struct *fsp, char *fname,uint32 *major,
585 if ((buf=malloc(PE_HEADER_SIZE)) == NULL) {
586 DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
587 fname, PE_HEADER_SIZE));
591 /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
592 if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
593 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
595 goto no_version_info;
598 /* Is this really a DOS header? */
599 if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
600 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
601 fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
602 goto no_version_info;
605 /* Skip OEM header (if any) and the DOS stub to start of Windows header */
606 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
607 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
609 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
610 goto no_version_info;
613 if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
614 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
616 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
617 goto no_version_info;
620 /* The header may be a PE (Portable Executable) or an NE (New Executable) */
621 if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
623 int section_table_bytes;
625 if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {
626 DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
627 fname, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
628 /* At this point, we assume the file is in error. It still could be somthing
629 * else besides a PE file, but it unlikely at this point.
634 /* get the section table */
635 num_sections = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
636 section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
638 if ((buf=malloc(section_table_bytes)) == NULL) {
639 DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
640 fname, section_table_bytes));
644 if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
645 DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
650 /* Iterate the section table looking for the resource section ".rsrc" */
651 for (i = 0; i < num_sections; i++) {
652 int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
654 if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
655 int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
656 int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
659 if ((buf=malloc(section_bytes)) == NULL) {
660 DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
661 fname, section_bytes));
665 /* Seek to the start of the .rsrc section info */
666 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
667 DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
672 if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
673 DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
678 for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
679 /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
680 if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
681 /* Align to next long address */
682 int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;
684 if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
685 *major = IVAL(buf,pos+VS_MAJOR_OFFSET);
686 *minor = IVAL(buf,pos+VS_MINOR_OFFSET);
688 DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
689 fname, *major, *minor,
690 (*major>>16)&0xffff, *major&0xffff,
691 (*minor>>16)&0xffff, *minor&0xffff));
700 /* Version info not found, fall back to origin date/time */
701 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
705 } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
706 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
707 DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
708 fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
709 /* At this point, we assume the file is in error. It still could be somthing
710 * else besides a NE file, but it unlikely at this point. */
714 /* Allocate a bit more space to speed up things */
716 if ((buf=malloc(VS_NE_BUF_SIZE)) == NULL) {
717 DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes = %d\n",
718 fname, PE_HEADER_SIZE));
722 /* This is a HACK! I got tired of trying to sort through the messy
723 * 'NE' file format. If anyone wants to clean this up please have at
724 * it, but this works. 'NE' files will eventually fade away. JRR */
725 while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {
726 /* Cover case that should not occur in a well formed 'NE' .dll file */
727 if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;
729 for(i=0; i<byte_count; i++) {
730 /* Fast skip past data that can't possibly match */
731 if (buf[i] != 'V') continue;
733 /* Potential match data crosses buf boundry, move it to beginning
734 * of buf, and fill the buf with as much as it will hold. */
735 if (i>byte_count-VS_VERSION_INFO_SIZE) {
738 memcpy(buf, &buf[i], byte_count-i);
739 if ((bc = vfs_read_data(fsp, &buf[byte_count-i], VS_NE_BUF_SIZE-
740 (byte_count-i))) < 0) {
742 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
747 byte_count = bc + (byte_count - i);
748 if (byte_count<VS_VERSION_INFO_SIZE) break;
753 /* Check that the full signature string and the magic number that
754 * follows exist (not a perfect solution, but the chances that this
755 * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
756 * twice, as it is simpler to read the code. */
757 if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
758 /* Compute skip alignment to next long address */
759 int skip = -(fsp->conn->vfs_ops.lseek(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
760 sizeof(VS_SIGNATURE)) & 3;
761 if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
763 *major = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MAJOR_OFFSET);
764 *minor = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MINOR_OFFSET);
765 DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
766 fname, *major, *minor,
767 (*major>>16)&0xffff, *major&0xffff,
768 (*minor>>16)&0xffff, *minor&0xffff));
775 /* Version info not found, fall back to origin date/time */
776 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
781 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
782 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
783 fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
794 /****************************************************************************
795 Drivers for Microsoft systems contain multiple files. Often, multiple drivers
796 share one or more files. During the MS installation process files are checked
797 to insure that only a newer version of a shared file is installed over an
798 older version. There are several possibilities for this comparison. If there
799 is no previous version, the new one is newer (obviously). If either file is
800 missing the version info structure, compare the creation date (on Unix use
801 the modification date). Otherwise chose the numerically larger version number.
802 ****************************************************************************/
803 static int file_version_is_newer(connection_struct *conn, fstring new_file,
806 BOOL use_version = True;
811 time_t new_create_time;
815 time_t old_create_time;
819 files_struct *fsp = NULL;
821 SMB_STRUCT_STAT stat_buf;
825 ZERO_STRUCT(stat_buf);
826 new_create_time = (time_t)0;
827 old_create_time = (time_t)0;
829 /* Get file version info (if available) for previous file (if it exists) */
830 pstrcpy(filepath, old_file);
832 unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
834 fsp = open_file_shared(conn, filepath, &stat_buf,
835 SET_OPEN_MODE(DOS_OPEN_RDONLY),
836 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
837 0, 0, &access_mode, &action);
839 /* Old file not found, so by definition new file is in fact newer */
840 DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
845 int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
846 if (ret == -1) goto error_exit;
849 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
852 if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
853 old_create_time = st.st_mtime;
854 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
857 close_file(fsp, True);
859 /* Get file version info (if available) for new file */
860 pstrcpy(filepath, new_file);
861 unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
863 fsp = open_file_shared(conn, filepath, &stat_buf,
864 SET_OPEN_MODE(DOS_OPEN_RDONLY),
865 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
866 0, 0, &access_mode, &action);
868 /* New file not found, this shouldn't occur if the caller did its job */
869 DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
874 int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
875 if (ret == -1) goto error_exit;
878 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
881 if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
882 new_create_time = st.st_mtime;
883 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
886 close_file(fsp, True);
889 /* Compare versions and choose the larger version number */
890 if (new_major > old_major ||
891 (new_major == old_major && new_minor > old_minor)) {
893 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
897 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
902 /* Compare modification time/dates and choose the newest time/date */
903 if (new_create_time > old_create_time) {
904 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
908 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
915 close_file(fsp, True);
919 /****************************************************************************
920 Determine the correct cVersion associated with an architecture and driver
921 ****************************************************************************/
922 static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
923 struct current_user *user, WERROR *perr)
931 files_struct *fsp = NULL;
934 connection_struct *conn;
938 /* If architecture is Windows 95/98/ME, the version is always 0. */
939 if (strcmp(architecture, "WIN40") == 0) {
940 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
944 /* connect to the print$ share under the same account as the user connected to the rpc pipe */
945 /* Null password is ok - we are already an authenticated user... */
946 null_pw = data_blob(NULL, 0);
949 conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
953 DEBUG(0,("get_correct_cversion: Unable to connect\n"));
954 *perr = ntstatus_to_werror(nt_status);
958 /* We are temporarily becoming the connection user. */
959 if (!become_user(conn, conn->vuid)) {
960 DEBUG(0,("get_correct_cversion: Can't become user!\n"));
961 *perr = WERR_ACCESS_DENIED;
965 /* Open the driver file (Portable Executable format) and determine the
966 * deriver the cversion. */
967 slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
969 unix_convert(driverpath,conn,NULL,&bad_path,&st);
971 fsp = open_file_shared(conn, driverpath, &st,
972 SET_OPEN_MODE(DOS_OPEN_RDONLY),
973 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
974 0, 0, &access_mode, &action);
976 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
978 *perr = WERR_ACCESS_DENIED;
984 int ret = get_file_version(fsp, driverpath, &major, &minor);
985 if (ret == -1) goto error_exit;
988 DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath));
993 * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
994 * for more details. Version in this case is not just the version of the
995 * file, but the version in the sense of kernal mode (2) vs. user mode
996 * (3) drivers. Other bits of the version fields are the version info.
999 cversion = major & 0x0000ffff;
1001 case 2: /* WinNT drivers */
1002 case 3: /* Win2K drivers */
1006 DEBUG(6,("get_correct_cversion: cversion invalid [%s] cversion = %d\n",
1007 driverpath, cversion));
1011 DEBUG(10,("get_correct_cversion: Version info found [%s] major = 0x%x minor = 0x%x\n",
1012 driverpath, major, minor));
1015 DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
1016 driverpath, cversion));
1018 close_file(fsp, True);
1019 close_cnum(conn, user->vuid);
1026 close_file(fsp, True);
1028 close_cnum(conn, user->vuid);
1033 /****************************************************************************
1034 ****************************************************************************/
1035 static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
1036 struct current_user *user)
1038 fstring architecture;
1044 /* clean up the driver name.
1045 * we can get .\driver.dll
1046 * or worse c:\windows\system\driver.dll !
1048 /* using an intermediate string to not have overlaping memcpy()'s */
1049 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1050 fstrcpy(new_name, p+1);
1051 fstrcpy(driver->driverpath, new_name);
1054 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1055 fstrcpy(new_name, p+1);
1056 fstrcpy(driver->datafile, new_name);
1059 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1060 fstrcpy(new_name, p+1);
1061 fstrcpy(driver->configfile, new_name);
1064 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1065 fstrcpy(new_name, p+1);
1066 fstrcpy(driver->helpfile, new_name);
1069 if (driver->dependentfiles) {
1070 for (i=0; *driver->dependentfiles[i]; i++) {
1071 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1072 fstrcpy(new_name, p+1);
1073 fstrcpy(driver->dependentfiles[i], new_name);
1078 get_short_archi(architecture, driver->environment);
1080 /* jfm:7/16/2000 the client always sends the cversion=0.
1081 * The server should check which version the driver is by reading
1082 * the PE header of driver->driverpath.
1084 * For Windows 95/98 the version is 0 (so the value sent is correct)
1085 * For Windows NT (the architecture doesn't matter)
1086 * NT 3.1: cversion=0
1087 * NT 3.5/3.51: cversion=1
1091 if ((driver->cversion = get_correct_cversion( architecture,
1092 driver->driverpath, user, &err)) == -1)
1098 /****************************************************************************
1099 ****************************************************************************/
1100 static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
1101 struct current_user *user)
1103 fstring architecture;
1109 /* clean up the driver name.
1110 * we can get .\driver.dll
1111 * or worse c:\windows\system\driver.dll !
1113 /* using an intermediate string to not have overlaping memcpy()'s */
1114 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1115 fstrcpy(new_name, p+1);
1116 fstrcpy(driver->driverpath, new_name);
1119 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1120 fstrcpy(new_name, p+1);
1121 fstrcpy(driver->datafile, new_name);
1124 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1125 fstrcpy(new_name, p+1);
1126 fstrcpy(driver->configfile, new_name);
1129 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1130 fstrcpy(new_name, p+1);
1131 fstrcpy(driver->helpfile, new_name);
1134 if (driver->dependentfiles) {
1135 for (i=0; *driver->dependentfiles[i]; i++) {
1136 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1137 fstrcpy(new_name, p+1);
1138 fstrcpy(driver->dependentfiles[i], new_name);
1143 get_short_archi(architecture, driver->environment);
1145 /* jfm:7/16/2000 the client always sends the cversion=0.
1146 * The server should check which version the driver is by reading
1147 * the PE header of driver->driverpath.
1149 * For Windows 95/98 the version is 0 (so the value sent is correct)
1150 * For Windows NT (the architecture doesn't matter)
1151 * NT 3.1: cversion=0
1152 * NT 3.5/3.51: cversion=1
1156 if ((driver->version = get_correct_cversion(architecture,
1157 driver->driverpath, user, &err)) == -1)
1163 /****************************************************************************
1164 ****************************************************************************/
1165 WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
1166 uint32 level, struct current_user *user)
1171 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1172 driver=driver_abstract.info_3;
1173 return clean_up_driver_struct_level_3(driver, user);
1177 NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
1178 driver=driver_abstract.info_6;
1179 return clean_up_driver_struct_level_6(driver, user);
1182 return WERR_INVALID_PARAM;
1186 /****************************************************************************
1187 This function sucks and should be replaced. JRA.
1188 ****************************************************************************/
1190 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
1192 dst->cversion = src->version;
1194 fstrcpy( dst->name, src->name);
1195 fstrcpy( dst->environment, src->environment);
1196 fstrcpy( dst->driverpath, src->driverpath);
1197 fstrcpy( dst->datafile, src->datafile);
1198 fstrcpy( dst->configfile, src->configfile);
1199 fstrcpy( dst->helpfile, src->helpfile);
1200 fstrcpy( dst->monitorname, src->monitorname);
1201 fstrcpy( dst->defaultdatatype, src->defaultdatatype);
1202 dst->dependentfiles = src->dependentfiles;
1205 #if 0 /* Debugging function */
1207 static char* ffmt(unsigned char *c){
1209 static char ffmt_str[17];
1211 for (i=0; i<16; i++) {
1212 if ((c[i] < ' ') || (c[i] > '~'))
1223 /****************************************************************************
1224 ****************************************************************************/
1225 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level,
1226 struct current_user *user, WERROR *perr)
1228 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1229 NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
1230 fstring architecture;
1235 connection_struct *conn;
1243 driver=driver_abstract.info_3;
1244 else if (level==6) {
1245 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
1246 driver = &converted_driver;
1248 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
1252 get_short_archi(architecture, driver->environment);
1254 /* connect to the print$ share under the same account as the user connected to the rpc pipe */
1255 /* Null password is ok - we are already an authenticated user... */
1256 null_pw = data_blob(NULL, 0);
1257 conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
1260 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
1261 *perr = ntstatus_to_werror(nt_status);
1266 * Save who we are - we are temporarily becoming the connection user.
1271 if (!become_user(conn, conn->vuid)) {
1272 DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
1278 * make the directories version and version\driver_name
1279 * under the architecture directory.
1281 DEBUG(5,("Creating first directory\n"));
1282 slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
1283 mkdir_internal(conn, new_dir);
1285 /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
1286 * listed for this driver which has already been moved, skip it (note:
1287 * drivers may list the same file name several times. Then check if the
1288 * file already exists in archi\cversion\, if so, check that the version
1289 * info (or time stamps if version info is unavailable) is newer (or the
1290 * date is later). If it is, move it to archi\cversion\filexxx.yyy.
1291 * Otherwise, delete the file.
1293 * If a file is not moved to archi\cversion\ because of an error, all the
1294 * rest of the 'unmoved' driver files are removed from archi\. If one or
1295 * more of the driver's files was already moved to archi\cversion\, it
1296 * potentially leaves the driver in a partially updated state. Version
1297 * trauma will most likely occur if an client attempts to use any printer
1298 * bound to the driver. Perhaps a rewrite to make sure the moves can be
1299 * done is appropriate... later JRR
1302 DEBUG(5,("Moving files now !\n"));
1304 if (driver->driverpath && strlen(driver->driverpath)) {
1305 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);
1306 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);
1307 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1309 status = rename_internals(conn, new_name, old_name, True);
1310 if (!NT_STATUS_IS_OK(status)) {
1311 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1312 new_name, old_name));
1313 *perr = ntstatus_to_werror(status);
1314 unlink_internals(conn, 0, new_name);
1319 unlink_internals(conn, 0, new_name);
1322 if (driver->datafile && strlen(driver->datafile)) {
1323 if (!strequal(driver->datafile, driver->driverpath)) {
1324 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);
1325 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);
1326 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1328 status = rename_internals(conn, new_name, old_name, True);
1329 if (!NT_STATUS_IS_OK(status)) {
1330 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1331 new_name, old_name));
1332 *perr = ntstatus_to_werror(status);
1333 unlink_internals(conn, 0, new_name);
1338 unlink_internals(conn, 0, new_name);
1342 if (driver->configfile && strlen(driver->configfile)) {
1343 if (!strequal(driver->configfile, driver->driverpath) &&
1344 !strequal(driver->configfile, driver->datafile)) {
1345 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);
1346 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);
1347 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1349 status = rename_internals(conn, new_name, old_name, True);
1350 if (!NT_STATUS_IS_OK(status)) {
1351 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1352 new_name, old_name));
1353 *perr = ntstatus_to_werror(status);
1354 unlink_internals(conn, 0, new_name);
1359 unlink_internals(conn, 0, new_name);
1363 if (driver->helpfile && strlen(driver->helpfile)) {
1364 if (!strequal(driver->helpfile, driver->driverpath) &&
1365 !strequal(driver->helpfile, driver->datafile) &&
1366 !strequal(driver->helpfile, driver->configfile)) {
1367 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);
1368 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);
1369 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1371 status = rename_internals(conn, new_name, old_name, True);
1372 if (!NT_STATUS_IS_OK(status)) {
1373 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1374 new_name, old_name));
1375 *perr = ntstatus_to_werror(status);
1376 unlink_internals(conn, 0, new_name);
1381 unlink_internals(conn, 0, new_name);
1385 if (driver->dependentfiles) {
1386 for (i=0; *driver->dependentfiles[i]; i++) {
1387 if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
1388 !strequal(driver->dependentfiles[i], driver->datafile) &&
1389 !strequal(driver->dependentfiles[i], driver->configfile) &&
1390 !strequal(driver->dependentfiles[i], driver->helpfile)) {
1392 for (j=0; j < i; j++) {
1393 if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
1398 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);
1399 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);
1400 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1402 status = rename_internals(conn, new_name, old_name, True);
1403 if (!NT_STATUS_IS_OK(status)) {
1404 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1405 new_name, old_name));
1406 *perr = ntstatus_to_werror(status);
1407 unlink_internals(conn, 0, new_name);
1412 unlink_internals(conn, 0, new_name);
1418 close_cnum(conn, user->vuid);
1421 return ver == -1 ? False : True;
1424 /****************************************************************************
1425 ****************************************************************************/
1426 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
1429 fstring architecture;
1435 TDB_DATA kbuf, dbuf;
1437 get_short_archi(architecture, driver->environment);
1439 /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
1440 * \\server is added in the rpc server layer.
1441 * It does make sense to NOT store the server's name in the printer TDB.
1444 slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion);
1446 /* .inf files do not always list a file for each of the four standard files.
1447 * Don't prepend a path to a null filename, or client claims:
1448 * "The server on which the printer resides does not have a suitable
1449 * <printer driver name> printer driver installed. Click OK if you
1450 * wish to install the driver on your local machine."
1452 if (strlen(driver->driverpath)) {
1453 fstrcpy(temp_name, driver->driverpath);
1454 slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name);
1457 if (strlen(driver->datafile)) {
1458 fstrcpy(temp_name, driver->datafile);
1459 slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name);
1462 if (strlen(driver->configfile)) {
1463 fstrcpy(temp_name, driver->configfile);
1464 slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name);
1467 if (strlen(driver->helpfile)) {
1468 fstrcpy(temp_name, driver->helpfile);
1469 slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name);
1472 if (driver->dependentfiles) {
1473 for (i=0; *driver->dependentfiles[i]; i++) {
1474 fstrcpy(temp_name, driver->dependentfiles[i]);
1475 slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", directory, temp_name);
1479 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
1481 DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
1488 len += tdb_pack(buf+len, buflen-len, "dffffffff",
1491 driver->environment,
1496 driver->monitorname,
1497 driver->defaultdatatype);
1499 if (driver->dependentfiles) {
1500 for (i=0; *driver->dependentfiles[i]; i++) {
1501 len += tdb_pack(buf+len, buflen-len, "f",
1502 driver->dependentfiles[i]);
1506 if (len != buflen) {
1509 tb = (char *)Realloc(buf, len);
1511 DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
1522 kbuf.dsize = strlen(key)+1;
1526 ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
1530 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
1536 /****************************************************************************
1537 ****************************************************************************/
1538 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
1540 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
1543 info3.cversion = driver->version;
1544 fstrcpy(info3.name,driver->name);
1545 fstrcpy(info3.environment,driver->environment);
1546 fstrcpy(info3.driverpath,driver->driverpath);
1547 fstrcpy(info3.datafile,driver->datafile);
1548 fstrcpy(info3.configfile,driver->configfile);
1549 fstrcpy(info3.helpfile,driver->helpfile);
1550 fstrcpy(info3.monitorname,driver->monitorname);
1551 fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
1552 info3.dependentfiles = driver->dependentfiles;
1554 return add_a_printer_driver_3(&info3);
1558 /****************************************************************************
1559 ****************************************************************************/
1560 static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
1562 NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
1566 fstrcpy(info.name, in_prt);
1567 fstrcpy(info.defaultdatatype, "RAW");
1569 fstrcpy(info.driverpath, "");
1570 fstrcpy(info.datafile, "");
1571 fstrcpy(info.configfile, "");
1572 fstrcpy(info.helpfile, "");
1574 if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
1577 memset(info.dependentfiles, '\0', 2*sizeof(fstring));
1578 fstrcpy(info.dependentfiles[0], "");
1580 *info_ptr = memdup(&info, sizeof(info));
1585 /****************************************************************************
1586 ****************************************************************************/
1587 static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
1589 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
1590 TDB_DATA kbuf, dbuf;
1591 fstring architecture;
1596 ZERO_STRUCT(driver);
1598 get_short_archi(architecture, in_arch);
1600 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
1602 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
1605 kbuf.dsize = strlen(key)+1;
1607 dbuf = tdb_fetch(tdb_drivers, kbuf);
1609 if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1611 if (!dbuf.dptr) return WERR_ACCESS_DENIED;
1613 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
1622 driver.defaultdatatype);
1625 while (len < dbuf.dsize) {
1628 tddfs = (fstring *)Realloc(driver.dependentfiles,
1629 sizeof(fstring)*(i+2));
1630 if (tddfs == NULL) {
1631 DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
1634 else driver.dependentfiles = tddfs;
1636 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
1637 &driver.dependentfiles[i]);
1640 if (driver.dependentfiles != NULL)
1641 fstrcpy(driver.dependentfiles[i], "");
1643 SAFE_FREE(dbuf.dptr);
1645 if (len != dbuf.dsize) {
1646 SAFE_FREE(driver.dependentfiles);
1648 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1651 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
1656 /****************************************************************************
1657 ****************************************************************************/
1658 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
1660 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1666 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
1667 DEBUG(10,("driver key: [%s]\n", key));
1670 kbuf.dsize = strlen(key)+1;
1671 if (!tdb_exists(tdb_drivers, kbuf)) return False;
1674 get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
1676 DEBUGADD(10,("info3->name [%s]\n", info3->name));
1677 DEBUGADD(10,("info3->datafile [%s]\n", info3->datafile));
1678 DEBUGADD(10,("info3->helpfile [%s]\n", info3->helpfile));
1679 DEBUGADD(10,("info3->monitorname [%s]\n", info3->monitorname));
1680 DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
1681 for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1682 DEBUGADD(10,("info3->dependentfiles [%s]\n", info3->dependentfiles[i]));
1684 DEBUGADD(10,("info3->environment [%s]\n", info3->environment));
1685 DEBUGADD(10,("info3->driverpath [%s]\n", info3->driverpath));
1686 DEBUGADD(10,("info3->configfile [%s]\n", info3->configfile));
1688 /*pstrcat(line, info3->name); pstrcat(line, ":");*/
1689 trim_string(info3->configfile, "\\print$\\WIN40\\0\\", 0);
1690 pstrcat(line, info3->configfile);
1692 trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
1693 pstrcat(line, info3->datafile);
1695 trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
1696 pstrcat(line, info3->helpfile);
1698 trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
1699 pstrcat(line, info3->monitorname);
1701 pstrcat(line, "RAW"); /*info3->defaultdatatype);*/
1704 for (i=0; info3->dependentfiles &&
1705 *info3->dependentfiles[i]; i++) {
1706 if (i) pstrcat(line, ","); /* don't end in a "," */
1707 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
1708 pstrcat(line, info3->dependentfiles[i]);
1716 /****************************************************************************
1717 debugging function, dump at level 6 the struct in the logs
1718 ****************************************************************************/
1719 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1722 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1725 DEBUG(106,("Dumping printer driver at level [%d]\n", level));
1731 if (driver.info_3 == NULL)
1734 info3=driver.info_3;
1736 DEBUGADD(106,("version:[%d]\n", info3->cversion));
1737 DEBUGADD(106,("name:[%s]\n", info3->name));
1738 DEBUGADD(106,("environment:[%s]\n", info3->environment));
1739 DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
1740 DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
1741 DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
1742 DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
1743 DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
1744 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
1746 for (i=0; info3->dependentfiles &&
1747 *info3->dependentfiles[i]; i++) {
1748 DEBUGADD(106,("dependentfile:[%s]\n",
1749 info3->dependentfiles[i]));
1756 DEBUGADD(1,("Level not implemented\n"));
1764 /****************************************************************************
1765 ****************************************************************************/
1766 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
1770 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
1772 if (!nt_devmode) return len;
1774 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1775 nt_devmode->devicename,
1776 nt_devmode->formname,
1778 nt_devmode->specversion,
1779 nt_devmode->driverversion,
1781 nt_devmode->driverextra,
1782 nt_devmode->orientation,
1783 nt_devmode->papersize,
1784 nt_devmode->paperlength,
1785 nt_devmode->paperwidth,
1788 nt_devmode->defaultsource,
1789 nt_devmode->printquality,
1792 nt_devmode->yresolution,
1793 nt_devmode->ttoption,
1794 nt_devmode->collate,
1795 nt_devmode->logpixels,
1798 nt_devmode->bitsperpel,
1799 nt_devmode->pelswidth,
1800 nt_devmode->pelsheight,
1801 nt_devmode->displayflags,
1802 nt_devmode->displayfrequency,
1803 nt_devmode->icmmethod,
1804 nt_devmode->icmintent,
1805 nt_devmode->mediatype,
1806 nt_devmode->dithertype,
1807 nt_devmode->reserved1,
1808 nt_devmode->reserved2,
1809 nt_devmode->panningwidth,
1810 nt_devmode->panningheight,
1811 nt_devmode->private);
1814 if (nt_devmode->private) {
1815 len += tdb_pack(buf+len, buflen-len, "B",
1816 nt_devmode->driverextra,
1817 nt_devmode->private);
1820 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
1825 /****************************************************************************
1826 ****************************************************************************/
1827 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
1831 while (param != NULL) {
1832 len += tdb_pack(buf+len, buflen-len, "pfdB",
1841 len += tdb_pack(buf+len, buflen-len, "p", param);
1847 /****************************************************************************
1848 delete a printer - this just deletes the printer info file, any open
1849 handles are not affected
1850 ****************************************************************************/
1851 uint32 del_a_printer(char *sharename)
1856 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
1859 kbuf.dsize=strlen(key)+1;
1861 tdb_delete(tdb_printers, kbuf);
1865 /* FIXME!!! Reorder so this forward declaration is not necessary --jerry */
1866 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring);
1867 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
1868 /****************************************************************************
1869 ****************************************************************************/
1870 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
1876 TDB_DATA kbuf, dbuf;
1879 * in addprinter: no servername and the printer is the name
1880 * in setprinter: servername is \\server
1881 * and printer is \\server\\printer
1883 * Samba manages only local printers.
1884 * we currently don't support things like path=\\other_server\printer
1887 if (info->servername[0]!='\0') {
1888 trim_string(info->printername, info->servername, NULL);
1889 trim_string(info->printername, "\\", NULL);
1890 info->servername[0]='\0';
1894 * JFM: one day I'll forget.
1895 * below that's info->portname because that's the SAMBA sharename
1896 * and I made NT 'thinks' it's the portname
1897 * the info->sharename is the thing you can name when you add a printer
1898 * that's the short-name when you create shared printer for 95/98
1899 * So I've made a limitation in SAMBA: you can only have 1 printer model
1900 * behind a SAMBA share.
1908 len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
1911 info->default_priority,
1928 info->printprocessor,
1932 len += pack_devicemode(info->devmode, buf+len, buflen-len);
1934 len += pack_specifics(info->specific, buf+len, buflen-len);
1936 if (buflen != len) {
1939 tb = (char *)Realloc(buf, len);
1941 DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
1951 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, info->sharename);
1954 kbuf.dsize = strlen(key)+1;
1958 ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
1961 if (!W_ERROR_IS_OK(ret))
1962 DEBUG(8, ("error updating printer to tdb on disk\n"));
1966 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
1967 info->sharename, info->drivername, info->portname, len));
1973 /****************************************************************************
1974 ****************************************************************************/
1975 void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM **param)
1977 NT_PRINTER_PARAM *current;
1979 DEBUG(108,("add_a_specific_param\n"));
1981 (*param)->next=NULL;
1983 if (info_2->specific == NULL)
1985 info_2->specific=*param;
1989 current=info_2->specific;
1990 while (current->next != NULL) {
1991 current=current->next;
1993 current->next=*param;
1999 /****************************************************************************
2000 ****************************************************************************/
2001 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
2003 NT_PRINTER_PARAM *current;
2004 NT_PRINTER_PARAM *previous;
2006 current=info_2->specific;
2009 if (current==NULL) return (False);
2011 if ( !strcmp(current->value, param->value) &&
2012 (strlen(current->value)==strlen(param->value)) ) {
2013 DEBUG(109,("deleting first value\n"));
2014 info_2->specific=current->next;
2015 SAFE_FREE(current->data);
2017 DEBUG(109,("deleted first value\n"));
2021 current=previous->next;
2023 while ( current!=NULL ) {
2024 if (!strcmp(current->value, param->value) &&
2025 strlen(current->value)==strlen(param->value) ) {
2026 DEBUG(109,("deleting current value\n"));
2027 previous->next=current->next;
2028 SAFE_FREE(current->data);
2030 DEBUG(109,("deleted current value\n"));
2034 previous=previous->next;
2035 current=current->next;
2040 /****************************************************************************
2041 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
2042 ****************************************************************************/
2043 void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
2045 NT_PRINTER_PARAM *param = *param_ptr;
2050 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
2052 SAFE_FREE(param->data);
2053 SAFE_FREE(*param_ptr);
2056 /****************************************************************************
2057 Malloc and return an NT devicemode.
2058 ****************************************************************************/
2060 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
2063 * should I init this ones ???
2064 nt_devmode->devicename
2068 NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
2070 if (nt_devmode == NULL) {
2071 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
2075 ZERO_STRUCTP(nt_devmode);
2077 safe_strcpy(adevice, default_devicename, sizeof(adevice));
2078 fstrcpy(nt_devmode->devicename, adevice);
2080 fstrcpy(nt_devmode->formname, "Letter");
2082 nt_devmode->specversion = 0x0401;
2083 nt_devmode->driverversion = 0x0400;
2084 nt_devmode->size = 0x00DC;
2085 nt_devmode->driverextra = 0x0000;
2086 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
2087 DEFAULTSOURCE | COPIES | SCALE |
2088 PAPERSIZE | ORIENTATION;
2089 nt_devmode->orientation = 1;
2090 nt_devmode->papersize = PAPER_LETTER;
2091 nt_devmode->paperlength = 0;
2092 nt_devmode->paperwidth = 0;
2093 nt_devmode->scale = 0x64;
2094 nt_devmode->copies = 01;
2095 nt_devmode->defaultsource = BIN_FORMSOURCE;
2096 nt_devmode->printquality = RES_HIGH; /* 0x0258 */
2097 nt_devmode->color = COLOR_MONOCHROME;
2098 nt_devmode->duplex = DUP_SIMPLEX;
2099 nt_devmode->yresolution = 0;
2100 nt_devmode->ttoption = TT_SUBDEV;
2101 nt_devmode->collate = COLLATE_FALSE;
2102 nt_devmode->icmmethod = 0;
2103 nt_devmode->icmintent = 0;
2104 nt_devmode->mediatype = 0;
2105 nt_devmode->dithertype = 0;
2107 /* non utilisés par un driver d'imprimante */
2108 nt_devmode->logpixels = 0;
2109 nt_devmode->bitsperpel = 0;
2110 nt_devmode->pelswidth = 0;
2111 nt_devmode->pelsheight = 0;
2112 nt_devmode->displayflags = 0;
2113 nt_devmode->displayfrequency = 0;
2114 nt_devmode->reserved1 = 0;
2115 nt_devmode->reserved2 = 0;
2116 nt_devmode->panningwidth = 0;
2117 nt_devmode->panningheight = 0;
2119 nt_devmode->private = NULL;
2123 /****************************************************************************
2124 Deepcopy an NT devicemode.
2125 ****************************************************************************/
2127 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
2129 NT_DEVICEMODE *new_nt_devicemode = NULL;
2131 if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
2132 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2136 new_nt_devicemode->private = NULL;
2137 if (nt_devicemode->private != NULL) {
2138 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
2139 SAFE_FREE(new_nt_devicemode);
2140 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2145 return new_nt_devicemode;
2148 /****************************************************************************
2149 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
2150 ****************************************************************************/
2152 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
2154 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
2156 if(nt_devmode == NULL)
2159 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
2161 SAFE_FREE(nt_devmode->private);
2162 SAFE_FREE(*devmode_ptr);
2165 /****************************************************************************
2166 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
2167 ****************************************************************************/
2168 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
2170 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
2171 NT_PRINTER_PARAM *param_ptr;
2176 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
2178 free_nt_devicemode(&info->devmode);
2180 for(param_ptr = info->specific; param_ptr; ) {
2181 NT_PRINTER_PARAM *tofree = param_ptr;
2183 param_ptr = param_ptr->next;
2184 free_nt_printer_param(&tofree);
2187 SAFE_FREE(*info_ptr);
2191 /****************************************************************************
2192 ****************************************************************************/
2193 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
2197 NT_DEVICEMODE devmode;
2199 ZERO_STRUCT(devmode);
2201 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
2203 if (!*nt_devmode) return len;
2205 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
2209 &devmode.specversion,
2210 &devmode.driverversion,
2212 &devmode.driverextra,
2213 &devmode.orientation,
2215 &devmode.paperlength,
2216 &devmode.paperwidth,
2219 &devmode.defaultsource,
2220 &devmode.printquality,
2223 &devmode.yresolution,
2229 &devmode.bitsperpel,
2231 &devmode.pelsheight,
2232 &devmode.displayflags,
2233 &devmode.displayfrequency,
2237 &devmode.dithertype,
2240 &devmode.panningwidth,
2241 &devmode.panningheight,
2244 if (devmode.private) {
2245 /* the len in tdb_unpack is an int value and
2246 * devmode.driverextra is only a short
2248 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
2249 devmode.driverextra=(uint16)extra_len;
2251 /* check to catch an invalid TDB entry so we don't segfault */
2252 if (devmode.driverextra == 0) {
2253 devmode.private = NULL;
2257 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
2259 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
2260 if (devmode.private)
2261 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
2266 /****************************************************************************
2267 ****************************************************************************/
2268 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
2271 NT_PRINTER_PARAM param, *p;
2276 len += tdb_unpack(buf+len, buflen-len, "p", &p);
2279 len += tdb_unpack(buf+len, buflen-len, "fdB",
2285 *list = memdup(¶m, sizeof(param));
2287 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
2293 static void map_to_os2_driver(fstring drivername)
2295 static BOOL initialised=False;
2296 static fstring last_from,last_to;
2297 char *mapfile = lp_os2_driver_map();
2298 char **lines = NULL;
2302 if (!strlen(drivername))
2309 *last_from = *last_to = 0;
2313 if (strequal(drivername,last_from)) {
2314 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,last_to));
2315 fstrcpy(drivername,last_to);
2319 lines = file_lines_load(mapfile, &numlines);
2320 if (numlines == 0) {
2321 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
2325 DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
2327 for( i = 0; i < numlines; i++) {
2328 char *nt_name = lines[i];
2329 char *os2_name = strchr(nt_name,'=');
2336 while (isspace(*nt_name))
2339 if (!*nt_name || strchr("#;",*nt_name))
2343 int l = strlen(nt_name);
2344 while (l && isspace(nt_name[l-1])) {
2350 while (isspace(*os2_name))
2354 int l = strlen(os2_name);
2355 while (l && isspace(os2_name[l-1])) {
2361 if (strequal(nt_name,drivername)) {
2362 DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
2363 fstrcpy(last_from,drivername);
2364 fstrcpy(last_to,os2_name);
2365 fstrcpy(drivername,os2_name);
2366 file_lines_free(lines);
2371 file_lines_free(lines);
2374 /****************************************************************************
2375 get a default printer info 2 struct
2376 ****************************************************************************/
2377 static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2379 extern pstring global_myname;
2381 NT_PRINTER_INFO_LEVEL_2 info;
2385 snum = lp_servicenumber(sharename);
2387 slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", global_myname);
2388 slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s",
2389 global_myname, sharename);
2390 fstrcpy(info.sharename, sharename);
2391 fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
2392 fstrcpy(info.drivername, lp_printerdriver(snum));
2394 /* by setting the driver name to an empty string, a local NT admin
2395 can now run the **local** APW to install a local printer driver
2396 for a Samba shared printer in 2.2. Without this, drivers **must** be
2397 installed on the Samba server for NT clients --jerry */
2398 #if 0 /* JERRY --do not uncomment-- */
2399 if (!*info.drivername)
2400 fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
2404 DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info.drivername));
2406 pstrcpy(info.comment, "");
2407 fstrcpy(info.printprocessor, "winprint");
2408 fstrcpy(info.datatype, "RAW");
2410 info.attributes = PRINTER_ATTRIBUTE_SHARED \
2411 | PRINTER_ATTRIBUTE_LOCAL \
2412 | PRINTER_ATTRIBUTE_RAW_ONLY \
2413 | PRINTER_ATTRIBUTE_QUEUED ; /* attributes */
2415 info.starttime = 0; /* Minutes since 12:00am GMT */
2416 info.untiltime = 0; /* Minutes since 12:00am GMT */
2418 info.default_priority = 1;
2419 info.setuptime = (uint32)time(NULL) - 86400; /* minus 1 day */
2422 * I changed this as I think it is better to have a generic
2423 * DEVMODE than to crash Win2k explorer.exe --jerry
2424 * See the HP Deskjet 990c Win2k drivers for an example.
2427 #if 0 /* JRA - NO NOT CHANGE ! */
2428 info.devmode = NULL;
2431 * We should not return a default devicemode, as this causes
2432 * Win2K to not send the correct one on PCL drivers. It needs to
2433 * see a null devicemode so it can then overwrite the devicemode
2434 * on OpenPrinterEx. Yes this *is* insane :-). JRA.
2436 if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
2440 /* This will get the current RPC talloc context, but we should be
2441 passing this as a parameter... fixme... JRA ! */
2443 if (!nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf))
2446 *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
2448 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
2457 free_nt_devicemode(&info.devmode);
2458 return WERR_ACCESS_DENIED;
2461 /****************************************************************************
2462 ****************************************************************************/
2463 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2466 NT_PRINTER_INFO_LEVEL_2 info;
2468 TDB_DATA kbuf, dbuf;
2469 fstring printername;
2473 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
2476 kbuf.dsize = strlen(key)+1;
2478 dbuf = tdb_fetch(tdb_printers, kbuf);
2480 return get_a_printer_2_default(info_ptr, sharename);
2482 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
2485 &info.default_priority,
2502 info.printprocessor,
2506 /* Samba has to have shared raw drivers. */
2507 info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
2509 /* Restore the stripped strings. */
2510 slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", global_myname);
2511 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", global_myname,
2513 fstrcpy(info.printername, printername);
2515 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2518 * Some client drivers freak out if there is a NULL devmode
2519 * (probably the driver is not checking before accessing
2520 * the devmode pointer) --jerry
2524 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
2526 info.devmode = construct_nt_devicemode(printername);
2529 len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
2531 /* This will get the current RPC talloc context, but we should be
2532 passing this as a parameter... fixme... JRA ! */
2534 nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
2536 /* Fix for OS/2 drivers. */
2538 if (get_remote_arch() == RA_OS2)
2539 map_to_os2_driver(info.drivername);
2541 SAFE_FREE(dbuf.dptr);
2542 *info_ptr=memdup(&info, sizeof(info));
2544 DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
2545 sharename, info.printername, info.drivername));
2550 /****************************************************************************
2551 debugging function, dump at level 6 the struct in the logs
2552 ****************************************************************************/
2553 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2556 NT_PRINTER_INFO_LEVEL_2 *info2;
2558 DEBUG(106,("Dumping printer at level [%d]\n", level));
2564 if (printer.info_2 == NULL)
2568 info2=printer.info_2;
2570 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
2571 DEBUGADD(106,("priority:[%d]\n", info2->priority));
2572 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
2573 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
2574 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
2575 DEBUGADD(106,("status:[%s]\n", werror_str(info2->status)));
2576 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
2577 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
2578 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
2579 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
2580 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
2582 DEBUGADD(106,("servername:[%s]\n", info2->servername));
2583 DEBUGADD(106,("printername:[%s]\n", info2->printername));
2584 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
2585 DEBUGADD(106,("portname:[%s]\n", info2->portname));
2586 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
2587 DEBUGADD(106,("comment:[%s]\n", info2->comment));
2588 DEBUGADD(106,("location:[%s]\n", info2->location));
2589 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
2590 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
2591 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
2592 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
2598 DEBUGADD(1,("Level not implemented\n"));
2606 /****************************************************************************
2607 Get the parameters we can substitute in an NT print job.
2608 ****************************************************************************/
2610 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
2612 NT_PRINTER_INFO_LEVEL *printer = NULL;
2614 **printername = **sharename = **portname = '\0';
2616 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
2619 fstrcpy(*printername, printer->info_2->printername);
2620 fstrcpy(*sharename, printer->info_2->sharename);
2621 fstrcpy(*portname, printer->info_2->portname);
2623 free_a_printer(&printer, 2);
2627 * The function below are the high level ones.
2628 * only those ones must be called from the spoolss code.
2632 /****************************************************************************
2633 Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
2634 ****************************************************************************/
2636 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2640 dump_a_printer(printer, level);
2646 printer.info_2->c_setprinter++;
2647 result=update_a_printer_2(printer.info_2);
2651 result=WERR_UNKNOWN_LEVEL;
2658 /****************************************************************************
2659 Add a printer. This is called from ADDPRINTER(EX) and also SETPRINTER.
2660 We split this out from mod_a_printer as it updates the id's and timestamps.
2661 ****************************************************************************/
2663 WERROR add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2667 dump_a_printer(printer, level);
2674 * Update the changestamp.
2675 * Note we must *not* do this in mod_a_printer().
2678 time_t time_unix = time(NULL);
2679 unix_to_nt_time(&time_nt, time_unix);
2680 if (printer.info_2->changeid==time_nt.low)
2681 printer.info_2->changeid++;
2683 printer.info_2->changeid=time_nt.low;
2685 printer.info_2->c_setprinter++;
2687 result=update_a_printer_2(printer.info_2);
2691 result=WERR_UNKNOWN_LEVEL;
2698 /****************************************************************************
2699 Initialize printer devmode & data with previously saved driver init values.
2700 ****************************************************************************/
2701 static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
2705 TDB_DATA kbuf, dbuf;
2706 NT_PRINTER_PARAM *current;
2707 NT_PRINTER_INFO_LEVEL_2 info;
2711 slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
2714 kbuf.dsize = strlen(key)+1;
2716 dbuf = tdb_fetch(tdb_drivers, kbuf);
2721 * Get the saved DEVMODE..
2723 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2726 * The saved DEVMODE contains the devicename from the printer used during
2727 * the initialization save. Change it to reflect the new printer.
2729 ZERO_STRUCT(info.devmode->devicename);
2730 fstrcpy(info.devmode->devicename, info_ptr->printername);
2733 * Bind the saved DEVMODE to the new the printer.
2735 free_nt_devicemode(&info_ptr->devmode);
2736 info_ptr->devmode = info.devmode;
2738 DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
2739 info_ptr->printername, info_ptr->drivername));
2742 * There should not be any printer data 'specifics' already set during the
2743 * add printer operation, if there are delete them.
2745 while ( (current=info_ptr->specific) != NULL ) {
2746 info_ptr->specific=current->next;
2747 SAFE_FREE(current->data);
2752 * Add the printer data 'specifics' to the new printer
2754 len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
2756 SAFE_FREE(dbuf.dptr);
2761 /****************************************************************************
2762 Initialize printer devmode & data with previously saved driver init values.
2763 When a printer is created using AddPrinter, the drivername bound to the
2764 printer is used to lookup previously saved driver initialization info, which
2765 is bound to the new printer.
2766 ****************************************************************************/
2768 uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
2776 result=set_driver_init_2(printer->info_2);
2787 /****************************************************************************
2788 Pack up the DEVMODE and specifics for a printer into a 'driver init' entry
2789 in the tdb. Note: this is different from the driver entry and the printer
2790 entry. There should be a single driver init entry for each driver regardless
2791 of whether it was installed from NT or 2K. Technically, they should be
2792 different, but they work out to the same struct.
2793 ****************************************************************************/
2794 static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
2798 int buflen, len, ret;
2799 TDB_DATA kbuf, dbuf;
2806 len += pack_devicemode(info->devmode, buf+len, buflen-len);
2808 len += pack_specifics(info->specific, buf+len, buflen-len);
2810 if (buflen != len) {
2813 tb = (char *)Realloc(buf, len);
2815 DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
2824 slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername);
2827 kbuf.dsize = strlen(key)+1;
2831 ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
2835 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
2839 DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
2840 info->sharename, info->drivername));
2845 /****************************************************************************
2846 Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
2847 ****************************************************************************/
2849 static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2853 dump_a_printer(printer, level);
2859 result=update_driver_init_2(printer.info_2);
2870 /****************************************************************************
2871 Convert the printer data value, a REG_BINARY array, into an initialization
2872 DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
2873 got to keep the endians happy :).
2874 ****************************************************************************/
2876 static BOOL convert_driver_init(NT_PRINTER_PARAM *param, TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode)
2878 BOOL result = False;
2882 ZERO_STRUCT(devmode);
2884 prs_init(&ps, 0, ctx, UNMARSHALL);
2885 ps.data_p = (char *)param->data;
2886 ps.buffer_size = param->data_len;
2888 if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
2889 result = convert_devicemode("", &devmode, &nt_devmode);
2891 DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
2896 /****************************************************************************
2897 Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
2899 1. Use the driver's config DLL to this UNC printername and:
2900 a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
2901 b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
2902 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
2904 The last step triggers saving the "driver initialization" information for
2905 this printer into the tdb. Later, new printers that use this driver will
2906 have this initialization information bound to them. This simulates the
2907 driver initialization, as if it had run on the Samba server (as it would
2910 The Win32 client side code requirement sucks! But until we can run arbitrary
2911 Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
2913 It would have been easier to use SetPrinter because all the UNMARSHALLING of
2914 the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
2915 about it and you will realize why. JRR 010720
2916 ****************************************************************************/
2918 static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARAM *param)
2920 WERROR status = WERR_OK;
2921 TALLOC_CTX *ctx = NULL;
2922 NT_DEVICEMODE *nt_devmode = NULL;
2923 NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
2926 * Set devmode on printer info, so entire printer initialization can be
2929 if ((ctx = talloc_init()) == NULL)
2932 if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) {
2933 status = WERR_NOMEM;
2937 ZERO_STRUCTP(nt_devmode);
2940 * The DEVMODE is held in the 'data' component of the param in raw binary.
2941 * Convert it to to a devmode structure
2943 if (!convert_driver_init(param, ctx, nt_devmode)) {
2944 DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
2945 status = WERR_INVALID_PARAM;
2950 * Pack up and add (or update) the DEVMODE and any current printer data to
2951 * a 'driver init' element in the tdb
2954 printer->info_2->devmode = nt_devmode;
2955 if (update_driver_init(*printer, 2)!=0) {
2956 DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
2957 status = WERR_NOMEM;
2962 * If driver initialization info was successfully saved, set the current
2963 * printer to match it. This allows initialization of the current printer
2964 * as well as the driver.
2966 status = mod_a_printer(*printer, 2);
2967 if (!W_ERROR_IS_OK(status)) {
2968 DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
2969 printer->info_2->printername));
2973 talloc_destroy(ctx);
2975 SAFE_FREE(nt_devmode->private);
2976 SAFE_FREE(nt_devmode);
2977 printer->info_2->devmode = tmp_devmode;
2982 /****************************************************************************
2983 Update the driver init info (DEVMODE and specifics) for a printer
2984 ****************************************************************************/
2986 WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param)
2988 WERROR status = WERR_OK;
2994 status=save_driver_init_2(printer, param);
2998 status=WERR_UNKNOWN_LEVEL;
3005 /****************************************************************************
3006 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
3007 ****************************************************************************/
3009 WERROR get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
3012 NT_PRINTER_INFO_LEVEL *printer = NULL;
3016 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
3022 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
3023 DEBUG(0,("get_a_printer: malloc fail.\n"));
3026 ZERO_STRUCTP(printer);
3027 result=get_a_printer_2(&printer->info_2, sharename);
3028 if (W_ERROR_IS_OK(result)) {
3029 dump_a_printer(*printer, level);
3030 *pp_printer = printer;
3037 result=WERR_UNKNOWN_LEVEL;
3041 DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", sharename, (unsigned int)level, werror_str(result)));
3046 /****************************************************************************
3047 Deletes a NT_PRINTER_INFO_LEVEL struct.
3048 ****************************************************************************/
3050 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
3053 NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
3055 DEBUG(104,("freeing a printer at level [%d]\n", level));
3057 if (printer == NULL)
3064 if (printer->info_2 != NULL)
3066 free_nt_printer_info_level_2(&printer->info_2);
3080 SAFE_FREE(*pp_printer);
3084 /****************************************************************************
3085 ****************************************************************************/
3086 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
3089 DEBUG(104,("adding a printer at level [%d]\n", level));
3090 dump_a_printer_driver(driver, level);
3096 result=add_a_printer_driver_3(driver.info_3);
3102 result=add_a_printer_driver_6(driver.info_6);
3112 /****************************************************************************
3113 ****************************************************************************/
3114 WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
3115 fstring printername, fstring architecture, uint32 version)
3123 result=get_a_printer_driver_3(&driver->info_3, printername, architecture, version);
3131 if (W_ERROR_IS_OK(result))
3132 dump_a_printer_driver(*driver, level);
3136 /****************************************************************************
3137 ****************************************************************************/
3138 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
3146 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
3147 if (driver.info_3 != NULL)
3149 info3=driver.info_3;
3150 SAFE_FREE(info3->dependentfiles);
3151 ZERO_STRUCTP(info3);
3163 NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
3164 if (driver.info_6 != NULL)
3166 info6=driver.info_6;
3167 SAFE_FREE(info6->dependentfiles);
3168 SAFE_FREE(info6->previousnames);
3169 ZERO_STRUCTP(info6);
3187 /****************************************************************************
3188 Determine whether or not a particular driver is currently assigned
3190 ****************************************************************************/
3191 BOOL printer_driver_in_use (char *arch, char *driver)
3193 TDB_DATA kbuf, newkey, dbuf;
3194 NT_PRINTER_INFO_LEVEL_2 info;
3198 if (!nt_printing_init())
3201 DEBUG(5,("printer_driver_in_use: Beginning search through printers.tdb...\n"));
3203 /* loop through the printers.tdb and check for the drivername */
3204 for (kbuf = tdb_firstkey(tdb_printers); kbuf.dptr;
3205 newkey = tdb_nextkey(tdb_printers, kbuf), safe_free(kbuf.dptr), kbuf=newkey)
3208 dbuf = tdb_fetch(tdb_printers, kbuf);
3212 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) != 0)
3215 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddddddfffffPfffff",
3218 &info.default_priority,
3235 info.printprocessor,
3239 SAFE_FREE(dbuf.dptr);
3242 DEBUG (0,("printer_driver_in_use: tdb_unpack failed for printer %s\n",
3247 DEBUG (10,("printer_driver_in_use: Printer - %s (%s)\n",
3248 info.printername, info.drivername));
3250 if (strcmp(info.drivername, driver) == 0)
3252 DEBUG(5,("printer_driver_in_use: Printer %s using %s\n",
3253 info.printername, driver));
3257 DEBUG(5,("printer_driver_in_use: Completed search through printers.tdb...\n"));
3261 /* report that the driver is in use by default */
3265 /****************************************************************************
3266 Remove a printer driver from the TDB. This assumes that the the driver was
3267 previously looked up.
3268 ***************************************************************************/
3269 WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i)
3276 get_short_archi(arch, i->environment);
3277 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
3278 arch, i->cversion, i->name);
3279 DEBUG(5,("delete_printer_driver: key = [%s]\n", key));
3282 kbuf.dsize=strlen(key)+1;
3284 if (tdb_delete(tdb_drivers, kbuf) == -1) {
3285 DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
3286 return WERR_ACCESS_DENIED;
3289 DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
3294 /****************************************************************************
3295 ****************************************************************************/
3296 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
3297 fstring value, uint8 **data, uint32 *type, uint32 *len)
3299 /* right now that's enough ! */
3300 NT_PRINTER_PARAM *param;
3303 param=printer.info_2->specific;
3305 while (param != NULL && i < param_index) {
3313 /* exited because it exist */
3315 StrnCpy(value, param->value, sizeof(fstring)-1);
3316 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
3319 ZERO_STRUCTP(*data);
3320 memcpy(*data, param->data, param->data_len);
3321 *len=param->data_len;
3325 /****************************************************************************
3326 ****************************************************************************/
3327 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
3328 fstring value, uint8 **data, uint32 *type, uint32 *len)
3330 /* right now that's enough ! */
3331 NT_PRINTER_PARAM *param;
3333 DEBUG(10, ("get_specific_param\n"));
3335 param=printer.info_2->specific;
3337 while (param != NULL)
3339 #if 1 /* JRA - I think this should be case insensitive.... */
3340 if ( strequal(value, param->value)
3342 if ( !strcmp(value, param->value)
3344 && strlen(value)==strlen(param->value))
3352 DEBUGADD(10, ("get_specific_param: found one param\n"));
3353 /* exited because it exist */
3356 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
3359 memcpy(*data, param->data, param->data_len);
3360 *len=param->data_len;
3362 DEBUGADD(10, ("get_specific_param: exit true\n"));
3365 DEBUGADD(10, ("get_specific_param: exit false\n"));
3369 /****************************************************************************
3370 Store a security desc for a printer.
3371 ****************************************************************************/
3373 WERROR nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
3375 SEC_DESC_BUF *new_secdesc_ctr = NULL;
3376 SEC_DESC_BUF *old_secdesc_ctr = NULL;
3378 TALLOC_CTX *mem_ctx = NULL;
3382 mem_ctx = talloc_init();
3383 if (mem_ctx == NULL)
3386 /* The old owner and group sids of the security descriptor are not
3387 present when new ACEs are added or removed by changing printer
3388 permissions through NT. If they are NULL in the new security
3389 descriptor then copy them over from the old one. */
3391 if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
3392 DOM_SID *owner_sid, *group_sid;
3393 SEC_ACL *dacl, *sacl;
3394 SEC_DESC *psd = NULL;
3397 nt_printing_getsec(mem_ctx, printername, &old_secdesc_ctr);
3399 /* Pick out correct owner and group sids */
3401 owner_sid = secdesc_ctr->sec->owner_sid ?
3402 secdesc_ctr->sec->owner_sid :
3403 old_secdesc_ctr->sec->owner_sid;
3405 group_sid = secdesc_ctr->sec->grp_sid ?
3406 secdesc_ctr->sec->grp_sid :
3407 old_secdesc_ctr->sec->grp_sid;
3409 dacl = secdesc_ctr->sec->dacl ?
3410 secdesc_ctr->sec->dacl :
3411 old_secdesc_ctr->sec->dacl;
3413 sacl = secdesc_ctr->sec->sacl ?
3414 secdesc_ctr->sec->sacl :
3415 old_secdesc_ctr->sec->sacl;
3417 /* Make a deep copy of the security descriptor */
3419 psd = make_sec_desc(mem_ctx, secdesc_ctr->sec->revision,
3420 owner_sid, group_sid,
3425 new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);
3428 if (!new_secdesc_ctr) {
3429 new_secdesc_ctr = secdesc_ctr;
3432 /* Store the security descriptor in a tdb */
3434 prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
3435 sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
3437 if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
3439 status = WERR_BADFUNC;
3443 slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
3445 if (tdb_prs_store(tdb_printers, key, &ps)==0) {
3448 DEBUG(1,("Failed to store secdesc for %s\n", printername));
3449 status = WERR_BADFUNC;
3452 /* Free malloc'ed memory */
3458 talloc_destroy(mem_ctx);
3462 /****************************************************************************
3463 Construct a default security descriptor buffer for a printer.
3464 ****************************************************************************/
3466 static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
3470 SEC_ACL *psa = NULL;
3471 SEC_DESC_BUF *sdb = NULL;
3472 SEC_DESC *psd = NULL;
3475 enum SID_NAME_USE name_type;
3477 /* Create an ACE where Everyone is allowed to print */
3479 init_sec_access(&sa, PRINTER_ACE_PRINT);
3480 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
3481 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
3483 /* Make the security descriptor owned by the Administrators group
3484 on the PDC of the domain. */
3486 if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
3487 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
3491 /* Backup plan - make printer owned by admins or root.
3492 This should emulate a lanman printer as security
3493 settings can't be changed. */
3495 sid_peek_rid(&owner_sid, &owner_rid);
3497 if (owner_rid != BUILTIN_ALIAS_RID_PRINT_OPS &&
3498 owner_rid != BUILTIN_ALIAS_RID_ADMINS &&
3499 owner_rid != DOMAIN_USER_RID_ADMIN &&
3500 !lookup_name("root", &owner_sid, &name_type)) {
3501 sid_copy(&owner_sid, &global_sid_World);
3505 init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
3506 init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
3507 sa, SEC_ACE_FLAG_OBJECT_INHERIT |
3508 SEC_ACE_FLAG_INHERIT_ONLY);
3510 init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
3511 init_sec_ace(&ace[2], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
3512 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
3514 /* The ACL revision number in rpc_secdesc.h differs from the one
3515 created by NT when setting ACE entries in printer
3516 descriptors. NT4 complains about the property being edited by a
3519 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) != NULL) {
3520 psd = make_sec_desc(ctx, SEC_DESC_REVISION,
3522 NULL, psa, &sd_size);
3526 DEBUG(0,("construct_default_printer_sdb: Failed to make SEC_DESC.\n"));
3530 sdb = make_sec_desc_buf(ctx, sd_size, psd);
3532 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
3533 (unsigned int)sd_size));
3538 /****************************************************************************
3539 Get a security desc for a printer.
3540 ****************************************************************************/
3542 BOOL nt_printing_getsec(TALLOC_CTX *ctx, char *printername, SEC_DESC_BUF **secdesc_ctr)
3548 if ((temp = strchr(printername + 2, '\\'))) {
3549 printername = temp + 1;
3552 /* Fetch security descriptor from tdb */
3554 slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
3556 if (tdb_prs_fetch(tdb_printers, key, &ps, ctx)!=0 ||
3557 !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
3559 DEBUG(4,("using default secdesc for %s\n", printername));
3561 if (!(*secdesc_ctr = construct_default_printer_sdb(ctx))) {
3565 /* Save default security descriptor for later */
3567 prs_init(&ps, (uint32)sec_desc_size((*secdesc_ctr)->sec) +
3568 sizeof(SEC_DESC_BUF), ctx, MARSHALL);
3570 if (sec_io_desc_buf("nt_printing_setsec", secdesc_ctr, &ps, 1))
3571 tdb_prs_store(tdb_printers, key, &ps);
3578 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
3579 this security descriptor has been created when winbindd was
3580 down. Take ownership of security descriptor. */
3582 if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
3584 enum SID_NAME_USE name_type;
3586 /* Change sd owner to workgroup administrator */
3588 if (winbind_lookup_name(lp_workgroup(), &owner_sid,
3590 SEC_DESC_BUF *new_secdesc_ctr = NULL;
3591 SEC_DESC *psd = NULL;
3596 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
3598 psd = make_sec_desc(ctx, (*secdesc_ctr)->sec->revision,
3600 (*secdesc_ctr)->sec->grp_sid,
3601 (*secdesc_ctr)->sec->sacl,
3602 (*secdesc_ctr)->sec->dacl,
3605 new_secdesc_ctr = make_sec_desc_buf(ctx, size, psd);
3607 /* Swap with other one */
3609 *secdesc_ctr = new_secdesc_ctr;
3613 nt_printing_setsec(printername, *secdesc_ctr);
3617 if (DEBUGLEVEL >= 10) {
3618 SEC_ACL *the_acl = (*secdesc_ctr)->sec->dacl;
3621 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
3622 printername, the_acl->num_aces));
3624 for (i = 0; i < the_acl->num_aces; i++) {
3627 sid_to_string(sid_str, &the_acl->ace[i].trustee);
3629 DEBUG(10, ("%s %d %d 0x%08x\n", sid_str,
3630 the_acl->ace[i].type, the_acl->ace[i].flags,
3631 the_acl->ace[i].info.mask));
3641 1: level not implemented
3642 2: file doesn't exist
3643 3: can't allocate memory
3644 4: can't free memory
3645 5: non existant struct
3649 A printer and a printer driver are 2 different things.
3650 NT manages them separatelly, Samba does the same.
3651 Why ? Simply because it's easier and it makes sense !
3653 Now explanation: You have 3 printers behind your samba server,
3654 2 of them are the same make and model (laser A and B). But laser B
3655 has an 3000 sheet feeder and laser A doesn't such an option.
3656 Your third printer is an old dot-matrix model for the accounting :-).
3658 If the /usr/local/samba/lib directory (default dir), you will have
3659 5 files to describe all of this.
3661 3 files for the printers (1 by printer):
3664 NTprinter_accounting
3665 2 files for the drivers (1 for the laser and 1 for the dot matrix)
3666 NTdriver_printer model X
3667 NTdriver_printer model Y
3669 jfm: I should use this comment for the text file to explain
3670 same thing for the forms BTW.
3671 Je devrais mettre mes commentaires en francais, ca serait mieux :-)
3675 /* Convert generic access rights to printer object specific access rights.
3676 It turns out that NT4 security descriptors use generic access rights and
3677 NT5 the object specific ones. */
3679 void map_printer_permissions(SEC_DESC *sd)
3683 for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
3684 se_map_generic(&sd->dacl->ace[i].info.mask,
3685 &printer_generic_mapping);
3689 /****************************************************************************
3690 Check a user has permissions to perform the given operation. We use the
3691 permission constants defined in include/rpc_spoolss.h to check the various
3692 actions we perform when checking printer access.
3694 PRINTER_ACCESS_ADMINISTER:
3695 print_queue_pause, print_queue_resume, update_printer_sec,
3696 update_printer, spoolss_addprinterex_level_2,
3697 _spoolss_setprinterdata
3702 JOB_ACCESS_ADMINISTER:
3703 print_job_delete, print_job_pause, print_job_resume,
3706 ****************************************************************************/
3707 BOOL print_access_check(struct current_user *user, int snum, int access_type)
3709 SEC_DESC_BUF *secdesc = NULL;
3710 uint32 access_granted;
3714 TALLOC_CTX *mem_ctx = NULL;
3715 extern struct current_user current_user;
3717 /* If user is NULL then use the current_user structure */
3720 user = ¤t_user;
3722 /* Always allow root or printer admins to do anything */
3724 if (user->uid == 0 ||
3725 user_in_list(uidtoname(user->uid), lp_printer_admin(snum))) {
3729 /* Get printer name */
3731 pname = PRINTERNAME(snum);
3733 if (!pname || !*pname) {
3738 /* Get printer security descriptor */
3740 if(!(mem_ctx = talloc_init())) {
3745 nt_printing_getsec(mem_ctx, pname, &secdesc);
3747 if (access_type == JOB_ACCESS_ADMINISTER) {
3748 SEC_DESC_BUF *parent_secdesc = secdesc;
3750 /* Create a child security descriptor to check permissions
3751 against. This is because print jobs are child objects
3752 objects of a printer. */
3754 secdesc = se_create_child_secdesc(mem_ctx, parent_secdesc->sec, False);
3756 /* Now this is the bit that really confuses me. The access
3757 type needs to be changed from JOB_ACCESS_ADMINISTER to
3758 PRINTER_ACCESS_ADMINISTER for this to work. Something
3759 to do with the child (job) object becoming like a
3762 access_type = PRINTER_ACCESS_ADMINISTER;
3767 map_printer_permissions(secdesc->sec);
3769 result = se_access_check(secdesc->sec, user->nt_user_token, access_type,
3770 &access_granted, &status);
3772 DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
3774 talloc_destroy(mem_ctx);
3782 /****************************************************************************
3783 Check the time parameters allow a print operation.
3784 *****************************************************************************/
3786 BOOL print_time_access_check(int snum)
3788 NT_PRINTER_INFO_LEVEL *printer = NULL;
3790 time_t now = time(NULL);
3794 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
3797 if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
3801 mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
3803 if (mins >= printer->info_2->starttime && mins <= printer->info_2->untiltime)
3806 free_a_printer(&printer, 2);
3814 /****************************************************************************
3815 Attempt to write a default device.
3816 *****************************************************************************/
3818 WERROR printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_default)
3820 NT_PRINTER_INFO_LEVEL *printer = NULL;
3824 * Don't bother if no default devicemode was sent.
3827 if (printer_default->devmode_cont.devmode == NULL)
3830 result = get_a_printer(&printer, 2, lp_servicename(snum));
3831 if (!W_ERROR_IS_OK(result)) return result;
3834 * Just ignore it if we already have a devmode.
3837 if (printer->info_2->devmode != NULL)
3841 * We don't have a devicemode and we're trying to write
3842 * one. Check we have the access needed.
3844 DEBUG(5,("printer_write_default_dev: access: %x\n", printer_default->access_required));
3846 if ( (printer_default->access_required & PRINTER_ACCESS_ADMINISTER) !=
3847 PRINTER_ACCESS_ADMINISTER) {
3848 DEBUG(5,("printer_write_default_dev: invalid request access to update: %x\n", printer_default->access_required));
3849 result = WERR_ACCESS_DENIED;
3853 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
3854 DEBUG(5,("printer_write_default_dev: Access denied for printer %s\n",
3855 lp_servicename(snum) ));
3856 result = WERR_ACCESS_DENIED;
3857 /*result = NT_STATUS_NO_PROBLEMO;*/
3861 DEBUG(5,("printer_write_default_dev: updating, check OK.\n"));
3864 * Convert the on the wire devicemode format to the internal one.
3867 if (!convert_devicemode(printer->info_2->printername,
3868 printer_default->devmode_cont.devmode,
3869 &printer->info_2->devmode)) {
3870 result = WERR_NOMEM;
3875 * Finally write back to the tdb.
3878 result = add_a_printer(*printer, 2);
3882 free_a_printer(&printer, 2);