2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 extern int DEBUGLEVEL;
26 extern pstring global_myname;
28 static TDB_CONTEXT *tdb; /* used for driver files */
30 #define FORMS_PREFIX "FORMS/"
31 #define DRIVERS_PREFIX "DRIVERS/"
32 #define PRINTERS_PREFIX "PRINTERS/"
34 #define DATABASE_VERSION 1
36 /* we need to have a small set of default forms to support our
38 static nt_forms_struct default_forms[] = {
39 {"Letter", 0x20, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367},
40 {"A4", 0xb0, 0x3354f, 0x4884e, 0x0, 0x0, 0x3354f, 0x4884e}
44 /****************************************************************************
45 open the NT printing tdb
46 ****************************************************************************/
47 BOOL nt_printing_init(void)
49 static pid_t local_pid;
51 if (tdb && local_pid == sys_getpid()) return True;
52 tdb = tdb_open(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
54 DEBUG(0,("Failed to open nt drivers database\n"));
58 local_pid = sys_getpid();
60 /* handle a Samba upgrade */
62 if (tdb_fetch_int(tdb, "INFO/version") != DATABASE_VERSION) {
63 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
64 tdb_store_int(tdb, "INFO/version", DATABASE_VERSION);
72 /****************************************************************************
73 get a form struct list
74 ****************************************************************************/
75 int get_ntforms(nt_forms_struct **list)
77 TDB_DATA kbuf, newkey, dbuf;
82 for (kbuf = tdb_firstkey(tdb);
84 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
85 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
87 dbuf = tdb_fetch(tdb, kbuf);
88 if (!dbuf.dptr) continue;
90 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
91 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddddddd",
92 &form.flag, &form.width, &form.length, &form.left,
93 &form.top, &form.right, &form.bottom);
95 if (ret != dbuf.dsize) continue;
97 *list = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
102 /* we should never return a null forms list or NT gets unhappy */
104 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
105 n = sizeof(default_forms) / sizeof(default_forms[0]);
112 /****************************************************************************
113 write a form struct list
114 ****************************************************************************/
115 int write_ntforms(nt_forms_struct **list, int number)
122 for (i=0;i<number;i++) {
123 len = tdb_pack(buf, sizeof(buf), "ddddddd",
124 (*list)[i].flag, (*list)[i].width, (*list)[i].length,
125 (*list)[i].left, (*list)[i].top, (*list)[i].right,
127 if (len > sizeof(buf)) break;
128 slprintf(key, sizeof(key), "%s%s", FORMS_PREFIX, (*list)[i].name);
129 kbuf.dsize = strlen(key)+1;
133 if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) break;
139 /****************************************************************************
140 add a form struct at the end of the list
141 ****************************************************************************/
142 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
149 * NT tries to add forms even when
150 * they are already in the base
151 * only update the values if already present
156 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
157 for (n=0; n<*count && update==False; n++)
159 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
161 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
168 if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
170 unistr2_to_ascii((*list)[n].name, &(form->name), sizeof((*list)[n].name)-1);
174 (*list)[n].flag=form->flags;
175 (*list)[n].width=form->size_x;
176 (*list)[n].length=form->size_y;
177 (*list)[n].left=form->left;
178 (*list)[n].top=form->top;
179 (*list)[n].right=form->right;
180 (*list)[n].bottom=form->bottom;
185 /****************************************************************************
187 ****************************************************************************/
188 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
192 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
194 DEBUG(106, ("[%s]\n", form_name));
195 for (n=0; n<count; n++)
197 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
198 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
202 if (n==count) return;
204 (*list)[n].flag=form->flags;
205 (*list)[n].width=form->size_x;
206 (*list)[n].length=form->size_y;
207 (*list)[n].left=form->left;
208 (*list)[n].top=form->top;
209 (*list)[n].right=form->right;
210 (*list)[n].bottom=form->bottom;
213 /****************************************************************************
214 get the nt drivers list
216 traverse the database and look-up the matching names
217 ****************************************************************************/
218 int get_ntdrivers(fstring **list, char *architecture)
223 TDB_DATA kbuf, newkey;
225 get_short_archi(short_archi, architecture);
226 slprintf(key, sizeof(key), "%s%s/", DRIVERS_PREFIX, short_archi);
228 for (kbuf = tdb_firstkey(tdb);
230 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
231 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
233 if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
236 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
243 /****************************************************************************
244 function to do the mapping between the long architecture name and
246 ****************************************************************************/
247 void get_short_archi(char *short_archi, char *long_archi)
254 struct table archi_table[]=
256 {"Windows 4.0", "WIN40" },
257 {"Windows NT x86", "W32X86" },
258 {"Windows NT R4000", "W32mips" },
259 {"Windows NT Alpha_AXP", "W32alpha" },
260 {"Windows NT PowerPC", "W32ppc" },
266 DEBUG(107,("Getting architecture dependant directory\n"));
269 } while ( (archi_table[i].long_archi!=NULL ) && strncmp(long_archi, archi_table[i].long_archi, strlen(long_archi)) );
271 if (archi_table[i].long_archi==NULL)
273 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
275 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
277 DEBUGADD(108,("index: [%d]\n", i));
278 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
279 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
282 /****************************************************************************
283 ****************************************************************************/
284 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
287 fstring architecture;
293 get_short_archi(architecture, driver->environment);
294 slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, driver->name);
297 * cversion must be 2.
298 * when adding a printer ON the SERVER
299 * rpcAddPrinterDriver defines it to zero
311 len += tdb_pack(buf+len, buflen-len, "dffffffff",
320 driver->defaultdatatype);
322 if (driver->dependentfiles) {
323 for (i=0; *driver->dependentfiles[i]; i++) {
324 len += tdb_pack(buf+len, buflen-len, "f",
325 driver->dependentfiles[i]);
330 buf = (char *)Realloc(buf, len);
337 kbuf.dsize = strlen(key)+1;
341 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
347 /****************************************************************************
348 ****************************************************************************/
349 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
351 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
354 info3.cversion = driver->version;
355 fstrcpy(info3.environment,driver->environment);
356 fstrcpy(info3.driverpath,driver->driverpath);
357 fstrcpy(info3.datafile,driver->datafile);
358 fstrcpy(info3.configfile,driver->configfile);
359 fstrcpy(info3.helpfile,driver->helpfile);
360 fstrcpy(info3.monitorname,driver->monitorname);
361 fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
362 info3.dependentfiles = driver->dependentfiles;
364 return add_a_printer_driver_3(&info3);
368 /****************************************************************************
369 ****************************************************************************/
370 static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
372 NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
376 fstrcpy(info.name, in_prt);
377 fstrcpy(info.defaultdatatype, "RAW");
379 fstrcpy(info.driverpath, "");
380 fstrcpy(info.datafile, "");
381 fstrcpy(info.configfile, "");
382 fstrcpy(info.helpfile, "");
384 if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
385 return ERROR_NOT_ENOUGH_MEMORY;
387 memset(info.dependentfiles, '\0', 2*sizeof(fstring));
388 fstrcpy(info.dependentfiles[0], "");
390 *info_ptr = memdup(&info, sizeof(info));
395 /****************************************************************************
396 ****************************************************************************/
397 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
399 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
401 fstring architecture;
408 get_short_archi(architecture, in_arch);
409 slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, in_prt);
412 kbuf.dsize = strlen(key)+1;
414 dbuf = tdb_fetch(tdb, kbuf);
415 if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
417 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
426 driver.defaultdatatype);
429 while (len < dbuf.dsize) {
430 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
431 sizeof(fstring)*(i+2));
432 if (driver.dependentfiles == NULL)
435 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
436 &driver.dependentfiles[i]);
439 if (driver.dependentfiles != NULL)
440 fstrcpy(driver.dependentfiles[i], "");
442 safe_free(dbuf.dptr);
444 if (len != dbuf.dsize) {
445 if (driver.dependentfiles != NULL)
446 safe_free(driver.dependentfiles);
448 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
451 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
456 /****************************************************************************
457 debugging function, dump at level 6 the struct in the logs
458 ****************************************************************************/
459 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
462 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
465 DEBUG(106,("Dumping printer driver at level [%d]\n", level));
471 if (driver.info_3 == NULL)
476 DEBUGADD(106,("version:[%d]\n", info3->cversion));
477 DEBUGADD(106,("name:[%s]\n", info3->name));
478 DEBUGADD(106,("environment:[%s]\n", info3->environment));
479 DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
480 DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
481 DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
482 DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
483 DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
484 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
486 for (i=0; info3->dependentfiles &&
487 *info3->dependentfiles[i]; i++) {
488 DEBUGADD(106,("dependentfile:[%s]\n",
489 info3->dependentfiles[i]));
496 DEBUGADD(1,("Level not implemented\n"));
504 /****************************************************************************
505 ****************************************************************************/
506 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
510 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
512 if (!nt_devmode) return len;
514 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
515 nt_devmode->devicename,
516 nt_devmode->formname,
518 nt_devmode->specversion,
519 nt_devmode->driverversion,
521 nt_devmode->driverextra,
522 nt_devmode->orientation,
523 nt_devmode->papersize,
524 nt_devmode->paperlength,
525 nt_devmode->paperwidth,
528 nt_devmode->defaultsource,
529 nt_devmode->printquality,
532 nt_devmode->yresolution,
533 nt_devmode->ttoption,
535 nt_devmode->logpixels,
538 nt_devmode->bitsperpel,
539 nt_devmode->pelswidth,
540 nt_devmode->pelsheight,
541 nt_devmode->displayflags,
542 nt_devmode->displayfrequency,
543 nt_devmode->icmmethod,
544 nt_devmode->icmintent,
545 nt_devmode->mediatype,
546 nt_devmode->dithertype,
547 nt_devmode->reserved1,
548 nt_devmode->reserved2,
549 nt_devmode->panningwidth,
550 nt_devmode->panningheight,
551 nt_devmode->private);
554 if (nt_devmode->private) {
555 len += tdb_pack(buf+len, buflen-len, "B",
556 nt_devmode->driverextra,
557 nt_devmode->private);
560 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
565 /****************************************************************************
566 ****************************************************************************/
567 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
571 while (param != NULL) {
572 len += tdb_pack(buf+len, buflen-len, "pfdB",
581 len += tdb_pack(buf+len, buflen-len, "p", param);
587 /****************************************************************************
588 delete a printer - this just deletes the printer info file, any open
589 handles are not affected
590 ****************************************************************************/
591 uint32 del_a_printer(char *portname)
596 slprintf(key, sizeof(key), "%s%s",
597 PRINTERS_PREFIX, portname);
600 kbuf.dsize=strlen(key)+1;
602 tdb_delete(tdb, kbuf);
606 /****************************************************************************
607 ****************************************************************************/
608 static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
612 int buflen, len, ret;
616 * in addprinter: no servername and the printer is the name
617 * in setprinter: servername is \\server
618 * and printer is \\server\\printer
620 * Samba manages only local printers.
621 * we currently don't support things like path=\\other_server\printer
623 if (info->servername[0]!='\0')
625 trim_string(info->printername, info->servername, NULL);
626 trim_string(info->printername, "\\", NULL);
627 info->servername[0]='\0';
631 * JFM: one day I'll forget.
632 * below that's info->portname because that's the SAMBA sharename
633 * and I made NT 'thinks' it's the portname
634 * the info->sharename is the thing you can name when you add a printer
635 * that's the short-name when you create shared printer for 95/98
636 * So I've made a limitation in SAMBA: you can only have 1 printer model
637 * behind a SAMBA share.
646 len += tdb_pack(buf+len, buflen-len, "dddddddddddffffffffff",
649 info->default_priority,
665 info->printprocessor,
669 len += pack_devicemode(info->devmode, buf+len, buflen-len);
670 len += pack_specifics(info->specific, buf+len, buflen-len);
673 buf = (char *)Realloc(buf, len);
679 slprintf(key, sizeof(key), "%s%s",
680 PRINTERS_PREFIX, info->portname);
683 kbuf.dsize = strlen(key)+1;
687 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
691 DEBUG(8,("packed printer [%s] with printprocessor [%s] parameters=[%s] len=%d\n",
692 info->portname, info->printprocessor, info->parameters, len));
698 /****************************************************************************
699 ****************************************************************************/
700 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
702 NT_PRINTER_PARAM *current;
704 DEBUG(108,("add_a_specific_param\n"));
708 if (info_2->specific == NULL)
710 info_2->specific=param;
714 current=info_2->specific;
715 while (current->next != NULL) {
716 current=current->next;
723 /****************************************************************************
724 ****************************************************************************/
725 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
727 NT_PRINTER_PARAM *current;
728 NT_PRINTER_PARAM *previous;
730 current=info_2->specific;
733 if (current==NULL) return (False);
735 if ( !strcmp(current->value, param->value) &&
736 (strlen(current->value)==strlen(param->value)) ) {
737 DEBUG(109,("deleting first value\n"));
738 info_2->specific=current->next;
739 safe_free(current->data);
741 DEBUG(109,("deleted first value\n"));
745 current=previous->next;
747 while ( current!=NULL ) {
748 if (!strcmp(current->value, param->value) &&
749 strlen(current->value)==strlen(param->value) ) {
750 DEBUG(109,("deleting current value\n"));
751 previous->next=current->next;
752 safe_free(current->data);
754 DEBUG(109,("deleted current value\n"));
758 previous=previous->next;
759 current=current->next;
764 /****************************************************************************
765 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
766 ****************************************************************************/
767 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
769 NT_PRINTER_PARAM *param = *param_ptr;
774 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
777 safe_free(param->data);
783 /****************************************************************************
784 Malloc and return an NT devicemode.
785 ****************************************************************************/
787 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
790 * should I init this ones ???
791 nt_devmode->devicename
795 NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
797 if (nt_devmode == NULL) {
798 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
802 ZERO_STRUCTP(nt_devmode);
804 snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, default_devicename);
805 fstrcpy(nt_devmode->devicename, adevice);
808 fstrcpy(nt_devmode->formname, "Letter");
810 nt_devmode->specversion = 0x0401;
811 nt_devmode->driverversion = 0x0400;
812 nt_devmode->size = 0x00DC;
813 nt_devmode->driverextra = 0x0000;
814 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
815 DEFAULTSOURCE | COPIES | SCALE |
816 PAPERSIZE | ORIENTATION;
817 nt_devmode->orientation = 1;
818 nt_devmode->papersize = PAPER_LETTER;
819 nt_devmode->paperlength = 0;
820 nt_devmode->paperwidth = 0;
821 nt_devmode->scale = 0x64;
822 nt_devmode->copies = 01;
823 nt_devmode->defaultsource = BIN_FORMSOURCE;
824 nt_devmode->printquality = 0x0258;
825 nt_devmode->color = COLOR_MONOCHROME;
826 nt_devmode->duplex = DUP_SIMPLEX;
827 nt_devmode->yresolution = 0;
828 nt_devmode->ttoption = TT_SUBDEV;
829 nt_devmode->collate = COLLATE_FALSE;
830 nt_devmode->icmmethod = 0;
831 nt_devmode->icmintent = 0;
832 nt_devmode->mediatype = 0;
833 nt_devmode->dithertype = 0;
835 /* non utilisés par un driver d'imprimante */
836 nt_devmode->logpixels = 0;
837 nt_devmode->bitsperpel = 0;
838 nt_devmode->pelswidth = 0;
839 nt_devmode->pelsheight = 0;
840 nt_devmode->displayflags = 0;
841 nt_devmode->displayfrequency = 0;
842 nt_devmode->reserved1 = 0;
843 nt_devmode->reserved2 = 0;
844 nt_devmode->panningwidth = 0;
845 nt_devmode->panningheight = 0;
847 nt_devmode->private=NULL;
852 /****************************************************************************
853 Deepcopy an NT devicemode.
854 ****************************************************************************/
856 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
858 NT_DEVICEMODE *new_nt_devicemode = NULL;
860 if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
861 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
865 new_nt_devicemode->private = NULL;
866 if (nt_devicemode->private != NULL) {
867 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
868 safe_free(new_nt_devicemode);
869 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
874 return new_nt_devicemode;
877 /****************************************************************************
878 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
879 ****************************************************************************/
881 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
883 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
885 if(nt_devmode == NULL)
888 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
890 if(nt_devmode->private)
891 safe_free(nt_devmode->private);
893 safe_free(nt_devmode);
897 /****************************************************************************
898 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
899 ****************************************************************************/
900 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
902 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
903 NT_PRINTER_PARAM *param_ptr;
908 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
910 free_nt_devicemode(&info->devmode);
911 free_sec_desc_buf(&info->secdesc_buf);
913 for(param_ptr = info->specific; param_ptr; ) {
914 NT_PRINTER_PARAM *tofree = param_ptr;
916 param_ptr = param_ptr->next;
917 free_nt_printer_param(&tofree);
920 safe_free(*info_ptr);
925 /****************************************************************************
926 ****************************************************************************/
927 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
930 NT_DEVICEMODE devmode;
932 ZERO_STRUCT(devmode);
934 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
936 if (!*nt_devmode) return len;
938 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
942 &devmode.specversion,
943 &devmode.driverversion,
945 &devmode.driverextra,
946 &devmode.orientation,
948 &devmode.paperlength,
952 &devmode.defaultsource,
953 &devmode.printquality,
956 &devmode.yresolution,
965 &devmode.displayflags,
966 &devmode.displayfrequency,
973 &devmode.panningwidth,
974 &devmode.panningheight,
977 if (devmode.private) {
978 devmode.private = (uint8 *)malloc(devmode.driverextra);
979 if (!devmode.private) return 2;
980 len += tdb_unpack(buf+len, buflen-len, "B",
985 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
987 DEBUG(8,("Unpacked devicemode [%s]\n", devmode.formname));
992 /****************************************************************************
993 ****************************************************************************/
994 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
997 NT_PRINTER_PARAM param, *p;
1002 len += tdb_unpack(buf+len, buflen-len, "p", &p);
1005 len += tdb_unpack(buf+len, buflen-len, "fdB",
1011 *list = memdup(¶m, sizeof(param));
1018 /****************************************************************************
1019 get a default printer info 2 struct
1020 ****************************************************************************/
1021 static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1023 extern pstring global_myname;
1025 NT_PRINTER_INFO_LEVEL_2 info;
1029 snum = lp_servicenumber(sharename);
1031 fstrcpy(info.servername, global_myname);
1032 fstrcpy(info.printername, sharename);
1033 fstrcpy(info.portname, sharename);
1034 fstrcpy(info.drivername, lp_printerdriver(snum));
1035 fstrcpy(info.printprocessor, "winprint");
1036 fstrcpy(info.datatype, "RAW");
1038 info.attributes = PRINTER_ATTRIBUTE_SHARED \
1039 | PRINTER_ATTRIBUTE_LOCAL \
1040 | PRINTER_ATTRIBUTE_RAW_ONLY ; /* attributes */
1042 info.starttime = 0; /* Minutes since 12:00am GMT */
1043 info.untiltime = 0; /* Minutes since 12:00am GMT */
1045 info.default_priority = 1;
1047 if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
1050 if (!nt_printing_getsec(sharename, &info.secdesc_buf))
1053 *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
1055 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
1064 free_nt_devicemode(&info.devmode);
1065 if (info.secdesc_buf)
1066 free_sec_desc_buf(&info.secdesc_buf);
1070 /****************************************************************************
1071 ****************************************************************************/
1072 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1075 NT_PRINTER_INFO_LEVEL_2 info;
1077 TDB_DATA kbuf, dbuf;
1081 slprintf(key, sizeof(key), "%s%s",
1082 PRINTERS_PREFIX, sharename);
1085 kbuf.dsize = strlen(key)+1;
1087 dbuf = tdb_fetch(tdb, kbuf);
1089 if (!dbuf.dptr) return get_a_printer_2_default(info_ptr, sharename);
1091 if (!dbuf.dptr) return 1;
1094 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddffffffffff",
1097 &info.default_priority,
1113 info.printprocessor,
1117 info.attributes |= PRINTER_ATTRIBUTE_RAW_ONLY; /* Samba has to have raw drivers. */
1119 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
1120 len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
1123 nt_printing_getsec(sharename, &info.secdesc_buf);
1124 #endif /* JRATEST */
1126 fstrcpy(info.sharename, "");
1128 safe_free(dbuf.dptr);
1129 *info_ptr=memdup(&info, sizeof(info));
1131 DEBUG(9,("Unpacked printprocessor for [%s] of [%s]\n",
1132 sharename, info.printprocessor));
1138 /****************************************************************************
1139 debugging function, dump at level 6 the struct in the logs
1140 ****************************************************************************/
1141 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1144 NT_PRINTER_INFO_LEVEL_2 *info2;
1146 DEBUG(106,("Dumping printer at level [%d]\n", level));
1152 if (printer.info_2 == NULL)
1156 info2=printer.info_2;
1158 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
1159 DEBUGADD(106,("priority:[%d]\n", info2->priority));
1160 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
1161 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
1162 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
1163 DEBUGADD(106,("status:[%d]\n", info2->status));
1164 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
1165 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
1166 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
1167 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
1168 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
1170 DEBUGADD(106,("servername:[%s]\n", info2->servername));
1171 DEBUGADD(106,("printername:[%s]\n", info2->printername));
1172 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
1173 DEBUGADD(106,("portname:[%s]\n", info2->portname));
1174 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
1175 DEBUGADD(106,("location:[%s]\n", info2->location));
1176 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
1177 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
1178 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
1179 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
1185 DEBUGADD(1,("Level not implemented\n"));
1194 * The function below are the high level ones.
1195 * only those ones must be called from the spoolss code.
1200 /****************************************************************************
1201 ****************************************************************************/
1202 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1206 dump_a_printer(printer, level);
1212 success=add_a_printer_2(printer.info_2);
1223 /****************************************************************************
1224 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
1225 ****************************************************************************/
1227 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
1230 NT_PRINTER_INFO_LEVEL *printer = NULL;
1234 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1240 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
1241 DEBUG(0,("get_a_printer: malloc fail.\n"));
1244 ZERO_STRUCTP(printer);
1245 success=get_a_printer_2(&printer->info_2, sharename);
1247 dump_a_printer(*printer, level);
1248 *pp_printer = printer;
1259 DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1264 /****************************************************************************
1265 Deletes a NT_PRINTER_INFO_LEVEL struct.
1266 ****************************************************************************/
1268 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
1271 NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
1273 DEBUG(104,("freeing a printer at level [%d]\n", level));
1275 if (printer == NULL)
1282 if (printer->info_2 != NULL)
1284 free_nt_printer_info_level_2(&printer->info_2);
1303 /****************************************************************************
1304 ****************************************************************************/
1305 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1308 DEBUG(104,("adding a printer at level [%d]\n", level));
1309 dump_a_printer_driver(driver, level);
1315 success=add_a_printer_driver_3(driver.info_3);
1321 success=add_a_printer_driver_6(driver.info_6);
1331 /****************************************************************************
1332 ****************************************************************************/
1333 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
1334 fstring printername, fstring architecture)
1342 success=get_a_printer_driver_3(&(driver->info_3),
1352 if (success == 0) dump_a_printer_driver(*driver, level);
1356 /****************************************************************************
1357 ****************************************************************************/
1358 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1366 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1367 if (driver.info_3 != NULL)
1369 info3=driver.info_3;
1370 safe_free(info3->dependentfiles);
1371 ZERO_STRUCTP(info3);
1383 NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
1384 if (driver.info_6 != NULL)
1386 info6=driver.info_6;
1387 safe_free(info6->dependentfiles);
1388 safe_free(info6->previousnames);
1389 ZERO_STRUCTP(info6);
1406 /****************************************************************************
1407 ****************************************************************************/
1408 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
1409 fstring value, uint8 **data, uint32 *type, uint32 *len)
1411 /* right now that's enough ! */
1412 NT_PRINTER_PARAM *param;
1415 param=printer.info_2->specific;
1417 while (param != NULL && i <= param_index)
1426 /* exited because it exist */
1428 StrnCpy(value, param->value, sizeof(fstring)-1);
1429 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1432 memcpy(*data, param->data, param->data_len);
1433 *len=param->data_len;
1437 /****************************************************************************
1438 ****************************************************************************/
1439 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
1440 fstring value, uint8 **data, uint32 *type, uint32 *len)
1442 /* right now that's enough ! */
1443 NT_PRINTER_PARAM *param;
1445 DEBUG(105, ("get_specific_param\n"));
1447 param=printer.info_2->specific;
1449 while (param != NULL)
1451 if ( !strcmp(value, param->value)
1452 && strlen(value)==strlen(param->value))
1458 DEBUG(106, ("found one param\n"));
1461 /* exited because it exist */
1464 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1467 memcpy(*data, param->data, param->data_len);
1468 *len=param->data_len;
1470 DEBUG(106, ("exit of get_specific_param:true\n"));
1473 DEBUG(106, ("exit of get_specific_param:false\n"));
1478 /****************************************************************************
1479 store a security desc for a printer
1480 ****************************************************************************/
1481 uint32 nt_printing_setsec(char *printername, struct current_user *user,
1482 SEC_DESC_BUF *secdesc_ctr)
1484 SEC_DESC_BUF *new_secdesc_ctr = NULL;
1485 SEC_DESC_BUF *old_secdesc_ctr = NULL;
1488 uint32 acc_granted, status;
1490 /* Get old security descriptor */
1492 if (!nt_printing_getsec(printername, &old_secdesc_ctr)) {
1493 DEBUG(3, ("could not get old security descriptor for "
1494 "printer %s", printername));
1495 return ERROR_INVALID_FUNCTION;
1498 /* Check the user has permissions to change the security
1499 descriptor. By experimentation with two NT machines, the user
1500 requires Full Access to the printer to change security
1503 if (!se_access_check(old_secdesc_ctr->sec, user->uid, user->gid,
1504 user->ngroups, user->groups,
1505 PRINTER_ACE_FULL_CONTROL, &acc_granted,
1507 DEBUG(3, ("security descriptor change denied by existing "
1508 "security descriptor\n"));
1509 free_sec_desc_buf(&old_secdesc_ctr);
1513 /* The old owner and group sids of the security descriptor are not
1514 present when new ACEs are added or removed by changing printer
1515 permissions through NT. If they are NULL in the new security
1516 descriptor then copy them over from the old one. */
1518 if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
1519 DOM_SID *owner_sid, *group_sid;
1520 SEC_DESC *psd = NULL;
1523 /* Pick out correct owner and group sids */
1525 owner_sid = secdesc_ctr->sec->owner_sid ?
1526 secdesc_ctr->sec->owner_sid :
1527 old_secdesc_ctr->sec->owner_sid;
1529 group_sid = secdesc_ctr->sec->grp_sid ?
1530 secdesc_ctr->sec->grp_sid :
1531 old_secdesc_ctr->sec->grp_sid;
1533 /* Make a deep copy of the security descriptor */
1535 psd = make_sec_desc(secdesc_ctr->sec->revision,
1536 secdesc_ctr->sec->type,
1537 owner_sid, group_sid,
1538 secdesc_ctr->sec->sacl,
1539 secdesc_ctr->sec->dacl,
1542 new_secdesc_ctr = make_sec_desc_buf(size, psd);
1544 /* Free up memory */
1546 free_sec_desc(&psd);
1549 if (!new_secdesc_ctr) {
1550 new_secdesc_ctr = secdesc_ctr;
1553 /* Store the security descriptor in a tdb */
1555 prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
1556 sizeof(SEC_DESC_BUF), 4, MARSHALL);
1558 if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
1560 status = ERROR_INVALID_FUNCTION;
1564 slprintf(key, sizeof(key), "SECDESC/%s", printername);
1566 if (tdb_prs_store(tdb, key, &ps)==0) {
1569 DEBUG(1,("Failed to store secdesc for %s\n", printername));
1570 status = ERROR_INVALID_FUNCTION;
1573 /* Free mallocated memory */
1576 free_sec_desc_buf(&old_secdesc_ctr);
1578 if (new_secdesc_ctr != secdesc_ctr) {
1579 free_sec_desc_buf(&new_secdesc_ctr);
1586 /* Call winbindd to convert a name to a sid */
1588 BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type)
1590 struct winbindd_request request;
1591 struct winbindd_response response;
1592 enum nss_status result;
1594 if (!sid || !name_type) return False;
1596 /* Send off request */
1598 ZERO_STRUCT(request);
1599 ZERO_STRUCT(response);
1601 fstrcpy(request.data.name, name);
1602 if ((result = winbindd_request(WINBINDD_LOOKUPNAME, &request,
1603 &response)) == NSS_STATUS_SUCCESS) {
1604 string_to_sid(sid, response.data.sid.sid);
1605 *name_type = response.data.sid.type;
1608 return result == NSS_STATUS_SUCCESS;
1611 /****************************************************************************
1612 Construct a default security descriptor buffer for a printer.
1613 ****************************************************************************/
1615 static SEC_DESC_BUF *construct_default_printer_sdb(void)
1617 extern DOM_SID global_sid_World;
1620 SEC_ACL *psa = NULL;
1621 SEC_DESC_BUF *sdb = NULL;
1622 SEC_DESC *psd = NULL;
1627 /* Create an ACE where Everyone is allowed to print */
1629 init_sec_access(&sa, PRINTER_ACE_PRINT);
1630 init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
1631 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
1633 /* Make the security descriptor owned by the Administrators group
1634 on the PDC of the domain. */
1636 if (!winbind_lookup_name("Administrator", &owner_sid, &name_type)) {
1637 return NULL; /* Doh */
1642 /* The ACL revision number in rpc_secdesc.h differs from the one
1643 created by NT when setting ACE entries in printer
1644 descriptors. NT4 complains about the property being edited by a
1647 #define NT4_ACL_REVISION 0x2
1649 if ((psa = make_sec_acl(NT4_ACL_REVISION, 1, &ace)) != NULL) {
1650 psd = make_sec_desc(SEC_DESC_REVISION,
1651 SEC_DESC_SELF_RELATIVE |
1652 SEC_DESC_DACL_PRESENT,
1654 NULL, psa, &sd_size);
1659 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
1663 sdb = make_sec_desc_buf(sd_size, psd);
1665 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
1666 (unsigned int)sd_size));
1668 free_sec_desc(&psd);
1672 /****************************************************************************
1673 Get a security desc for a printer.
1674 ****************************************************************************/
1676 BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr)
1681 slprintf(key, sizeof(key), "SECDESC/%s", printername);
1683 if (tdb_prs_fetch(tdb, key, &ps)!=0 ||
1684 !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
1686 DEBUG(4,("using default secdesc for %s\n", printername));
1688 if (!(*secdesc_ctr = construct_default_printer_sdb()))
1700 1: level not implemented
1701 2: file doesn't exist
1702 3: can't allocate memory
1703 4: can't free memory
1704 5: non existant struct
1708 A printer and a printer driver are 2 different things.
1709 NT manages them separatelly, Samba does the same.
1710 Why ? Simply because it's easier and it makes sense !
1712 Now explanation: You have 3 printers behind your samba server,
1713 2 of them are the same make and model (laser A and B). But laser B
1714 has an 3000 sheet feeder and laser A doesn't such an option.
1715 Your third printer is an old dot-matrix model for the accounting :-).
1717 If the /usr/local/samba/lib directory (default dir), you will have
1718 5 files to describe all of this.
1720 3 files for the printers (1 by printer):
1723 NTprinter_accounting
1724 2 files for the drivers (1 for the laser and 1 for the dot matrix)
1725 NTdriver_printer model X
1726 NTdriver_printer model Y
1728 jfm: I should use this comment for the text file to explain
1729 same thing for the forms BTW.
1730 Je devrais mettre mes commentaires en francais, ca serait mieux :-)
1734 /* Check a user has permissions to perform the given operation */
1736 BOOL print_access_check(struct current_user *user, int snum,
1737 uint32 required_access)
1739 SEC_DESC_BUF *secdesc = NULL;
1740 uint32 access_granted, status;
1745 /* Get printer name */
1747 pname = PRINTERNAME(snum);
1748 if (!pname || !*pname) pname = SERVICE(snum);
1750 /* Get printer security descriptor */
1752 nt_printing_getsec(pname, &secdesc);
1754 /* The ACE for Full Control in a printer security descriptor
1755 doesn't seem to map properly to the access checking model. For
1756 it to work properly it should be the logical OR of all the other
1757 values, i.e PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT.
1758 This would cause the access check to simply fall out when we
1759 check against any subset of these bits. To get things to work,
1760 change every ACE mask of PRINTER_ACE_FULL_CONTROL to
1761 PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT before
1762 performing the access check. I'm sure there is a better way to
1765 if (secdesc && secdesc->sec && secdesc->sec->dacl &&
1766 secdesc->sec->dacl->ace) {
1767 for(i = 0; i < secdesc->sec->dacl->num_aces; i++) {
1768 if (secdesc->sec->dacl->ace[i].info.mask ==
1769 PRINTER_ACE_FULL_CONTROL) {
1770 secdesc->sec->dacl->ace[i].info.mask =
1771 PRINTER_ACE_MANAGE_DOCUMENTS |
1779 result = se_access_check(secdesc->sec, user->uid, user->gid,
1780 user->ngroups, user->groups,
1781 required_access, &access_granted, &status);
1783 DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
1785 /* Free mallocated memory */
1787 free_sec_desc_buf(&secdesc);