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