TDB password backend support written by Simo Sorce <simo.sorce@polimi.it>
[kamenim/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 ERROR_INVALID_PARAMETER;     /* 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 ERROR_INVALID_PARAMETER;     /* Not the best error. Fix JRR */
580
581         return NT_STATUS_NO_PROBLEMO;
582 }
583
584 /****************************************************************************
585 ****************************************************************************/
586 void 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                         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                         clean_up_driver_struct_level_6(driver);
601                         break;
602                 }
603         }
604 }
605
606 /****************************************************************************
607  This function sucks and should be replaced. JRA.
608 ****************************************************************************/
609
610 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
611 {
612     dst->cversion  = src->version;
613
614     fstrcpy( dst->name, src->name);
615     fstrcpy( dst->environment, src->environment);
616     fstrcpy( dst->driverpath, src->driverpath);
617     fstrcpy( dst->datafile, src->datafile);
618     fstrcpy( dst->configfile, src->configfile);
619     fstrcpy( dst->helpfile, src->helpfile);
620     fstrcpy( dst->monitorname, src->monitorname);
621     fstrcpy( dst->defaultdatatype, src->defaultdatatype);
622     dst->dependentfiles = src->dependentfiles;
623 }
624
625
626 /****************************************************************************
627 ****************************************************************************/
628 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user, uint32 *perr)
629 {
630         NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
631         NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
632         fstring architecture;
633         pstring new_dir;
634         pstring old_name;
635         pstring new_name;
636         fstring user_name;
637         fstring null_pw;
638         connection_struct *conn;
639         pstring inbuf;
640         pstring outbuf;
641         struct smb_passwd *smb_pass;
642         int ecode;
643         int outsize = 0;
644         int i;
645
646         *perr = 0;
647         memset(inbuf, '\0', sizeof(inbuf));
648         memset(outbuf, '\0', sizeof(outbuf));
649
650         if (level==3)
651                 driver=driver_abstract.info_3;
652         else if (level==6) {
653                 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
654                 driver = &converted_driver;
655         } else {
656                 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
657                 return False;
658         }
659
660         get_short_archi(architecture, driver->environment);
661
662         become_root();
663         smb_pass = getsmbpwuid(user->uid);
664         if(smb_pass == NULL) {
665                 DEBUG(0,("move_driver_to_download_area: Unable to get smbpasswd entry for uid %u\n",
666                                 (unsigned int)user->uid ));
667                 unbecome_root();
668                 return False;
669         }
670         unbecome_root();
671
672         /* connect to the print$ share under the same account as the user connected to the rpc pipe */  
673         fstrcpy(user_name, smb_pass->smb_name );
674         DEBUG(10,("move_driver_to_download_area: uid %d -> user %s\n", (int)user->uid, user_name));
675
676         /* Null password is ok - we are already an authenticated user... */
677         *null_pw = '\0';
678         conn = make_connection("print$", user_name, null_pw, 0, "A:", user->vuid, &ecode);
679
680         if (conn == NULL) {
681                 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
682                 *perr = (uint32)ecode;
683                 return False;
684         }
685
686         /*
687          * Save who we are - we are temporarily becoming the connection user.
688          */
689
690         push_sec_ctx();
691
692         if (!become_user(conn, conn->vuid)) {
693                 DEBUG(0,("move_driver_to_download_area: Can't become user %s\n", user_name ));
694                 pop_sec_ctx();
695                 return False;
696         }
697
698         /* 
699          * make the directories version and version\driver_name 
700          * under the architecture directory.
701          */
702         DEBUG(5,("Creating first directory\n"));
703         slprintf(new_dir, sizeof(new_dir), "%s\\%d", architecture, driver->cversion);
704         mkdir_internal(conn, inbuf, outbuf, new_dir);
705
706         /* move all the files, one by one, 
707          * from archi\filexxx.yyy to
708          * archi\version\filexxx.yyy
709          *
710          * Note: drivers may list the same file name in several places. This
711          * causes problems on a second attempt to move the file. JRR
712          *
713          * Note: use the replace flag on rename_internals() call, otherwise it
714          * is very difficult to change previously installed drivers... the Windows
715          * GUI offers the user the choice to replace or keep exisitng driver. JRR
716          */
717
718         DEBUG(5,("Moving file now !\n"));
719
720         if (driver->driverpath && strlen(driver->driverpath)) {
721         slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->driverpath);       
722         slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->driverpath);    
723         if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
724                 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
725                                 old_name, new_name ));
726                 close_cnum(conn, user->vuid);
727                 pop_sec_ctx();
728                 *perr = (uint32)SVAL(outbuf,smb_err);
729                 return False;
730         }
731         }
732
733         if (driver->datafile && strlen(driver->datafile)) {
734         if (!strequal(driver->datafile, driver->driverpath)) {
735                 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->datafile); 
736                 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->datafile);      
737                 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
738                         DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
739                                         old_name, new_name ));
740                         close_cnum(conn, user->vuid);
741                         pop_sec_ctx();
742                         *perr = (uint32)SVAL(outbuf,smb_err);
743                         return False;
744                 }
745         }
746         }
747
748         if (driver->configfile && strlen(driver->configfile)) {
749         if (!strequal(driver->configfile, driver->driverpath) &&
750                 !strequal(driver->configfile, driver->datafile)) {
751                 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->configfile);       
752                 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->configfile);    
753                 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
754                         DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
755                                 old_name, new_name ));
756                         close_cnum(conn, user->vuid);
757                         pop_sec_ctx();
758                         *perr = (uint32)SVAL(outbuf,smb_err);
759                         return False;
760                 }
761         }
762         }
763
764         if (driver->helpfile && strlen(driver->helpfile)) {
765         if (!strequal(driver->helpfile, driver->driverpath) &&
766                         !strequal(driver->helpfile, driver->datafile) &&
767                         !strequal(driver->helpfile, driver->configfile)) {
768                 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->helpfile); 
769                 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->helpfile);      
770                 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
771                         DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
772                                 old_name, new_name ));
773                         close_cnum(conn, user->vuid);
774                         pop_sec_ctx();
775                         *perr = (uint32)SVAL(outbuf,smb_err);
776                         return False;
777                 }
778         }
779         }
780
781         if (driver->dependentfiles) {
782                 for (i=0; *driver->dependentfiles[i]; i++) {
783                         if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
784                                         !strequal(driver->dependentfiles[i], driver->datafile) &&
785                                         !strequal(driver->dependentfiles[i], driver->configfile) &&
786                                         !strequal(driver->dependentfiles[i], driver->helpfile)) {
787                                 int j;
788                                 for (j=0; j < i; j++) {
789                                         if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
790                                                 goto NextDriver;
791                                         }
792                                 }
793
794                                 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->dependentfiles[i]);        
795                                 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->dependentfiles[i]);     
796                                 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
797                                         DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
798                                                 old_name, new_name ));
799                                         close_cnum(conn, user->vuid);
800                                         pop_sec_ctx();
801                                         *perr = (uint32)SVAL(outbuf,smb_err);
802                                         return False;
803                                 }
804                         }
805                 NextDriver: ;
806                 }
807         }
808
809         close_cnum(conn, user->vuid);
810         pop_sec_ctx();
811
812         return True;
813 }
814
815 /****************************************************************************
816 ****************************************************************************/
817 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
818 {
819         int len, buflen;
820         fstring architecture;
821         pstring directory;
822         pstring temp_name;
823         pstring key;
824         char *buf;
825         int i, ret;
826         TDB_DATA kbuf, dbuf;
827
828         get_short_archi(architecture, driver->environment);
829
830         /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
831          * \\server is added in the rpc server layer.
832          * It does make sense to NOT store the server's name in the printer TDB.
833          */
834
835         slprintf(directory, sizeof(directory), "\\print$\\%s\\%d\\", architecture, driver->cversion);
836
837         
838         fstrcpy(temp_name, driver->driverpath);
839         slprintf(driver->driverpath, sizeof(driver->driverpath), "%s%s", directory, temp_name);
840
841         fstrcpy(temp_name, driver->datafile);
842         slprintf(driver->datafile, sizeof(driver->datafile), "%s%s", directory, temp_name);
843
844         fstrcpy(temp_name, driver->configfile);
845         slprintf(driver->configfile, sizeof(driver->configfile), "%s%s", directory, temp_name);
846
847         fstrcpy(temp_name, driver->helpfile);
848         slprintf(driver->helpfile, sizeof(driver->helpfile), "%s%s", directory, temp_name);
849
850         if (driver->dependentfiles) {
851                 for (i=0; *driver->dependentfiles[i]; i++) {
852                         fstrcpy(temp_name, driver->dependentfiles[i]);
853                         slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i]), "%s%s", directory, temp_name);
854                 }
855         }
856
857         slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
858
859         DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
860
861         buf = NULL;
862         len = buflen = 0;
863
864  again:
865         len = 0;
866         len += tdb_pack(buf+len, buflen-len, "dffffffff", 
867                         driver->cversion,
868                         driver->name,
869                         driver->environment,
870                         driver->driverpath,
871                         driver->datafile,
872                         driver->configfile,
873                         driver->helpfile,
874                         driver->monitorname,
875                         driver->defaultdatatype);
876
877         if (driver->dependentfiles) {
878                 for (i=0; *driver->dependentfiles[i]; i++) {
879                         len += tdb_pack(buf+len, buflen-len, "f", 
880                                         driver->dependentfiles[i]);
881                 }
882         }
883
884         if (len != buflen) {
885                 buf = (char *)Realloc(buf, len);
886                 buflen = len;
887                 goto again;
888         }
889
890
891         kbuf.dptr = key;
892         kbuf.dsize = strlen(key)+1;
893         dbuf.dptr = buf;
894         dbuf.dsize = len;
895         
896         ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
897
898         if (ret)
899                 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
900
901         safe_free(buf);
902         return ret;
903 }
904
905 /****************************************************************************
906 ****************************************************************************/
907 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
908 {
909         NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
910
911         ZERO_STRUCT(info3);
912         info3.cversion = driver->version;
913         fstrcpy(info3.name,driver->name);
914         fstrcpy(info3.environment,driver->environment);
915         fstrcpy(info3.driverpath,driver->driverpath);
916         fstrcpy(info3.datafile,driver->datafile);
917         fstrcpy(info3.configfile,driver->configfile);
918         fstrcpy(info3.helpfile,driver->helpfile);
919         fstrcpy(info3.monitorname,driver->monitorname);
920         fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
921         info3.dependentfiles = driver->dependentfiles;
922
923         return add_a_printer_driver_3(&info3);
924 }
925
926
927 /****************************************************************************
928 ****************************************************************************/
929 static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
930 {
931         NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
932
933         ZERO_STRUCT(info);
934
935         fstrcpy(info.name, in_prt);
936         fstrcpy(info.defaultdatatype, "RAW");
937         
938         fstrcpy(info.driverpath, "");
939         fstrcpy(info.datafile, "");
940         fstrcpy(info.configfile, "");
941         fstrcpy(info.helpfile, "");
942
943         if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
944                 return ERROR_NOT_ENOUGH_MEMORY;
945
946         memset(info.dependentfiles, '\0', 2*sizeof(fstring));
947         fstrcpy(info.dependentfiles[0], "");
948
949         *info_ptr = memdup(&info, sizeof(info));
950         
951         return 0;       
952 }
953
954 /****************************************************************************
955 ****************************************************************************/
956 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
957 {
958         NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
959         TDB_DATA kbuf, dbuf;
960         fstring architecture;
961         int len = 0;
962         int i;
963         pstring key;
964
965         ZERO_STRUCT(driver);
966
967         get_short_archi(architecture, in_arch);
968
969         DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
970
971         slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
972
973         kbuf.dptr = key;
974         kbuf.dsize = strlen(key)+1;
975         
976         dbuf = tdb_fetch(tdb, kbuf);
977 #if 0
978         if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
979 #else
980         if (!dbuf.dptr) return 5;
981 #endif
982         len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff", 
983                           &driver.cversion,
984                           driver.name,
985                           driver.environment,
986                           driver.driverpath,
987                           driver.datafile,
988                           driver.configfile,
989                           driver.helpfile,
990                           driver.monitorname,
991                           driver.defaultdatatype);
992
993         i=0;
994         while (len < dbuf.dsize) {
995                 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
996                                                          sizeof(fstring)*(i+2));
997                 if (driver.dependentfiles == NULL)
998                         break;
999
1000                 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", 
1001                                   &driver.dependentfiles[i]);
1002                 i++;
1003         }
1004         if (driver.dependentfiles != NULL)
1005                 fstrcpy(driver.dependentfiles[i], "");
1006
1007         safe_free(dbuf.dptr);
1008
1009         if (len != dbuf.dsize) {
1010                 if (driver.dependentfiles != NULL)
1011                         safe_free(driver.dependentfiles);
1012
1013                 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1014         }
1015
1016         *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
1017
1018         return 0;
1019 }
1020
1021 /****************************************************************************
1022 ****************************************************************************/
1023 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
1024 {
1025         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1026         TDB_DATA kbuf;
1027         pstring key;
1028         int i;
1029         line[0] = '\0';
1030
1031         slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
1032         DEBUG(10,("driver key: [%s]\n", key));
1033         
1034         kbuf.dptr = key;
1035         kbuf.dsize = strlen(key)+1;
1036         if (!tdb_exists(tdb, kbuf)) return False;
1037
1038         ZERO_STRUCT(info3);
1039         get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
1040         
1041     DEBUGADD(10,("info3->name            [%s]\n", info3->name));
1042     DEBUGADD(10,("info3->datafile        [%s]\n", info3->datafile));
1043     DEBUGADD(10,("info3->helpfile        [%s]\n", info3->helpfile));
1044     DEBUGADD(10,("info3->monitorname     [%s]\n", info3->monitorname));
1045     DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
1046         for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1047     DEBUGADD(10,("info3->dependentfiles  [%s]\n", info3->dependentfiles[i]));
1048     }
1049     DEBUGADD(10,("info3->environment     [%s]\n", info3->environment));
1050     DEBUGADD(10,("info3->driverpath      [%s]\n", info3->driverpath));
1051     DEBUGADD(10,("info3->configfile      [%s]\n", info3->configfile));
1052
1053         /*pstrcat(line, info3->name);             pstrcat(line, ":");*/
1054         trim_string(info3->configfile, "\\print$\\WIN40\\0\\", 0);
1055         pstrcat(line, info3->configfile);
1056     pstrcat(line, ":");
1057         trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
1058         pstrcat(line, info3->datafile);
1059     pstrcat(line, ":");
1060         trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
1061         pstrcat(line, info3->helpfile);
1062     pstrcat(line, ":");
1063         trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
1064         pstrcat(line, info3->monitorname);
1065     pstrcat(line, ":");
1066         pstrcat(line, "RAW");                /*info3->defaultdatatype);*/
1067     pstrcat(line, ":");
1068
1069         for (i=0; info3->dependentfiles &&
1070                  *info3->dependentfiles[i]; i++) {
1071                 if (i) pstrcat(line, ",");               /* don't end in a "," */
1072                 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
1073                 pstrcat(line, info3->dependentfiles[i]);
1074         }
1075         
1076         free(info3);
1077
1078         return True;    
1079 }
1080
1081 /****************************************************************************
1082 debugging function, dump at level 6 the struct in the logs
1083 ****************************************************************************/
1084 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1085 {
1086         uint32 success;
1087         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1088         int i;
1089         
1090         DEBUG(106,("Dumping printer driver at level [%d]\n", level));
1091         
1092         switch (level)
1093         {
1094                 case 3: 
1095                 {
1096                         if (driver.info_3 == NULL)
1097                                 success=5;
1098                         else {
1099                                 info3=driver.info_3;
1100                         
1101                                 DEBUGADD(106,("version:[%d]\n",         info3->cversion));
1102                                 DEBUGADD(106,("name:[%s]\n",            info3->name));
1103                                 DEBUGADD(106,("environment:[%s]\n",     info3->environment));
1104                                 DEBUGADD(106,("driverpath:[%s]\n",      info3->driverpath));
1105                                 DEBUGADD(106,("datafile:[%s]\n",        info3->datafile));
1106                                 DEBUGADD(106,("configfile:[%s]\n",      info3->configfile));
1107                                 DEBUGADD(106,("helpfile:[%s]\n",        info3->helpfile));
1108                                 DEBUGADD(106,("monitorname:[%s]\n",     info3->monitorname));
1109                                 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
1110                                 
1111                                 for (i=0; info3->dependentfiles &&
1112                                           *info3->dependentfiles[i]; i++) {
1113                                         DEBUGADD(106,("dependentfile:[%s]\n", 
1114                                                       info3->dependentfiles[i]));
1115                                 }
1116                                 success=0;
1117                         }
1118                         break;
1119                 }
1120                 default:
1121                         DEBUGADD(1,("Level not implemented\n"));
1122                         success=1;
1123                         break;
1124         }
1125         
1126         return (success);
1127 }
1128
1129 /****************************************************************************
1130 ****************************************************************************/
1131 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
1132 {
1133         int len = 0;
1134
1135         len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
1136
1137         if (!nt_devmode) return len;
1138
1139         len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1140                         nt_devmode->devicename,
1141                         nt_devmode->formname,
1142
1143                         nt_devmode->specversion,
1144                         nt_devmode->driverversion,
1145                         nt_devmode->size,
1146                         nt_devmode->driverextra,
1147                         nt_devmode->orientation,
1148                         nt_devmode->papersize,
1149                         nt_devmode->paperlength,
1150                         nt_devmode->paperwidth,
1151                         nt_devmode->scale,
1152                         nt_devmode->copies,
1153                         nt_devmode->defaultsource,
1154                         nt_devmode->printquality,
1155                         nt_devmode->color,
1156                         nt_devmode->duplex,
1157                         nt_devmode->yresolution,
1158                         nt_devmode->ttoption,
1159                         nt_devmode->collate,
1160                         nt_devmode->logpixels,
1161                         
1162                         nt_devmode->fields,
1163                         nt_devmode->bitsperpel,
1164                         nt_devmode->pelswidth,
1165                         nt_devmode->pelsheight,
1166                         nt_devmode->displayflags,
1167                         nt_devmode->displayfrequency,
1168                         nt_devmode->icmmethod,
1169                         nt_devmode->icmintent,
1170                         nt_devmode->mediatype,
1171                         nt_devmode->dithertype,
1172                         nt_devmode->reserved1,
1173                         nt_devmode->reserved2,
1174                         nt_devmode->panningwidth,
1175                         nt_devmode->panningheight,
1176                         nt_devmode->private);
1177
1178         
1179         if (nt_devmode->private) {
1180                 len += tdb_pack(buf+len, buflen-len, "B",
1181                                 nt_devmode->driverextra,
1182                                 nt_devmode->private);
1183         }
1184
1185         DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
1186
1187         return len;
1188 }
1189
1190 /****************************************************************************
1191 ****************************************************************************/
1192 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
1193 {
1194         int len = 0;
1195
1196         while (param != NULL) {
1197                 len += tdb_pack(buf+len, buflen-len, "pfdB",
1198                                 param,
1199                                 param->value, 
1200                                 param->type, 
1201                                 param->data_len,
1202                                 param->data);
1203                 param=param->next;      
1204         }
1205
1206         len += tdb_pack(buf+len, buflen-len, "p", param);
1207
1208         return len;
1209 }
1210
1211
1212 /****************************************************************************
1213 delete a printer - this just deletes the printer info file, any open
1214 handles are not affected
1215 ****************************************************************************/
1216 uint32 del_a_printer(char *sharename)
1217 {
1218         pstring key;
1219         TDB_DATA kbuf;
1220
1221         slprintf(key, sizeof(key), "%s%s",
1222                  PRINTERS_PREFIX, sharename);
1223
1224         kbuf.dptr=key;
1225         kbuf.dsize=strlen(key)+1;
1226
1227         tdb_delete(tdb, kbuf);
1228         return 0;
1229 }
1230
1231 /****************************************************************************
1232 ****************************************************************************/
1233 static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
1234 {
1235         pstring key;
1236         char *buf;
1237         int buflen, len, ret;
1238         TDB_DATA kbuf, dbuf;
1239         NTTIME time_nt;
1240         time_t time_unix = time(NULL);
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         unix_to_nt_time(&time_nt, time_unix);
1268         info->changeid=time_nt.low;
1269         info->c_setprinter++;
1270
1271         buf = NULL;
1272         buflen = 0;
1273
1274  again: 
1275         len = 0;
1276         len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
1277                         info->attributes,
1278                         info->priority,
1279                         info->default_priority,
1280                         info->starttime,
1281                         info->untiltime,
1282                         info->status,
1283                         info->cjobs,
1284                         info->averageppm,
1285                         info->changeid,
1286                         info->c_setprinter,
1287                         info->setuptime,
1288                         info->servername,
1289                         info->printername,
1290                         info->sharename,
1291                         info->portname,
1292                         info->drivername,
1293                         info->comment,
1294                         info->location,
1295                         info->sepfile,
1296                         info->printprocessor,
1297                         info->datatype,
1298                         info->parameters);
1299
1300         len += pack_devicemode(info->devmode, buf+len, buflen-len);
1301         len += pack_specifics(info->specific, buf+len, buflen-len);
1302
1303         if (buflen != len) {
1304                 buf = (char *)Realloc(buf, len);
1305                 buflen = len;
1306                 goto again;
1307         }
1308         
1309
1310         slprintf(key, sizeof(key), "%s%s",
1311                  PRINTERS_PREFIX, info->sharename);
1312
1313         kbuf.dptr = key;
1314         kbuf.dsize = strlen(key)+1;
1315         dbuf.dptr = buf;
1316         dbuf.dsize = len;
1317
1318         ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
1319
1320         if (ret == -1)
1321                 DEBUG(8, ("error updating printer to tdb on disk\n"));
1322
1323         safe_free(buf);
1324
1325         DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n", 
1326                  info->sharename, info->drivername, info->portname, len));
1327
1328         return ret;
1329 }
1330
1331
1332 /****************************************************************************
1333 ****************************************************************************/
1334 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1335 {
1336         NT_PRINTER_PARAM *current;
1337         
1338         DEBUG(108,("add_a_specific_param\n"));  
1339
1340         param->next=NULL;
1341         
1342         if (info_2->specific == NULL)
1343         {
1344                 info_2->specific=param;
1345         }
1346         else
1347         {
1348                 current=info_2->specific;               
1349                 while (current->next != NULL) {
1350                         current=current->next;
1351                 }               
1352                 current->next=param;
1353         }
1354         return (True);
1355 }
1356
1357 /****************************************************************************
1358 ****************************************************************************/
1359 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1360 {
1361         NT_PRINTER_PARAM *current;
1362         NT_PRINTER_PARAM *previous;
1363         
1364         current=info_2->specific;
1365         previous=current;
1366         
1367         if (current==NULL) return (False);
1368         
1369         if ( !strcmp(current->value, param->value) && 
1370             (strlen(current->value)==strlen(param->value)) ) {
1371                 DEBUG(109,("deleting first value\n"));
1372                 info_2->specific=current->next;
1373                 safe_free(current->data);
1374                 safe_free(current);
1375                 DEBUG(109,("deleted first value\n"));
1376                 return (True);
1377         }
1378
1379         current=previous->next;
1380                 
1381         while ( current!=NULL ) {
1382                 if (!strcmp(current->value, param->value) &&
1383                     strlen(current->value)==strlen(param->value) ) {
1384                         DEBUG(109,("deleting current value\n"));
1385                         previous->next=current->next;
1386                         safe_free(current->data);
1387                         safe_free(current);
1388                         DEBUG(109,("deleted current value\n"));
1389                         return(True);
1390                 }
1391                 
1392                 previous=previous->next;
1393                 current=current->next;
1394         }
1395         return (False);
1396 }
1397
1398 /****************************************************************************
1399  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
1400 ****************************************************************************/
1401 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
1402 {
1403         NT_PRINTER_PARAM *param = *param_ptr;
1404
1405         if(param == NULL)
1406                 return;
1407
1408         DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
1409
1410         if(param->data)
1411                 safe_free(param->data);
1412
1413         safe_free(param);
1414         *param_ptr = NULL;
1415 }
1416
1417 /****************************************************************************
1418  Malloc and return an NT devicemode.
1419 ****************************************************************************/
1420
1421 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
1422 {
1423 /*
1424  * should I init this ones ???
1425         nt_devmode->devicename
1426 */
1427
1428         char adevice[32];
1429         NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
1430
1431         if (nt_devmode == NULL) {
1432                 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
1433                 return NULL;
1434         }
1435
1436         ZERO_STRUCTP(nt_devmode);
1437
1438         snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, default_devicename);
1439         fstrcpy(nt_devmode->devicename, adevice);
1440         
1441         
1442         fstrcpy(nt_devmode->formname, "Letter");
1443
1444         nt_devmode->specversion      = 0x0401;
1445         nt_devmode->driverversion    = 0x0400;
1446         nt_devmode->size             = 0x00DC;
1447         nt_devmode->driverextra      = 0x0000;
1448         nt_devmode->fields           = FORMNAME | TTOPTION | PRINTQUALITY | 
1449                                        DEFAULTSOURCE | COPIES | SCALE | 
1450                                        PAPERSIZE | ORIENTATION;
1451         nt_devmode->orientation      = 1;
1452         nt_devmode->papersize        = PAPER_LETTER;
1453         nt_devmode->paperlength      = 0;
1454         nt_devmode->paperwidth       = 0;
1455         nt_devmode->scale            = 0x64;
1456         nt_devmode->copies           = 01;
1457         nt_devmode->defaultsource    = BIN_FORMSOURCE;
1458         nt_devmode->printquality     = RES_HIGH;           /* 0x0258 */
1459         nt_devmode->color            = COLOR_MONOCHROME;
1460         nt_devmode->duplex           = DUP_SIMPLEX;
1461         nt_devmode->yresolution      = 0;
1462         nt_devmode->ttoption         = TT_SUBDEV;
1463         nt_devmode->collate          = COLLATE_FALSE;
1464         nt_devmode->icmmethod        = 0;
1465         nt_devmode->icmintent        = 0;
1466         nt_devmode->mediatype        = 0;
1467         nt_devmode->dithertype       = 0;
1468
1469         /* non utilisés par un driver d'imprimante */
1470         nt_devmode->logpixels        = 0;
1471         nt_devmode->bitsperpel       = 0;
1472         nt_devmode->pelswidth        = 0;
1473         nt_devmode->pelsheight       = 0;
1474         nt_devmode->displayflags     = 0;
1475         nt_devmode->displayfrequency = 0;
1476         nt_devmode->reserved1        = 0;
1477         nt_devmode->reserved2        = 0;
1478         nt_devmode->panningwidth     = 0;
1479         nt_devmode->panningheight    = 0;
1480         
1481         nt_devmode->private=NULL;
1482
1483         return nt_devmode;
1484 }
1485
1486 /****************************************************************************
1487  Deepcopy an NT devicemode.
1488 ****************************************************************************/
1489
1490 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
1491 {
1492         NT_DEVICEMODE *new_nt_devicemode = NULL;
1493
1494         if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
1495                 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
1496                 return NULL;
1497         }
1498
1499         new_nt_devicemode->private = NULL;
1500         if (nt_devicemode->private != NULL) {
1501                 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
1502                         safe_free(new_nt_devicemode);
1503                         DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
1504                         return NULL;
1505         }
1506         }
1507
1508         return new_nt_devicemode;
1509 }
1510
1511 /****************************************************************************
1512  Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
1513 ****************************************************************************/
1514
1515 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
1516 {
1517         NT_DEVICEMODE *nt_devmode = *devmode_ptr;
1518
1519         if(nt_devmode == NULL)
1520                 return;
1521
1522         DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
1523
1524         if(nt_devmode->private)
1525                 safe_free(nt_devmode->private);
1526
1527         safe_free(nt_devmode);
1528         *devmode_ptr = NULL;
1529 }
1530
1531 /****************************************************************************
1532  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
1533 ****************************************************************************/
1534 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
1535 {
1536         NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
1537         NT_PRINTER_PARAM *param_ptr;
1538
1539         if(info == NULL)
1540                 return;
1541
1542         DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
1543
1544         free_nt_devicemode(&info->devmode);
1545         free_sec_desc_buf(&info->secdesc_buf);
1546
1547         for(param_ptr = info->specific; param_ptr; ) {
1548                 NT_PRINTER_PARAM *tofree = param_ptr;
1549
1550                 param_ptr = param_ptr->next;
1551                 free_nt_printer_param(&tofree);
1552         }
1553
1554         safe_free(*info_ptr);
1555         *info_ptr = NULL;
1556 }
1557
1558
1559 /****************************************************************************
1560 ****************************************************************************/
1561 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
1562 {
1563         int len = 0;
1564         int extra_len = 0;
1565         NT_DEVICEMODE devmode;
1566
1567         ZERO_STRUCT(devmode);
1568
1569         len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
1570
1571         if (!*nt_devmode) return len;
1572
1573         len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1574                           devmode.devicename,
1575                           devmode.formname,
1576
1577                           &devmode.specversion,
1578                           &devmode.driverversion,
1579                           &devmode.size,
1580                           &devmode.driverextra,
1581                           &devmode.orientation,
1582                           &devmode.papersize,
1583                           &devmode.paperlength,
1584                           &devmode.paperwidth,
1585                           &devmode.scale,
1586                           &devmode.copies,
1587                           &devmode.defaultsource,
1588                           &devmode.printquality,
1589                           &devmode.color,
1590                           &devmode.duplex,
1591                           &devmode.yresolution,
1592                           &devmode.ttoption,
1593                           &devmode.collate,
1594                           &devmode.logpixels,
1595                           
1596                           &devmode.fields,
1597                           &devmode.bitsperpel,
1598                           &devmode.pelswidth,
1599                           &devmode.pelsheight,
1600                           &devmode.displayflags,
1601                           &devmode.displayfrequency,
1602                           &devmode.icmmethod,
1603                           &devmode.icmintent,
1604                           &devmode.mediatype,
1605                           &devmode.dithertype,
1606                           &devmode.reserved1,
1607                           &devmode.reserved2,
1608                           &devmode.panningwidth,
1609                           &devmode.panningheight,
1610                           &devmode.private);
1611         
1612         if (devmode.private) {
1613                 /* the len in tdb_unpack is an int value and
1614                  * devmoce.driverextra is only a short
1615                  */
1616                 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
1617                 devmode.driverextra=(uint16)extra_len;
1618         }
1619
1620         *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
1621
1622         DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
1623         if (devmode.private)
1624                 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
1625
1626         return len;
1627 }
1628
1629 /****************************************************************************
1630 ****************************************************************************/
1631 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
1632 {
1633         int len = 0;
1634         NT_PRINTER_PARAM param, *p;
1635
1636         *list = NULL;
1637
1638         while (1) {
1639                 len += tdb_unpack(buf+len, buflen-len, "p", &p);
1640                 if (!p) break;
1641
1642                 len += tdb_unpack(buf+len, buflen-len, "fdB",
1643                                   param.value, 
1644                                   &param.type, 
1645                                   &param.data_len,
1646                                   &param.data);
1647                 param.next = *list;
1648                 *list = memdup(&param, sizeof(param));
1649
1650                 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
1651         }
1652
1653         return len;
1654 }
1655
1656
1657 /****************************************************************************
1658 get a default printer info 2 struct
1659 ****************************************************************************/
1660 static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1661 {
1662         extern pstring global_myname;
1663         int snum;
1664         NT_PRINTER_INFO_LEVEL_2 info;
1665
1666         ZERO_STRUCT(info);
1667
1668         snum = lp_servicenumber(sharename);
1669
1670         fstrcpy(info.servername, global_myname);
1671         fstrcpy(info.printername, sharename);
1672         fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
1673         fstrcpy(info.drivername, lp_printerdriver(snum));
1674         pstrcpy(info.comment, "");
1675         fstrcpy(info.printprocessor, "winprint");
1676         fstrcpy(info.datatype, "RAW");
1677
1678         info.attributes = PRINTER_ATTRIBUTE_SHARED   \
1679                          | PRINTER_ATTRIBUTE_LOCAL  \
1680                          | PRINTER_ATTRIBUTE_RAW_ONLY \
1681                          | PRINTER_ATTRIBUTE_QUEUED ;            /* attributes */
1682
1683         info.starttime = 0; /* Minutes since 12:00am GMT */
1684         info.untiltime = 0; /* Minutes since 12:00am GMT */
1685         info.priority = 1;
1686         info.default_priority = 1;
1687
1688         if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
1689                 goto fail;
1690
1691         if (!nt_printing_getsec(sharename, &info.secdesc_buf))
1692                 goto fail;
1693
1694         *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
1695         if (! *info_ptr) {
1696                 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
1697                 goto fail;
1698         }
1699
1700         return (0);     
1701
1702   fail:
1703
1704         if (info.devmode)
1705                 free_nt_devicemode(&info.devmode);
1706         if (info.secdesc_buf)
1707                 free_sec_desc_buf(&info.secdesc_buf);
1708         return 2;
1709 }
1710
1711 /****************************************************************************
1712 ****************************************************************************/
1713 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1714 {
1715         pstring key;
1716         NT_PRINTER_INFO_LEVEL_2 info;
1717         int len = 0;
1718         TDB_DATA kbuf, dbuf;
1719                 
1720         ZERO_STRUCT(info);
1721
1722         slprintf(key, sizeof(key), "%s%s", PRINTERS_PREFIX, sharename);
1723
1724         kbuf.dptr = key;
1725         kbuf.dsize = strlen(key)+1;
1726
1727         dbuf = tdb_fetch(tdb, kbuf);
1728 #if 1 /* JRATEST */
1729         if (!dbuf.dptr)
1730                 return get_a_printer_2_default(info_ptr, sharename);
1731 #else
1732         if (!dbuf.dptr) return 1;
1733 #endif
1734
1735         len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
1736                         &info.attributes,
1737                         &info.priority,
1738                         &info.default_priority,
1739                         &info.starttime,
1740                         &info.untiltime,
1741                         &info.status,
1742                         &info.cjobs,
1743                         &info.averageppm,
1744                         &info.changeid,
1745                         &info.c_setprinter,
1746                         &info.setuptime,
1747                         info.servername,
1748                         info.printername,
1749                         info.sharename,
1750                         info.portname,
1751                         info.drivername,
1752                         info.comment,
1753                         info.location,
1754                         info.sepfile,
1755                         info.printprocessor,
1756                         info.datatype,
1757                         info.parameters);
1758
1759         /* Samba has to have shared raw drivers. */
1760         info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
1761
1762         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
1763         len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
1764
1765 #if 1 /* JRATEST */
1766         nt_printing_getsec(sharename, &info.secdesc_buf);
1767 #endif /* JRATEST */
1768
1769         safe_free(dbuf.dptr);
1770         *info_ptr=memdup(&info, sizeof(info));
1771
1772         DEBUG(9,("Unpacked printer [%s] running driver [%s]\n",
1773                  sharename, info.drivername));
1774
1775         
1776         return 0;       
1777 }
1778
1779 /****************************************************************************
1780 debugging function, dump at level 6 the struct in the logs
1781 ****************************************************************************/
1782 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1783 {
1784         uint32 success;
1785         NT_PRINTER_INFO_LEVEL_2 *info2;
1786         
1787         DEBUG(106,("Dumping printer at level [%d]\n", level));
1788         
1789         switch (level)
1790         {
1791                 case 2: 
1792                 {
1793                         if (printer.info_2 == NULL)
1794                                 success=5;
1795                         else
1796                         {
1797                                 info2=printer.info_2;
1798                         
1799                                 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
1800                                 DEBUGADD(106,("priority:[%d]\n", info2->priority));
1801                                 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
1802                                 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
1803                                 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
1804                                 DEBUGADD(106,("status:[%d]\n", info2->status));
1805                                 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
1806                                 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
1807                                 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
1808                                 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
1809                                 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
1810
1811                                 DEBUGADD(106,("servername:[%s]\n", info2->servername));
1812                                 DEBUGADD(106,("printername:[%s]\n", info2->printername));
1813                                 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
1814                                 DEBUGADD(106,("portname:[%s]\n", info2->portname));
1815                                 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
1816                                 DEBUGADD(106,("comment:[%s]\n", info2->comment));
1817                                 DEBUGADD(106,("location:[%s]\n", info2->location));
1818                                 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
1819                                 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
1820                                 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
1821                                 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
1822                                 success=0;
1823                         }
1824                         break;
1825                 }
1826                 default:
1827                         DEBUGADD(1,("Level not implemented\n"));
1828                         success=1;
1829                         break;
1830         }
1831         
1832         return (success);
1833 }
1834
1835 /****************************************************************************
1836  Get the parameters we can substitute in an NT print job.
1837 ****************************************************************************/
1838
1839 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
1840 {
1841         NT_PRINTER_INFO_LEVEL *printer = NULL;
1842
1843         **printername = **sharename = **portname = '\0';
1844
1845         if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1846                 return;
1847
1848         fstrcpy(*printername, printer->info_2->printername);
1849         fstrcpy(*sharename, printer->info_2->sharename);
1850         fstrcpy(*portname, printer->info_2->portname);
1851
1852         free_a_printer(&printer, 2);
1853 }
1854
1855 /*
1856  * The function below are the high level ones.
1857  * only those ones must be called from the spoolss code.
1858  * JFM.
1859  */
1860
1861 /****************************************************************************
1862 ****************************************************************************/
1863 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1864 {
1865         uint32 success;
1866         
1867         dump_a_printer(printer, level); 
1868         
1869         switch (level)
1870         {
1871                 case 2: 
1872                 {
1873                         success=add_a_printer_2(printer.info_2);
1874                         break;
1875                 }
1876                 default:
1877                         success=1;
1878                         break;
1879         }
1880         
1881         return (success);
1882 }
1883
1884 /****************************************************************************
1885  Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
1886 ****************************************************************************/
1887
1888 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
1889 {
1890         uint32 success;
1891         NT_PRINTER_INFO_LEVEL *printer = NULL;
1892         
1893         *pp_printer = NULL;
1894
1895         DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1896
1897         switch (level)
1898         {
1899                 case 2: 
1900                 {
1901                         if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
1902                                 DEBUG(0,("get_a_printer: malloc fail.\n"));
1903                                 return 1;
1904                         }
1905                         ZERO_STRUCTP(printer);
1906                         success=get_a_printer_2(&printer->info_2, sharename);
1907                         if (success == 0) {
1908                                 dump_a_printer(*printer, level);
1909                                 *pp_printer = printer;
1910                         } else {
1911                                 safe_free(printer);
1912                         }
1913                         break;
1914                 }
1915                 default:
1916                         success=1;
1917                         break;
1918         }
1919         
1920         DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1921
1922         return (success);
1923 }
1924
1925 /****************************************************************************
1926  Deletes a NT_PRINTER_INFO_LEVEL struct.
1927 ****************************************************************************/
1928
1929 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
1930 {
1931         uint32 success;
1932         NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
1933
1934         DEBUG(104,("freeing a printer at level [%d]\n", level));
1935
1936         if (printer == NULL)
1937                 return 0;
1938         
1939         switch (level)
1940         {
1941                 case 2: 
1942                 {
1943                         if (printer->info_2 != NULL)
1944                         {
1945                                 free_nt_printer_info_level_2(&printer->info_2);
1946                                 success=0;
1947                         }
1948                         else
1949                         {
1950                                 success=4;
1951                         }
1952                         break;
1953                 }
1954                 default:
1955                         success=1;
1956                         break;
1957         }
1958
1959         safe_free(printer);
1960         *pp_printer = NULL;
1961         return (success);
1962 }
1963
1964 /****************************************************************************
1965 ****************************************************************************/
1966 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1967 {
1968         uint32 success;
1969         DEBUG(104,("adding a printer at level [%d]\n", level));
1970         dump_a_printer_driver(driver, level);
1971         
1972         switch (level)
1973         {
1974                 case 3: 
1975                 {
1976                         success=add_a_printer_driver_3(driver.info_3);
1977                         break;
1978                 }
1979
1980                 case 6: 
1981                 {
1982                         success=add_a_printer_driver_6(driver.info_6);
1983                         break;
1984                 }
1985                 default:
1986                         success=1;
1987                         break;
1988         }
1989         
1990         return (success);
1991 }
1992 /****************************************************************************
1993 ****************************************************************************/
1994 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, 
1995                             fstring printername, fstring architecture, uint32 version)
1996 {
1997         uint32 success;
1998         
1999         switch (level)
2000         {
2001                 case 3: 
2002                 {
2003                         success=get_a_printer_driver_3(&driver->info_3, printername, architecture, version);
2004                         break;
2005                 }
2006                 default:
2007                         success=1;
2008                         break;
2009         }
2010         
2011         if (success == 0)
2012                 dump_a_printer_driver(*driver, level);
2013         return (success);
2014 }
2015
2016 /****************************************************************************
2017 ****************************************************************************/
2018 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
2019 {
2020         uint32 success;
2021         
2022         switch (level)
2023         {
2024                 case 3: 
2025                 {
2026                         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
2027                         if (driver.info_3 != NULL)
2028                         {
2029                                 info3=driver.info_3;
2030                                 safe_free(info3->dependentfiles);
2031                                 ZERO_STRUCTP(info3);
2032                                 safe_free(info3);
2033                                 success=0;
2034                         }
2035                         else
2036                         {
2037                                 success=4;
2038                         }
2039                         break;
2040                 }
2041                 case 6: 
2042                 {
2043                         NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
2044                         if (driver.info_6 != NULL)
2045                         {
2046                                 info6=driver.info_6;
2047                                 safe_free(info6->dependentfiles);
2048                                 safe_free(info6->previousnames);
2049                                 ZERO_STRUCTP(info6);
2050                                 safe_free(info6);
2051                                 success=0;
2052                         }
2053                         else
2054                         {
2055                                 success=4;
2056                         }
2057                         break;
2058                 }
2059                 default:
2060                         success=1;
2061                         break;
2062         }
2063         return (success);
2064 }
2065
2066 /****************************************************************************
2067 ****************************************************************************/
2068 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
2069                                  fstring value, uint8 **data, uint32 *type, uint32 *len)
2070 {
2071         /* right now that's enough ! */ 
2072         NT_PRINTER_PARAM *param;
2073         int i=0;
2074         
2075         param=printer.info_2->specific;
2076         
2077         while (param != NULL && i < param_index) {
2078                 param=param->next;
2079                 i++;
2080         }
2081         
2082         if (param == NULL)
2083                 return False;
2084
2085         /* exited because it exist */
2086         *type=param->type;              
2087         StrnCpy(value, param->value, sizeof(fstring)-1);
2088         *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
2089         if(*data == NULL)
2090                 return False;
2091         ZERO_STRUCTP(*data);
2092         memcpy(*data, param->data, param->data_len);
2093         *len=param->data_len;
2094         return True;
2095 }
2096
2097 /****************************************************************************
2098 ****************************************************************************/
2099 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level, 
2100                         fstring value, uint8 **data, uint32 *type, uint32 *len)
2101 {
2102         /* right now that's enough ! */ 
2103         NT_PRINTER_PARAM *param;
2104         
2105         DEBUG(105, ("get_specific_param\n"));
2106         
2107         param=printer.info_2->specific;
2108                 
2109         while (param != NULL)
2110         {
2111 #if 1 /* JRA - I think this should be case insensitive.... */
2112                 if ( strequal(value, param->value) 
2113 #else
2114                 if ( !strcmp(value, param->value) 
2115 #endif
2116                     && strlen(value)==strlen(param->value))
2117                         break;
2118                         
2119                 param=param->next;
2120         }
2121         
2122         DEBUG(106, ("found one param\n"));
2123         if (param != NULL)
2124         {
2125                 /* exited because it exist */
2126                 *type=param->type;      
2127                 
2128                 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
2129                 if(*data == NULL)
2130                         return False;
2131                 memcpy(*data, param->data, param->data_len);
2132                 *len=param->data_len;
2133
2134                 DEBUG(106, ("exit of get_specific_param:true\n"));
2135                 return (True);
2136         }
2137         DEBUG(106, ("exit of get_specific_param:false\n"));
2138         return (False);
2139 }
2140
2141 /****************************************************************************
2142  Store a security desc for a printer.
2143 ****************************************************************************/
2144
2145 uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
2146 {
2147         SEC_DESC_BUF *new_secdesc_ctr = NULL;
2148         SEC_DESC_BUF *old_secdesc_ctr = NULL;
2149         prs_struct ps;
2150         TALLOC_CTX *mem_ctx = NULL;
2151         fstring key;
2152         uint32 status;
2153
2154         mem_ctx = talloc_init();
2155         if (mem_ctx == NULL)
2156                 return False;
2157
2158         /* The old owner and group sids of the security descriptor are not
2159            present when new ACEs are added or removed by changing printer
2160            permissions through NT.  If they are NULL in the new security
2161            descriptor then copy them over from the old one. */
2162
2163         if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
2164                 DOM_SID *owner_sid, *group_sid;
2165                 SEC_ACL *dacl, *sacl;
2166                 SEC_DESC *psd = NULL;
2167                 size_t size;
2168
2169                 nt_printing_getsec(printername, &old_secdesc_ctr);
2170
2171                 /* Pick out correct owner and group sids */
2172
2173                 owner_sid = secdesc_ctr->sec->owner_sid ?
2174                         secdesc_ctr->sec->owner_sid :
2175                         old_secdesc_ctr->sec->owner_sid;
2176
2177                 group_sid = secdesc_ctr->sec->grp_sid ?
2178                         secdesc_ctr->sec->grp_sid :
2179                         old_secdesc_ctr->sec->grp_sid;
2180
2181                 dacl = secdesc_ctr->sec->dacl ?
2182                         secdesc_ctr->sec->dacl :
2183                         old_secdesc_ctr->sec->dacl;
2184
2185                 sacl = secdesc_ctr->sec->sacl ?
2186                         secdesc_ctr->sec->sacl :
2187                         old_secdesc_ctr->sec->sacl;
2188
2189                 /* Make a deep copy of the security descriptor */
2190
2191                 psd = make_sec_desc(secdesc_ctr->sec->revision,
2192                                     secdesc_ctr->sec->type,
2193                                     owner_sid, group_sid,
2194                                     sacl,
2195                                     dacl,
2196                                     &size);
2197
2198                 new_secdesc_ctr = make_sec_desc_buf(size, psd);
2199
2200                 /* Free up memory */
2201
2202                 free_sec_desc(&psd);
2203                 free_sec_desc_buf(&old_secdesc_ctr);
2204         }
2205
2206         if (!new_secdesc_ctr) {
2207                 new_secdesc_ctr = secdesc_ctr;
2208         }
2209
2210         /* Store the security descriptor in a tdb */
2211
2212         prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) + 
2213                  sizeof(SEC_DESC_BUF), 4, mem_ctx, MARSHALL);
2214
2215         if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr, 
2216                              &ps, 1)) {
2217                 status = ERROR_INVALID_FUNCTION;
2218                 goto out;
2219         }
2220
2221         slprintf(key, sizeof(key), "SECDESC/%s", printername);
2222
2223         if (tdb_prs_store(tdb, key, &ps)==0) {
2224                 status = 0;
2225         } else {
2226                 DEBUG(1,("Failed to store secdesc for %s\n", printername));
2227                 status = ERROR_INVALID_FUNCTION;
2228         }
2229
2230         /* Free mallocated memory */
2231
2232  out:
2233         free_sec_desc_buf(&old_secdesc_ctr);
2234
2235         if (new_secdesc_ctr != secdesc_ctr) {
2236                 free_sec_desc_buf(&new_secdesc_ctr);
2237         }
2238
2239         prs_mem_free(&ps);
2240         if (mem_ctx)
2241                 talloc_destroy(mem_ctx);
2242         return status;
2243 }
2244
2245 /****************************************************************************
2246  Construct a default security descriptor buffer for a printer.
2247 ****************************************************************************/
2248
2249 static SEC_DESC_BUF *construct_default_printer_sdb(void)
2250 {
2251         SEC_ACE ace[2];
2252         SEC_ACCESS sa;
2253         SEC_ACL *psa = NULL;
2254         SEC_DESC_BUF *sdb = NULL;
2255         SEC_DESC *psd = NULL;
2256         DOM_SID owner_sid;
2257         size_t sd_size;
2258         enum SID_NAME_USE name_type;
2259
2260         /* Create an ACE where Everyone is allowed to print */
2261
2262         init_sec_access(&sa, PRINTER_ACE_PRINT);
2263         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
2264                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2265
2266
2267         /* Make the security descriptor owned by the Administrators group
2268            on the PDC of the domain. */
2269
2270         if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
2271                 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
2272         } else {
2273
2274                 /* Backup plan - make printer owned by admins or root.  This should
2275                    emulate a lanman printer as security settings can't be
2276                    changed. */
2277
2278                 if (!lookup_name( "Printer Administrators", &owner_sid, &name_type) &&
2279                         !lookup_name( "Administrators", &owner_sid, &name_type) &&
2280                         !lookup_name( "Administrator", &owner_sid, &name_type) &&
2281                         !lookup_name("root", &owner_sid, &name_type)) {
2282                                                 sid_copy(&owner_sid, &global_sid_World);
2283                 }
2284         }
2285
2286         init_sec_access(&sa, PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT);
2287         init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
2288                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2289
2290         /* The ACL revision number in rpc_secdesc.h differs from the one
2291            created by NT when setting ACE entries in printer
2292            descriptors.  NT4 complains about the property being edited by a
2293            NT5 machine. */
2294
2295 #define NT4_ACL_REVISION 0x2
2296
2297         if ((psa = make_sec_acl(NT4_ACL_REVISION, 2, ace)) != NULL) {
2298                 psd = make_sec_desc(SEC_DESC_REVISION, 
2299                                     SEC_DESC_SELF_RELATIVE | 
2300                                     SEC_DESC_DACL_PRESENT,
2301                                     &owner_sid, NULL,
2302                                     NULL, psa, &sd_size);
2303                 free_sec_acl(&psa);
2304         }
2305
2306         if (!psd) {
2307                 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
2308                 return NULL;
2309         }
2310
2311         sdb = make_sec_desc_buf(sd_size, psd);
2312
2313         DEBUG(4,("construct_default_printer_sdb: size = %u.\n", 
2314                  (unsigned int)sd_size));
2315
2316         free_sec_desc(&psd);
2317         return sdb;
2318 }
2319
2320 /****************************************************************************
2321  Get a security desc for a printer.
2322 ****************************************************************************/
2323
2324 BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr)
2325 {
2326         prs_struct ps;
2327         TALLOC_CTX *mem_ctx = NULL;
2328         fstring key;
2329
2330         mem_ctx = talloc_init();
2331         if (mem_ctx == NULL)
2332                 return False;
2333
2334         /* Fetch security descriptor from tdb */
2335
2336         slprintf(key, sizeof(key), "SECDESC/%s", printername);
2337
2338         if (tdb_prs_fetch(tdb, key, &ps, mem_ctx)!=0 ||
2339             !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
2340
2341                 DEBUG(4,("using default secdesc for %s\n", printername));
2342
2343                 if (!(*secdesc_ctr = construct_default_printer_sdb())) {
2344                         talloc_destroy(mem_ctx);
2345                         return False;
2346                 }
2347
2348                 talloc_destroy(mem_ctx);
2349                 return True;
2350         }
2351
2352         /* If security descriptor is owned by S-1-1-0 and winbindd is up,
2353            this security descriptor has been created when winbindd was
2354            down.  Take ownership of security descriptor. */
2355
2356         if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
2357                 DOM_SID owner_sid;
2358                 enum SID_NAME_USE name_type;
2359
2360                 /* Change sd owner to workgroup administrator */
2361
2362                 if (winbind_lookup_name(lp_workgroup(), &owner_sid,
2363                                         &name_type)) {
2364                         SEC_DESC_BUF *new_secdesc_ctr = NULL;
2365                         SEC_DESC *psd = NULL;
2366                         size_t size;
2367
2368                         /* Create new sd */
2369
2370                         sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
2371
2372                         psd = make_sec_desc((*secdesc_ctr)->sec->revision,
2373                                             (*secdesc_ctr)->sec->type,
2374                                             &owner_sid,
2375                                             (*secdesc_ctr)->sec->grp_sid,
2376                                             (*secdesc_ctr)->sec->sacl,
2377                                             (*secdesc_ctr)->sec->dacl,
2378                                             &size);
2379
2380                         new_secdesc_ctr = make_sec_desc_buf(size, psd);
2381
2382                         free_sec_desc(&psd);
2383
2384                         /* Swap with other one */
2385
2386                         free_sec_desc_buf(secdesc_ctr);
2387                         *secdesc_ctr = new_secdesc_ctr;
2388
2389                         /* Set it */
2390
2391                         nt_printing_setsec(printername, *secdesc_ctr);
2392                 }
2393         }
2394
2395         prs_mem_free(&ps);
2396         talloc_destroy(mem_ctx);
2397         return True;
2398 }
2399
2400 /* error code:
2401         0: everything OK
2402         1: level not implemented
2403         2: file doesn't exist
2404         3: can't allocate memory
2405         4: can't free memory
2406         5: non existant struct
2407 */
2408
2409 /*
2410         A printer and a printer driver are 2 different things.
2411         NT manages them separatelly, Samba does the same.
2412         Why ? Simply because it's easier and it makes sense !
2413         
2414         Now explanation: You have 3 printers behind your samba server,
2415         2 of them are the same make and model (laser A and B). But laser B 
2416         has an 3000 sheet feeder and laser A doesn't such an option.
2417         Your third printer is an old dot-matrix model for the accounting :-).
2418         
2419         If the /usr/local/samba/lib directory (default dir), you will have
2420         5 files to describe all of this.
2421         
2422         3 files for the printers (1 by printer):
2423                 NTprinter_laser A
2424                 NTprinter_laser B
2425                 NTprinter_accounting
2426         2 files for the drivers (1 for the laser and 1 for the dot matrix)
2427                 NTdriver_printer model X
2428                 NTdriver_printer model Y
2429
2430 jfm: I should use this comment for the text file to explain 
2431         same thing for the forms BTW.
2432         Je devrais mettre mes commentaires en francais, ca serait mieux :-)
2433
2434 */
2435
2436 /****************************************************************************
2437  Check a user has permissions to perform the given operation.  We use some
2438  constants defined in include/rpc_spoolss.h that look relevant to check
2439  the various actions we perform when checking printer access.
2440
2441    PRINTER_ACCESS_ADMINISTER:
2442        print_queue_pause, print_queue_resume, update_printer_sec,
2443        update_printer, spoolss_addprinterex_level_2,
2444        _spoolss_setprinterdata
2445         
2446    PRINTER_ACCESS_USE:
2447        print_job_start
2448
2449    JOB_ACCESS_ADMINISTER:
2450        print_job_delete, print_job_pause, print_job_resume,
2451        print_queue_purge
2452
2453  ****************************************************************************/
2454 BOOL print_access_check(struct current_user *user, int snum, int access_type)
2455 {
2456         SEC_DESC_BUF *secdesc = NULL;
2457         uint32 access_granted, status, required_access = 0;
2458         BOOL result;
2459         char *pname;
2460         int i;
2461         extern struct current_user current_user;
2462         
2463         /* If user is NULL then use the current_user structure */
2464
2465         if (!user) user = &current_user;
2466
2467         /* Always allow root or printer admins to do anything */
2468
2469         if (user->uid == 0 ||
2470             user_in_list(uidtoname(user->uid), lp_printer_admin(snum))) {
2471                 return True;
2472         }
2473
2474         /* Get printer name */
2475
2476         pname = PRINTERNAME(snum);
2477
2478         if (!pname || !*pname)
2479                 pname = SERVICE(snum);
2480
2481         if (!pname || !*pname) {
2482                 errno = EACCES;
2483                 return False;
2484         }
2485
2486         /* Get printer security descriptor */
2487
2488         nt_printing_getsec(pname, &secdesc);
2489
2490         /* Check against NT4 ACE mask values.  From observation these
2491            values are:
2492
2493                Access Type       ACE Mask    Constant
2494                -------------------------------------
2495                Full Control      0x10000000  PRINTER_ACE_FULL_CONTROL
2496                Print             0xe0000000  PRINTER_ACE_PRINT
2497                Manage Documents  0x00020000  PRINTER_ACE_MANAGE_DOCUMENTS
2498         */
2499
2500         switch (access_type) {
2501         case PRINTER_ACCESS_USE:
2502                 required_access = PRINTER_ACE_PRINT;
2503                 break;
2504         case PRINTER_ACCESS_ADMINISTER:
2505                 required_access = PRINTER_ACE_MANAGE_DOCUMENTS | 
2506                         PRINTER_ACE_PRINT;
2507                 break;
2508         case JOB_ACCESS_ADMINISTER:
2509                 required_access = PRINTER_ACE_MANAGE_DOCUMENTS;
2510                 break;
2511         default:
2512                 DEBUG(0, ("invalid value passed to print_access_check()\n"));
2513                 result = False;
2514                 goto done;
2515         }       
2516
2517         /* The ACE for Full Control in a printer security descriptor
2518            doesn't seem to map properly to the access checking model.  For
2519            it to work properly it should be the logical OR of all the other
2520            values, i.e PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT.
2521            This would cause the access check to simply fall out when we
2522            check against any subset of these bits.  To get things to work,
2523            change every ACE mask of PRINTER_ACE_FULL_CONTROL to 
2524            PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT before
2525            performing the access check.  I'm sure there is a better way to
2526            do this! */
2527
2528         if (secdesc && secdesc->sec && secdesc->sec->dacl &&
2529             secdesc->sec->dacl->ace) {
2530                 for(i = 0; i < secdesc->sec->dacl->num_aces; i++) {
2531                         if (secdesc->sec->dacl->ace[i].info.mask ==
2532                             PRINTER_ACE_FULL_CONTROL) {
2533                                 secdesc->sec->dacl->ace[i].info.mask =
2534                                         PRINTER_ACE_MANAGE_DOCUMENTS | 
2535                                         PRINTER_ACE_PRINT;
2536                         }
2537                 }
2538         }
2539
2540         if ((result = se_access_check(secdesc->sec, user, required_access, 
2541                                       &access_granted, &status))) {
2542                 goto done;
2543         }
2544
2545         /* Check against NT5 ACE mask values.  From observation these
2546            values are:
2547
2548                Access Type       ACE Mask    Constant
2549                -------------------------------------
2550                Full Control      0x000f000c  PRINTER_ACE_NT5_FULL_CONTROL
2551                Print             0x00020008  PRINTER_ACE_NT5_PRINT
2552                Manage Documents  0x00020000  PRINTER_ACE_NT5_MANAGE_DOCUMENTS
2553
2554            NT5 likes to rewrite the security descriptor and change the ACE
2555            masks from NT4 format to NT5 format making them unreadable by
2556            NT4 clients. */
2557
2558         switch (access_type) {
2559         case PRINTER_ACCESS_USE:
2560                 required_access = PRINTER_ACE_NT5_PRINT;
2561                 break;
2562         case PRINTER_ACCESS_ADMINISTER:
2563                 required_access = PRINTER_ACE_NT5_FULL_CONTROL;
2564                 break;
2565         case JOB_ACCESS_ADMINISTER:
2566                 required_access = PRINTER_ACE_NT5_MANAGE_DOCUMENTS;
2567                 break;
2568         }       
2569
2570         result = se_access_check(secdesc->sec, user, required_access, 
2571                                  &access_granted, &status);
2572
2573         /* Check access */
2574         
2575  done:
2576         DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
2577         
2578         /* Free mallocated memory */
2579
2580         free_sec_desc_buf(&secdesc);
2581
2582         if (!result)
2583                 errno = EACCES;
2584
2585         return result;
2586 }
2587
2588 /****************************************************************************
2589  Check the time parameters allow a print operation.
2590 *****************************************************************************/
2591
2592 BOOL print_time_access_check(int snum)
2593 {
2594         NT_PRINTER_INFO_LEVEL *printer = NULL;
2595         BOOL ok = False;
2596         time_t now = time(NULL);
2597         struct tm *t;
2598         uint32 mins;
2599
2600         if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
2601                 return False;
2602
2603         if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
2604                 ok = True;
2605
2606         t = gmtime(&now);
2607         mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
2608
2609         if (mins >= printer->info_2->starttime && mins <= printer->info_2->untiltime)
2610                 ok = True;
2611
2612         free_a_printer(&printer, 2);
2613
2614         if (!ok)
2615                 errno = EACCES;
2616
2617         return ok;
2618 }
2619
2620
2621 #undef OLD_NTDOMAIN