fixed!!
[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
27 static TDB_CONTEXT *tdb; /* used for driver files */
28
29 #define FORMS_PREFIX "FORMS/"
30 #define DRIVERS_PREFIX "DRIVERS/"
31 #define PRINTERS_PREFIX "PRINTERS/"
32
33 #define DATABASE_VERSION 1
34
35 /* we need to have a small set of default forms to support our
36    default printer */
37 static nt_forms_struct default_forms[] = {
38         {"A4", 0xb0, 0x3354f, 0x4884e, 0x0, 0x0, 0x3354f, 0x4884e},
39         {"Letter", 0x20, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367}
40 };
41
42
43 /****************************************************************************
44 open the NT printing tdb
45 ****************************************************************************/
46 BOOL nt_printing_init(void)
47 {
48         static pid_t local_pid;
49
50         if (tdb && local_pid == sys_getpid()) return True;
51         tdb = tdb_open(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
52         if (!tdb) {
53                 DEBUG(0,("Failed to open nt drivers database\n"));
54                 return False;
55         }
56
57         local_pid = sys_getpid();
58
59         /* handle a Samba upgrade */
60         tdb_writelock(tdb);
61         if (tdb_fetch_int(tdb, "INFO/version") != DATABASE_VERSION) {
62                 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
63                 tdb_store_int(tdb, "INFO/version", DATABASE_VERSION);
64         }
65         tdb_writeunlock(tdb);
66
67         return True;
68 }
69
70   
71 /****************************************************************************
72 get a form struct list
73 ****************************************************************************/
74 int get_ntforms(nt_forms_struct **list)
75 {
76         TDB_DATA kbuf, newkey, dbuf;
77         nt_forms_struct form;
78         int ret;
79         int n = 0;
80
81         for (kbuf = tdb_firstkey(tdb); 
82              kbuf.dptr; 
83              newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
84                 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
85                 
86                 dbuf = tdb_fetch(tdb, kbuf);
87                 if (!dbuf.dptr) continue;
88
89                 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
90                 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddddddd",
91                                  &form.flag, &form.width, &form.length, &form.left,
92                                  &form.top, &form.right, &form.bottom);
93                 safe_free(dbuf.dptr);
94                 if (ret != dbuf.dsize) continue;
95
96                 *list = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
97                 (*list)[n] = form;
98                 n++;
99         }
100
101         /* we should never return a null forms list or NT gets unhappy */
102         if (n == 0) {
103                 *list = (nt_forms_struct *)memdup(&default_forms, sizeof(default_forms));
104                 n = sizeof(sizeof(default_forms))/ sizeof(sizeof(default_forms[0]));
105         }
106         
107
108         return n;
109 }
110
111 /****************************************************************************
112 write a form struct list
113 ****************************************************************************/
114 int write_ntforms(nt_forms_struct **list, int number)
115 {
116         pstring buf, key;
117         int len;
118         TDB_DATA kbuf,dbuf;
119         int i;
120
121         for (i=0;i<number;i++) {
122                 len = tdb_pack(buf, sizeof(buf), "ddddddd", 
123                                (*list)[i].flag, (*list)[i].width, (*list)[i].length,
124                                (*list)[i].left, (*list)[i].top, (*list)[i].right, 
125                                (*list)[i].bottom);
126                 if (len > sizeof(buf)) break;
127                 slprintf(key, sizeof(key), "%s%s", FORMS_PREFIX, (*list)[i].name);
128                 kbuf.dsize = strlen(key)+1;
129                 kbuf.dptr = key;
130                 dbuf.dsize = len;
131                 dbuf.dptr = buf;
132                 if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) break;
133        }
134
135        return i;
136 }
137
138 /****************************************************************************
139 add a form struct at the end of the list
140 ****************************************************************************/
141 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
142 {
143         int n=0;
144         BOOL update;
145         fstring form_name;
146
147         /* 
148          * NT tries to add forms even when 
149          * they are already in the base
150          * only update the values if already present
151          */
152
153         update=False;
154         
155         unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
156         for (n=0; n<*count && update==False; n++)
157         {
158                 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
159                 {
160                         DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
161                         update=True;
162                 }
163         }
164
165         if (update==False)
166         {
167                 if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
168                         return False;
169                 unistr2_to_ascii((*list)[n].name, &(form->name), sizeof((*list)[n].name)-1);
170                 (*count)++;
171         }
172         
173         (*list)[n].flag=form->flags;
174         (*list)[n].width=form->size_x;
175         (*list)[n].length=form->size_y;
176         (*list)[n].left=form->left;
177         (*list)[n].top=form->top;
178         (*list)[n].right=form->right;
179         (*list)[n].bottom=form->bottom;
180
181         return True;
182 }
183
184 /****************************************************************************
185 update a form struct 
186 ****************************************************************************/
187 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
188 {
189         int n=0;
190         fstring form_name;
191         unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
192
193         DEBUG(106, ("[%s]\n", form_name));
194         for (n=0; n<count; n++)
195         {
196                 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
197                 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
198                         break;
199         }
200
201         if (n==count) return;
202
203         (*list)[n].flag=form->flags;
204         (*list)[n].width=form->size_x;
205         (*list)[n].length=form->size_y;
206         (*list)[n].left=form->left;
207         (*list)[n].top=form->top;
208         (*list)[n].right=form->right;
209         (*list)[n].bottom=form->bottom;
210 }
211  
212 /****************************************************************************
213 get the nt drivers list
214
215 traverse the database and look-up the matching names
216 ****************************************************************************/
217 int get_ntdrivers(fstring **list, char *architecture)
218 {
219         int total=0;
220         fstring short_archi;
221         pstring key;
222         TDB_DATA kbuf, newkey;
223
224         get_short_archi(short_archi, architecture);
225         slprintf(key, sizeof(key), "%s%s/", DRIVERS_PREFIX, short_archi);
226
227         for (kbuf = tdb_firstkey(tdb); 
228              kbuf.dptr; 
229              newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
230                 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
231                 
232                 if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
233                         return -1;
234
235                 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
236                 total++;
237         }
238
239         return(total);
240 }
241
242 /****************************************************************************
243 function to do the mapping between the long architecture name and
244 the short one.
245 ****************************************************************************/
246 void get_short_archi(char *short_archi, char *long_archi)
247 {
248         struct table {
249                 char *long_archi;
250                 char *short_archi;
251         };
252         
253         struct table archi_table[]=
254         {
255                 {"Windows 4.0",          "WIN40"    },
256                 {"Windows NT x86",       "W32X86"   },
257                 {"Windows NT R4000",     "W32mips"  },
258                 {"Windows NT Alpha_AXP", "W32alpha" },
259                 {"Windows NT PowerPC",   "W32ppc"   },
260                 {NULL,                   ""         }
261         };
262         
263         int i=-1;
264
265         DEBUG(107,("Getting architecture dependant directory\n"));
266         do {
267                 i++;
268         } while ( (archi_table[i].long_archi!=NULL ) && strncmp(long_archi, archi_table[i].long_archi, strlen(long_archi)) );
269
270         if (archi_table[i].long_archi==NULL)
271         {
272                 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
273         }
274         StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
275
276         DEBUGADD(108,("index: [%d]\n", i));
277         DEBUGADD(108,("long architecture: [%s]\n", long_archi));
278         DEBUGADD(108,("short architecture: [%s]\n", short_archi));
279 }
280
281 /****************************************************************************
282 ****************************************************************************/
283 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
284 {
285         int len, buflen;
286         fstring architecture;
287         pstring key;
288         char *buf;
289         int i, ret;
290         TDB_DATA kbuf, dbuf;
291
292         get_short_archi(architecture, driver->environment);
293         slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, driver->name);
294
295         /*
296          * cversion must be 2.
297          * when adding a printer ON the SERVER
298          * rpcAddPrinterDriver defines it to zero
299          * which is wrong !!!
300          *
301          * JFM, 4/14/99
302          */
303         driver->cversion=2;
304         
305         buf = NULL;
306         len = buflen = 0;
307
308  again:
309         len = 0;
310         len += tdb_pack(buf+len, buflen-len, "dffffffff", 
311                         driver->cversion,
312                         driver->name,
313                         driver->environment,
314                         driver->driverpath,
315                         driver->datafile,
316                         driver->configfile,
317                         driver->helpfile,
318                         driver->monitorname,
319                         driver->defaultdatatype);
320         
321         if (driver->dependentfiles) {
322                 for (i=0; *driver->dependentfiles[i]; i++) {
323                         len += tdb_pack(buf+len, buflen-len, "f", 
324                                         driver->dependentfiles[i]);
325                 }
326         }
327
328         if (len != buflen) {
329                 buf = (char *)Realloc(buf, len);
330                 buflen = len;
331                 goto again;
332         }
333
334
335         kbuf.dptr = key;
336         kbuf.dsize = strlen(key)+1;
337         dbuf.dptr = buf;
338         dbuf.dsize = len;
339         
340         ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
341
342         safe_free(buf);
343         return ret;
344 }
345
346 /****************************************************************************
347 ****************************************************************************/
348 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
349 {
350         NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
351
352         info3.cversion = driver->version;
353         fstrcpy(info3.environment,driver->environment);
354         fstrcpy(info3.driverpath,driver->driverpath);
355         fstrcpy(info3.datafile,driver->datafile);
356         fstrcpy(info3.configfile,driver->configfile);
357         fstrcpy(info3.helpfile,driver->helpfile);
358         fstrcpy(info3.monitorname,driver->monitorname);
359         fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
360         info3.dependentfiles = driver->dependentfiles;
361
362         return add_a_printer_driver_3(&info3);
363 }
364
365
366 /****************************************************************************
367 ****************************************************************************/
368 static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
369 {
370         NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
371         int snum;
372
373         ZERO_STRUCT(info);
374
375         snum = lp_servicenumber(in_prt);
376
377         fstrcpy(info.name, lp_printerdriver(snum));
378         fstrcpy(info.defaultdatatype, "RAW");
379         
380         if ((info.dependentfiles=(fstring *)malloc(sizeof(fstring))) == NULL)
381                 return ERROR_NOT_ENOUGH_MEMORY;
382
383         fstrcpy(info.dependentfiles[0], "");
384
385         *info_ptr = memdup(&info, sizeof(info));
386         
387         return 0;       
388 }
389
390 /****************************************************************************
391 ****************************************************************************/
392 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
393 {
394         NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
395         TDB_DATA kbuf, dbuf;
396         fstring architecture;
397         int len = 0;
398         int i;
399         pstring key;
400
401         ZERO_STRUCT(driver);
402
403         get_short_archi(architecture, in_arch);
404         slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, in_prt);
405
406         kbuf.dptr = key;
407         kbuf.dsize = strlen(key)+1;
408         
409         dbuf = tdb_fetch(tdb, kbuf);
410         if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
411
412         len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff", 
413                           &driver.cversion,
414                           driver.name,
415                           driver.environment,
416                           driver.driverpath,
417                           driver.datafile,
418                           driver.configfile,
419                           driver.helpfile,
420                           driver.monitorname,
421                           driver.defaultdatatype);
422
423         i=0;
424         while (len < dbuf.dsize) {
425                 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
426                                                          sizeof(fstring)*(i+2));
427                 if (driver.dependentfiles == NULL)
428                         break;
429
430                 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", 
431                                   &driver.dependentfiles[i]);
432                 i++;
433         }
434         if (driver.dependentfiles != NULL)
435                 fstrcpy(driver.dependentfiles[i], "");
436
437         safe_free(dbuf.dptr);
438
439         if (len != dbuf.dsize) {
440                 if (driver.dependentfiles != NULL)
441                         safe_free(driver.dependentfiles);
442
443                 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
444         }
445
446         *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
447
448         return 0;
449 }
450
451 /****************************************************************************
452 debugging function, dump at level 6 the struct in the logs
453 ****************************************************************************/
454 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
455 {
456         uint32 success;
457         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
458         int i;
459         
460         DEBUG(106,("Dumping printer driver at level [%d]\n", level));
461         
462         switch (level)
463         {
464                 case 3: 
465                 {
466                         if (driver.info_3 == NULL)
467                                 success=5;
468                         else {
469                                 info3=driver.info_3;
470                         
471                                 DEBUGADD(106,("version:[%d]\n",         info3->cversion));
472                                 DEBUGADD(106,("name:[%s]\n",            info3->name));
473                                 DEBUGADD(106,("environment:[%s]\n",     info3->environment));
474                                 DEBUGADD(106,("driverpath:[%s]\n",      info3->driverpath));
475                                 DEBUGADD(106,("datafile:[%s]\n",        info3->datafile));
476                                 DEBUGADD(106,("configfile:[%s]\n",      info3->configfile));
477                                 DEBUGADD(106,("helpfile:[%s]\n",        info3->helpfile));
478                                 DEBUGADD(106,("monitorname:[%s]\n",     info3->monitorname));
479                                 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
480                                 
481                                 for (i=0; info3->dependentfiles &&
482                                           *info3->dependentfiles[i]; i++) {
483                                         DEBUGADD(106,("dependentfile:[%s]\n", 
484                                                       info3->dependentfiles[i]));
485                                 }
486                                 success=0;
487                         }
488                         break;
489                 }
490                 default:
491                         DEBUGADD(1,("Level not implemented\n"));
492                         success=1;
493                         break;
494         }
495         
496         return (success);
497 }
498
499 /****************************************************************************
500 ****************************************************************************/
501 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
502 {
503         int len = 0;
504
505         len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
506
507         if (!nt_devmode) return len;
508
509         len += tdb_pack(buf+len, buflen-len, "fwwwwwwwwwwwwwwwwwwddddddddddddddp",
510                         nt_devmode->formname,
511
512                         nt_devmode->specversion,
513                         nt_devmode->driverversion,
514                         nt_devmode->size,
515                         nt_devmode->driverextra,
516                         nt_devmode->orientation,
517                         nt_devmode->papersize,
518                         nt_devmode->paperlength,
519                         nt_devmode->paperwidth,
520                         nt_devmode->scale,
521                         nt_devmode->copies,
522                         nt_devmode->defaultsource,
523                         nt_devmode->printquality,
524                         nt_devmode->color,
525                         nt_devmode->duplex,
526                         nt_devmode->yresolution,
527                         nt_devmode->ttoption,
528                         nt_devmode->collate,
529                         nt_devmode->logpixels,
530                         
531                         nt_devmode->fields,
532                         nt_devmode->bitsperpel,
533                         nt_devmode->pelswidth,
534                         nt_devmode->pelsheight,
535                         nt_devmode->displayflags,
536                         nt_devmode->displayfrequency,
537                         nt_devmode->icmmethod,
538                         nt_devmode->icmintent,
539                         nt_devmode->mediatype,
540                         nt_devmode->dithertype,
541                         nt_devmode->reserved1,
542                         nt_devmode->reserved2,
543                         nt_devmode->panningwidth,
544                         nt_devmode->panningheight,
545                         nt_devmode->private);
546
547         
548         if (nt_devmode->private) {
549                 len += tdb_pack(buf+len, buflen-len, "B",
550                                 nt_devmode->driverextra,
551                                 nt_devmode->private);
552         }
553
554         DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
555
556         return len;
557 }
558
559 /****************************************************************************
560 ****************************************************************************/
561 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
562 {
563         int len = 0;
564
565         while (param != NULL) {
566                 len += tdb_pack(buf+len, buflen-len, "pfdB",
567                                 param,
568                                 param->value, 
569                                 param->type, 
570                                 param->data_len,
571                                 param->data);
572                 param=param->next;      
573         }
574
575         len += tdb_pack(buf+len, buflen-len, "p", param);
576
577         return len;
578 }
579
580
581 /****************************************************************************
582 delete a printer - this just deletes the printer info file, any open
583 handles are not affected
584 ****************************************************************************/
585 uint32 del_a_printer(char *portname)
586 {
587         pstring key;
588         TDB_DATA kbuf;
589
590         slprintf(key, sizeof(key), "%s%s",
591                  PRINTERS_PREFIX, portname);
592
593         kbuf.dptr=key;
594         kbuf.dsize=strlen(key)+1;
595
596         tdb_delete(tdb, kbuf);
597         return 0;
598 }
599
600 /****************************************************************************
601 ****************************************************************************/
602 static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
603 {
604         pstring key;
605         char *buf;
606         int buflen, len, ret;
607         TDB_DATA kbuf, dbuf;
608         
609         /* 
610          * in addprinter: no servername and the printer is the name
611          * in setprinter: servername is \\server
612          *                and printer is \\server\\printer
613          *
614          * Samba manages only local printers.
615          * we currently don't support things like path=\\other_server\printer
616          */
617         if (info->servername[0]!='\0')
618         {
619                 trim_string(info->printername, info->servername, NULL);
620                 trim_string(info->printername, "\\", NULL);
621                 info->servername[0]='\0';
622         }
623
624         /*
625          * JFM: one day I'll forget.
626          * below that's info->portname because that's the SAMBA sharename
627          * and I made NT 'thinks' it's the portname
628          * the info->sharename is the thing you can name when you add a printer
629          * that's the short-name when you create shared printer for 95/98
630          * So I've made a limitation in SAMBA: you can only have 1 printer model
631          * behind a SAMBA share.
632          */
633
634
635         buf = NULL;
636         buflen = 0;
637
638  again: 
639         len = 0;
640         len += tdb_pack(buf+len, buflen-len, "dddddddddddffffffffff",
641                         info->attributes,
642                         info->priority,
643                         info->default_priority,
644                         info->starttime,
645                         info->untiltime,
646                         info->status,
647                         info->cjobs,
648                         info->averageppm,
649                         info->changeid,
650                         info->c_setprinter,
651                         info->setuptime,
652                         info->servername,
653                         info->printername,
654                         info->sharename,
655                         info->portname,
656                         info->drivername,
657                         info->location,
658                         info->sepfile,
659                         info->printprocessor,
660                         info->datatype,
661                         info->parameters);
662
663         len += pack_devicemode(info->devmode, buf+len, buflen-len);
664         len += pack_specifics(info->specific, buf+len, buflen-len);
665
666         if (buflen != len) {
667                 buf = (char *)Realloc(buf, len);
668                 buflen = len;
669                 goto again;
670         }
671         
672
673         slprintf(key, sizeof(key), "%s%s",
674                  PRINTERS_PREFIX, info->portname);
675
676         kbuf.dptr = key;
677         kbuf.dsize = strlen(key)+1;
678         dbuf.dptr = buf;
679         dbuf.dsize = len;
680
681         ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
682
683         safe_free(buf);
684
685         DEBUG(8,("packed printer [%s] with printprocessor [%s] parameters=[%s] len=%d\n", 
686                  info->portname, info->printprocessor, info->parameters, len));
687
688         return ret;
689 }
690
691
692 /****************************************************************************
693 ****************************************************************************/
694 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
695 {
696         NT_PRINTER_PARAM *current;
697         
698         DEBUG(108,("add_a_specific_param\n"));  
699
700         param->next=NULL;
701         
702         if (info_2->specific == NULL)
703         {
704                 info_2->specific=param;
705         }
706         else
707         {
708                 current=info_2->specific;               
709                 while (current->next != NULL) {
710                         current=current->next;
711                 }               
712                 current->next=param;
713         }
714         return (True);
715 }
716
717 /****************************************************************************
718 ****************************************************************************/
719 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
720 {
721         NT_PRINTER_PARAM *current;
722         NT_PRINTER_PARAM *previous;
723         
724         current=info_2->specific;
725         previous=current;
726         
727         if (current==NULL) return (False);
728         
729         if ( !strcmp(current->value, param->value) && 
730             (strlen(current->value)==strlen(param->value)) )
731         {
732                 DEBUG(109,("deleting first value\n"));
733                 info_2->specific=current->next;
734                 safe_free(current->data);
735                 safe_free(current);
736                 DEBUG(109,("deleted first value\n"));
737                 return (True);
738         }
739
740         current=previous->next;
741                 
742         while ( current!=NULL )
743         {
744                 if (!strcmp(current->value, param->value) &&
745                     strlen(current->value)==strlen(param->value) )
746                 {
747                         DEBUG(109,("deleting current value\n"));
748                         previous->next=current->next;
749                         safe_free(current);
750                         DEBUG(109,("deleted current value\n"));
751                         return(True);
752                 }
753                 
754                 previous=previous->next;
755                 current=current->next;
756         }
757         return (False);
758 }
759
760 /****************************************************************************
761  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
762 ****************************************************************************/
763 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
764 {
765         NT_PRINTER_PARAM *param = *param_ptr;
766
767         if(param == NULL)
768                 return;
769
770         DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
771
772         if(param->data)
773                 safe_free(param->data);
774
775         safe_free(param);
776         *param_ptr = NULL;
777 }
778
779 /****************************************************************************
780  Malloc and return an NT devicemode.
781 ****************************************************************************/
782
783 NT_DEVICEMODE *construct_nt_devicemode(void)
784 {
785 /*
786  * should I init this ones ???
787         nt_devmode->devicename
788 */
789
790         NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
791
792         if (nt_devmode == NULL) {
793                 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
794                 return NULL;
795         }
796
797         ZERO_STRUCTP(nt_devmode);
798
799         fstrcpy(nt_devmode->formname, "Letter");
800
801         nt_devmode->specversion      = 0x0401;
802         nt_devmode->driverversion    = 0x0400;
803         nt_devmode->size             = 0x00DC;
804         nt_devmode->driverextra      = 0x0000;
805         nt_devmode->fields           = FORMNAME | TTOPTION | PRINTQUALITY | 
806                                        DEFAULTSOURCE | COPIES | SCALE | 
807                                        PAPERSIZE | ORIENTATION;
808         nt_devmode->orientation      = 1;
809         nt_devmode->papersize        = PAPER_LETTER;
810         nt_devmode->paperlength      = 0;
811         nt_devmode->paperwidth       = 0;
812         nt_devmode->scale            = 0x64;
813         nt_devmode->copies           = 01;
814         nt_devmode->defaultsource    = BIN_FORMSOURCE;
815         nt_devmode->printquality     = 0x0258;
816         nt_devmode->color            = COLOR_MONOCHROME;
817         nt_devmode->duplex           = DUP_SIMPLEX;
818         nt_devmode->yresolution      = 0;
819         nt_devmode->ttoption         = TT_SUBDEV;
820         nt_devmode->collate          = COLLATE_FALSE;
821         nt_devmode->icmmethod        = 0;
822         nt_devmode->icmintent        = 0;
823         nt_devmode->mediatype        = 0;
824         nt_devmode->dithertype       = 0;
825
826         /* non utilisés par un driver d'imprimante */
827         nt_devmode->logpixels        = 0;
828         nt_devmode->bitsperpel       = 0;
829         nt_devmode->pelswidth        = 0;
830         nt_devmode->pelsheight       = 0;
831         nt_devmode->displayflags     = 0;
832         nt_devmode->displayfrequency = 0;
833         nt_devmode->reserved1        = 0;
834         nt_devmode->reserved2        = 0;
835         nt_devmode->panningwidth     = 0;
836         nt_devmode->panningheight    = 0;
837         
838         nt_devmode->private=NULL;
839
840         return nt_devmode;
841 }
842
843 /****************************************************************************
844  Deepcopy an NT devicemode.
845 ****************************************************************************/
846
847 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
848 {
849         NT_DEVICEMODE *new_nt_devicemode = NULL;
850
851         if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
852                 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
853                 return NULL;
854         }
855
856         new_nt_devicemode->private = NULL;
857         if (nt_devicemode->private != NULL) {
858                 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
859                         safe_free(new_nt_devicemode);
860                         DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
861                         return NULL;
862         }
863         }
864
865         return new_nt_devicemode;
866 }
867
868 /****************************************************************************
869  Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
870 ****************************************************************************/
871
872 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
873 {
874         NT_DEVICEMODE *nt_devmode = *devmode_ptr;
875
876         if(nt_devmode == NULL)
877                 return;
878
879         DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
880
881         if(nt_devmode->private)
882                 safe_free(nt_devmode->private);
883
884         safe_free(nt_devmode);
885         *devmode_ptr = NULL;
886 }
887
888 /****************************************************************************
889  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
890 ****************************************************************************/
891 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
892 {
893         NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
894         NT_PRINTER_PARAM *param_ptr;
895
896         if(info == NULL)
897                 return;
898
899         DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
900
901         free_nt_devicemode(&info->devmode);
902         free_sec_desc_buf(&info->secdesc_buf);
903
904         for(param_ptr = info->specific; param_ptr; ) {
905                 NT_PRINTER_PARAM *tofree = param_ptr;
906
907                 param_ptr = param_ptr->next;
908                 free_nt_printer_param(&tofree);
909         }
910
911         safe_free(*info_ptr);
912         *info_ptr = NULL;
913 }
914
915
916 /****************************************************************************
917 ****************************************************************************/
918 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
919 {
920         int len = 0;
921         NT_DEVICEMODE devmode;
922
923         ZERO_STRUCT(devmode);
924
925         len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
926
927         if (!*nt_devmode) return len;
928
929         len += tdb_unpack(buf+len, buflen-len, "fwwwwwwwwwwwwwwwwwwddddddddddddddp",
930                           devmode.formname,
931
932                           &devmode.specversion,
933                           &devmode.driverversion,
934                           &devmode.size,
935                           &devmode.driverextra,
936                           &devmode.orientation,
937                           &devmode.papersize,
938                           &devmode.paperlength,
939                           &devmode.paperwidth,
940                           &devmode.scale,
941                           &devmode.copies,
942                           &devmode.defaultsource,
943                           &devmode.printquality,
944                           &devmode.color,
945                           &devmode.duplex,
946                           &devmode.yresolution,
947                           &devmode.ttoption,
948                           &devmode.collate,
949                           &devmode.logpixels,
950                           
951                           &devmode.fields,
952                           &devmode.bitsperpel,
953                           &devmode.pelswidth,
954                           &devmode.pelsheight,
955                           &devmode.displayflags,
956                           &devmode.displayfrequency,
957                           &devmode.icmmethod,
958                           &devmode.icmintent,
959                           &devmode.mediatype,
960                           &devmode.dithertype,
961                           &devmode.reserved1,
962                           &devmode.reserved2,
963                           &devmode.panningwidth,
964                           &devmode.panningheight,
965                           &devmode.private);
966         
967         if (devmode.private) {
968                 devmode.private = (uint8 *)malloc(devmode.driverextra);
969                 if (!devmode.private) return 2;
970                 len += tdb_unpack(buf+len, buflen-len, "B",
971                                   devmode.driverextra,
972                                   devmode.private);
973         }
974
975         *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
976
977         DEBUG(8,("Unpacked devicemode [%s]\n", devmode.formname));
978
979         return len;
980 }
981
982 /****************************************************************************
983 ****************************************************************************/
984 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
985 {
986         int len = 0;
987         NT_PRINTER_PARAM param, *p;
988
989         *list = NULL;
990
991         while (1) {
992                 len += tdb_unpack(buf+len, buflen-len, "p", &p);
993                 if (!p) break;
994
995                 len += tdb_unpack(buf+len, buflen-len, "fdB",
996                                   param.value, 
997                                   &param.type, 
998                                   &param.data_len,
999                                   &param.data);
1000                 param.next = *list;
1001                 *list = memdup(&param, sizeof(param));
1002         }
1003
1004         return len;
1005 }
1006
1007
1008 /****************************************************************************
1009 get a default printer info 2 struct
1010 ****************************************************************************/
1011 static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1012 {
1013         extern pstring global_myname;
1014         int snum;
1015         NT_PRINTER_INFO_LEVEL_2 info;
1016
1017         ZERO_STRUCT(info);
1018
1019         snum = lp_servicenumber(sharename);
1020
1021         fstrcpy(info.servername, global_myname);
1022         fstrcpy(info.printername, sharename);
1023         fstrcpy(info.portname, sharename);
1024         fstrcpy(info.drivername, lp_printerdriver(snum));
1025         fstrcpy(info.printprocessor, "winprint");
1026         fstrcpy(info.datatype, "RAW");
1027
1028         info.attributes = PRINTER_ATTRIBUTE_SHARED   \
1029                                                 | PRINTER_ATTRIBUTE_LOCAL  \
1030                                                 | PRINTER_ATTRIBUTE_RAW_ONLY ;            /* attributes */
1031
1032         info.starttime = 0; /* Minutes since 12:00am GMT */
1033         info.untiltime = 1440; /* Minutes since 12:00am GMT */
1034
1035         if ((info.devmode = construct_nt_devicemode()) == NULL)
1036                 goto fail;
1037
1038         if (!nt_printing_getsec(sharename, &info.secdesc_buf))
1039                 goto fail;
1040
1041         *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
1042         if (! *info_ptr) {
1043                 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
1044                 goto fail;
1045         }
1046
1047         return (0);     
1048
1049   fail:
1050
1051         if (info.devmode)
1052                 free_nt_devicemode(&info.devmode);
1053         if (info.secdesc_buf)
1054                 free_sec_desc_buf(&info.secdesc_buf);
1055         return 2;
1056 }
1057
1058 /****************************************************************************
1059 ****************************************************************************/
1060 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1061 {
1062         pstring key;
1063         NT_PRINTER_INFO_LEVEL_2 info;
1064         int len = 0;
1065         TDB_DATA kbuf, dbuf;
1066                 
1067         ZERO_STRUCT(info);
1068
1069         slprintf(key, sizeof(key), "%s%s",
1070                  PRINTERS_PREFIX, sharename);
1071
1072         kbuf.dptr = key;
1073         kbuf.dsize = strlen(key)+1;
1074
1075         dbuf = tdb_fetch(tdb, kbuf);
1076         if (!dbuf.dptr) return get_a_printer_2_default(info_ptr, sharename);
1077
1078         len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddffffffffff",
1079                         &info.attributes,
1080                         &info.priority,
1081                         &info.default_priority,
1082                         &info.starttime,
1083                         &info.untiltime,
1084                         &info.status,
1085                         &info.cjobs,
1086                         &info.averageppm,
1087                         &info.changeid,
1088                         &info.c_setprinter,
1089                         &info.setuptime,
1090                         info.servername,
1091                         info.printername,
1092                         info.sharename,
1093                         info.portname,
1094                         info.drivername,
1095                         info.location,
1096                         info.sepfile,
1097                         info.printprocessor,
1098                         info.datatype,
1099                         info.parameters);
1100
1101         info.attributes |= PRINTER_ATTRIBUTE_RAW_ONLY; /* Samba has to have raw drivers. */
1102
1103         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
1104         len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
1105
1106         nt_printing_getsec(sharename, &info.secdesc_buf);
1107
1108         fstrcpy(info.sharename, "");
1109
1110         safe_free(dbuf.dptr);
1111         *info_ptr=memdup(&info, sizeof(info));
1112
1113         DEBUG(9,("Unpacked printprocessor for [%s] of [%s]\n",
1114                  sharename, info.printprocessor));
1115
1116         
1117         return 0;       
1118 }
1119
1120 /****************************************************************************
1121 debugging function, dump at level 6 the struct in the logs
1122 ****************************************************************************/
1123 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1124 {
1125         uint32 success;
1126         NT_PRINTER_INFO_LEVEL_2 *info2;
1127         
1128         DEBUG(106,("Dumping printer at level [%d]\n", level));
1129         
1130         switch (level)
1131         {
1132                 case 2: 
1133                 {
1134                         if (printer.info_2 == NULL)
1135                                 success=5;
1136                         else
1137                         {
1138                                 info2=printer.info_2;
1139                         
1140                                 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
1141                                 DEBUGADD(106,("priority:[%d]\n", info2->priority));
1142                                 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
1143                                 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
1144                                 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
1145                                 DEBUGADD(106,("status:[%d]\n", info2->status));
1146                                 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
1147                                 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
1148                                 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
1149                                 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
1150                                 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
1151
1152                                 DEBUGADD(106,("servername:[%s]\n", info2->servername));
1153                                 DEBUGADD(106,("printername:[%s]\n", info2->printername));
1154                                 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
1155                                 DEBUGADD(106,("portname:[%s]\n", info2->portname));
1156                                 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
1157                                 DEBUGADD(106,("location:[%s]\n", info2->location));
1158                                 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
1159                                 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
1160                                 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
1161                                 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
1162                                 success=0;
1163                         }
1164                         break;
1165                 }
1166                 default:
1167                         DEBUGADD(1,("Level not implemented\n"));
1168                         success=1;
1169                         break;
1170         }
1171         
1172         return (success);
1173 }
1174
1175 /*
1176  * The function below are the high level ones.
1177  * only those ones must be called from the spoolss code.
1178  * JFM.
1179  */
1180
1181
1182 /****************************************************************************
1183 ****************************************************************************/
1184 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1185 {
1186         uint32 success;
1187         
1188         dump_a_printer(printer, level); 
1189         
1190         switch (level)
1191         {
1192                 case 2: 
1193                 {
1194                         success=add_a_printer_2(printer.info_2);
1195                         break;
1196                 }
1197                 default:
1198                         success=1;
1199                         break;
1200         }
1201         
1202         return (success);
1203 }
1204
1205 /****************************************************************************
1206  Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
1207 ****************************************************************************/
1208
1209 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
1210 {
1211         uint32 success;
1212         NT_PRINTER_INFO_LEVEL *printer = NULL;
1213         
1214         *pp_printer = NULL;
1215
1216         DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1217
1218         switch (level)
1219         {
1220                 case 2: 
1221                 {
1222                         if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
1223                                 DEBUG(0,("get_a_printer: malloc fail.\n"));
1224                                 return 1;
1225                         }
1226                         ZERO_STRUCTP(printer);
1227                         success=get_a_printer_2(&printer->info_2, sharename);
1228                         if (success == 0) {
1229                                 dump_a_printer(*printer, level);
1230                                 *pp_printer = printer;
1231                         } else {
1232                                 safe_free(printer);
1233                         }
1234                         break;
1235                 }
1236                 default:
1237                         success=1;
1238                         break;
1239         }
1240         
1241         DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1242
1243         return (success);
1244 }
1245
1246 /****************************************************************************
1247  Deletes a NT_PRINTER_INFO_LEVEL struct.
1248 ****************************************************************************/
1249
1250 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
1251 {
1252         uint32 success;
1253         NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
1254
1255         DEBUG(104,("freeing a printer at level [%d]\n", level));
1256
1257         if (printer == NULL)
1258                 return 0;
1259         
1260         switch (level)
1261         {
1262                 case 2: 
1263                 {
1264                         if (printer->info_2 != NULL)
1265                         {
1266                                 free_nt_printer_info_level_2(&printer->info_2);
1267                                 success=0;
1268                         }
1269                         else
1270                         {
1271                                 success=4;
1272                         }
1273                         break;
1274                 }
1275                 default:
1276                         success=1;
1277                         break;
1278         }
1279
1280         safe_free(printer);
1281         *pp_printer = NULL;
1282         return (success);
1283 }
1284
1285 /****************************************************************************
1286 ****************************************************************************/
1287 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1288 {
1289         uint32 success;
1290         DEBUG(104,("adding a printer at level [%d]\n", level));
1291         dump_a_printer_driver(driver, level);
1292         
1293         switch (level)
1294         {
1295                 case 3: 
1296                 {
1297                         success=add_a_printer_driver_3(driver.info_3);
1298                         break;
1299                 }
1300
1301                 case 6: 
1302                 {
1303                         success=add_a_printer_driver_6(driver.info_6);
1304                         break;
1305                 }
1306                 default:
1307                         success=1;
1308                         break;
1309         }
1310         
1311         return (success);
1312 }
1313 /****************************************************************************
1314 ****************************************************************************/
1315 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, 
1316                             fstring printername, fstring architecture)
1317 {
1318         uint32 success;
1319         
1320         switch (level)
1321         {
1322                 case 3: 
1323                 {
1324                         success=get_a_printer_driver_3(&(driver->info_3), 
1325                                                        printername,
1326                                                        architecture);
1327                         break;
1328                 }
1329                 default:
1330                         success=1;
1331                         break;
1332         }
1333         
1334         if (success == 0) dump_a_printer_driver(*driver, level);
1335         return (success);
1336 }
1337
1338 /****************************************************************************
1339 ****************************************************************************/
1340 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1341 {
1342         uint32 success;
1343         
1344         switch (level)
1345         {
1346                 case 3: 
1347                 {
1348                         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1349                         if (driver.info_3 != NULL)
1350                         {
1351                                 info3=driver.info_3;
1352                                 safe_free(info3->dependentfiles);
1353                                 ZERO_STRUCTP(info3);
1354                                 safe_free(info3);
1355                                 success=0;
1356                         }
1357                         else
1358                         {
1359                                 success=4;
1360                         }
1361                         break;
1362                 }
1363                 case 6: 
1364                 {
1365                         NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
1366                         if (driver.info_6 != NULL)
1367                         {
1368                                 info6=driver.info_6;
1369                                 safe_free(info6->dependentfiles);
1370                                 ZERO_STRUCTP(info6);
1371                                 safe_free(info6);
1372                                 success=0;
1373                         }
1374                         else
1375                         {
1376                                 success=4;
1377                         }
1378                         break;
1379                 }
1380                 default:
1381                         success=1;
1382                         break;
1383         }
1384         return (success);
1385 }
1386
1387 /****************************************************************************
1388 ****************************************************************************/
1389 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
1390                                  fstring value, uint8 **data, uint32 *type, uint32 *len)
1391 {
1392         /* right now that's enough ! */ 
1393         NT_PRINTER_PARAM *param;
1394         int i=0;
1395         
1396         param=printer.info_2->specific;
1397         
1398         while (param != NULL && i <= param_index)
1399         {
1400                 param=param->next;
1401                 i++;
1402         }
1403         
1404         if (param == NULL)
1405                 return False;
1406
1407         /* exited because it exist */
1408         *type=param->type;              
1409         StrnCpy(value, param->value, sizeof(fstring)-1);
1410         *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1411         if(*data == NULL)
1412                 return False;
1413         memcpy(*data, param->data, param->data_len);
1414         *len=param->data_len;
1415         return True;
1416 }
1417
1418 /****************************************************************************
1419 ****************************************************************************/
1420 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level, 
1421                         fstring value, uint8 **data, uint32 *type, uint32 *len)
1422 {
1423         /* right now that's enough ! */ 
1424         NT_PRINTER_PARAM *param;
1425         
1426         DEBUG(105, ("get_specific_param\n"));
1427         
1428         param=printer.info_2->specific;
1429                 
1430         while (param != NULL)
1431         {
1432                 if ( !strcmp(value, param->value) 
1433                     && strlen(value)==strlen(param->value))
1434                         break;
1435                         
1436                 param=param->next;
1437         }
1438         
1439         DEBUG(106, ("found one param\n"));
1440         if (param != NULL)
1441         {
1442                 /* exited because it exist */
1443                 *type=param->type;      
1444                 
1445                 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1446                 if(*data == NULL)
1447                         return False;
1448                 memcpy(*data, param->data, param->data_len);
1449                 *len=param->data_len;
1450
1451                 DEBUG(106, ("exit of get_specific_param:true\n"));
1452                 return (True);
1453         }
1454         DEBUG(106, ("exit of get_specific_param:false\n"));
1455         return (False);
1456 }
1457
1458
1459 /****************************************************************************
1460 store a security desc for a printer
1461 ****************************************************************************/
1462 uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
1463 {
1464         prs_struct ps;
1465         fstring key;
1466         uint32 status;
1467
1468         prs_init(&ps, (uint32)sec_desc_size(secdesc_ctr->sec), 4, MARSHALL);
1469
1470         if (!sec_io_desc_buf("nt_printing_setsec", &secdesc_ctr, &ps, 1)) {
1471                 status = ERROR_INVALID_FUNCTION;
1472                 goto out;
1473         }
1474
1475         slprintf(key, sizeof(key), "SECDESC/%s", printername);
1476
1477         if (tdb_prs_store(tdb, key, &ps)==0) {
1478                 status = 0;
1479         } else {
1480                 DEBUG(1,("Failed to store secdesc for %s\n", printername));
1481                 status = ERROR_INVALID_FUNCTION;
1482         }
1483
1484  out:
1485         prs_mem_free(&ps);
1486         return status;
1487 }
1488
1489 /****************************************************************************
1490  Construct a default security descriptor buffer for a printer.
1491 ****************************************************************************/
1492
1493 static SEC_DESC_BUF *construct_default_printer_sdb(void)
1494 {
1495         extern DOM_SID global_sid_World; 
1496         SEC_DESC_BUF *sdb = NULL;
1497         size_t sd_size;
1498         SEC_DESC *psd = make_sec_desc(1, SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
1499                                                                 &global_sid_World, &global_sid_World,
1500                                                                 NULL, NULL, &sd_size);
1501
1502         if (!psd) {
1503                 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
1504                 return NULL;
1505         }
1506
1507         sdb = make_sec_desc_buf(sd_size, psd);
1508
1509         free_sec_desc(&psd);
1510         return sdb;
1511 }
1512
1513 /****************************************************************************
1514  Get a security desc for a printer.
1515 ****************************************************************************/
1516
1517 BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr)
1518 {
1519         prs_struct ps;
1520         fstring key;
1521
1522         slprintf(key, sizeof(key), "SECDESC/%s", printername);
1523
1524         if (tdb_prs_fetch(tdb, key, &ps)!=0 ||
1525             !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
1526
1527                 DEBUG(4,("using default secdesc for %s\n", printername));
1528
1529                 if (!(*secdesc_ctr = construct_default_printer_sdb()))
1530                         return False;
1531
1532                 return True;
1533         }
1534
1535         prs_mem_free(&ps);
1536         return True;
1537 }
1538
1539 /* error code:
1540         0: everything OK
1541         1: level not implemented
1542         2: file doesn't exist
1543         3: can't allocate memory
1544         4: can't free memory
1545         5: non existant struct
1546 */
1547
1548 /*
1549         A printer and a printer driver are 2 different things.
1550         NT manages them separatelly, Samba does the same.
1551         Why ? Simply because it's easier and it makes sense !
1552         
1553         Now explanation: You have 3 printers behind your samba server,
1554         2 of them are the same make and model (laser A and B). But laser B 
1555         has an 3000 sheet feeder and laser A doesn't such an option.
1556         Your third printer is an old dot-matrix model for the accounting :-).
1557         
1558         If the /usr/local/samba/lib directory (default dir), you will have
1559         5 files to describe all of this.
1560         
1561         3 files for the printers (1 by printer):
1562                 NTprinter_laser A
1563                 NTprinter_laser B
1564                 NTprinter_accounting
1565         2 files for the drivers (1 for the laser and 1 for the dot matrix)
1566                 NTdriver_printer model X
1567                 NTdriver_printer model Y
1568
1569 jfm: I should use this comment for the text file to explain 
1570         same thing for the forms BTW.
1571         Je devrais mettre mes commentaires en francais, ca serait mieux :-)
1572
1573 */
1574
1575