Code from John Reilly <jreilly@hp.com> to add tdb lookups into the Win95
[samba.git] / source3 / printing / nt_printing.c
1 /* 
2  *  Unix SMB/Netbios implementation.
3  *  Version 1.9.
4  *  RPC Pipe client / server routines
5  *  Copyright (C) Andrew Tridgell              1992-2000,
6  *  Copyright (C) Jean François Micouleau      1998-2000.
7  *  
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *  
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *  
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #include "includes.h"
24
25 extern int DEBUGLEVEL;
26 extern pstring global_myname;
27 extern DOM_SID global_sid_World; 
28
29 static TDB_CONTEXT *tdb; /* used for driver files */
30
31 #define FORMS_PREFIX "FORMS/"
32 #define DRIVERS_PREFIX "DRIVERS/"
33 #define PRINTERS_PREFIX "PRINTERS/"
34
35 #define DATABASE_VERSION 1
36
37 /* we need to have a small set of default forms to support our
38    default printer */
39 static nt_forms_struct default_forms[] = {
40         {"Letter", 0x20, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367},
41         {"A4", 0xb0, 0x3354f, 0x4884e, 0x0, 0x0, 0x3354f, 0x4884e}
42 };
43
44
45 /****************************************************************************
46 open the NT printing tdb
47 ****************************************************************************/
48 BOOL nt_printing_init(void)
49 {
50         static pid_t local_pid;
51
52         if (tdb && local_pid == sys_getpid()) return True;
53         tdb = tdb_open(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
54         if (!tdb) {
55                 DEBUG(0,("Failed to open nt drivers database\n"));
56                 return False;
57         }
58
59         local_pid = sys_getpid();
60
61         /* handle a Samba upgrade */
62         tdb_writelock(tdb);
63         if (tdb_fetch_int(tdb, "INFO/version") != DATABASE_VERSION) {
64                 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
65                 tdb_store_int(tdb, "INFO/version", DATABASE_VERSION);
66         }
67         tdb_writeunlock(tdb);
68
69         return True;
70 }
71
72   
73 /****************************************************************************
74 get a form struct list
75 ****************************************************************************/
76 int get_ntforms(nt_forms_struct **list)
77 {
78         TDB_DATA kbuf, newkey, dbuf;
79         nt_forms_struct form;
80         int ret;
81         int n = 0;
82
83         for (kbuf = tdb_firstkey(tdb); 
84              kbuf.dptr; 
85              newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
86                 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
87                 
88                 dbuf = tdb_fetch(tdb, kbuf);
89                 if (!dbuf.dptr) continue;
90
91                 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
92                 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddddddd",
93                                  &form.flag, &form.width, &form.length, &form.left,
94                                  &form.top, &form.right, &form.bottom);
95                 safe_free(dbuf.dptr);
96                 if (ret != dbuf.dsize) continue;
97
98                 *list = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
99                 (*list)[n] = form;
100                 n++;
101         }
102
103         /* we should never return a null forms list or NT gets unhappy */
104         if (n == 0) {
105                 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
106                 n = sizeof(default_forms) / sizeof(default_forms[0]);
107         }
108         
109
110         return n;
111 }
112
113 /****************************************************************************
114 write a form struct list
115 ****************************************************************************/
116 int write_ntforms(nt_forms_struct **list, int number)
117 {
118         pstring buf, key;
119         int len;
120         TDB_DATA kbuf,dbuf;
121         int i;
122
123         for (i=0;i<number;i++) {
124                 len = tdb_pack(buf, sizeof(buf), "ddddddd", 
125                                (*list)[i].flag, (*list)[i].width, (*list)[i].length,
126                                (*list)[i].left, (*list)[i].top, (*list)[i].right, 
127                                (*list)[i].bottom);
128                 if (len > sizeof(buf)) break;
129                 slprintf(key, sizeof(key), "%s%s", FORMS_PREFIX, (*list)[i].name);
130                 kbuf.dsize = strlen(key)+1;
131                 kbuf.dptr = key;
132                 dbuf.dsize = len;
133                 dbuf.dptr = buf;
134                 if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) break;
135        }
136
137        return i;
138 }
139
140 /****************************************************************************
141 add a form struct at the end of the list
142 ****************************************************************************/
143 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
144 {
145         int n=0;
146         BOOL update;
147         fstring form_name;
148
149         /* 
150          * NT tries to add forms even when 
151          * they are already in the base
152          * only update the values if already present
153          */
154
155         update=False;
156         
157         unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
158         for (n=0; n<*count && update==False; n++)
159         {
160                 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
161                 {
162                         DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
163                         update=True;
164                 }
165         }
166
167         if (update==False)
168         {
169                 if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
170                         return False;
171                 unistr2_to_ascii((*list)[n].name, &(form->name), sizeof((*list)[n].name)-1);
172                 (*count)++;
173         }
174         
175         (*list)[n].flag=form->flags;
176         (*list)[n].width=form->size_x;
177         (*list)[n].length=form->size_y;
178         (*list)[n].left=form->left;
179         (*list)[n].top=form->top;
180         (*list)[n].right=form->right;
181         (*list)[n].bottom=form->bottom;
182
183         return True;
184 }
185
186 /****************************************************************************
187 update a form struct 
188 ****************************************************************************/
189 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
190 {
191         int n=0;
192         fstring form_name;
193         unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
194
195         DEBUG(106, ("[%s]\n", form_name));
196         for (n=0; n<count; n++)
197         {
198                 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
199                 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
200                         break;
201         }
202
203         if (n==count) return;
204
205         (*list)[n].flag=form->flags;
206         (*list)[n].width=form->size_x;
207         (*list)[n].length=form->size_y;
208         (*list)[n].left=form->left;
209         (*list)[n].top=form->top;
210         (*list)[n].right=form->right;
211         (*list)[n].bottom=form->bottom;
212 }
213  
214 /****************************************************************************
215 get the nt drivers list
216
217 traverse the database and look-up the matching names
218 ****************************************************************************/
219 int get_ntdrivers(fstring **list, char *architecture)
220 {
221         int total=0;
222         fstring short_archi;
223         pstring key;
224         TDB_DATA kbuf, newkey;
225
226         get_short_archi(short_archi, architecture);
227         slprintf(key, sizeof(key), "%s%s/", DRIVERS_PREFIX, short_archi);
228
229         for (kbuf = tdb_firstkey(tdb); 
230              kbuf.dptr; 
231              newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
232                 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
233                 
234                 if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
235                         return -1;
236
237                 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
238                 total++;
239         }
240
241         return(total);
242 }
243
244 /****************************************************************************
245 function to do the mapping between the long architecture name and
246 the short one.
247 ****************************************************************************/
248 void get_short_archi(char *short_archi, char *long_archi)
249 {
250         struct table {
251                 char *long_archi;
252                 char *short_archi;
253         };
254         
255         struct table archi_table[]=
256         {
257                 {"Windows 4.0",          "WIN40"    },
258                 {"Windows NT x86",       "W32X86"   },
259                 {"Windows NT R4000",     "W32mips"  },
260                 {"Windows NT Alpha_AXP", "W32alpha" },
261                 {"Windows NT PowerPC",   "W32ppc"   },
262                 {NULL,                   ""         }
263         };
264         
265         int i=-1;
266
267         DEBUG(107,("Getting architecture dependant directory\n"));
268         do {
269                 i++;
270         } while ( (archi_table[i].long_archi!=NULL ) && strncmp(long_archi, archi_table[i].long_archi, strlen(long_archi)) );
271
272         if (archi_table[i].long_archi==NULL)
273         {
274                 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
275         }
276         StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
277
278         DEBUGADD(108,("index: [%d]\n", i));
279         DEBUGADD(108,("long architecture: [%s]\n", long_archi));
280         DEBUGADD(108,("short architecture: [%s]\n", short_archi));
281 }
282
283 /****************************************************************************
284 ****************************************************************************/
285 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
286 {
287         int len, buflen;
288         fstring architecture;
289         pstring key;
290         char *buf;
291         int i, ret;
292         TDB_DATA kbuf, dbuf;
293
294         get_short_archi(architecture, driver->environment);
295         slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, driver->name);
296
297         /*
298          * cversion must be 2.
299          * when adding a printer ON the SERVER
300          * rpcAddPrinterDriver defines it to zero
301          * which is wrong !!!
302          *
303          * JFM, 4/14/99
304          */
305         driver->cversion=2;
306         
307         buf = NULL;
308         len = buflen = 0;
309
310  again:
311         len = 0;
312         len += tdb_pack(buf+len, buflen-len, "dffffffff", 
313                         driver->cversion,
314                         driver->name,
315                         driver->environment,
316                         driver->driverpath,
317                         driver->datafile,
318                         driver->configfile,
319                         driver->helpfile,
320                         driver->monitorname,
321                         driver->defaultdatatype);
322         
323         if (driver->dependentfiles) {
324                 for (i=0; *driver->dependentfiles[i]; i++) {
325                         len += tdb_pack(buf+len, buflen-len, "f", 
326                                         driver->dependentfiles[i]);
327                 }
328         }
329
330         if (len != buflen) {
331                 buf = (char *)Realloc(buf, len);
332                 buflen = len;
333                 goto again;
334         }
335
336
337         kbuf.dptr = key;
338         kbuf.dsize = strlen(key)+1;
339         dbuf.dptr = buf;
340         dbuf.dsize = len;
341         
342         ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
343
344         safe_free(buf);
345         return ret;
346 }
347
348 /****************************************************************************
349 ****************************************************************************/
350 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
351 {
352         NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
353
354         ZERO_STRUCT(info3);
355         info3.cversion = driver->version;
356         fstrcpy(info3.environment,driver->environment);
357         fstrcpy(info3.driverpath,driver->driverpath);
358         fstrcpy(info3.datafile,driver->datafile);
359         fstrcpy(info3.configfile,driver->configfile);
360         fstrcpy(info3.helpfile,driver->helpfile);
361         fstrcpy(info3.monitorname,driver->monitorname);
362         fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
363         info3.dependentfiles = driver->dependentfiles;
364
365         return add_a_printer_driver_3(&info3);
366 }
367
368
369 /****************************************************************************
370 ****************************************************************************/
371 static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
372 {
373         NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
374
375         ZERO_STRUCT(info);
376
377         fstrcpy(info.name, in_prt);
378         fstrcpy(info.defaultdatatype, "RAW");
379         
380         fstrcpy(info.driverpath, "");
381         fstrcpy(info.datafile, "");
382         fstrcpy(info.configfile, "");
383         fstrcpy(info.helpfile, "");
384
385         if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
386                 return ERROR_NOT_ENOUGH_MEMORY;
387
388         memset(info.dependentfiles, '\0', 2*sizeof(fstring));
389         fstrcpy(info.dependentfiles[0], "");
390
391         *info_ptr = memdup(&info, sizeof(info));
392         
393         return 0;       
394 }
395
396 /****************************************************************************
397 ****************************************************************************/
398 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
399 {
400         NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
401         TDB_DATA kbuf, dbuf;
402         fstring architecture;
403         int len = 0;
404         int i;
405         pstring key;
406
407         ZERO_STRUCT(driver);
408
409         get_short_archi(architecture, in_arch);
410         slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, in_prt);
411
412         kbuf.dptr = key;
413         kbuf.dsize = strlen(key)+1;
414         
415         dbuf = tdb_fetch(tdb, kbuf);
416         if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
417
418         len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff", 
419                           &driver.cversion,
420                           driver.name,
421                           driver.environment,
422                           driver.driverpath,
423                           driver.datafile,
424                           driver.configfile,
425                           driver.helpfile,
426                           driver.monitorname,
427                           driver.defaultdatatype);
428
429         i=0;
430         while (len < dbuf.dsize) {
431                 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
432                                                          sizeof(fstring)*(i+2));
433                 if (driver.dependentfiles == NULL)
434                         break;
435
436                 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", 
437                                   &driver.dependentfiles[i]);
438                 i++;
439         }
440         if (driver.dependentfiles != NULL)
441                 fstrcpy(driver.dependentfiles[i], "");
442
443         safe_free(dbuf.dptr);
444
445         if (len != dbuf.dsize) {
446                 if (driver.dependentfiles != NULL)
447                         safe_free(driver.dependentfiles);
448
449                 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
450         }
451
452         *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
453
454         return 0;
455 }
456
457 /****************************************************************************
458 ****************************************************************************/
459 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
460 {
461         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
462         TDB_DATA kbuf, dbuf;
463         pstring key;
464         int i;
465         line[0] = '\0';
466
467         slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, "WIN40", model);
468         DEBUG(10,("driver key: [%s]\n", key));
469         
470         kbuf.dptr = key;
471         kbuf.dsize = strlen(key)+1;
472         if (!tdb_exists(tdb, kbuf)) return False;
473
474         ZERO_STRUCT(info3);
475         get_a_printer_driver_3(&info3, model, "Windows 4.0");
476         
477     DEBUGADD(10,("info3->name            [%s]\n", info3->name));
478     DEBUGADD(10,("info3->datafile        [%s]\n", info3->datafile));
479     DEBUGADD(10,("info3->helpfile        [%s]\n", info3->helpfile));
480     DEBUGADD(10,("info3->monitorname     [%s]\n", info3->monitorname));
481     DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
482         for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
483     DEBUGADD(10,("info3->dependentfiles  [%s]\n", info3->dependentfiles[i]));
484     }
485     DEBUGADD(10,("info3->environment     [%s]\n", info3->environment));
486     DEBUGADD(10,("info3->driverpath      [%s]\n", info3->driverpath));
487     DEBUGADD(10,("info3->configfile      [%s]\n", info3->configfile));
488
489         /*pstrcat(line, info3->name);             pstrcat(line, ":");*/
490         pstrcat(line, info3->configfile);
491     pstrcat(line, ":");
492         pstrcat(line, info3->datafile);
493     pstrcat(line, ":");
494         pstrcat(line, info3->helpfile);
495     pstrcat(line, ":");
496         pstrcat(line, info3->monitorname);
497     pstrcat(line, ":");
498         pstrcat(line, "RAW");                /*info3->defaultdatatype);*/
499     pstrcat(line, ":");
500
501         for (i=0; info3->dependentfiles &&
502                  *info3->dependentfiles[i]; i++) {
503                 if (i) pstrcat(line, ",");               /* don't end in a "," */
504                 pstrcat(line, info3->dependentfiles[i]);
505         }
506         
507         free(info3);
508
509         return True;    
510 }
511
512 /****************************************************************************
513 debugging function, dump at level 6 the struct in the logs
514 ****************************************************************************/
515 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
516 {
517         uint32 success;
518         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
519         int i;
520         
521         DEBUG(106,("Dumping printer driver at level [%d]\n", level));
522         
523         switch (level)
524         {
525                 case 3: 
526                 {
527                         if (driver.info_3 == NULL)
528                                 success=5;
529                         else {
530                                 info3=driver.info_3;
531                         
532                                 DEBUGADD(106,("version:[%d]\n",         info3->cversion));
533                                 DEBUGADD(106,("name:[%s]\n",            info3->name));
534                                 DEBUGADD(106,("environment:[%s]\n",     info3->environment));
535                                 DEBUGADD(106,("driverpath:[%s]\n",      info3->driverpath));
536                                 DEBUGADD(106,("datafile:[%s]\n",        info3->datafile));
537                                 DEBUGADD(106,("configfile:[%s]\n",      info3->configfile));
538                                 DEBUGADD(106,("helpfile:[%s]\n",        info3->helpfile));
539                                 DEBUGADD(106,("monitorname:[%s]\n",     info3->monitorname));
540                                 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
541                                 
542                                 for (i=0; info3->dependentfiles &&
543                                           *info3->dependentfiles[i]; i++) {
544                                         DEBUGADD(106,("dependentfile:[%s]\n", 
545                                                       info3->dependentfiles[i]));
546                                 }
547                                 success=0;
548                         }
549                         break;
550                 }
551                 default:
552                         DEBUGADD(1,("Level not implemented\n"));
553                         success=1;
554                         break;
555         }
556         
557         return (success);
558 }
559
560 /****************************************************************************
561 ****************************************************************************/
562 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
563 {
564         int len = 0;
565
566         len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
567
568         if (!nt_devmode) return len;
569
570         len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
571                         nt_devmode->devicename,
572                         nt_devmode->formname,
573
574                         nt_devmode->specversion,
575                         nt_devmode->driverversion,
576                         nt_devmode->size,
577                         nt_devmode->driverextra,
578                         nt_devmode->orientation,
579                         nt_devmode->papersize,
580                         nt_devmode->paperlength,
581                         nt_devmode->paperwidth,
582                         nt_devmode->scale,
583                         nt_devmode->copies,
584                         nt_devmode->defaultsource,
585                         nt_devmode->printquality,
586                         nt_devmode->color,
587                         nt_devmode->duplex,
588                         nt_devmode->yresolution,
589                         nt_devmode->ttoption,
590                         nt_devmode->collate,
591                         nt_devmode->logpixels,
592                         
593                         nt_devmode->fields,
594                         nt_devmode->bitsperpel,
595                         nt_devmode->pelswidth,
596                         nt_devmode->pelsheight,
597                         nt_devmode->displayflags,
598                         nt_devmode->displayfrequency,
599                         nt_devmode->icmmethod,
600                         nt_devmode->icmintent,
601                         nt_devmode->mediatype,
602                         nt_devmode->dithertype,
603                         nt_devmode->reserved1,
604                         nt_devmode->reserved2,
605                         nt_devmode->panningwidth,
606                         nt_devmode->panningheight,
607                         nt_devmode->private);
608
609         
610         if (nt_devmode->private) {
611                 len += tdb_pack(buf+len, buflen-len, "B",
612                                 nt_devmode->driverextra,
613                                 nt_devmode->private);
614         }
615
616         DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
617
618         return len;
619 }
620
621 /****************************************************************************
622 ****************************************************************************/
623 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
624 {
625         int len = 0;
626
627         while (param != NULL) {
628                 len += tdb_pack(buf+len, buflen-len, "pfdB",
629                                 param,
630                                 param->value, 
631                                 param->type, 
632                                 param->data_len,
633                                 param->data);
634                 param=param->next;      
635         }
636
637         len += tdb_pack(buf+len, buflen-len, "p", param);
638
639         return len;
640 }
641
642
643 /****************************************************************************
644 delete a printer - this just deletes the printer info file, any open
645 handles are not affected
646 ****************************************************************************/
647 uint32 del_a_printer(char *portname)
648 {
649         pstring key;
650         TDB_DATA kbuf;
651
652         slprintf(key, sizeof(key), "%s%s",
653                  PRINTERS_PREFIX, portname);
654
655         kbuf.dptr=key;
656         kbuf.dsize=strlen(key)+1;
657
658         tdb_delete(tdb, kbuf);
659         return 0;
660 }
661
662 /****************************************************************************
663 ****************************************************************************/
664 static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
665 {
666         pstring key;
667         char *buf;
668         int buflen, len, ret;
669         TDB_DATA kbuf, dbuf;
670         NTTIME time_nt;
671         time_t time_unix = time(NULL);
672         
673         /* 
674          * in addprinter: no servername and the printer is the name
675          * in setprinter: servername is \\server
676          *                and printer is \\server\\printer
677          *
678          * Samba manages only local printers.
679          * we currently don't support things like path=\\other_server\printer
680          */
681         if (info->servername[0]!='\0')
682         {
683                 trim_string(info->printername, info->servername, NULL);
684                 trim_string(info->printername, "\\", NULL);
685                 info->servername[0]='\0';
686         }
687
688         /*
689          * JFM: one day I'll forget.
690          * below that's info->portname because that's the SAMBA sharename
691          * and I made NT 'thinks' it's the portname
692          * the info->sharename is the thing you can name when you add a printer
693          * that's the short-name when you create shared printer for 95/98
694          * So I've made a limitation in SAMBA: you can only have 1 printer model
695          * behind a SAMBA share.
696          */
697
698         unix_to_nt_time(&time_nt, time_unix);
699         info->changeid=time_nt.low;
700         info->c_setprinter++;
701
702         buf = NULL;
703         buflen = 0;
704
705  again: 
706         len = 0;
707         len += tdb_pack(buf+len, buflen-len, "dddddddddddffffffffff",
708                         info->attributes,
709                         info->priority,
710                         info->default_priority,
711                         info->starttime,
712                         info->untiltime,
713                         info->status,
714                         info->cjobs,
715                         info->averageppm,
716                         info->changeid,
717                         info->c_setprinter,
718                         info->setuptime,
719                         info->servername,
720                         info->printername,
721                         info->sharename,
722                         info->portname,
723                         info->drivername,
724                         info->location,
725                         info->sepfile,
726                         info->printprocessor,
727                         info->datatype,
728                         info->parameters);
729
730         len += pack_devicemode(info->devmode, buf+len, buflen-len);
731         len += pack_specifics(info->specific, buf+len, buflen-len);
732
733         if (buflen != len) {
734                 buf = (char *)Realloc(buf, len);
735                 buflen = len;
736                 goto again;
737         }
738         
739
740         slprintf(key, sizeof(key), "%s%s",
741                  PRINTERS_PREFIX, info->sharename);
742
743         kbuf.dptr = key;
744         kbuf.dsize = strlen(key)+1;
745         dbuf.dptr = buf;
746         dbuf.dsize = len;
747
748         ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
749
750         if (ret == -1)
751                 DEBUG(8, ("error updating printer to tdb on disk\n"));
752
753         safe_free(buf);
754
755         DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n", 
756                  info->portname, info->drivername, info->portname, len));
757
758         return ret;
759 }
760
761
762 /****************************************************************************
763 ****************************************************************************/
764 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
765 {
766         NT_PRINTER_PARAM *current;
767         
768         DEBUG(108,("add_a_specific_param\n"));  
769
770         param->next=NULL;
771         
772         if (info_2->specific == NULL)
773         {
774                 info_2->specific=param;
775         }
776         else
777         {
778                 current=info_2->specific;               
779                 while (current->next != NULL) {
780                         current=current->next;
781                 }               
782                 current->next=param;
783         }
784         return (True);
785 }
786
787 /****************************************************************************
788 ****************************************************************************/
789 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
790 {
791         NT_PRINTER_PARAM *current;
792         NT_PRINTER_PARAM *previous;
793         
794         current=info_2->specific;
795         previous=current;
796         
797         if (current==NULL) return (False);
798         
799         if ( !strcmp(current->value, param->value) && 
800             (strlen(current->value)==strlen(param->value)) ) {
801                 DEBUG(109,("deleting first value\n"));
802                 info_2->specific=current->next;
803                 safe_free(current->data);
804                 safe_free(current);
805                 DEBUG(109,("deleted first value\n"));
806                 return (True);
807         }
808
809         current=previous->next;
810                 
811         while ( current!=NULL ) {
812                 if (!strcmp(current->value, param->value) &&
813                     strlen(current->value)==strlen(param->value) ) {
814                         DEBUG(109,("deleting current value\n"));
815                         previous->next=current->next;
816                         safe_free(current->data);
817                         safe_free(current);
818                         DEBUG(109,("deleted current value\n"));
819                         return(True);
820                 }
821                 
822                 previous=previous->next;
823                 current=current->next;
824         }
825         return (False);
826 }
827
828 /****************************************************************************
829  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
830 ****************************************************************************/
831 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
832 {
833         NT_PRINTER_PARAM *param = *param_ptr;
834
835         if(param == NULL)
836                 return;
837
838         DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
839
840         if(param->data)
841                 safe_free(param->data);
842
843         safe_free(param);
844         *param_ptr = NULL;
845 }
846
847 /****************************************************************************
848  Malloc and return an NT devicemode.
849 ****************************************************************************/
850
851 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
852 {
853 /*
854  * should I init this ones ???
855         nt_devmode->devicename
856 */
857
858         char adevice[32];
859         NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
860
861         if (nt_devmode == NULL) {
862                 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
863                 return NULL;
864         }
865
866         ZERO_STRUCTP(nt_devmode);
867
868         snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, default_devicename);
869         fstrcpy(nt_devmode->devicename, adevice);
870         
871         
872         fstrcpy(nt_devmode->formname, "Letter");
873
874         nt_devmode->specversion      = 0x0401;
875         nt_devmode->driverversion    = 0x0400;
876         nt_devmode->size             = 0x00DC;
877         nt_devmode->driverextra      = 0x0000;
878         nt_devmode->fields           = FORMNAME | TTOPTION | PRINTQUALITY | 
879                                        DEFAULTSOURCE | COPIES | SCALE | 
880                                        PAPERSIZE | ORIENTATION;
881         nt_devmode->orientation      = 1;
882         nt_devmode->papersize        = PAPER_LETTER;
883         nt_devmode->paperlength      = 0;
884         nt_devmode->paperwidth       = 0;
885         nt_devmode->scale            = 0x64;
886         nt_devmode->copies           = 01;
887         nt_devmode->defaultsource    = BIN_FORMSOURCE;
888         nt_devmode->printquality     = 0x0258;
889         nt_devmode->color            = COLOR_MONOCHROME;
890         nt_devmode->duplex           = DUP_SIMPLEX;
891         nt_devmode->yresolution      = 0;
892         nt_devmode->ttoption         = TT_SUBDEV;
893         nt_devmode->collate          = COLLATE_FALSE;
894         nt_devmode->icmmethod        = 0;
895         nt_devmode->icmintent        = 0;
896         nt_devmode->mediatype        = 0;
897         nt_devmode->dithertype       = 0;
898
899         /* non utilisés par un driver d'imprimante */
900         nt_devmode->logpixels        = 0;
901         nt_devmode->bitsperpel       = 0;
902         nt_devmode->pelswidth        = 0;
903         nt_devmode->pelsheight       = 0;
904         nt_devmode->displayflags     = 0;
905         nt_devmode->displayfrequency = 0;
906         nt_devmode->reserved1        = 0;
907         nt_devmode->reserved2        = 0;
908         nt_devmode->panningwidth     = 0;
909         nt_devmode->panningheight    = 0;
910         
911         nt_devmode->private=NULL;
912
913         return nt_devmode;
914 }
915
916 /****************************************************************************
917  Deepcopy an NT devicemode.
918 ****************************************************************************/
919
920 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
921 {
922         NT_DEVICEMODE *new_nt_devicemode = NULL;
923
924         if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
925                 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
926                 return NULL;
927         }
928
929         new_nt_devicemode->private = NULL;
930         if (nt_devicemode->private != NULL) {
931                 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
932                         safe_free(new_nt_devicemode);
933                         DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
934                         return NULL;
935         }
936         }
937
938         return new_nt_devicemode;
939 }
940
941 /****************************************************************************
942  Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
943 ****************************************************************************/
944
945 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
946 {
947         NT_DEVICEMODE *nt_devmode = *devmode_ptr;
948
949         if(nt_devmode == NULL)
950                 return;
951
952         DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
953
954         if(nt_devmode->private)
955                 safe_free(nt_devmode->private);
956
957         safe_free(nt_devmode);
958         *devmode_ptr = NULL;
959 }
960
961 /****************************************************************************
962  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
963 ****************************************************************************/
964 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
965 {
966         NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
967         NT_PRINTER_PARAM *param_ptr;
968
969         if(info == NULL)
970                 return;
971
972         DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
973
974         free_nt_devicemode(&info->devmode);
975         free_sec_desc_buf(&info->secdesc_buf);
976
977         for(param_ptr = info->specific; param_ptr; ) {
978                 NT_PRINTER_PARAM *tofree = param_ptr;
979
980                 param_ptr = param_ptr->next;
981                 free_nt_printer_param(&tofree);
982         }
983
984         safe_free(*info_ptr);
985         *info_ptr = NULL;
986 }
987
988
989 /****************************************************************************
990 ****************************************************************************/
991 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
992 {
993         int len = 0;
994         NT_DEVICEMODE devmode;
995
996         ZERO_STRUCT(devmode);
997
998         len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
999
1000         if (!*nt_devmode) return len;
1001
1002         len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1003                           devmode.devicename,
1004                           devmode.formname,
1005
1006                           &devmode.specversion,
1007                           &devmode.driverversion,
1008                           &devmode.size,
1009                           &devmode.driverextra,
1010                           &devmode.orientation,
1011                           &devmode.papersize,
1012                           &devmode.paperlength,
1013                           &devmode.paperwidth,
1014                           &devmode.scale,
1015                           &devmode.copies,
1016                           &devmode.defaultsource,
1017                           &devmode.printquality,
1018                           &devmode.color,
1019                           &devmode.duplex,
1020                           &devmode.yresolution,
1021                           &devmode.ttoption,
1022                           &devmode.collate,
1023                           &devmode.logpixels,
1024                           
1025                           &devmode.fields,
1026                           &devmode.bitsperpel,
1027                           &devmode.pelswidth,
1028                           &devmode.pelsheight,
1029                           &devmode.displayflags,
1030                           &devmode.displayfrequency,
1031                           &devmode.icmmethod,
1032                           &devmode.icmintent,
1033                           &devmode.mediatype,
1034                           &devmode.dithertype,
1035                           &devmode.reserved1,
1036                           &devmode.reserved2,
1037                           &devmode.panningwidth,
1038                           &devmode.panningheight,
1039                           &devmode.private);
1040         
1041         if (devmode.private)            
1042                 len += tdb_unpack(buf+len, buflen-len, "B", &devmode.driverextra, &devmode.private);
1043
1044         *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
1045
1046         DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
1047         if (devmode.private)
1048                 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
1049
1050         return len;
1051 }
1052
1053 /****************************************************************************
1054 ****************************************************************************/
1055 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
1056 {
1057         int len = 0;
1058         NT_PRINTER_PARAM param, *p;
1059
1060         *list = NULL;
1061
1062         while (1) {
1063                 len += tdb_unpack(buf+len, buflen-len, "p", &p);
1064                 if (!p) break;
1065
1066                 len += tdb_unpack(buf+len, buflen-len, "fdB",
1067                                   param.value, 
1068                                   &param.type, 
1069                                   &param.data_len,
1070                                   &param.data);
1071                 param.next = *list;
1072                 *list = memdup(&param, sizeof(param));
1073         }
1074
1075         return len;
1076 }
1077
1078
1079 /****************************************************************************
1080 get a default printer info 2 struct
1081 ****************************************************************************/
1082 static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1083 {
1084         extern pstring global_myname;
1085         int snum;
1086         NT_PRINTER_INFO_LEVEL_2 info;
1087
1088         ZERO_STRUCT(info);
1089
1090         snum = lp_servicenumber(sharename);
1091
1092         fstrcpy(info.servername, global_myname);
1093         fstrcpy(info.printername, sharename);
1094         fstrcpy(info.portname, sharename);
1095         fstrcpy(info.drivername, lp_printerdriver(snum));
1096         fstrcpy(info.printprocessor, "winprint");
1097         fstrcpy(info.datatype, "RAW");
1098
1099         info.attributes = PRINTER_ATTRIBUTE_SHARED   \
1100                          | PRINTER_ATTRIBUTE_LOCAL  \
1101                          | PRINTER_ATTRIBUTE_RAW_ONLY ;            /* attributes */
1102
1103         info.starttime = 0; /* Minutes since 12:00am GMT */
1104         info.untiltime = 0; /* Minutes since 12:00am GMT */
1105         info.priority = 1;
1106         info.default_priority = 1;
1107
1108         if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
1109                 goto fail;
1110
1111         if (!nt_printing_getsec(sharename, &info.secdesc_buf))
1112                 goto fail;
1113
1114         *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
1115         if (! *info_ptr) {
1116                 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
1117                 goto fail;
1118         }
1119
1120         return (0);     
1121
1122   fail:
1123
1124         if (info.devmode)
1125                 free_nt_devicemode(&info.devmode);
1126         if (info.secdesc_buf)
1127                 free_sec_desc_buf(&info.secdesc_buf);
1128         return 2;
1129 }
1130
1131 /****************************************************************************
1132 ****************************************************************************/
1133 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1134 {
1135         pstring key;
1136         NT_PRINTER_INFO_LEVEL_2 info;
1137         int len = 0;
1138         TDB_DATA kbuf, dbuf;
1139                 
1140         ZERO_STRUCT(info);
1141
1142         slprintf(key, sizeof(key), "%s%s",
1143                  PRINTERS_PREFIX, sharename);
1144
1145         kbuf.dptr = key;
1146         kbuf.dsize = strlen(key)+1;
1147
1148         dbuf = tdb_fetch(tdb, kbuf);
1149 #if 1 /* JRATEST */
1150         if (!dbuf.dptr) return get_a_printer_2_default(info_ptr, sharename);
1151 #else
1152         if (!dbuf.dptr) return 1;
1153 #endif
1154
1155         len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddffffffffff",
1156                         &info.attributes,
1157                         &info.priority,
1158                         &info.default_priority,
1159                         &info.starttime,
1160                         &info.untiltime,
1161                         &info.status,
1162                         &info.cjobs,
1163                         &info.averageppm,
1164                         &info.changeid,
1165                         &info.c_setprinter,
1166                         &info.setuptime,
1167                         info.servername,
1168                         info.printername,
1169                         info.sharename,
1170                         info.portname,
1171                         info.drivername,
1172                         info.location,
1173                         info.sepfile,
1174                         info.printprocessor,
1175                         info.datatype,
1176                         info.parameters);
1177
1178         info.attributes |= PRINTER_ATTRIBUTE_RAW_ONLY; /* Samba has to have raw drivers. */
1179
1180         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
1181         len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
1182
1183 #if 1 /* JRATEST */
1184         nt_printing_getsec(sharename, &info.secdesc_buf);
1185 #endif /* JRATEST */
1186
1187         fstrcpy(info.sharename, "");
1188
1189         safe_free(dbuf.dptr);
1190         *info_ptr=memdup(&info, sizeof(info));
1191
1192         DEBUG(9,("Unpacked printer [%s] running drier [%s]\n",
1193                  sharename, info.drivername));
1194
1195         
1196         return 0;       
1197 }
1198
1199 /****************************************************************************
1200 debugging function, dump at level 6 the struct in the logs
1201 ****************************************************************************/
1202 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1203 {
1204         uint32 success;
1205         NT_PRINTER_INFO_LEVEL_2 *info2;
1206         
1207         DEBUG(106,("Dumping printer at level [%d]\n", level));
1208         
1209         switch (level)
1210         {
1211                 case 2: 
1212                 {
1213                         if (printer.info_2 == NULL)
1214                                 success=5;
1215                         else
1216                         {
1217                                 info2=printer.info_2;
1218                         
1219                                 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
1220                                 DEBUGADD(106,("priority:[%d]\n", info2->priority));
1221                                 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
1222                                 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
1223                                 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
1224                                 DEBUGADD(106,("status:[%d]\n", info2->status));
1225                                 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
1226                                 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
1227                                 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
1228                                 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
1229                                 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
1230
1231                                 DEBUGADD(106,("servername:[%s]\n", info2->servername));
1232                                 DEBUGADD(106,("printername:[%s]\n", info2->printername));
1233                                 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
1234                                 DEBUGADD(106,("portname:[%s]\n", info2->portname));
1235                                 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
1236                                 DEBUGADD(106,("location:[%s]\n", info2->location));
1237                                 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
1238                                 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
1239                                 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
1240                                 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
1241                                 success=0;
1242                         }
1243                         break;
1244                 }
1245                 default:
1246                         DEBUGADD(1,("Level not implemented\n"));
1247                         success=1;
1248                         break;
1249         }
1250         
1251         return (success);
1252 }
1253
1254 /*
1255  * The function below are the high level ones.
1256  * only those ones must be called from the spoolss code.
1257  * JFM.
1258  */
1259
1260
1261 /****************************************************************************
1262 ****************************************************************************/
1263 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1264 {
1265         uint32 success;
1266         
1267         dump_a_printer(printer, level); 
1268         
1269         switch (level)
1270         {
1271                 case 2: 
1272                 {
1273                         success=add_a_printer_2(printer.info_2);
1274                         break;
1275                 }
1276                 default:
1277                         success=1;
1278                         break;
1279         }
1280         
1281         return (success);
1282 }
1283
1284 /****************************************************************************
1285  Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
1286 ****************************************************************************/
1287
1288 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
1289 {
1290         uint32 success;
1291         NT_PRINTER_INFO_LEVEL *printer = NULL;
1292         
1293         *pp_printer = NULL;
1294
1295         DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1296
1297         switch (level)
1298         {
1299                 case 2: 
1300                 {
1301                         if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
1302                                 DEBUG(0,("get_a_printer: malloc fail.\n"));
1303                                 return 1;
1304                         }
1305                         ZERO_STRUCTP(printer);
1306                         success=get_a_printer_2(&printer->info_2, sharename);
1307                         if (success == 0) {
1308                                 dump_a_printer(*printer, level);
1309                                 *pp_printer = printer;
1310                         } else {
1311                                 safe_free(printer);
1312                         }
1313                         break;
1314                 }
1315                 default:
1316                         success=1;
1317                         break;
1318         }
1319         
1320         DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1321
1322         return (success);
1323 }
1324
1325 /****************************************************************************
1326  Deletes a NT_PRINTER_INFO_LEVEL struct.
1327 ****************************************************************************/
1328
1329 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
1330 {
1331         uint32 success;
1332         NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
1333
1334         DEBUG(104,("freeing a printer at level [%d]\n", level));
1335
1336         if (printer == NULL)
1337                 return 0;
1338         
1339         switch (level)
1340         {
1341                 case 2: 
1342                 {
1343                         if (printer->info_2 != NULL)
1344                         {
1345                                 free_nt_printer_info_level_2(&printer->info_2);
1346                                 success=0;
1347                         }
1348                         else
1349                         {
1350                                 success=4;
1351                         }
1352                         break;
1353                 }
1354                 default:
1355                         success=1;
1356                         break;
1357         }
1358
1359         safe_free(printer);
1360         *pp_printer = NULL;
1361         return (success);
1362 }
1363
1364 /****************************************************************************
1365 ****************************************************************************/
1366 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1367 {
1368         uint32 success;
1369         DEBUG(104,("adding a printer at level [%d]\n", level));
1370         dump_a_printer_driver(driver, level);
1371         
1372         switch (level)
1373         {
1374                 case 3: 
1375                 {
1376                         success=add_a_printer_driver_3(driver.info_3);
1377                         break;
1378                 }
1379
1380                 case 6: 
1381                 {
1382                         success=add_a_printer_driver_6(driver.info_6);
1383                         break;
1384                 }
1385                 default:
1386                         success=1;
1387                         break;
1388         }
1389         
1390         return (success);
1391 }
1392 /****************************************************************************
1393 ****************************************************************************/
1394 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, 
1395                             fstring printername, fstring architecture)
1396 {
1397         uint32 success;
1398         
1399         switch (level)
1400         {
1401                 case 3: 
1402                 {
1403                         success=get_a_printer_driver_3(&(driver->info_3), 
1404                                                        printername,
1405                                                        architecture);
1406                         break;
1407                 }
1408                 default:
1409                         success=1;
1410                         break;
1411         }
1412         
1413         if (success == 0) dump_a_printer_driver(*driver, level);
1414         return (success);
1415 }
1416
1417 /****************************************************************************
1418 ****************************************************************************/
1419 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1420 {
1421         uint32 success;
1422         
1423         switch (level)
1424         {
1425                 case 3: 
1426                 {
1427                         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1428                         if (driver.info_3 != NULL)
1429                         {
1430                                 info3=driver.info_3;
1431                                 safe_free(info3->dependentfiles);
1432                                 ZERO_STRUCTP(info3);
1433                                 safe_free(info3);
1434                                 success=0;
1435                         }
1436                         else
1437                         {
1438                                 success=4;
1439                         }
1440                         break;
1441                 }
1442                 case 6: 
1443                 {
1444                         NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
1445                         if (driver.info_6 != NULL)
1446                         {
1447                                 info6=driver.info_6;
1448                                 safe_free(info6->dependentfiles);
1449                                 safe_free(info6->previousnames);
1450                                 ZERO_STRUCTP(info6);
1451                                 safe_free(info6);
1452                                 success=0;
1453                         }
1454                         else
1455                         {
1456                                 success=4;
1457                         }
1458                         break;
1459                 }
1460                 default:
1461                         success=1;
1462                         break;
1463         }
1464         return (success);
1465 }
1466
1467 /****************************************************************************
1468 ****************************************************************************/
1469 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
1470                                  fstring value, uint8 **data, uint32 *type, uint32 *len)
1471 {
1472         /* right now that's enough ! */ 
1473         NT_PRINTER_PARAM *param;
1474         int i=0;
1475         
1476         param=printer.info_2->specific;
1477         
1478         while (param != NULL && i < param_index) {
1479                 param=param->next;
1480                 i++;
1481         }
1482         
1483         if (param == NULL)
1484                 return False;
1485
1486         /* exited because it exist */
1487         *type=param->type;              
1488         StrnCpy(value, param->value, sizeof(fstring)-1);
1489         *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1490         if(*data == NULL)
1491                 return False;
1492         ZERO_STRUCTP(*data);
1493         memcpy(*data, param->data, param->data_len);
1494         *len=param->data_len;
1495         return True;
1496 }
1497
1498 /****************************************************************************
1499 ****************************************************************************/
1500 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level, 
1501                         fstring value, uint8 **data, uint32 *type, uint32 *len)
1502 {
1503         /* right now that's enough ! */ 
1504         NT_PRINTER_PARAM *param;
1505         
1506         DEBUG(105, ("get_specific_param\n"));
1507         
1508         param=printer.info_2->specific;
1509                 
1510         while (param != NULL)
1511         {
1512                 if ( !strcmp(value, param->value) 
1513                     && strlen(value)==strlen(param->value))
1514                         break;
1515                         
1516                 param=param->next;
1517         }
1518         
1519         DEBUG(106, ("found one param\n"));
1520         if (param != NULL)
1521         {
1522                 /* exited because it exist */
1523                 *type=param->type;      
1524                 
1525                 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1526                 if(*data == NULL)
1527                         return False;
1528                 memcpy(*data, param->data, param->data_len);
1529                 *len=param->data_len;
1530
1531                 DEBUG(106, ("exit of get_specific_param:true\n"));
1532                 return (True);
1533         }
1534         DEBUG(106, ("exit of get_specific_param:false\n"));
1535         return (False);
1536 }
1537
1538
1539 /****************************************************************************
1540 store a security desc for a printer
1541 ****************************************************************************/
1542 uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
1543 {
1544         SEC_DESC_BUF *new_secdesc_ctr = NULL;
1545         SEC_DESC_BUF *old_secdesc_ctr = NULL;
1546         prs_struct ps;
1547         fstring key;
1548         uint32 status;
1549
1550         /* The old owner and group sids of the security descriptor are not
1551            present when new ACEs are added or removed by changing printer
1552            permissions through NT.  If they are NULL in the new security
1553            descriptor then copy them over from the old one. */
1554
1555         if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
1556                 DOM_SID *owner_sid, *group_sid;
1557                 SEC_DESC *psd = NULL;
1558                 size_t size;
1559
1560                 nt_printing_getsec(printername, &old_secdesc_ctr);
1561
1562                 /* Pick out correct owner and group sids */
1563
1564                 owner_sid = secdesc_ctr->sec->owner_sid ?
1565                         secdesc_ctr->sec->owner_sid :
1566                         old_secdesc_ctr->sec->owner_sid;
1567
1568                 group_sid = secdesc_ctr->sec->grp_sid ?
1569                         secdesc_ctr->sec->grp_sid :
1570                         old_secdesc_ctr->sec->grp_sid;
1571
1572                 /* Make a deep copy of the security descriptor */
1573
1574                 psd = make_sec_desc(secdesc_ctr->sec->revision,
1575                                     secdesc_ctr->sec->type,
1576                                     owner_sid, group_sid,
1577                                     secdesc_ctr->sec->sacl,
1578                                     secdesc_ctr->sec->dacl,
1579                                     &size);
1580
1581                 new_secdesc_ctr = make_sec_desc_buf(size, psd);
1582
1583                 /* Free up memory */
1584
1585                 free_sec_desc(&psd);
1586                 free_sec_desc_buf(&old_secdesc_ctr);
1587         }
1588
1589         if (!new_secdesc_ctr) {
1590                 new_secdesc_ctr = secdesc_ctr;
1591         }
1592
1593         /* Store the security descriptor in a tdb */
1594
1595         prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) + 
1596                  sizeof(SEC_DESC_BUF), 4, MARSHALL);
1597
1598         if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr, 
1599                              &ps, 1)) {
1600                 status = ERROR_INVALID_FUNCTION;
1601                 goto out;
1602         }
1603
1604         slprintf(key, sizeof(key), "SECDESC/%s", printername);
1605
1606         if (tdb_prs_store(tdb, key, &ps)==0) {
1607                 status = 0;
1608         } else {
1609                 DEBUG(1,("Failed to store secdesc for %s\n", printername));
1610                 status = ERROR_INVALID_FUNCTION;
1611         }
1612
1613         /* Free mallocated memory */
1614
1615  out:
1616         free_sec_desc_buf(&old_secdesc_ctr);
1617
1618         if (new_secdesc_ctr != secdesc_ctr) {
1619                 free_sec_desc_buf(&new_secdesc_ctr);
1620         }
1621
1622         prs_mem_free(&ps);
1623         return status;
1624 }
1625
1626 /****************************************************************************
1627  Construct a default security descriptor buffer for a printer.
1628 ****************************************************************************/
1629
1630 static SEC_DESC_BUF *construct_default_printer_sdb(void)
1631 {
1632         SEC_ACE ace;
1633         SEC_ACCESS sa;
1634         SEC_ACL *psa = NULL;
1635         SEC_DESC_BUF *sdb = NULL;
1636         SEC_DESC *psd = NULL;
1637         DOM_SID owner_sid;
1638         size_t sd_size;
1639         uint8 name_type;
1640
1641         /* Create an ACE where Everyone is allowed to print */
1642
1643         init_sec_access(&sa, PRINTER_ACE_PRINT);
1644         init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
1645                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
1646
1647         /* Make the security descriptor owned by the Administrators group
1648            on the PDC of the domain. */
1649
1650         if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
1651                 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
1652         } else {
1653
1654                 /* Backup plan - make printer owned by world.  This should
1655                    emulate a lanman printer as security settings can't be
1656                    changed. */
1657
1658                 sid_copy(&owner_sid, &global_sid_World);
1659         }
1660
1661         /* The ACL revision number in rpc_secdesc.h differs from the one
1662            created by NT when setting ACE entries in printer
1663            descriptors.  NT4 complains about the property being edited by a
1664            NT5 machine. */
1665
1666 #define NT4_ACL_REVISION 0x2
1667
1668         if ((psa = make_sec_acl(NT4_ACL_REVISION, 1, &ace)) != NULL) {
1669                 psd = make_sec_desc(SEC_DESC_REVISION, 
1670                                     SEC_DESC_SELF_RELATIVE | 
1671                                     SEC_DESC_DACL_PRESENT,
1672                                     &owner_sid, NULL,
1673                                     NULL, psa, &sd_size);
1674                 free_sec_acl(&psa);
1675         }
1676
1677         if (!psd) {
1678                 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
1679                 return NULL;
1680         }
1681
1682         sdb = make_sec_desc_buf(sd_size, psd);
1683
1684         DEBUG(4,("construct_default_printer_sdb: size = %u.\n", 
1685                  (unsigned int)sd_size));
1686
1687         free_sec_desc(&psd);
1688         return sdb;
1689 }
1690
1691 /****************************************************************************
1692  Get a security desc for a printer.
1693 ****************************************************************************/
1694
1695 BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr)
1696 {
1697         prs_struct ps;
1698         fstring key;
1699
1700         /* Fetch security descriptor from tdb */
1701
1702         slprintf(key, sizeof(key), "SECDESC/%s", printername);
1703
1704         if (tdb_prs_fetch(tdb, key, &ps)!=0 ||
1705             !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
1706
1707                 DEBUG(4,("using default secdesc for %s\n", printername));
1708
1709                 if (!(*secdesc_ctr = construct_default_printer_sdb()))
1710                         return False;
1711
1712                 return True;
1713         }
1714
1715         /* If security descriptor is owned by S-1-1-0 and winbindd is up,
1716            this security descriptor has been created when winbindd was
1717            down.  Take ownership of security descriptor. */
1718
1719         if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
1720                 DOM_SID owner_sid;
1721                 uint8 name_type;
1722
1723                 /* Change sd owner to workgroup administrator */
1724
1725                 if (winbind_lookup_name(lp_workgroup(), &owner_sid,
1726                                         &name_type)) {
1727                         SEC_DESC_BUF *new_secdesc_ctr = NULL;
1728                         SEC_DESC *psd = NULL;
1729                         size_t size;
1730
1731                         /* Create new sd */
1732
1733                         sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
1734
1735                         psd = make_sec_desc((*secdesc_ctr)->sec->revision,
1736                                             (*secdesc_ctr)->sec->type,
1737                                             &owner_sid,
1738                                             (*secdesc_ctr)->sec->grp_sid,
1739                                             (*secdesc_ctr)->sec->sacl,
1740                                             (*secdesc_ctr)->sec->dacl,
1741                                             &size);
1742
1743                         new_secdesc_ctr = make_sec_desc_buf(size, psd);
1744
1745                         free_sec_desc(&psd);
1746
1747                         /* Swap with other one */
1748
1749                         free_sec_desc_buf(secdesc_ctr);
1750                         *secdesc_ctr = new_secdesc_ctr;
1751
1752                         /* Set it */
1753
1754                         nt_printing_setsec(printername, *secdesc_ctr);
1755                 }
1756         }
1757
1758         prs_mem_free(&ps);
1759         return True;
1760 }
1761
1762 /* error code:
1763         0: everything OK
1764         1: level not implemented
1765         2: file doesn't exist
1766         3: can't allocate memory
1767         4: can't free memory
1768         5: non existant struct
1769 */
1770
1771 /*
1772         A printer and a printer driver are 2 different things.
1773         NT manages them separatelly, Samba does the same.
1774         Why ? Simply because it's easier and it makes sense !
1775         
1776         Now explanation: You have 3 printers behind your samba server,
1777         2 of them are the same make and model (laser A and B). But laser B 
1778         has an 3000 sheet feeder and laser A doesn't such an option.
1779         Your third printer is an old dot-matrix model for the accounting :-).
1780         
1781         If the /usr/local/samba/lib directory (default dir), you will have
1782         5 files to describe all of this.
1783         
1784         3 files for the printers (1 by printer):
1785                 NTprinter_laser A
1786                 NTprinter_laser B
1787                 NTprinter_accounting
1788         2 files for the drivers (1 for the laser and 1 for the dot matrix)
1789                 NTdriver_printer model X
1790                 NTdriver_printer model Y
1791
1792 jfm: I should use this comment for the text file to explain 
1793         same thing for the forms BTW.
1794         Je devrais mettre mes commentaires en francais, ca serait mieux :-)
1795
1796 */
1797
1798 /* Check a user has permissions to perform the given operation */
1799
1800 BOOL print_access_check(struct current_user *user, int snum,
1801                         uint32 required_access)
1802 {
1803         SEC_DESC_BUF *secdesc = NULL;
1804         uint32 access_granted, status;
1805         BOOL result;
1806         char *pname;
1807         int i;
1808         
1809         /* Get printer name */
1810
1811         pname = PRINTERNAME(snum);
1812         if (!pname || !*pname) pname = SERVICE(snum);
1813
1814         /* Get printer security descriptor */
1815
1816         nt_printing_getsec(pname, &secdesc);
1817
1818         /* The ACE for Full Control in a printer security descriptor
1819            doesn't seem to map properly to the access checking model.  For
1820            it to work properly it should be the logical OR of all the other
1821            values, i.e PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT.
1822            This would cause the access check to simply fall out when we
1823            check against any subset of these bits.  To get things to work,
1824            change every ACE mask of PRINTER_ACE_FULL_CONTROL to 
1825            PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT before
1826            performing the access check.  I'm sure there is a better way to
1827            do this! */
1828
1829         if (secdesc && secdesc->sec && secdesc->sec->dacl &&
1830             secdesc->sec->dacl->ace) {
1831                 for(i = 0; i < secdesc->sec->dacl->num_aces; i++) {
1832                         if (secdesc->sec->dacl->ace[i].info.mask ==
1833                             PRINTER_ACE_FULL_CONTROL) {
1834                                 secdesc->sec->dacl->ace[i].info.mask =
1835                                         PRINTER_ACE_MANAGE_DOCUMENTS | 
1836                                         PRINTER_ACE_PRINT;
1837                         }
1838                 }
1839         }
1840
1841         /* Check access */
1842
1843         result = se_access_check(secdesc->sec, user, required_access, 
1844                                  &access_granted, &status);
1845
1846         DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
1847
1848         /* Free mallocated memory */
1849
1850         free_sec_desc_buf(&secdesc);
1851
1852         return result;
1853 }