printing/nt_printing.c: use getpwuid not smbgetpwuid. Canonicalize printernames.
[samba.git] / source3 / printing / nt_printing.c
1 #define OLD_NTDOMAIN 1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-2000,
7  *  Copyright (C) Jean François Micouleau      1998-2000.
8  *  
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *  
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *  
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #include "includes.h"
25
26 extern int DEBUGLEVEL;
27 extern pstring global_myname;
28 extern DOM_SID global_sid_World; 
29
30 static TDB_CONTEXT *tdb; /* used for driver files */
31
32 #define FORMS_PREFIX "FORMS/"
33 #define DRIVERS_PREFIX "DRIVERS/"
34 #define PRINTERS_PREFIX "PRINTERS/"
35
36 #define DATABASE_VERSION 1
37
38 /* We need one default form to support our default printer. Msoft adds the
39 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
40 array index). Letter is always first, so (for the current code) additions
41 always put things in the correct order. */
42 static nt_forms_struct default_forms[] = {
43         {"Letter", 0x2, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367},
44 };
45
46
47 /****************************************************************************
48 open the NT printing tdb
49 ****************************************************************************/
50 BOOL nt_printing_init(void)
51 {
52         static pid_t local_pid;
53         char *vstring = "INFO/version";
54
55         if (tdb && local_pid == sys_getpid()) return True;
56         tdb = tdb_open(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
57         if (!tdb) {
58                 DEBUG(0,("Failed to open nt drivers database\n"));
59                 return False;
60         }
61
62         local_pid = sys_getpid();
63
64         /* handle a Samba upgrade */
65         tdb_lock_bystring(tdb, vstring);
66         if (tdb_fetch_int(tdb, vstring) != DATABASE_VERSION) {
67                 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
68                 tdb_store_int(tdb, vstring, DATABASE_VERSION);
69         }
70         tdb_unlock_bystring(tdb, vstring);
71
72         return True;
73 }
74
75   
76 /****************************************************************************
77 get a form struct list
78 ****************************************************************************/
79 int get_ntforms(nt_forms_struct **list)
80 {
81         TDB_DATA kbuf, newkey, dbuf;
82         nt_forms_struct form;
83         int ret;
84         int i;
85         int n = 0;
86
87         for (kbuf = tdb_firstkey(tdb); 
88              kbuf.dptr; 
89              newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
90                 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
91                 
92                 dbuf = tdb_fetch(tdb, kbuf);
93                 if (!dbuf.dptr) continue;
94
95                 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
96                 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
97                                  &i, &form.flag, &form.width, &form.length, &form.left,
98                                  &form.top, &form.right, &form.bottom);
99                 safe_free(dbuf.dptr);
100                 if (ret != dbuf.dsize) continue;
101
102                 /* allocate space and populate the list in correct order */
103                 if (i+1 > n) {
104                         *list = Realloc(*list, sizeof(nt_forms_struct)*(i+1));
105                         n = i+1;
106                 }
107                 (*list)[i] = form;
108         }
109
110         /* we should never return a null forms list or NT gets unhappy */
111         if (n == 0) {
112                 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
113                 n = sizeof(default_forms) / sizeof(default_forms[0]);
114         }
115         
116
117         return n;
118 }
119
120 /****************************************************************************
121 write a form struct list
122 ****************************************************************************/
123 int write_ntforms(nt_forms_struct **list, int number)
124 {
125         pstring buf, key;
126         int len;
127         TDB_DATA kbuf,dbuf;
128         int i;
129
130         for (i=0;i<number;i++) {
131                 /* save index, so list is rebuilt in correct order */
132                 len = tdb_pack(buf, sizeof(buf), "dddddddd",
133                                i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
134                                (*list)[i].left, (*list)[i].top, (*list)[i].right, 
135                                (*list)[i].bottom);
136                 if (len > sizeof(buf)) break;
137                 slprintf(key, sizeof(key), "%s%s", FORMS_PREFIX, (*list)[i].name);
138                 kbuf.dsize = strlen(key)+1;
139                 kbuf.dptr = key;
140                 dbuf.dsize = len;
141                 dbuf.dptr = buf;
142                 if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) break;
143        }
144
145        return i;
146 }
147
148 /****************************************************************************
149 add a form struct at the end of the list
150 ****************************************************************************/
151 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
152 {
153         int n=0;
154         BOOL update;
155         fstring form_name;
156
157         /* 
158          * NT tries to add forms even when 
159          * they are already in the base
160          * only update the values if already present
161          */
162
163         update=False;
164         
165         unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
166         for (n=0; n<*count && update==False; n++)
167         {
168                 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
169                 {
170                         DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
171                         update=True;
172                 }
173         }
174
175         if (update==False)
176         {
177                 if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
178                         return False;
179                 unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
180                 (*count)++;
181         }
182         
183         (*list)[n].flag=form->flags;
184         (*list)[n].width=form->size_x;
185         (*list)[n].length=form->size_y;
186         (*list)[n].left=form->left;
187         (*list)[n].top=form->top;
188         (*list)[n].right=form->right;
189         (*list)[n].bottom=form->bottom;
190
191         return True;
192 }
193
194 /****************************************************************************
195  delete a named form struct 
196 ****************************************************************************/
197 BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, uint32 *ret)
198 {
199         pstring key;
200         TDB_DATA kbuf;
201         int n=0;
202         fstring form_name;
203
204         *ret = 0;
205
206         if (*count == 1) {
207                 /*
208                  * Don't delete the last form (no empty lists).
209                  * CHECKME ! Is this correct ? JRA.
210                  */
211                 *ret = ERROR_INVALID_PARAMETER;
212                 return False;
213         }
214
215         unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
216
217         for (n=0; n<*count; n++) {
218                 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
219                         DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
220                         break;
221                 }
222         }
223
224         if (n == *count) {
225                 DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
226                 *ret = ERROR_INVALID_PARAMETER;
227                 return False;
228         }
229
230         slprintf(key, sizeof(key), "%s%s", FORMS_PREFIX, (*list)[n].name);
231         kbuf.dsize = strlen(key)+1;
232         kbuf.dptr = key;
233         if (tdb_delete(tdb, kbuf) != 0) {
234                 *ret = ERROR_NOT_ENOUGH_MEMORY;
235                 return False;
236         }
237
238         return True;
239 }
240
241 /****************************************************************************
242 update a form struct 
243 ****************************************************************************/
244 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
245 {
246         int n=0;
247         fstring form_name;
248         unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
249
250         DEBUG(106, ("[%s]\n", form_name));
251         for (n=0; n<count; n++)
252         {
253                 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
254                 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
255                         break;
256         }
257
258         if (n==count) return;
259
260         (*list)[n].flag=form->flags;
261         (*list)[n].width=form->size_x;
262         (*list)[n].length=form->size_y;
263         (*list)[n].left=form->left;
264         (*list)[n].top=form->top;
265         (*list)[n].right=form->right;
266         (*list)[n].bottom=form->bottom;
267 }
268  
269 /****************************************************************************
270 get the nt drivers list
271
272 traverse the database and look-up the matching names
273 ****************************************************************************/
274 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
275 {
276         int total=0;
277         fstring short_archi;
278         pstring key;
279         TDB_DATA kbuf, newkey;
280
281         get_short_archi(short_archi, architecture);
282         slprintf(key, sizeof(key), "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
283
284         for (kbuf = tdb_firstkey(tdb); 
285              kbuf.dptr; 
286              newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
287                 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
288                 
289                 if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
290                         return -1;
291
292                 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
293                 total++;
294         }
295
296         return(total);
297 }
298
299 /****************************************************************************
300 function to do the mapping between the long architecture name and
301 the short one.
302 ****************************************************************************/
303 BOOL get_short_archi(char *short_archi, char *long_archi)
304 {
305         struct table {
306                 char *long_archi;
307                 char *short_archi;
308         };
309         
310         struct table archi_table[]=
311         {
312                 {"Windows 4.0",          "WIN40"    },
313                 {"Windows NT x86",       "W32X86"   },
314                 {"Windows NT R4000",     "W32MIPS"  },
315                 {"Windows NT Alpha_AXP", "W32ALPHA" },
316                 {"Windows NT PowerPC",   "W32PPC"   },
317                 {NULL,                   ""         }
318         };
319         
320         int i=-1;
321
322         DEBUG(107,("Getting architecture dependant directory\n"));
323         do {
324                 i++;
325         } while ( (archi_table[i].long_archi!=NULL ) && 
326                   StrCaseCmp(long_archi, archi_table[i].long_archi) );
327
328         if (archi_table[i].long_archi==NULL) {
329                 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
330                 return FALSE;
331         }
332
333         StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
334
335         DEBUGADD(108,("index: [%d]\n", i));
336         DEBUGADD(108,("long architecture: [%s]\n", long_archi));
337         DEBUGADD(108,("short architecture: [%s]\n", short_archi));
338         
339         return TRUE;
340 }
341
342 /****************************************************************************
343 Determine the correct cVersion associated with an architecture and driver
344 ****************************************************************************/
345 static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in)
346 {
347         int  fd = -1;
348         int  service;
349         int  cversion;
350         ssize_t  byte_count;
351         char buf[PE_HEADER_SIZE];
352         pstring driverpath;
353
354         /* If architecture is Windows 95/98, the version is always 0. */
355         if (strcmp(architecture, "WIN40") == 0) {
356                 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
357                 return 0;
358         }
359         
360         /* Open the driver file (Portable Executable format) and determine the
361          * deriver the cversion.
362          */
363         if ((service = find_service("print$")) == -1) {
364                 DEBUG(3,("get_correct_cversion: Can't find print$ service\n"));
365                 goto error_exit;
366         }
367
368         slprintf(driverpath, sizeof(driverpath), "%s/%s/%s",
369                          lp_pathname(service), architecture, driverpath_in);
370
371         dos_to_unix(driverpath, True);
372
373         if ((fd = sys_open(driverpath, O_RDONLY, 0)) == -1) {
374                 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
375                                 driverpath, errno));
376                 goto error_exit;
377         }
378          
379         if ((byte_count = read(fd, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
380                 DEBUG(3,("get_correct_cversion: File [%s] DOS header too short, bytes read = %d\n",
381                                 driverpath, byte_count));
382                 goto error_exit;
383         }
384
385         /* Is this really a DOS header? */
386         if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
387                 DEBUG(6,("get_correct_cversion: File [%s] bad DOS magic = 0x%x\n",
388                                 driverpath, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
389                 goto error_exit;
390         }
391
392         /* Skip OEM header (if any) and the DOS stub to start of Windows header */
393         if (sys_lseek(fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
394                 DEBUG(3,("get_correct_cversion: File [%s] too short, errno = %d\n",
395                                 driverpath, errno));
396                 goto error_exit;
397         }
398
399         if ((byte_count = read(fd, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
400                 DEBUG(3,("get_correct_cversion: File [%s] Windows header too short, bytes read = %d\n",
401                                 driverpath, byte_count));
402                 goto error_exit;
403         }
404         close(fd);
405
406         /* The header may be a PE (Portable Executable) or an NE (New Executable) */
407         if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
408                 if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) == PE_HEADER_MACHINE_I386) {
409
410                         switch (SVAL(buf,PE_HEADER_MAJOR_OS_VER_OFFSET)) {
411                                 case 4: cversion = 2; break;    /* Win NT 4 */
412                                 case 5: cversion = 3; break;    /* Win 2000 */
413                                 default:
414                                         DEBUG(6,("get_correct_cversion: PE formated file [%s] bad version = %d\n",
415                                                         driverpath, SVAL(buf,PE_HEADER_MAJOR_OS_VER_OFFSET)));
416                                         goto error_exit;
417                         }
418                 } else {
419                         DEBUG(6,("get_correct_cversion: PE formatted file [%s] wrong machine = 0x%x\n",
420                                         driverpath, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
421                         goto error_exit;
422                 }
423
424         } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
425                 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) == NE_HEADER_TARGOS_WIN ) {
426
427                         switch (CVAL(buf,NE_HEADER_MAJOR_VER_OFFSET)) {
428                                 case 3: cversion = 0; break;    /* Win 3.x / Win 9x / Win ME */
429                         /*      case ?: cversion = 1; break;*/  /* Win NT 3.51 ... needs research JRR */
430                                 default:
431                                         DEBUG(6,("get_correct_cversion: NE formated file [%s] bad version = %d\n",
432                                                         driverpath, CVAL(buf,NE_HEADER_MAJOR_VER_OFFSET)));
433                                         goto error_exit;
434                         }
435                 } else {
436                         DEBUG(6,("get_correct_cversion: NE formatted file [%s] wrong target OS = 0x%x\n",
437                                         driverpath, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
438                         goto error_exit;
439                 }
440
441         } else {
442                 DEBUG(6,("get_correct_cversion: Unknown file format [%s], signature = 0x%x\n",
443                                 driverpath, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
444                 goto error_exit;
445         }
446
447         DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
448                         driverpath, cversion));
449         return cversion;
450
451
452         error_exit:
453                 if(fd != -1)
454                         close(fd);
455                 return -1;
456 }
457
458 /****************************************************************************
459 ****************************************************************************/
460 static uint32 clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
461 {
462         fstring architecture;
463         fstring new_name;
464         char *p;
465         int i;
466
467         /* clean up the driver name.
468          * we can get .\driver.dll
469          * or worse c:\windows\system\driver.dll !
470          */
471         /* using an intermediate string to not have overlaping memcpy()'s */
472         if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
473                 fstrcpy(new_name, p+1);
474                 fstrcpy(driver->driverpath, new_name);
475         }
476
477         if ((p = strrchr(driver->datafile,'\\')) != NULL) {
478                 fstrcpy(new_name, p+1);
479                 fstrcpy(driver->datafile, new_name);
480         }
481
482         if ((p = strrchr(driver->configfile,'\\')) != NULL) {
483                 fstrcpy(new_name, p+1);
484                 fstrcpy(driver->configfile, new_name);
485         }
486
487         if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
488                 fstrcpy(new_name, p+1);
489                 fstrcpy(driver->helpfile, new_name);
490         }
491
492         if (driver->dependentfiles) {
493                 for (i=0; *driver->dependentfiles[i]; i++) {
494                         if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
495                                 fstrcpy(new_name, p+1);
496                                 fstrcpy(driver->dependentfiles[i], new_name);
497                         }
498                 }
499         }
500
501         get_short_archi(architecture, driver->environment);
502         
503         /* jfm:7/16/2000 the client always sends the cversion=0.
504          * The server should check which version the driver is by reading
505          * the PE header of driver->driverpath.
506          *
507          * For Windows 95/98 the version is 0 (so the value sent is correct)
508          * For Windows NT (the architecture doesn't matter)
509          *      NT 3.1: cversion=0
510          *      NT 3.5/3.51: cversion=1
511          *      NT 4: cversion=2
512          *      NT2K: cversion=3
513          */
514         if ((driver->cversion = get_correct_cversion(architecture,
515                                                                                         driver->driverpath)) == -1)
516                 return NT_STATUS_FILE_INVALID;     /* Not the best error. Fix JRR */
517
518         return NT_STATUS_NO_PROBLEMO;
519 }
520          
521 /****************************************************************************
522 ****************************************************************************/
523 static uint32 clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
524 {
525         fstring architecture;
526         fstring new_name;
527         char *p;
528         int i;
529
530         /* clean up the driver name.
531          * we can get .\driver.dll
532          * or worse c:\windows\system\driver.dll !
533          */
534         /* using an intermediate string to not have overlaping memcpy()'s */
535         if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
536                 fstrcpy(new_name, p+1);
537                 fstrcpy(driver->driverpath, new_name);
538         }
539
540         if ((p = strrchr(driver->datafile,'\\')) != NULL) {
541                 fstrcpy(new_name, p+1);
542                 fstrcpy(driver->datafile, new_name);
543         }
544
545         if ((p = strrchr(driver->configfile,'\\')) != NULL) {
546                 fstrcpy(new_name, p+1);
547                 fstrcpy(driver->configfile, new_name);
548         }
549
550         if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
551                 fstrcpy(new_name, p+1);
552                 fstrcpy(driver->helpfile, new_name);
553         }
554
555         if (driver->dependentfiles) {
556                 for (i=0; *driver->dependentfiles[i]; i++) {
557                         if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
558                                 fstrcpy(new_name, p+1);
559                                 fstrcpy(driver->dependentfiles[i], new_name);
560                         }
561                 }
562         }
563
564         get_short_archi(architecture, driver->environment);
565
566         /* jfm:7/16/2000 the client always sends the cversion=0.
567          * The server should check which version the driver is by reading
568          * the PE header of driver->driverpath.
569          *
570          * For Windows 95/98 the version is 0 (so the value sent is correct)
571          * For Windows NT (the architecture doesn't matter)
572          *      NT 3.1: cversion=0
573          *      NT 3.5/3.51: cversion=1
574          *      NT 4: cversion=2
575          *      NT2K: cversion=3
576          */
577         if ((driver->version = get_correct_cversion(architecture,
578                                                                                         driver->driverpath)) == -1)
579                 return NT_STATUS_FILE_INVALID;     /* Not the best error. Fix JRR */
580
581         return NT_STATUS_NO_PROBLEMO;
582 }
583
584 /****************************************************************************
585 ****************************************************************************/
586 uint32 clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level)
587 {
588         switch (level) {
589                 case 3:
590                 {
591                         NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
592                         driver=driver_abstract.info_3;
593                         return clean_up_driver_struct_level_3(driver);
594                         break;
595                 }
596                 case 6:
597                 {
598                         NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
599                         driver=driver_abstract.info_6;
600                         return clean_up_driver_struct_level_6(driver);
601                         break;
602                 }
603                 default:
604                         return ERROR_INVALID_PARAMETER;
605         }
606 }
607
608 /****************************************************************************
609  This function sucks and should be replaced. JRA.
610 ****************************************************************************/
611
612 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
613 {
614     dst->cversion  = src->version;
615
616     fstrcpy( dst->name, src->name);
617     fstrcpy( dst->environment, src->environment);
618     fstrcpy( dst->driverpath, src->driverpath);
619     fstrcpy( dst->datafile, src->datafile);
620     fstrcpy( dst->configfile, src->configfile);
621     fstrcpy( dst->helpfile, src->helpfile);
622     fstrcpy( dst->monitorname, src->monitorname);
623     fstrcpy( dst->defaultdatatype, src->defaultdatatype);
624     dst->dependentfiles = src->dependentfiles;
625 }
626
627
628 /****************************************************************************
629 ****************************************************************************/
630 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user, uint32 *perr)
631 {
632         NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
633         NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
634         fstring architecture;
635         pstring new_dir;
636         pstring old_name;
637         pstring new_name;
638         fstring user_name;
639         fstring null_pw;
640         connection_struct *conn;
641         pstring inbuf;
642         pstring outbuf;
643         struct passwd *pass;
644         int ecode;
645         int outsize = 0;
646         int i;
647
648         *perr = 0;
649         memset(inbuf, '\0', sizeof(inbuf));
650         memset(outbuf, '\0', sizeof(outbuf));
651
652         if (level==3)
653                 driver=driver_abstract.info_3;
654         else if (level==6) {
655                 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
656                 driver = &converted_driver;
657         } else {
658                 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
659                 return False;
660         }
661
662         get_short_archi(architecture, driver->environment);
663
664         become_root();
665         pass = getpwuid(user->uid);
666         if(pass == NULL) {
667                 DEBUG(0,("move_driver_to_download_area: Unable to get passwd entry for uid %u\n",
668                                 (unsigned int)user->uid ));
669                 unbecome_root();
670                 return False;
671         }
672         unbecome_root();
673
674         /* connect to the print$ share under the same account as the user connected to the rpc pipe */  
675         fstrcpy(user_name, pass->pw_name );
676         DEBUG(10,("move_driver_to_download_area: uid %d -> user %s\n", (int)user->uid, user_name));
677
678         /* Null password is ok - we are already an authenticated user... */
679         *null_pw = '\0';
680         conn = make_connection("print$", user_name, null_pw, 0, "A:", user->vuid, &ecode);
681
682         if (conn == NULL) {
683                 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
684                 *perr = (uint32)ecode;
685                 return False;
686         }
687
688         /*
689          * Save who we are - we are temporarily becoming the connection user.
690          */
691
692         push_sec_ctx();
693
694         if (!become_user(conn, conn->vuid)) {
695                 DEBUG(0,("move_driver_to_download_area: Can't become user %s\n", user_name ));
696                 pop_sec_ctx();
697                 return False;
698         }
699
700         /* 
701          * make the directories version and version\driver_name 
702          * under the architecture directory.
703          */
704         DEBUG(5,("Creating first directory\n"));
705         slprintf(new_dir, sizeof(new_dir), "%s\\%d", architecture, driver->cversion);
706         mkdir_internal(conn, inbuf, outbuf, new_dir);
707
708         /* move all the files, one by one, 
709          * from archi\filexxx.yyy to
710          * archi\version\filexxx.yyy
711          *
712          * Note: drivers may list the same file name in several places. This
713          * causes problems on a second attempt to move the file. JRR
714          *
715          * Note: use the replace flag on rename_internals() call, otherwise it
716          * is very difficult to change previously installed drivers... the Windows
717          * GUI offers the user the choice to replace or keep exisitng driver. JRR
718          */
719
720         DEBUG(5,("Moving file now !\n"));
721
722         if (driver->driverpath && strlen(driver->driverpath)) {
723         slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->driverpath);       
724         slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->driverpath);    
725         if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
726                 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
727                                 old_name, new_name ));
728                 close_cnum(conn, user->vuid);
729                 pop_sec_ctx();
730                 *perr = (uint32)SVAL(outbuf,smb_err);
731                 return False;
732         }
733         }
734
735         if (driver->datafile && strlen(driver->datafile)) {
736         if (!strequal(driver->datafile, driver->driverpath)) {
737                 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->datafile); 
738                 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->datafile);      
739                 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
740                         DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
741                                         old_name, new_name ));
742                         close_cnum(conn, user->vuid);
743                         pop_sec_ctx();
744                         *perr = (uint32)SVAL(outbuf,smb_err);
745                         return False;
746                 }
747         }
748         }
749
750         if (driver->configfile && strlen(driver->configfile)) {
751         if (!strequal(driver->configfile, driver->driverpath) &&
752                 !strequal(driver->configfile, driver->datafile)) {
753                 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->configfile);       
754                 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->configfile);    
755                 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
756                         DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
757                                 old_name, new_name ));
758                         close_cnum(conn, user->vuid);
759                         pop_sec_ctx();
760                         *perr = (uint32)SVAL(outbuf,smb_err);
761                         return False;
762                 }
763         }
764         }
765
766         if (driver->helpfile && strlen(driver->helpfile)) {
767         if (!strequal(driver->helpfile, driver->driverpath) &&
768                         !strequal(driver->helpfile, driver->datafile) &&
769                         !strequal(driver->helpfile, driver->configfile)) {
770                 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->helpfile); 
771                 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->helpfile);      
772                 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
773                         DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
774                                 old_name, new_name ));
775                         close_cnum(conn, user->vuid);
776                         pop_sec_ctx();
777                         *perr = (uint32)SVAL(outbuf,smb_err);
778                         return False;
779                 }
780         }
781         }
782
783         if (driver->dependentfiles) {
784                 for (i=0; *driver->dependentfiles[i]; i++) {
785                         if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
786                                         !strequal(driver->dependentfiles[i], driver->datafile) &&
787                                         !strequal(driver->dependentfiles[i], driver->configfile) &&
788                                         !strequal(driver->dependentfiles[i], driver->helpfile)) {
789                                 int j;
790                                 for (j=0; j < i; j++) {
791                                         if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
792                                                 goto NextDriver;
793                                         }
794                                 }
795
796                                 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->dependentfiles[i]);        
797                                 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->dependentfiles[i]);     
798                                 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
799                                         DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
800                                                 old_name, new_name ));
801                                         close_cnum(conn, user->vuid);
802                                         pop_sec_ctx();
803                                         *perr = (uint32)SVAL(outbuf,smb_err);
804                                         return False;
805                                 }
806                         }
807                 NextDriver: ;
808                 }
809         }
810
811         close_cnum(conn, user->vuid);
812         pop_sec_ctx();
813
814         return True;
815 }
816
817 /****************************************************************************
818 ****************************************************************************/
819 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
820 {
821         int len, buflen;
822         fstring architecture;
823         pstring directory;
824         pstring temp_name;
825         pstring key;
826         char *buf;
827         int i, ret;
828         TDB_DATA kbuf, dbuf;
829
830         get_short_archi(architecture, driver->environment);
831
832         /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
833          * \\server is added in the rpc server layer.
834          * It does make sense to NOT store the server's name in the printer TDB.
835          */
836
837         slprintf(directory, sizeof(directory), "\\print$\\%s\\%d\\", architecture, driver->cversion);
838
839         
840         fstrcpy(temp_name, driver->driverpath);
841         slprintf(driver->driverpath, sizeof(driver->driverpath), "%s%s", directory, temp_name);
842
843         fstrcpy(temp_name, driver->datafile);
844         slprintf(driver->datafile, sizeof(driver->datafile), "%s%s", directory, temp_name);
845
846         fstrcpy(temp_name, driver->configfile);
847         slprintf(driver->configfile, sizeof(driver->configfile), "%s%s", directory, temp_name);
848
849         fstrcpy(temp_name, driver->helpfile);
850         slprintf(driver->helpfile, sizeof(driver->helpfile), "%s%s", directory, temp_name);
851
852         if (driver->dependentfiles) {
853                 for (i=0; *driver->dependentfiles[i]; i++) {
854                         fstrcpy(temp_name, driver->dependentfiles[i]);
855                         slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i]), "%s%s", directory, temp_name);
856                 }
857         }
858
859         slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
860
861         DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
862
863         buf = NULL;
864         len = buflen = 0;
865
866  again:
867         len = 0;
868         len += tdb_pack(buf+len, buflen-len, "dffffffff", 
869                         driver->cversion,
870                         driver->name,
871                         driver->environment,
872                         driver->driverpath,
873                         driver->datafile,
874                         driver->configfile,
875                         driver->helpfile,
876                         driver->monitorname,
877                         driver->defaultdatatype);
878
879         if (driver->dependentfiles) {
880                 for (i=0; *driver->dependentfiles[i]; i++) {
881                         len += tdb_pack(buf+len, buflen-len, "f", 
882                                         driver->dependentfiles[i]);
883                 }
884         }
885
886         if (len != buflen) {
887                 buf = (char *)Realloc(buf, len);
888                 buflen = len;
889                 goto again;
890         }
891
892
893         kbuf.dptr = key;
894         kbuf.dsize = strlen(key)+1;
895         dbuf.dptr = buf;
896         dbuf.dsize = len;
897         
898         ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
899
900         if (ret)
901                 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
902
903         safe_free(buf);
904         return ret;
905 }
906
907 /****************************************************************************
908 ****************************************************************************/
909 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
910 {
911         NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
912
913         ZERO_STRUCT(info3);
914         info3.cversion = driver->version;
915         fstrcpy(info3.name,driver->name);
916         fstrcpy(info3.environment,driver->environment);
917         fstrcpy(info3.driverpath,driver->driverpath);
918         fstrcpy(info3.datafile,driver->datafile);
919         fstrcpy(info3.configfile,driver->configfile);
920         fstrcpy(info3.helpfile,driver->helpfile);
921         fstrcpy(info3.monitorname,driver->monitorname);
922         fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
923         info3.dependentfiles = driver->dependentfiles;
924
925         return add_a_printer_driver_3(&info3);
926 }
927
928
929 /****************************************************************************
930 ****************************************************************************/
931 static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
932 {
933         NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
934
935         ZERO_STRUCT(info);
936
937         fstrcpy(info.name, in_prt);
938         fstrcpy(info.defaultdatatype, "RAW");
939         
940         fstrcpy(info.driverpath, "");
941         fstrcpy(info.datafile, "");
942         fstrcpy(info.configfile, "");
943         fstrcpy(info.helpfile, "");
944
945         if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
946                 return ERROR_NOT_ENOUGH_MEMORY;
947
948         memset(info.dependentfiles, '\0', 2*sizeof(fstring));
949         fstrcpy(info.dependentfiles[0], "");
950
951         *info_ptr = memdup(&info, sizeof(info));
952         
953         return 0;       
954 }
955
956 /****************************************************************************
957 ****************************************************************************/
958 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
959 {
960         NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
961         TDB_DATA kbuf, dbuf;
962         fstring architecture;
963         int len = 0;
964         int i;
965         pstring key;
966
967         ZERO_STRUCT(driver);
968
969         get_short_archi(architecture, in_arch);
970
971         DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
972
973         slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
974
975         kbuf.dptr = key;
976         kbuf.dsize = strlen(key)+1;
977         
978         dbuf = tdb_fetch(tdb, kbuf);
979 #if 0
980         if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
981 #else
982         if (!dbuf.dptr) return 5;
983 #endif
984         len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff", 
985                           &driver.cversion,
986                           driver.name,
987                           driver.environment,
988                           driver.driverpath,
989                           driver.datafile,
990                           driver.configfile,
991                           driver.helpfile,
992                           driver.monitorname,
993                           driver.defaultdatatype);
994
995         i=0;
996         while (len < dbuf.dsize) {
997                 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
998                                                          sizeof(fstring)*(i+2));
999                 if (driver.dependentfiles == NULL)
1000                         break;
1001
1002                 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", 
1003                                   &driver.dependentfiles[i]);
1004                 i++;
1005         }
1006         if (driver.dependentfiles != NULL)
1007                 fstrcpy(driver.dependentfiles[i], "");
1008
1009         safe_free(dbuf.dptr);
1010
1011         if (len != dbuf.dsize) {
1012                 if (driver.dependentfiles != NULL)
1013                         safe_free(driver.dependentfiles);
1014
1015                 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1016         }
1017
1018         *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
1019
1020         return 0;
1021 }
1022
1023 /****************************************************************************
1024 ****************************************************************************/
1025 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
1026 {
1027         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1028         TDB_DATA kbuf;
1029         pstring key;
1030         int i;
1031         line[0] = '\0';
1032
1033         slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
1034         DEBUG(10,("driver key: [%s]\n", key));
1035         
1036         kbuf.dptr = key;
1037         kbuf.dsize = strlen(key)+1;
1038         if (!tdb_exists(tdb, kbuf)) return False;
1039
1040         ZERO_STRUCT(info3);
1041         get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
1042         
1043     DEBUGADD(10,("info3->name            [%s]\n", info3->name));
1044     DEBUGADD(10,("info3->datafile        [%s]\n", info3->datafile));
1045     DEBUGADD(10,("info3->helpfile        [%s]\n", info3->helpfile));
1046     DEBUGADD(10,("info3->monitorname     [%s]\n", info3->monitorname));
1047     DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
1048         for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1049     DEBUGADD(10,("info3->dependentfiles  [%s]\n", info3->dependentfiles[i]));
1050     }
1051     DEBUGADD(10,("info3->environment     [%s]\n", info3->environment));
1052     DEBUGADD(10,("info3->driverpath      [%s]\n", info3->driverpath));
1053     DEBUGADD(10,("info3->configfile      [%s]\n", info3->configfile));
1054
1055         /*pstrcat(line, info3->name);             pstrcat(line, ":");*/
1056         trim_string(info3->configfile, "\\print$\\WIN40\\0\\", 0);
1057         pstrcat(line, info3->configfile);
1058     pstrcat(line, ":");
1059         trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
1060         pstrcat(line, info3->datafile);
1061     pstrcat(line, ":");
1062         trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
1063         pstrcat(line, info3->helpfile);
1064     pstrcat(line, ":");
1065         trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
1066         pstrcat(line, info3->monitorname);
1067     pstrcat(line, ":");
1068         pstrcat(line, "RAW");                /*info3->defaultdatatype);*/
1069     pstrcat(line, ":");
1070
1071         for (i=0; info3->dependentfiles &&
1072                  *info3->dependentfiles[i]; i++) {
1073                 if (i) pstrcat(line, ",");               /* don't end in a "," */
1074                 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
1075                 pstrcat(line, info3->dependentfiles[i]);
1076         }
1077         
1078         free(info3);
1079
1080         return True;    
1081 }
1082
1083 /****************************************************************************
1084 debugging function, dump at level 6 the struct in the logs
1085 ****************************************************************************/
1086 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1087 {
1088         uint32 success;
1089         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1090         int i;
1091         
1092         DEBUG(106,("Dumping printer driver at level [%d]\n", level));
1093         
1094         switch (level)
1095         {
1096                 case 3: 
1097                 {
1098                         if (driver.info_3 == NULL)
1099                                 success=5;
1100                         else {
1101                                 info3=driver.info_3;
1102                         
1103                                 DEBUGADD(106,("version:[%d]\n",         info3->cversion));
1104                                 DEBUGADD(106,("name:[%s]\n",            info3->name));
1105                                 DEBUGADD(106,("environment:[%s]\n",     info3->environment));
1106                                 DEBUGADD(106,("driverpath:[%s]\n",      info3->driverpath));
1107                                 DEBUGADD(106,("datafile:[%s]\n",        info3->datafile));
1108                                 DEBUGADD(106,("configfile:[%s]\n",      info3->configfile));
1109                                 DEBUGADD(106,("helpfile:[%s]\n",        info3->helpfile));
1110                                 DEBUGADD(106,("monitorname:[%s]\n",     info3->monitorname));
1111                                 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
1112                                 
1113                                 for (i=0; info3->dependentfiles &&
1114                                           *info3->dependentfiles[i]; i++) {
1115                                         DEBUGADD(106,("dependentfile:[%s]\n", 
1116                                                       info3->dependentfiles[i]));
1117                                 }
1118                                 success=0;
1119                         }
1120                         break;
1121                 }
1122                 default:
1123                         DEBUGADD(1,("Level not implemented\n"));
1124                         success=1;
1125                         break;
1126         }
1127         
1128         return (success);
1129 }
1130
1131 /****************************************************************************
1132 ****************************************************************************/
1133 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
1134 {
1135         int len = 0;
1136
1137         len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
1138
1139         if (!nt_devmode) return len;
1140
1141         len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1142                         nt_devmode->devicename,
1143                         nt_devmode->formname,
1144
1145                         nt_devmode->specversion,
1146                         nt_devmode->driverversion,
1147                         nt_devmode->size,
1148                         nt_devmode->driverextra,
1149                         nt_devmode->orientation,
1150                         nt_devmode->papersize,
1151                         nt_devmode->paperlength,
1152                         nt_devmode->paperwidth,
1153                         nt_devmode->scale,
1154                         nt_devmode->copies,
1155                         nt_devmode->defaultsource,
1156                         nt_devmode->printquality,
1157                         nt_devmode->color,
1158                         nt_devmode->duplex,
1159                         nt_devmode->yresolution,
1160                         nt_devmode->ttoption,
1161                         nt_devmode->collate,
1162                         nt_devmode->logpixels,
1163                         
1164                         nt_devmode->fields,
1165                         nt_devmode->bitsperpel,
1166                         nt_devmode->pelswidth,
1167                         nt_devmode->pelsheight,
1168                         nt_devmode->displayflags,
1169                         nt_devmode->displayfrequency,
1170                         nt_devmode->icmmethod,
1171                         nt_devmode->icmintent,
1172                         nt_devmode->mediatype,
1173                         nt_devmode->dithertype,
1174                         nt_devmode->reserved1,
1175                         nt_devmode->reserved2,
1176                         nt_devmode->panningwidth,
1177                         nt_devmode->panningheight,
1178                         nt_devmode->private);
1179
1180         
1181         if (nt_devmode->private) {
1182                 len += tdb_pack(buf+len, buflen-len, "B",
1183                                 nt_devmode->driverextra,
1184                                 nt_devmode->private);
1185         }
1186
1187         DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
1188
1189         return len;
1190 }
1191
1192 /****************************************************************************
1193 ****************************************************************************/
1194 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
1195 {
1196         int len = 0;
1197
1198         while (param != NULL) {
1199                 len += tdb_pack(buf+len, buflen-len, "pfdB",
1200                                 param,
1201                                 param->value, 
1202                                 param->type, 
1203                                 param->data_len,
1204                                 param->data);
1205                 param=param->next;      
1206         }
1207
1208         len += tdb_pack(buf+len, buflen-len, "p", param);
1209
1210         return len;
1211 }
1212
1213
1214 /****************************************************************************
1215 delete a printer - this just deletes the printer info file, any open
1216 handles are not affected
1217 ****************************************************************************/
1218 uint32 del_a_printer(char *sharename)
1219 {
1220         pstring key;
1221         TDB_DATA kbuf;
1222
1223         slprintf(key, sizeof(key), "%s%s",
1224                  PRINTERS_PREFIX, sharename);
1225
1226         kbuf.dptr=key;
1227         kbuf.dsize=strlen(key)+1;
1228
1229         tdb_delete(tdb, kbuf);
1230         return 0;
1231 }
1232
1233 /****************************************************************************
1234 ****************************************************************************/
1235 static uint32 update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
1236 {
1237         pstring key;
1238         char *buf;
1239         int buflen, len, ret;
1240         TDB_DATA kbuf, dbuf;
1241         
1242         /* 
1243          * in addprinter: no servername and the printer is the name
1244          * in setprinter: servername is \\server
1245          *                and printer is \\server\\printer
1246          *
1247          * Samba manages only local printers.
1248          * we currently don't support things like path=\\other_server\printer
1249          */
1250
1251         if (info->servername[0]!='\0') {
1252                 trim_string(info->printername, info->servername, NULL);
1253                 trim_string(info->printername, "\\", NULL);
1254                 info->servername[0]='\0';
1255         }
1256
1257         /*
1258          * JFM: one day I'll forget.
1259          * below that's info->portname because that's the SAMBA sharename
1260          * and I made NT 'thinks' it's the portname
1261          * the info->sharename is the thing you can name when you add a printer
1262          * that's the short-name when you create shared printer for 95/98
1263          * So I've made a limitation in SAMBA: you can only have 1 printer model
1264          * behind a SAMBA share.
1265          */
1266
1267         buf = NULL;
1268         buflen = 0;
1269
1270  again: 
1271         len = 0;
1272         len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
1273                         info->attributes,
1274                         info->priority,
1275                         info->default_priority,
1276                         info->starttime,
1277                         info->untiltime,
1278                         info->status,
1279                         info->cjobs,
1280                         info->averageppm,
1281                         info->changeid,
1282                         info->c_setprinter,
1283                         info->setuptime,
1284                         info->servername,
1285                         info->printername,
1286                         info->sharename,
1287                         info->portname,
1288                         info->drivername,
1289                         info->comment,
1290                         info->location,
1291                         info->sepfile,
1292                         info->printprocessor,
1293                         info->datatype,
1294                         info->parameters);
1295
1296         len += pack_devicemode(info->devmode, buf+len, buflen-len);
1297         len += pack_specifics(info->specific, buf+len, buflen-len);
1298
1299         if (buflen != len) {
1300                 buf = (char *)Realloc(buf, len);
1301                 buflen = len;
1302                 goto again;
1303         }
1304         
1305
1306         slprintf(key, sizeof(key), "%s%s",
1307                  PRINTERS_PREFIX, info->sharename);
1308
1309         kbuf.dptr = key;
1310         kbuf.dsize = strlen(key)+1;
1311         dbuf.dptr = buf;
1312         dbuf.dsize = len;
1313
1314         ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
1315
1316         if (ret == -1)
1317                 DEBUG(8, ("error updating printer to tdb on disk\n"));
1318
1319         safe_free(buf);
1320
1321         DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n", 
1322                  info->sharename, info->drivername, info->portname, len));
1323
1324         return ret;
1325 }
1326
1327
1328 /****************************************************************************
1329 ****************************************************************************/
1330 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1331 {
1332         NT_PRINTER_PARAM *current;
1333         
1334         DEBUG(108,("add_a_specific_param\n"));  
1335
1336         param->next=NULL;
1337         
1338         if (info_2->specific == NULL)
1339         {
1340                 info_2->specific=param;
1341         }
1342         else
1343         {
1344                 current=info_2->specific;               
1345                 while (current->next != NULL) {
1346                         current=current->next;
1347                 }               
1348                 current->next=param;
1349         }
1350         return (True);
1351 }
1352
1353 /****************************************************************************
1354 ****************************************************************************/
1355 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1356 {
1357         NT_PRINTER_PARAM *current;
1358         NT_PRINTER_PARAM *previous;
1359         
1360         current=info_2->specific;
1361         previous=current;
1362         
1363         if (current==NULL) return (False);
1364         
1365         if ( !strcmp(current->value, param->value) && 
1366             (strlen(current->value)==strlen(param->value)) ) {
1367                 DEBUG(109,("deleting first value\n"));
1368                 info_2->specific=current->next;
1369                 safe_free(current->data);
1370                 safe_free(current);
1371                 DEBUG(109,("deleted first value\n"));
1372                 return (True);
1373         }
1374
1375         current=previous->next;
1376                 
1377         while ( current!=NULL ) {
1378                 if (!strcmp(current->value, param->value) &&
1379                     strlen(current->value)==strlen(param->value) ) {
1380                         DEBUG(109,("deleting current value\n"));
1381                         previous->next=current->next;
1382                         safe_free(current->data);
1383                         safe_free(current);
1384                         DEBUG(109,("deleted current value\n"));
1385                         return(True);
1386                 }
1387                 
1388                 previous=previous->next;
1389                 current=current->next;
1390         }
1391         return (False);
1392 }
1393
1394 /****************************************************************************
1395  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
1396 ****************************************************************************/
1397 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
1398 {
1399         NT_PRINTER_PARAM *param = *param_ptr;
1400
1401         if(param == NULL)
1402                 return;
1403
1404         DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
1405
1406         if(param->data)
1407                 safe_free(param->data);
1408
1409         safe_free(param);
1410         *param_ptr = NULL;
1411 }
1412
1413 /****************************************************************************
1414  Malloc and return an NT devicemode.
1415 ****************************************************************************/
1416
1417 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
1418 {
1419 /*
1420  * should I init this ones ???
1421         nt_devmode->devicename
1422 */
1423
1424         char adevice[32];
1425         NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
1426
1427         if (nt_devmode == NULL) {
1428                 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
1429                 return NULL;
1430         }
1431
1432         ZERO_STRUCTP(nt_devmode);
1433
1434         safe_strcpy(adevice, default_devicename, sizeof(adevice));
1435         fstrcpy(nt_devmode->devicename, adevice);       
1436         
1437         fstrcpy(nt_devmode->formname, "Letter");
1438
1439         nt_devmode->specversion      = 0x0401;
1440         nt_devmode->driverversion    = 0x0400;
1441         nt_devmode->size             = 0x00DC;
1442         nt_devmode->driverextra      = 0x0000;
1443         nt_devmode->fields           = FORMNAME | TTOPTION | PRINTQUALITY | 
1444                                        DEFAULTSOURCE | COPIES | SCALE | 
1445                                        PAPERSIZE | ORIENTATION;
1446         nt_devmode->orientation      = 1;
1447         nt_devmode->papersize        = PAPER_LETTER;
1448         nt_devmode->paperlength      = 0;
1449         nt_devmode->paperwidth       = 0;
1450         nt_devmode->scale            = 0x64;
1451         nt_devmode->copies           = 01;
1452         nt_devmode->defaultsource    = BIN_FORMSOURCE;
1453         nt_devmode->printquality     = RES_HIGH;           /* 0x0258 */
1454         nt_devmode->color            = COLOR_MONOCHROME;
1455         nt_devmode->duplex           = DUP_SIMPLEX;
1456         nt_devmode->yresolution      = 0;
1457         nt_devmode->ttoption         = TT_SUBDEV;
1458         nt_devmode->collate          = COLLATE_FALSE;
1459         nt_devmode->icmmethod        = 0;
1460         nt_devmode->icmintent        = 0;
1461         nt_devmode->mediatype        = 0;
1462         nt_devmode->dithertype       = 0;
1463
1464         /* non utilisés par un driver d'imprimante */
1465         nt_devmode->logpixels        = 0;
1466         nt_devmode->bitsperpel       = 0;
1467         nt_devmode->pelswidth        = 0;
1468         nt_devmode->pelsheight       = 0;
1469         nt_devmode->displayflags     = 0;
1470         nt_devmode->displayfrequency = 0;
1471         nt_devmode->reserved1        = 0;
1472         nt_devmode->reserved2        = 0;
1473         nt_devmode->panningwidth     = 0;
1474         nt_devmode->panningheight    = 0;
1475         
1476         nt_devmode->private=NULL;
1477
1478         return nt_devmode;
1479 }
1480
1481 /****************************************************************************
1482  Deepcopy an NT devicemode.
1483 ****************************************************************************/
1484
1485 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
1486 {
1487         NT_DEVICEMODE *new_nt_devicemode = NULL;
1488
1489         if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
1490                 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
1491                 return NULL;
1492         }
1493
1494         new_nt_devicemode->private = NULL;
1495         if (nt_devicemode->private != NULL) {
1496                 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
1497                         safe_free(new_nt_devicemode);
1498                         DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
1499                         return NULL;
1500         }
1501         }
1502
1503         return new_nt_devicemode;
1504 }
1505
1506 /****************************************************************************
1507  Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
1508 ****************************************************************************/
1509
1510 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
1511 {
1512         NT_DEVICEMODE *nt_devmode = *devmode_ptr;
1513
1514         if(nt_devmode == NULL)
1515                 return;
1516
1517         DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
1518
1519         if(nt_devmode->private)
1520                 safe_free(nt_devmode->private);
1521
1522         safe_free(nt_devmode);
1523         *devmode_ptr = NULL;
1524 }
1525
1526 /****************************************************************************
1527  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
1528 ****************************************************************************/
1529 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
1530 {
1531         NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
1532         NT_PRINTER_PARAM *param_ptr;
1533
1534         if(info == NULL)
1535                 return;
1536
1537         DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
1538
1539         free_nt_devicemode(&info->devmode);
1540         free_sec_desc_buf(&info->secdesc_buf);
1541
1542         for(param_ptr = info->specific; param_ptr; ) {
1543                 NT_PRINTER_PARAM *tofree = param_ptr;
1544
1545                 param_ptr = param_ptr->next;
1546                 free_nt_printer_param(&tofree);
1547         }
1548
1549         safe_free(*info_ptr);
1550         *info_ptr = NULL;
1551 }
1552
1553
1554 /****************************************************************************
1555 ****************************************************************************/
1556 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
1557 {
1558         int len = 0;
1559         int extra_len = 0;
1560         NT_DEVICEMODE devmode;
1561
1562         ZERO_STRUCT(devmode);
1563
1564         len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
1565
1566         if (!*nt_devmode) return len;
1567
1568         len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1569                           devmode.devicename,
1570                           devmode.formname,
1571
1572                           &devmode.specversion,
1573                           &devmode.driverversion,
1574                           &devmode.size,
1575                           &devmode.driverextra,
1576                           &devmode.orientation,
1577                           &devmode.papersize,
1578                           &devmode.paperlength,
1579                           &devmode.paperwidth,
1580                           &devmode.scale,
1581                           &devmode.copies,
1582                           &devmode.defaultsource,
1583                           &devmode.printquality,
1584                           &devmode.color,
1585                           &devmode.duplex,
1586                           &devmode.yresolution,
1587                           &devmode.ttoption,
1588                           &devmode.collate,
1589                           &devmode.logpixels,
1590                           
1591                           &devmode.fields,
1592                           &devmode.bitsperpel,
1593                           &devmode.pelswidth,
1594                           &devmode.pelsheight,
1595                           &devmode.displayflags,
1596                           &devmode.displayfrequency,
1597                           &devmode.icmmethod,
1598                           &devmode.icmintent,
1599                           &devmode.mediatype,
1600                           &devmode.dithertype,
1601                           &devmode.reserved1,
1602                           &devmode.reserved2,
1603                           &devmode.panningwidth,
1604                           &devmode.panningheight,
1605                           &devmode.private);
1606         
1607         if (devmode.private) {
1608                 /* the len in tdb_unpack is an int value and
1609                  * devmoce.driverextra is only a short
1610                  */
1611                 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
1612                 devmode.driverextra=(uint16)extra_len;
1613         }
1614
1615         *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
1616
1617         DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
1618         if (devmode.private)
1619                 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
1620
1621         return len;
1622 }
1623
1624 /****************************************************************************
1625 ****************************************************************************/
1626 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
1627 {
1628         int len = 0;
1629         NT_PRINTER_PARAM param, *p;
1630
1631         *list = NULL;
1632
1633         while (1) {
1634                 len += tdb_unpack(buf+len, buflen-len, "p", &p);
1635                 if (!p) break;
1636
1637                 len += tdb_unpack(buf+len, buflen-len, "fdB",
1638                                   param.value, 
1639                                   &param.type, 
1640                                   &param.data_len,
1641                                   &param.data);
1642                 param.next = *list;
1643                 *list = memdup(&param, sizeof(param));
1644
1645                 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
1646         }
1647
1648         return len;
1649 }
1650
1651
1652 /****************************************************************************
1653 get a default printer info 2 struct
1654 ****************************************************************************/
1655 static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1656 {
1657         extern pstring global_myname;
1658         int snum;
1659         NT_PRINTER_INFO_LEVEL_2 info;
1660
1661         ZERO_STRUCT(info);
1662
1663         snum = lp_servicenumber(sharename);
1664
1665         slprintf(info.servername, sizeof(info.servername), "\\\\%s", global_myname);
1666         slprintf(info.printername, sizeof(info.printername), "\\\\%s\\%s", 
1667                  global_myname, sharename);
1668         fstrcpy(info.sharename, sharename);
1669         fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
1670         fstrcpy(info.drivername, lp_printerdriver(snum));
1671         pstrcpy(info.comment, "");
1672         fstrcpy(info.printprocessor, "winprint");
1673         fstrcpy(info.datatype, "RAW");
1674
1675         info.attributes = PRINTER_ATTRIBUTE_SHARED   \
1676                          | PRINTER_ATTRIBUTE_LOCAL  \
1677                          | PRINTER_ATTRIBUTE_RAW_ONLY \
1678                          | PRINTER_ATTRIBUTE_QUEUED ;            /* attributes */
1679
1680         info.starttime = 0; /* Minutes since 12:00am GMT */
1681         info.untiltime = 0; /* Minutes since 12:00am GMT */
1682         info.priority = 1;
1683         info.default_priority = 1;
1684         info.setuptime = (uint32)time(NULL);
1685
1686         if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
1687                 goto fail;
1688
1689         if (!nt_printing_getsec(sharename, &info.secdesc_buf))
1690                 goto fail;
1691
1692         *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
1693         if (! *info_ptr) {
1694                 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
1695                 goto fail;
1696         }
1697
1698         return (0);     
1699
1700   fail:
1701
1702         if (info.devmode)
1703                 free_nt_devicemode(&info.devmode);
1704         if (info.secdesc_buf)
1705                 free_sec_desc_buf(&info.secdesc_buf);
1706         return 2;
1707 }
1708
1709 /****************************************************************************
1710 ****************************************************************************/
1711 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1712 {
1713         pstring key;
1714         NT_PRINTER_INFO_LEVEL_2 info;
1715         int len = 0;
1716         TDB_DATA kbuf, dbuf;
1717         fstring printername;
1718                 
1719         ZERO_STRUCT(info);
1720
1721         slprintf(key, sizeof(key), "%s%s", PRINTERS_PREFIX, sharename);
1722
1723         kbuf.dptr = key;
1724         kbuf.dsize = strlen(key)+1;
1725
1726         dbuf = tdb_fetch(tdb, kbuf);
1727         if (!dbuf.dptr)
1728                 return get_a_printer_2_default(info_ptr, sharename);
1729
1730         len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
1731                         &info.attributes,
1732                         &info.priority,
1733                         &info.default_priority,
1734                         &info.starttime,
1735                         &info.untiltime,
1736                         &info.status,
1737                         &info.cjobs,
1738                         &info.averageppm,
1739                         &info.changeid,
1740                         &info.c_setprinter,
1741                         &info.setuptime,
1742                         info.servername,
1743                         info.printername,
1744                         info.sharename,
1745                         info.portname,
1746                         info.drivername,
1747                         info.comment,
1748                         info.location,
1749                         info.sepfile,
1750                         info.printprocessor,
1751                         info.datatype,
1752                         info.parameters);
1753
1754         /* Samba has to have shared raw drivers. */
1755         info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
1756
1757         /* Restore the stripped strings. */
1758         slprintf(info.servername, sizeof(info.servername), "\\\\%s", global_myname);
1759         slprintf(printername, sizeof(printername), "\\\\%s\\%s", global_myname,
1760                         info.printername);
1761         fstrcpy(info.printername, printername);
1762
1763         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
1764         len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
1765
1766         nt_printing_getsec(sharename, &info.secdesc_buf);
1767
1768         safe_free(dbuf.dptr);
1769         *info_ptr=memdup(&info, sizeof(info));
1770
1771         DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
1772                  sharename, info.printername, info.drivername));
1773
1774         
1775         return 0;       
1776 }
1777
1778 /****************************************************************************
1779 debugging function, dump at level 6 the struct in the logs
1780 ****************************************************************************/
1781 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1782 {
1783         uint32 success;
1784         NT_PRINTER_INFO_LEVEL_2 *info2;
1785         
1786         DEBUG(106,("Dumping printer at level [%d]\n", level));
1787         
1788         switch (level)
1789         {
1790                 case 2: 
1791                 {
1792                         if (printer.info_2 == NULL)
1793                                 success=5;
1794                         else
1795                         {
1796                                 info2=printer.info_2;
1797                         
1798                                 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
1799                                 DEBUGADD(106,("priority:[%d]\n", info2->priority));
1800                                 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
1801                                 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
1802                                 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
1803                                 DEBUGADD(106,("status:[%d]\n", info2->status));
1804                                 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
1805                                 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
1806                                 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
1807                                 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
1808                                 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
1809
1810                                 DEBUGADD(106,("servername:[%s]\n", info2->servername));
1811                                 DEBUGADD(106,("printername:[%s]\n", info2->printername));
1812                                 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
1813                                 DEBUGADD(106,("portname:[%s]\n", info2->portname));
1814                                 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
1815                                 DEBUGADD(106,("comment:[%s]\n", info2->comment));
1816                                 DEBUGADD(106,("location:[%s]\n", info2->location));
1817                                 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
1818                                 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
1819                                 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
1820                                 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
1821                                 success=0;
1822                         }
1823                         break;
1824                 }
1825                 default:
1826                         DEBUGADD(1,("Level not implemented\n"));
1827                         success=1;
1828                         break;
1829         }
1830         
1831         return (success);
1832 }
1833
1834 /****************************************************************************
1835  Get the parameters we can substitute in an NT print job.
1836 ****************************************************************************/
1837
1838 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
1839 {
1840         NT_PRINTER_INFO_LEVEL *printer = NULL;
1841
1842         **printername = **sharename = **portname = '\0';
1843
1844         if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1845                 return;
1846
1847         fstrcpy(*printername, printer->info_2->printername);
1848         fstrcpy(*sharename, printer->info_2->sharename);
1849         fstrcpy(*portname, printer->info_2->portname);
1850
1851         free_a_printer(&printer, 2);
1852 }
1853
1854 /*
1855  * The function below are the high level ones.
1856  * only those ones must be called from the spoolss code.
1857  * JFM.
1858  */
1859
1860 /****************************************************************************
1861  Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
1862 ****************************************************************************/
1863
1864 uint32 mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1865 {
1866         uint32 success;
1867         
1868         dump_a_printer(printer, level); 
1869         
1870         switch (level)
1871         {
1872                 case 2:
1873                 {
1874                         printer.info_2->c_setprinter++;
1875                         success=update_a_printer_2(printer.info_2);
1876                         break;
1877                 }
1878                 default:
1879                         success=1;
1880                         break;
1881         }
1882         
1883         return (success);
1884 }
1885
1886 /****************************************************************************
1887  Add a printer. This is called from ADDPRINTER(EX) and also SETPRINTER.
1888  We split this out from mod_a_printer as it updates the id's and timestamps.
1889 ****************************************************************************/
1890
1891 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1892 {
1893         uint32 success;
1894         
1895         dump_a_printer(printer, level); 
1896         
1897         switch (level)
1898         {
1899                 case 2: 
1900                 {
1901                         /*
1902                          * Update the changestamp.
1903                          * Note we must *not* do this in mod_a_printer().
1904                          */
1905                         NTTIME time_nt;
1906                         time_t time_unix = time(NULL);
1907                         unix_to_nt_time(&time_nt, time_unix);
1908                         printer.info_2->changeid=time_nt.low;
1909
1910                         printer.info_2->c_setprinter++;
1911                         success=update_a_printer_2(printer.info_2);
1912                         break;
1913                 }
1914                 default:
1915                         success=1;
1916                         break;
1917         }
1918         
1919         return (success);
1920 }
1921
1922 /****************************************************************************
1923  Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
1924 ****************************************************************************/
1925
1926 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
1927 {
1928         uint32 success;
1929         NT_PRINTER_INFO_LEVEL *printer = NULL;
1930         
1931         *pp_printer = NULL;
1932
1933         DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1934
1935         switch (level)
1936         {
1937                 case 2: 
1938                 {
1939                         if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
1940                                 DEBUG(0,("get_a_printer: malloc fail.\n"));
1941                                 return 1;
1942                         }
1943                         ZERO_STRUCTP(printer);
1944                         success=get_a_printer_2(&printer->info_2, sharename);
1945                         if (success == 0) {
1946                                 dump_a_printer(*printer, level);
1947                                 *pp_printer = printer;
1948                         } else {
1949                                 safe_free(printer);
1950                         }
1951                         break;
1952                 }
1953                 default:
1954                         success=1;
1955                         break;
1956         }
1957         
1958         DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1959
1960         return (success);
1961 }
1962
1963 /****************************************************************************
1964  Deletes a NT_PRINTER_INFO_LEVEL struct.
1965 ****************************************************************************/
1966
1967 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
1968 {
1969         uint32 success;
1970         NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
1971
1972         DEBUG(104,("freeing a printer at level [%d]\n", level));
1973
1974         if (printer == NULL)
1975                 return 0;
1976         
1977         switch (level)
1978         {
1979                 case 2: 
1980                 {
1981                         if (printer->info_2 != NULL)
1982                         {
1983                                 free_nt_printer_info_level_2(&printer->info_2);
1984                                 success=0;
1985                         }
1986                         else
1987                         {
1988                                 success=4;
1989                         }
1990                         break;
1991                 }
1992                 default:
1993                         success=1;
1994                         break;
1995         }
1996
1997         safe_free(printer);
1998         *pp_printer = NULL;
1999         return (success);
2000 }
2001
2002 /****************************************************************************
2003 ****************************************************************************/
2004 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
2005 {
2006         uint32 success;
2007         DEBUG(104,("adding a printer at level [%d]\n", level));
2008         dump_a_printer_driver(driver, level);
2009         
2010         switch (level)
2011         {
2012                 case 3: 
2013                 {
2014                         success=add_a_printer_driver_3(driver.info_3);
2015                         break;
2016                 }
2017
2018                 case 6: 
2019                 {
2020                         success=add_a_printer_driver_6(driver.info_6);
2021                         break;
2022                 }
2023                 default:
2024                         success=1;
2025                         break;
2026         }
2027         
2028         return (success);
2029 }
2030 /****************************************************************************
2031 ****************************************************************************/
2032 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, 
2033                             fstring printername, fstring architecture, uint32 version)
2034 {
2035         uint32 success;
2036         
2037         switch (level)
2038         {
2039                 case 3: 
2040                 {
2041                         success=get_a_printer_driver_3(&driver->info_3, printername, architecture, version);
2042                         break;
2043                 }
2044                 default:
2045                         success=1;
2046                         break;
2047         }
2048         
2049         if (success == 0)
2050                 dump_a_printer_driver(*driver, level);
2051         return (success);
2052 }
2053
2054 /****************************************************************************
2055 ****************************************************************************/
2056 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
2057 {
2058         uint32 success;
2059         
2060         switch (level)
2061         {
2062                 case 3: 
2063                 {
2064                         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
2065                         if (driver.info_3 != NULL)
2066                         {
2067                                 info3=driver.info_3;
2068                                 safe_free(info3->dependentfiles);
2069                                 ZERO_STRUCTP(info3);
2070                                 safe_free(info3);
2071                                 success=0;
2072                         }
2073                         else
2074                         {
2075                                 success=4;
2076                         }
2077                         break;
2078                 }
2079                 case 6: 
2080                 {
2081                         NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
2082                         if (driver.info_6 != NULL)
2083                         {
2084                                 info6=driver.info_6;
2085                                 safe_free(info6->dependentfiles);
2086                                 safe_free(info6->previousnames);
2087                                 ZERO_STRUCTP(info6);
2088                                 safe_free(info6);
2089                                 success=0;
2090                         }
2091                         else
2092                         {
2093                                 success=4;
2094                         }
2095                         break;
2096                 }
2097                 default:
2098                         success=1;
2099                         break;
2100         }
2101         return (success);
2102 }
2103
2104 /****************************************************************************
2105 ****************************************************************************/
2106 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
2107                                  fstring value, uint8 **data, uint32 *type, uint32 *len)
2108 {
2109         /* right now that's enough ! */ 
2110         NT_PRINTER_PARAM *param;
2111         int i=0;
2112         
2113         param=printer.info_2->specific;
2114         
2115         while (param != NULL && i < param_index) {
2116                 param=param->next;
2117                 i++;
2118         }
2119         
2120         if (param == NULL)
2121                 return False;
2122
2123         /* exited because it exist */
2124         *type=param->type;              
2125         StrnCpy(value, param->value, sizeof(fstring)-1);
2126         *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
2127         if(*data == NULL)
2128                 return False;
2129         ZERO_STRUCTP(*data);
2130         memcpy(*data, param->data, param->data_len);
2131         *len=param->data_len;
2132         return True;
2133 }
2134
2135 /****************************************************************************
2136 ****************************************************************************/
2137 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level, 
2138                         fstring value, uint8 **data, uint32 *type, uint32 *len)
2139 {
2140         /* right now that's enough ! */ 
2141         NT_PRINTER_PARAM *param;
2142         
2143         DEBUG(105, ("get_specific_param\n"));
2144         
2145         param=printer.info_2->specific;
2146                 
2147         while (param != NULL)
2148         {
2149 #if 1 /* JRA - I think this should be case insensitive.... */
2150                 if ( strequal(value, param->value) 
2151 #else
2152                 if ( !strcmp(value, param->value) 
2153 #endif
2154                     && strlen(value)==strlen(param->value))
2155                         break;
2156                         
2157                 param=param->next;
2158         }
2159         
2160         DEBUG(106, ("found one param\n"));
2161         if (param != NULL)
2162         {
2163                 /* exited because it exist */
2164                 *type=param->type;      
2165                 
2166                 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
2167                 if(*data == NULL)
2168                         return False;
2169                 memcpy(*data, param->data, param->data_len);
2170                 *len=param->data_len;
2171
2172                 DEBUG(106, ("exit of get_specific_param:true\n"));
2173                 return (True);
2174         }
2175         DEBUG(106, ("exit of get_specific_param:false\n"));
2176         return (False);
2177 }
2178
2179 /****************************************************************************
2180  Store a security desc for a printer.
2181 ****************************************************************************/
2182
2183 uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
2184 {
2185         prs_struct ps;
2186         TALLOC_CTX *mem_ctx = NULL;
2187         fstring key;
2188         uint32 status;
2189
2190         mem_ctx = talloc_init();
2191         if (mem_ctx == NULL) return False;
2192
2193         /* Store the security descriptor in a tdb */
2194
2195         prs_init(&ps, (uint32)sec_desc_size(secdesc_ctr->sec) + 
2196                  sizeof(SEC_DESC_BUF), 4, mem_ctx, MARSHALL);
2197
2198         if (!sec_io_desc_buf("nt_printing_setsec", &secdesc_ctr, &ps, 1)) {
2199                 status = ERROR_INVALID_FUNCTION;
2200                 goto done;
2201         }
2202
2203         slprintf(key, sizeof(key), "SECDESC/%s", printername);
2204
2205         if (tdb_prs_store(tdb, key, &ps)==0) {
2206                 status = 0;
2207         } else {
2208                 DEBUG(1,("Failed to store secdesc for %s\n", printername));
2209                 status = ERROR_INVALID_FUNCTION;
2210         }
2211
2212         /* Free mallocated memory */
2213
2214  done:
2215         prs_mem_free(&ps);
2216
2217         if (mem_ctx) talloc_destroy(mem_ctx);
2218
2219         return status;
2220 }
2221
2222 /****************************************************************************
2223  Construct a default security descriptor buffer for a printer.
2224 ****************************************************************************/
2225
2226 static SEC_DESC_BUF *construct_default_printer_sdb(void)
2227 {
2228         SEC_ACE ace[2];
2229         SEC_ACCESS sa;
2230         SEC_ACL *psa = NULL;
2231         SEC_DESC_BUF *sdb = NULL;
2232         SEC_DESC *psd = NULL;
2233         DOM_SID owner_sid;
2234         size_t sd_size;
2235         enum SID_NAME_USE name_type;
2236
2237         /* Create an ACE where Everyone is allowed to print */
2238
2239         init_sec_access(&sa, PRINTER_ACE_PRINT);
2240         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
2241                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2242
2243
2244         /* Make the security descriptor owned by the Administrators group
2245            on the PDC of the domain. */
2246
2247         if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
2248                 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
2249         } else {
2250
2251                 /* Backup plan - make printer owned by admins or root.  This should
2252                    emulate a lanman printer as security settings can't be
2253                    changed. */
2254
2255                 if (!lookup_name( "Printer Administrators", &owner_sid, &name_type) &&
2256                         !lookup_name( "Administrators", &owner_sid, &name_type) &&
2257                         !lookup_name( "Administrator", &owner_sid, &name_type) &&
2258                         !lookup_name("root", &owner_sid, &name_type)) {
2259                                                 sid_copy(&owner_sid, &global_sid_World);
2260                 }
2261         }
2262
2263         init_sec_access(&sa, PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT);
2264         init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
2265                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2266
2267         /* The ACL revision number in rpc_secdesc.h differs from the one
2268            created by NT when setting ACE entries in printer
2269            descriptors.  NT4 complains about the property being edited by a
2270            NT5 machine. */
2271
2272 #define NT4_ACL_REVISION 0x2
2273
2274         if ((psa = make_sec_acl(NT4_ACL_REVISION, 2, ace)) != NULL) {
2275                 psd = make_sec_desc(SEC_DESC_REVISION, 
2276                                     SEC_DESC_SELF_RELATIVE | 
2277                                     SEC_DESC_DACL_PRESENT,
2278                                     &owner_sid, NULL,
2279                                     NULL, psa, &sd_size);
2280                 free_sec_acl(&psa);
2281         }
2282
2283         if (!psd) {
2284                 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
2285                 return NULL;
2286         }
2287
2288         sdb = make_sec_desc_buf(sd_size, psd);
2289
2290         DEBUG(4,("construct_default_printer_sdb: size = %u.\n", 
2291                  (unsigned int)sd_size));
2292
2293         free_sec_desc(&psd);
2294         return sdb;
2295 }
2296
2297 /****************************************************************************
2298  Get a security desc for a printer.
2299 ****************************************************************************/
2300
2301 BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr)
2302 {
2303         prs_struct ps;
2304         TALLOC_CTX *mem_ctx = NULL;
2305         fstring key;
2306
2307         mem_ctx = talloc_init();
2308         if (mem_ctx == NULL)
2309                 return False;
2310
2311         /* Fetch security descriptor from tdb */
2312
2313         slprintf(key, sizeof(key), "SECDESC/%s", printername);
2314
2315         if (tdb_prs_fetch(tdb, key, &ps, mem_ctx)!=0 ||
2316             !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
2317
2318                 DEBUG(4,("using default secdesc for %s\n", printername));
2319
2320                 if (!(*secdesc_ctr = construct_default_printer_sdb())) {
2321                         talloc_destroy(mem_ctx);
2322                         return False;
2323                 }
2324
2325                 talloc_destroy(mem_ctx);
2326                 return True;
2327         }
2328
2329         /* If security descriptor is owned by S-1-1-0 and winbindd is up,
2330            this security descriptor has been created when winbindd was
2331            down.  Take ownership of security descriptor. */
2332
2333         if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
2334                 DOM_SID owner_sid;
2335                 enum SID_NAME_USE name_type;
2336
2337                 /* Change sd owner to workgroup administrator */
2338
2339                 if (winbind_lookup_name(lp_workgroup(), &owner_sid,
2340                                         &name_type)) {
2341                         SEC_DESC_BUF *new_secdesc_ctr = NULL;
2342                         SEC_DESC *psd = NULL;
2343                         size_t size;
2344
2345                         /* Create new sd */
2346
2347                         sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
2348
2349                         psd = make_sec_desc((*secdesc_ctr)->sec->revision,
2350                                             (*secdesc_ctr)->sec->type,
2351                                             &owner_sid,
2352                                             (*secdesc_ctr)->sec->grp_sid,
2353                                             (*secdesc_ctr)->sec->sacl,
2354                                             (*secdesc_ctr)->sec->dacl,
2355                                             &size);
2356
2357                         new_secdesc_ctr = make_sec_desc_buf(size, psd);
2358
2359                         free_sec_desc(&psd);
2360
2361                         /* Swap with other one */
2362
2363                         free_sec_desc_buf(secdesc_ctr);
2364                         *secdesc_ctr = new_secdesc_ctr;
2365
2366                         /* Set it */
2367
2368                         nt_printing_setsec(printername, *secdesc_ctr);
2369                 }
2370         }
2371
2372         prs_mem_free(&ps);
2373         talloc_destroy(mem_ctx);
2374         return True;
2375 }
2376
2377 /* error code:
2378         0: everything OK
2379         1: level not implemented
2380         2: file doesn't exist
2381         3: can't allocate memory
2382         4: can't free memory
2383         5: non existant struct
2384 */
2385
2386 /*
2387         A printer and a printer driver are 2 different things.
2388         NT manages them separatelly, Samba does the same.
2389         Why ? Simply because it's easier and it makes sense !
2390         
2391         Now explanation: You have 3 printers behind your samba server,
2392         2 of them are the same make and model (laser A and B). But laser B 
2393         has an 3000 sheet feeder and laser A doesn't such an option.
2394         Your third printer is an old dot-matrix model for the accounting :-).
2395         
2396         If the /usr/local/samba/lib directory (default dir), you will have
2397         5 files to describe all of this.
2398         
2399         3 files for the printers (1 by printer):
2400                 NTprinter_laser A
2401                 NTprinter_laser B
2402                 NTprinter_accounting
2403         2 files for the drivers (1 for the laser and 1 for the dot matrix)
2404                 NTdriver_printer model X
2405                 NTdriver_printer model Y
2406
2407 jfm: I should use this comment for the text file to explain 
2408         same thing for the forms BTW.
2409         Je devrais mettre mes commentaires en francais, ca serait mieux :-)
2410
2411 */
2412
2413 /****************************************************************************
2414  Check a user has permissions to perform the given operation.  We use some
2415  constants defined in include/rpc_spoolss.h that look relevant to check
2416  the various actions we perform when checking printer access.
2417
2418    PRINTER_ACCESS_ADMINISTER:
2419        print_queue_pause, print_queue_resume, update_printer_sec,
2420        update_printer, spoolss_addprinterex_level_2,
2421        _spoolss_setprinterdata
2422         
2423    PRINTER_ACCESS_USE:
2424        print_job_start
2425
2426    JOB_ACCESS_ADMINISTER:
2427        print_job_delete, print_job_pause, print_job_resume,
2428        print_queue_purge
2429
2430  ****************************************************************************/
2431 BOOL print_access_check(struct current_user *user, int snum, int access_type)
2432 {
2433         SEC_DESC_BUF *secdesc = NULL;
2434         uint32 access_granted, status, required_access = 0;
2435         BOOL result;
2436         char *pname;
2437         int i;
2438         extern struct current_user current_user;
2439         
2440         /* If user is NULL then use the current_user structure */
2441
2442         if (!user) user = &current_user;
2443
2444         /* Always allow root or printer admins to do anything */
2445
2446         if (user->uid == 0 ||
2447             user_in_list(uidtoname(user->uid), lp_printer_admin(snum))) {
2448                 return True;
2449         }
2450
2451         /* Get printer name */
2452
2453         pname = PRINTERNAME(snum);
2454
2455         if (!pname || !*pname)
2456                 pname = SERVICE(snum);
2457
2458         if (!pname || !*pname) {
2459                 errno = EACCES;
2460                 return False;
2461         }
2462
2463         /* Get printer security descriptor */
2464
2465         nt_printing_getsec(pname, &secdesc);
2466
2467         /* Check against NT4 ACE mask values.  From observation these
2468            values are:
2469
2470                Access Type       ACE Mask    Constant
2471                -------------------------------------
2472                Full Control      0x10000000  PRINTER_ACE_FULL_CONTROL
2473                Print             0xe0000000  PRINTER_ACE_PRINT
2474                Manage Documents  0x00020000  PRINTER_ACE_MANAGE_DOCUMENTS
2475         */
2476
2477         switch (access_type) {
2478         case PRINTER_ACCESS_USE:
2479                 required_access = PRINTER_ACE_PRINT;
2480                 break;
2481         case PRINTER_ACCESS_ADMINISTER:
2482                 required_access = PRINTER_ACE_MANAGE_DOCUMENTS | 
2483                         PRINTER_ACE_PRINT;
2484                 break;
2485         case JOB_ACCESS_ADMINISTER:
2486                 required_access = PRINTER_ACE_MANAGE_DOCUMENTS;
2487                 break;
2488         default:
2489                 DEBUG(0, ("invalid value passed to print_access_check()\n"));
2490                 result = False;
2491                 goto done;
2492         }       
2493
2494         /* The ACE for Full Control in a printer security descriptor
2495            doesn't seem to map properly to the access checking model.  For
2496            it to work properly it should be the logical OR of all the other
2497            values, i.e PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT.
2498            This would cause the access check to simply fall out when we
2499            check against any subset of these bits.  To get things to work,
2500            change every ACE mask of PRINTER_ACE_FULL_CONTROL to 
2501            PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT before
2502            performing the access check.  I'm sure there is a better way to
2503            do this! */
2504
2505         if (secdesc && secdesc->sec && secdesc->sec->dacl &&
2506             secdesc->sec->dacl->ace) {
2507                 for(i = 0; i < secdesc->sec->dacl->num_aces; i++) {
2508                         if (secdesc->sec->dacl->ace[i].info.mask ==
2509                             PRINTER_ACE_FULL_CONTROL) {
2510                                 secdesc->sec->dacl->ace[i].info.mask =
2511                                         PRINTER_ACE_MANAGE_DOCUMENTS | 
2512                                         PRINTER_ACE_PRINT;
2513                         }
2514                 }
2515         }
2516
2517         if ((result = se_access_check(secdesc->sec, user, required_access, 
2518                                       &access_granted, &status))) {
2519                 goto done;
2520         }
2521
2522         /* Check against NT5 ACE mask values.  From observation these
2523            values are:
2524
2525                Access Type       ACE Mask    Constant
2526                -------------------------------------
2527                Full Control      0x000f000c  PRINTER_ACE_NT5_FULL_CONTROL
2528                Print             0x00020008  PRINTER_ACE_NT5_PRINT
2529                Manage Documents  0x00020000  PRINTER_ACE_NT5_MANAGE_DOCUMENTS
2530
2531            NT5 likes to rewrite the security descriptor and change the ACE
2532            masks from NT4 format to NT5 format making them unreadable by
2533            NT4 clients. */
2534
2535         switch (access_type) {
2536         case PRINTER_ACCESS_USE:
2537                 required_access = PRINTER_ACE_NT5_PRINT;
2538                 break;
2539         case PRINTER_ACCESS_ADMINISTER:
2540                 required_access = PRINTER_ACE_NT5_FULL_CONTROL;
2541                 break;
2542         case JOB_ACCESS_ADMINISTER:
2543                 required_access = PRINTER_ACE_NT5_MANAGE_DOCUMENTS;
2544                 break;
2545         }       
2546
2547         result = se_access_check(secdesc->sec, user, required_access, 
2548                                  &access_granted, &status);
2549
2550         /* Check access */
2551         
2552  done:
2553         DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
2554         
2555         /* Free mallocated memory */
2556
2557         free_sec_desc_buf(&secdesc);
2558
2559         if (!result)
2560                 errno = EACCES;
2561
2562         return result;
2563 }
2564
2565 /****************************************************************************
2566  Check the time parameters allow a print operation.
2567 *****************************************************************************/
2568
2569 BOOL print_time_access_check(int snum)
2570 {
2571         NT_PRINTER_INFO_LEVEL *printer = NULL;
2572         BOOL ok = False;
2573         time_t now = time(NULL);
2574         struct tm *t;
2575         uint32 mins;
2576
2577         if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
2578                 return False;
2579
2580         if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
2581                 ok = True;
2582
2583         t = gmtime(&now);
2584         mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
2585
2586         if (mins >= printer->info_2->starttime && mins <= printer->info_2->untiltime)
2587                 ok = True;
2588
2589         free_a_printer(&printer, 2);
2590
2591         if (!ok)
2592                 errno = EACCES;
2593
2594         return ok;
2595 }
2596
2597
2598 #undef OLD_NTDOMAIN