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;
27 extern DOM_SID global_sid_World;
29 static TDB_CONTEXT *tdb; /* used for driver files */
31 #define FORMS_PREFIX "FORMS/"
32 #define DRIVERS_PREFIX "DRIVERS/"
33 #define PRINTERS_PREFIX "PRINTERS/"
35 #define DATABASE_VERSION 1
37 /* we need to have a small set of default forms to support our
39 static nt_forms_struct default_forms[] = {
40 {"Letter", 0x2, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367},
41 {"A4", 0x2, 0x3354f, 0x4884e, 0x0, 0x0, 0x3354f, 0x4884e}
45 /****************************************************************************
46 open the NT printing tdb
47 ****************************************************************************/
48 BOOL nt_printing_init(void)
50 static pid_t local_pid;
52 if (tdb && local_pid == sys_getpid()) return True;
53 tdb = tdb_open(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
55 DEBUG(0,("Failed to open nt drivers database\n"));
59 local_pid = sys_getpid();
61 /* handle a Samba upgrade */
63 if (tdb_fetch_int(tdb, "INFO/version") != DATABASE_VERSION) {
64 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
65 tdb_store_int(tdb, "INFO/version", DATABASE_VERSION);
73 /****************************************************************************
74 get a form struct list
75 ****************************************************************************/
76 int get_ntforms(nt_forms_struct **list)
78 TDB_DATA kbuf, newkey, dbuf;
83 for (kbuf = tdb_firstkey(tdb);
85 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
86 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
88 dbuf = tdb_fetch(tdb, kbuf);
89 if (!dbuf.dptr) continue;
91 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
92 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddddddd",
93 &form.flag, &form.width, &form.length, &form.left,
94 &form.top, &form.right, &form.bottom);
96 if (ret != dbuf.dsize) continue;
98 *list = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
103 /* we should never return a null forms list or NT gets unhappy */
105 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
106 n = sizeof(default_forms) / sizeof(default_forms[0]);
113 /****************************************************************************
114 write a form struct list
115 ****************************************************************************/
116 int write_ntforms(nt_forms_struct **list, int number)
123 for (i=0;i<number;i++) {
124 len = tdb_pack(buf, sizeof(buf), "ddddddd",
125 (*list)[i].flag, (*list)[i].width, (*list)[i].length,
126 (*list)[i].left, (*list)[i].top, (*list)[i].right,
128 if (len > sizeof(buf)) break;
129 slprintf(key, sizeof(key), "%s%s", FORMS_PREFIX, (*list)[i].name);
130 kbuf.dsize = strlen(key)+1;
134 if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) break;
140 /****************************************************************************
141 add a form struct at the end of the list
142 ****************************************************************************/
143 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
150 * NT tries to add forms even when
151 * they are already in the base
152 * only update the values if already present
157 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
158 for (n=0; n<*count && update==False; n++)
160 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
162 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
169 if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
171 unistr2_to_ascii((*list)[n].name, &(form->name), sizeof((*list)[n].name)-1);
175 (*list)[n].flag=form->flags;
176 (*list)[n].width=form->size_x;
177 (*list)[n].length=form->size_y;
178 (*list)[n].left=form->left;
179 (*list)[n].top=form->top;
180 (*list)[n].right=form->right;
181 (*list)[n].bottom=form->bottom;
186 /****************************************************************************
188 ****************************************************************************/
189 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
193 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
195 DEBUG(106, ("[%s]\n", form_name));
196 for (n=0; n<count; n++)
198 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
199 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
203 if (n==count) return;
205 (*list)[n].flag=form->flags;
206 (*list)[n].width=form->size_x;
207 (*list)[n].length=form->size_y;
208 (*list)[n].left=form->left;
209 (*list)[n].top=form->top;
210 (*list)[n].right=form->right;
211 (*list)[n].bottom=form->bottom;
214 /****************************************************************************
215 get the nt drivers list
217 traverse the database and look-up the matching names
218 ****************************************************************************/
219 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
224 TDB_DATA kbuf, newkey;
226 get_short_archi(short_archi, architecture);
227 slprintf(key, sizeof(key), "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
229 for (kbuf = tdb_firstkey(tdb);
231 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
232 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
234 if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
237 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
244 /****************************************************************************
245 function to do the mapping between the long architecture name and
247 ****************************************************************************/
248 BOOL get_short_archi(char *short_archi, char *long_archi)
255 struct table archi_table[]=
257 {"Windows 4.0", "WIN40" },
258 {"Windows NT x86", "W32X86" },
259 {"Windows NT R4000", "W32MIPS" },
260 {"Windows NT Alpha_AXP", "W32ALPHA" },
261 {"Windows NT PowerPC", "W32PPC" },
267 DEBUG(107,("Getting architecture dependant directory\n"));
270 } while ( (archi_table[i].long_archi!=NULL ) &&
271 StrCaseCmp(long_archi, archi_table[i].long_archi) );
273 if (archi_table[i].long_archi==NULL) {
274 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
278 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
280 DEBUGADD(108,("index: [%d]\n", i));
281 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
282 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
287 /****************************************************************************
288 ****************************************************************************/
289 static void clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
291 fstring architecture;
296 /* jfm:7/16/2000 the client always sends the cversion=0.
297 * The server should check which version the driver is by reading the PE header
298 * of driver->driverpath.
300 * For Windows 95/98 the version is 0 (so the value sent is correct)
301 * For Windows NT (the architecture doesn't matter)
303 * NT 3.5/3.51: cversion=1
308 get_short_archi(architecture, driver->environment);
310 /* if it's Windows 95/98, we keep the version at 0
311 * jfmxxx: I need to redo that more correctly for NT2K.
314 if (StrCaseCmp(driver->environment, "Windows 4.0")==0)
319 /* clean up the driver name.
320 * we can get .\driver.dll
321 * or worse c:\windows\system\driver.dll !
323 /* using an intermediate string to not have overlaping memcpy()'s */
324 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
325 fstrcpy(new_name, p+1);
326 fstrcpy(driver->driverpath, new_name);
329 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
330 fstrcpy(new_name, p+1);
331 fstrcpy(driver->datafile, new_name);
334 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
335 fstrcpy(new_name, p+1);
336 fstrcpy(driver->configfile, new_name);
339 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
340 fstrcpy(new_name, p+1);
341 fstrcpy(driver->helpfile, new_name);
344 if (driver->dependentfiles) {
345 for (i=0; *driver->dependentfiles[i]; i++) {
346 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
347 fstrcpy(new_name, p+1);
348 fstrcpy(driver->dependentfiles[i], new_name);
354 /****************************************************************************
355 ****************************************************************************/
356 static void clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
361 /****************************************************************************
362 ****************************************************************************/
363 void clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level)
368 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
369 driver=driver_abstract.info_3;
370 clean_up_driver_struct_level_3(driver);
375 NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
376 driver=driver_abstract.info_6;
377 clean_up_driver_struct_level_6(driver);
383 /****************************************************************************
384 ****************************************************************************/
385 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user)
387 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
388 fstring architecture;
389 fstring clean_driver_name;
394 connection_struct *conn;
397 struct smb_passwd *smb_pass;
403 driver=driver_abstract.info_3;
405 get_short_archi(architecture, driver->environment);
407 /* clean up the driver's name */
408 fstrcpy(clean_driver_name, driver->name);
409 all_string_sub(clean_driver_name, "/", "#", 0);
411 /* connect to the print$ share under the same account as the user connected to the rpc pipe */
412 fstrcpy(user_name, uidtoname(user->uid));
413 if((smb_pass = getsmbpwnam(user_name)) == NULL) {
414 DEBUG(0,("move_driver_to_download_area: Unable to get smbpasswd entry for user %s\n",
419 conn = make_connection("print$", uidtoname(user->uid), smb_pass->smb_nt_passwd, 24, "A:", user->vuid, &ecode);
422 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
427 * make the directories version and version\driver_name
428 * under the architecture directory.
430 DEBUG(5,("Creating first directory\n"));
431 slprintf(new_dir, sizeof(new_dir), "%s\\%d", architecture, driver->cversion);
432 mkdir_internal(conn, inbuf, outbuf, new_dir);
434 slprintf(new_dir, sizeof(new_dir), "%s\\%d\\%s", architecture, driver->cversion, clean_driver_name);
435 mkdir_internal(conn, inbuf, outbuf, new_dir);
437 /* move all the files, one by one,
438 * from archi\filexxx.yyy to
439 * archi\version\driver name\filexxx.yyy
442 DEBUG(5,("Moving file now !\n"));
443 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->driverpath);
444 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->driverpath);
445 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False)) != 0) {
446 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
447 old_name, new_name ));
451 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->datafile);
452 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->datafile);
453 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False)) != 0) {
454 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
455 old_name, new_name ));
459 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->configfile);
460 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->configfile);
461 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False)) != 0) {
462 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
463 old_name, new_name ));
467 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->helpfile);
468 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->helpfile);
469 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False)) != 0) {
470 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
471 old_name, new_name ));
475 if (driver->dependentfiles) {
476 for (i=0; *driver->dependentfiles[i]; i++) {
477 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->dependentfiles[i]);
478 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->dependentfiles[i]);
479 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False)) != 0) {
480 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
481 old_name, new_name ));
487 close_cnum(conn, user->vuid);
492 /****************************************************************************
493 ****************************************************************************/
494 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
497 fstring architecture;
499 fstring clean_driver_name;
506 get_short_archi(architecture, driver->environment);
508 /* The names are relative. We store them in the form: \print$\arch\version\printer-name\driver.xxx
509 * \\server is added in the rpc server layer.
510 * It does make sense to NOT store the server's name in the printer TDB.
513 /* clean up the driver's name */
514 fstrcpy(clean_driver_name, driver->name);
515 all_string_sub(clean_driver_name, "/", "#", 0);
517 slprintf(directory, sizeof(directory), "\\print$\\%s\\%d\\%s\\", architecture, driver->cversion, clean_driver_name);
520 fstrcpy(temp_name, driver->driverpath);
521 slprintf(driver->driverpath, sizeof(driver->driverpath), "%s%s", directory, temp_name);
523 fstrcpy(temp_name, driver->datafile);
524 slprintf(driver->datafile, sizeof(driver->datafile), "%s%s", directory, temp_name);
526 fstrcpy(temp_name, driver->configfile);
527 slprintf(driver->configfile, sizeof(driver->configfile), "%s%s", directory, temp_name);
529 fstrcpy(temp_name, driver->helpfile);
530 slprintf(driver->helpfile, sizeof(driver->helpfile), "%s%s", directory, temp_name);
532 if (driver->dependentfiles) {
533 for (i=0; *driver->dependentfiles[i]; i++) {
534 fstrcpy(temp_name, driver->dependentfiles[i]);
535 slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i]), "%s%s", directory, temp_name);
539 slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
546 len += tdb_pack(buf+len, buflen-len, "dffffffff",
555 driver->defaultdatatype);
557 if (driver->dependentfiles) {
558 for (i=0; *driver->dependentfiles[i]; i++) {
559 len += tdb_pack(buf+len, buflen-len, "f",
560 driver->dependentfiles[i]);
565 buf = (char *)Realloc(buf, len);
572 kbuf.dsize = strlen(key)+1;
576 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
582 /****************************************************************************
583 ****************************************************************************/
584 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
586 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
589 info3.cversion = driver->version;
590 fstrcpy(info3.environment,driver->environment);
591 fstrcpy(info3.driverpath,driver->driverpath);
592 fstrcpy(info3.datafile,driver->datafile);
593 fstrcpy(info3.configfile,driver->configfile);
594 fstrcpy(info3.helpfile,driver->helpfile);
595 fstrcpy(info3.monitorname,driver->monitorname);
596 fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
597 info3.dependentfiles = driver->dependentfiles;
599 return add_a_printer_driver_3(&info3);
603 /****************************************************************************
604 ****************************************************************************/
605 static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
607 NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
611 fstrcpy(info.name, in_prt);
612 fstrcpy(info.defaultdatatype, "RAW");
614 fstrcpy(info.driverpath, "");
615 fstrcpy(info.datafile, "");
616 fstrcpy(info.configfile, "");
617 fstrcpy(info.helpfile, "");
619 if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
620 return ERROR_NOT_ENOUGH_MEMORY;
622 memset(info.dependentfiles, '\0', 2*sizeof(fstring));
623 fstrcpy(info.dependentfiles[0], "");
625 *info_ptr = memdup(&info, sizeof(info));
630 /****************************************************************************
631 ****************************************************************************/
632 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
634 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
636 fstring architecture;
643 get_short_archi(architecture, in_arch);
645 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
647 slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
650 kbuf.dsize = strlen(key)+1;
652 dbuf = tdb_fetch(tdb, kbuf);
654 if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
656 if (!dbuf.dptr) return 5;
658 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
667 driver.defaultdatatype);
670 while (len < dbuf.dsize) {
671 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
672 sizeof(fstring)*(i+2));
673 if (driver.dependentfiles == NULL)
676 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
677 &driver.dependentfiles[i]);
680 if (driver.dependentfiles != NULL)
681 fstrcpy(driver.dependentfiles[i], "");
683 safe_free(dbuf.dptr);
685 if (len != dbuf.dsize) {
686 if (driver.dependentfiles != NULL)
687 safe_free(driver.dependentfiles);
689 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
692 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
697 /****************************************************************************
698 ****************************************************************************/
699 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
701 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
707 slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
708 DEBUG(10,("driver key: [%s]\n", key));
711 kbuf.dsize = strlen(key)+1;
712 if (!tdb_exists(tdb, kbuf)) return False;
715 get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
717 DEBUGADD(10,("info3->name [%s]\n", info3->name));
718 DEBUGADD(10,("info3->datafile [%s]\n", info3->datafile));
719 DEBUGADD(10,("info3->helpfile [%s]\n", info3->helpfile));
720 DEBUGADD(10,("info3->monitorname [%s]\n", info3->monitorname));
721 DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
722 for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
723 DEBUGADD(10,("info3->dependentfiles [%s]\n", info3->dependentfiles[i]));
725 DEBUGADD(10,("info3->environment [%s]\n", info3->environment));
726 DEBUGADD(10,("info3->driverpath [%s]\n", info3->driverpath));
727 DEBUGADD(10,("info3->configfile [%s]\n", info3->configfile));
729 /*pstrcat(line, info3->name); pstrcat(line, ":");*/
730 pstrcat(line, info3->configfile);
732 pstrcat(line, info3->datafile);
734 pstrcat(line, info3->helpfile);
736 pstrcat(line, info3->monitorname);
738 pstrcat(line, "RAW"); /*info3->defaultdatatype);*/
741 for (i=0; info3->dependentfiles &&
742 *info3->dependentfiles[i]; i++) {
743 if (i) pstrcat(line, ","); /* don't end in a "," */
744 pstrcat(line, info3->dependentfiles[i]);
752 /****************************************************************************
753 debugging function, dump at level 6 the struct in the logs
754 ****************************************************************************/
755 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
758 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
761 DEBUG(106,("Dumping printer driver at level [%d]\n", level));
767 if (driver.info_3 == NULL)
772 DEBUGADD(106,("version:[%d]\n", info3->cversion));
773 DEBUGADD(106,("name:[%s]\n", info3->name));
774 DEBUGADD(106,("environment:[%s]\n", info3->environment));
775 DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
776 DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
777 DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
778 DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
779 DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
780 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
782 for (i=0; info3->dependentfiles &&
783 *info3->dependentfiles[i]; i++) {
784 DEBUGADD(106,("dependentfile:[%s]\n",
785 info3->dependentfiles[i]));
792 DEBUGADD(1,("Level not implemented\n"));
800 /****************************************************************************
801 ****************************************************************************/
802 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
806 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
808 if (!nt_devmode) return len;
810 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
811 nt_devmode->devicename,
812 nt_devmode->formname,
814 nt_devmode->specversion,
815 nt_devmode->driverversion,
817 nt_devmode->driverextra,
818 nt_devmode->orientation,
819 nt_devmode->papersize,
820 nt_devmode->paperlength,
821 nt_devmode->paperwidth,
824 nt_devmode->defaultsource,
825 nt_devmode->printquality,
828 nt_devmode->yresolution,
829 nt_devmode->ttoption,
831 nt_devmode->logpixels,
834 nt_devmode->bitsperpel,
835 nt_devmode->pelswidth,
836 nt_devmode->pelsheight,
837 nt_devmode->displayflags,
838 nt_devmode->displayfrequency,
839 nt_devmode->icmmethod,
840 nt_devmode->icmintent,
841 nt_devmode->mediatype,
842 nt_devmode->dithertype,
843 nt_devmode->reserved1,
844 nt_devmode->reserved2,
845 nt_devmode->panningwidth,
846 nt_devmode->panningheight,
847 nt_devmode->private);
850 if (nt_devmode->private) {
851 len += tdb_pack(buf+len, buflen-len, "B",
852 nt_devmode->driverextra,
853 nt_devmode->private);
856 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
861 /****************************************************************************
862 ****************************************************************************/
863 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
867 while (param != NULL) {
868 len += tdb_pack(buf+len, buflen-len, "pfdB",
877 len += tdb_pack(buf+len, buflen-len, "p", param);
883 /****************************************************************************
884 delete a printer - this just deletes the printer info file, any open
885 handles are not affected
886 ****************************************************************************/
887 uint32 del_a_printer(char *sharename)
892 slprintf(key, sizeof(key), "%s%s",
893 PRINTERS_PREFIX, sharename);
896 kbuf.dsize=strlen(key)+1;
898 tdb_delete(tdb, kbuf);
902 /****************************************************************************
903 ****************************************************************************/
904 static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
908 int buflen, len, ret;
911 time_t time_unix = time(NULL);
914 * in addprinter: no servername and the printer is the name
915 * in setprinter: servername is \\server
916 * and printer is \\server\\printer
918 * Samba manages only local printers.
919 * we currently don't support things like path=\\other_server\printer
922 if (info->servername[0]!='\0') {
923 trim_string(info->printername, info->servername, NULL);
924 trim_string(info->printername, "\\", NULL);
925 info->servername[0]='\0';
929 * JFM: one day I'll forget.
930 * below that's info->portname because that's the SAMBA sharename
931 * and I made NT 'thinks' it's the portname
932 * the info->sharename is the thing you can name when you add a printer
933 * that's the short-name when you create shared printer for 95/98
934 * So I've made a limitation in SAMBA: you can only have 1 printer model
935 * behind a SAMBA share.
938 unix_to_nt_time(&time_nt, time_unix);
939 info->changeid=time_nt.low;
940 info->c_setprinter++;
947 len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffffffff",
950 info->default_priority,
967 info->printprocessor,
971 len += pack_devicemode(info->devmode, buf+len, buflen-len);
972 len += pack_specifics(info->specific, buf+len, buflen-len);
975 buf = (char *)Realloc(buf, len);
981 slprintf(key, sizeof(key), "%s%s",
982 PRINTERS_PREFIX, info->sharename);
985 kbuf.dsize = strlen(key)+1;
989 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
992 DEBUG(8, ("error updating printer to tdb on disk\n"));
996 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
997 info->sharename, info->drivername, info->portname, len));
1003 /****************************************************************************
1004 ****************************************************************************/
1005 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1007 NT_PRINTER_PARAM *current;
1009 DEBUG(108,("add_a_specific_param\n"));
1013 if (info_2->specific == NULL)
1015 info_2->specific=param;
1019 current=info_2->specific;
1020 while (current->next != NULL) {
1021 current=current->next;
1023 current->next=param;
1028 /****************************************************************************
1029 ****************************************************************************/
1030 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1032 NT_PRINTER_PARAM *current;
1033 NT_PRINTER_PARAM *previous;
1035 current=info_2->specific;
1038 if (current==NULL) return (False);
1040 if ( !strcmp(current->value, param->value) &&
1041 (strlen(current->value)==strlen(param->value)) ) {
1042 DEBUG(109,("deleting first value\n"));
1043 info_2->specific=current->next;
1044 safe_free(current->data);
1046 DEBUG(109,("deleted first value\n"));
1050 current=previous->next;
1052 while ( current!=NULL ) {
1053 if (!strcmp(current->value, param->value) &&
1054 strlen(current->value)==strlen(param->value) ) {
1055 DEBUG(109,("deleting current value\n"));
1056 previous->next=current->next;
1057 safe_free(current->data);
1059 DEBUG(109,("deleted current value\n"));
1063 previous=previous->next;
1064 current=current->next;
1069 /****************************************************************************
1070 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
1071 ****************************************************************************/
1072 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
1074 NT_PRINTER_PARAM *param = *param_ptr;
1079 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
1082 safe_free(param->data);
1088 /****************************************************************************
1089 Malloc and return an NT devicemode.
1090 ****************************************************************************/
1092 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
1095 * should I init this ones ???
1096 nt_devmode->devicename
1100 NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
1102 if (nt_devmode == NULL) {
1103 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
1107 ZERO_STRUCTP(nt_devmode);
1109 snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, default_devicename);
1110 fstrcpy(nt_devmode->devicename, adevice);
1113 fstrcpy(nt_devmode->formname, "Letter");
1115 nt_devmode->specversion = 0x0401;
1116 nt_devmode->driverversion = 0x0400;
1117 nt_devmode->size = 0x00DC;
1118 nt_devmode->driverextra = 0x0000;
1119 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
1120 DEFAULTSOURCE | COPIES | SCALE |
1121 PAPERSIZE | ORIENTATION;
1122 nt_devmode->orientation = 1;
1123 nt_devmode->papersize = PAPER_LETTER;
1124 nt_devmode->paperlength = 0;
1125 nt_devmode->paperwidth = 0;
1126 nt_devmode->scale = 0x64;
1127 nt_devmode->copies = 01;
1128 nt_devmode->defaultsource = BIN_FORMSOURCE;
1129 nt_devmode->printquality = 0x0258;
1130 nt_devmode->color = COLOR_MONOCHROME;
1131 nt_devmode->duplex = DUP_SIMPLEX;
1132 nt_devmode->yresolution = 0;
1133 nt_devmode->ttoption = TT_SUBDEV;
1134 nt_devmode->collate = COLLATE_FALSE;
1135 nt_devmode->icmmethod = 0;
1136 nt_devmode->icmintent = 0;
1137 nt_devmode->mediatype = 0;
1138 nt_devmode->dithertype = 0;
1140 /* non utilisés par un driver d'imprimante */
1141 nt_devmode->logpixels = 0;
1142 nt_devmode->bitsperpel = 0;
1143 nt_devmode->pelswidth = 0;
1144 nt_devmode->pelsheight = 0;
1145 nt_devmode->displayflags = 0;
1146 nt_devmode->displayfrequency = 0;
1147 nt_devmode->reserved1 = 0;
1148 nt_devmode->reserved2 = 0;
1149 nt_devmode->panningwidth = 0;
1150 nt_devmode->panningheight = 0;
1152 nt_devmode->private=NULL;
1157 /****************************************************************************
1158 Deepcopy an NT devicemode.
1159 ****************************************************************************/
1161 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
1163 NT_DEVICEMODE *new_nt_devicemode = NULL;
1165 if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
1166 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
1170 new_nt_devicemode->private = NULL;
1171 if (nt_devicemode->private != NULL) {
1172 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
1173 safe_free(new_nt_devicemode);
1174 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
1179 return new_nt_devicemode;
1182 /****************************************************************************
1183 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
1184 ****************************************************************************/
1186 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
1188 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
1190 if(nt_devmode == NULL)
1193 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
1195 if(nt_devmode->private)
1196 safe_free(nt_devmode->private);
1198 safe_free(nt_devmode);
1199 *devmode_ptr = NULL;
1202 /****************************************************************************
1203 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
1204 ****************************************************************************/
1205 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
1207 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
1208 NT_PRINTER_PARAM *param_ptr;
1213 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
1215 free_nt_devicemode(&info->devmode);
1216 free_sec_desc_buf(&info->secdesc_buf);
1218 for(param_ptr = info->specific; param_ptr; ) {
1219 NT_PRINTER_PARAM *tofree = param_ptr;
1221 param_ptr = param_ptr->next;
1222 free_nt_printer_param(&tofree);
1225 safe_free(*info_ptr);
1230 /****************************************************************************
1231 ****************************************************************************/
1232 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
1235 NT_DEVICEMODE devmode;
1237 ZERO_STRUCT(devmode);
1239 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
1241 if (!*nt_devmode) return len;
1243 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1247 &devmode.specversion,
1248 &devmode.driverversion,
1250 &devmode.driverextra,
1251 &devmode.orientation,
1253 &devmode.paperlength,
1254 &devmode.paperwidth,
1257 &devmode.defaultsource,
1258 &devmode.printquality,
1261 &devmode.yresolution,
1267 &devmode.bitsperpel,
1269 &devmode.pelsheight,
1270 &devmode.displayflags,
1271 &devmode.displayfrequency,
1275 &devmode.dithertype,
1278 &devmode.panningwidth,
1279 &devmode.panningheight,
1282 if (devmode.private)
1283 len += tdb_unpack(buf+len, buflen-len, "B", &devmode.driverextra, &devmode.private);
1285 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
1287 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
1288 if (devmode.private)
1289 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
1294 /****************************************************************************
1295 ****************************************************************************/
1296 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
1299 NT_PRINTER_PARAM param, *p;
1304 len += tdb_unpack(buf+len, buflen-len, "p", &p);
1307 len += tdb_unpack(buf+len, buflen-len, "fdB",
1313 *list = memdup(¶m, sizeof(param));
1315 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
1322 /****************************************************************************
1323 get a default printer info 2 struct
1324 ****************************************************************************/
1325 static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1327 extern pstring global_myname;
1329 NT_PRINTER_INFO_LEVEL_2 info;
1333 snum = lp_servicenumber(sharename);
1335 fstrcpy(info.servername, global_myname);
1336 fstrcpy(info.printername, sharename);
1337 fstrcpy(info.portname, sharename);
1338 fstrcpy(info.drivername, lp_printerdriver(snum));
1339 fstrcpy(info.comment, "");
1340 fstrcpy(info.printprocessor, "winprint");
1341 fstrcpy(info.datatype, "RAW");
1343 info.attributes = PRINTER_ATTRIBUTE_SHARED \
1344 | PRINTER_ATTRIBUTE_LOCAL \
1345 | PRINTER_ATTRIBUTE_RAW_ONLY ; /* attributes */
1347 info.starttime = 0; /* Minutes since 12:00am GMT */
1348 info.untiltime = 0; /* Minutes since 12:00am GMT */
1350 info.default_priority = 1;
1352 if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
1356 if (!nt_printing_getsec(sharename, &info.secdesc_buf))
1360 *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
1362 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
1371 free_nt_devicemode(&info.devmode);
1372 if (info.secdesc_buf)
1373 free_sec_desc_buf(&info.secdesc_buf);
1377 /****************************************************************************
1378 ****************************************************************************/
1379 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1382 NT_PRINTER_INFO_LEVEL_2 info;
1384 TDB_DATA kbuf, dbuf;
1388 slprintf(key, sizeof(key), "%s%s", PRINTERS_PREFIX, sharename);
1391 kbuf.dsize = strlen(key)+1;
1393 dbuf = tdb_fetch(tdb, kbuf);
1395 if (!dbuf.dptr) return get_a_printer_2_default(info_ptr, sharename);
1397 if (!dbuf.dptr) return 1;
1400 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffffffff",
1403 &info.default_priority,
1420 info.printprocessor,
1424 /* Samba has to have shared raw drivers. */
1425 info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
1427 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
1428 len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
1431 nt_printing_getsec(sharename, &info.secdesc_buf);
1432 #endif /* JRATEST */
1434 safe_free(dbuf.dptr);
1435 *info_ptr=memdup(&info, sizeof(info));
1437 DEBUG(9,("Unpacked printer [%s] running driver [%s]\n",
1438 sharename, info.drivername));
1444 /****************************************************************************
1445 debugging function, dump at level 6 the struct in the logs
1446 ****************************************************************************/
1447 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1450 NT_PRINTER_INFO_LEVEL_2 *info2;
1452 DEBUG(106,("Dumping printer at level [%d]\n", level));
1458 if (printer.info_2 == NULL)
1462 info2=printer.info_2;
1464 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
1465 DEBUGADD(106,("priority:[%d]\n", info2->priority));
1466 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
1467 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
1468 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
1469 DEBUGADD(106,("status:[%d]\n", info2->status));
1470 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
1471 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
1472 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
1473 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
1474 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
1476 DEBUGADD(106,("servername:[%s]\n", info2->servername));
1477 DEBUGADD(106,("printername:[%s]\n", info2->printername));
1478 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
1479 DEBUGADD(106,("portname:[%s]\n", info2->portname));
1480 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
1481 DEBUGADD(106,("comment:[%s]\n", info2->comment));
1482 DEBUGADD(106,("location:[%s]\n", info2->location));
1483 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
1484 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
1485 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
1486 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
1492 DEBUGADD(1,("Level not implemented\n"));
1501 * The function below are the high level ones.
1502 * only those ones must be called from the spoolss code.
1507 /****************************************************************************
1508 ****************************************************************************/
1509 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1513 dump_a_printer(printer, level);
1519 success=add_a_printer_2(printer.info_2);
1530 /****************************************************************************
1531 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
1532 ****************************************************************************/
1534 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
1537 NT_PRINTER_INFO_LEVEL *printer = NULL;
1541 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1547 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
1548 DEBUG(0,("get_a_printer: malloc fail.\n"));
1551 ZERO_STRUCTP(printer);
1552 success=get_a_printer_2(&printer->info_2, sharename);
1554 dump_a_printer(*printer, level);
1555 *pp_printer = printer;
1566 DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1571 /****************************************************************************
1572 Deletes a NT_PRINTER_INFO_LEVEL struct.
1573 ****************************************************************************/
1575 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
1578 NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
1580 DEBUG(104,("freeing a printer at level [%d]\n", level));
1582 if (printer == NULL)
1589 if (printer->info_2 != NULL)
1591 free_nt_printer_info_level_2(&printer->info_2);
1610 /****************************************************************************
1611 ****************************************************************************/
1612 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1615 DEBUG(104,("adding a printer at level [%d]\n", level));
1616 dump_a_printer_driver(driver, level);
1622 success=add_a_printer_driver_3(driver.info_3);
1628 success=add_a_printer_driver_6(driver.info_6);
1638 /****************************************************************************
1639 ****************************************************************************/
1640 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
1641 fstring printername, fstring architecture, uint32 version)
1649 success=get_a_printer_driver_3(&(driver->info_3),
1651 architecture, version);
1659 if (success == 0) dump_a_printer_driver(*driver, level);
1663 /****************************************************************************
1664 ****************************************************************************/
1665 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1673 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1674 if (driver.info_3 != NULL)
1676 info3=driver.info_3;
1677 safe_free(info3->dependentfiles);
1678 ZERO_STRUCTP(info3);
1690 NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
1691 if (driver.info_6 != NULL)
1693 info6=driver.info_6;
1694 safe_free(info6->dependentfiles);
1695 safe_free(info6->previousnames);
1696 ZERO_STRUCTP(info6);
1713 /****************************************************************************
1714 ****************************************************************************/
1715 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
1716 fstring value, uint8 **data, uint32 *type, uint32 *len)
1718 /* right now that's enough ! */
1719 NT_PRINTER_PARAM *param;
1722 param=printer.info_2->specific;
1724 while (param != NULL && i < param_index) {
1732 /* exited because it exist */
1734 StrnCpy(value, param->value, sizeof(fstring)-1);
1735 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1738 ZERO_STRUCTP(*data);
1739 memcpy(*data, param->data, param->data_len);
1740 *len=param->data_len;
1744 /****************************************************************************
1745 ****************************************************************************/
1746 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
1747 fstring value, uint8 **data, uint32 *type, uint32 *len)
1749 /* right now that's enough ! */
1750 NT_PRINTER_PARAM *param;
1752 DEBUG(105, ("get_specific_param\n"));
1754 param=printer.info_2->specific;
1756 while (param != NULL)
1758 if ( !strcmp(value, param->value)
1759 && strlen(value)==strlen(param->value))
1765 DEBUG(106, ("found one param\n"));
1768 /* exited because it exist */
1771 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1774 memcpy(*data, param->data, param->data_len);
1775 *len=param->data_len;
1777 DEBUG(106, ("exit of get_specific_param:true\n"));
1780 DEBUG(106, ("exit of get_specific_param:false\n"));
1785 /****************************************************************************
1786 store a security desc for a printer
1787 ****************************************************************************/
1788 uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
1790 SEC_DESC_BUF *new_secdesc_ctr = NULL;
1791 SEC_DESC_BUF *old_secdesc_ctr = NULL;
1796 /* The old owner and group sids of the security descriptor are not
1797 present when new ACEs are added or removed by changing printer
1798 permissions through NT. If they are NULL in the new security
1799 descriptor then copy them over from the old one. */
1801 if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
1802 DOM_SID *owner_sid, *group_sid;
1803 SEC_DESC *psd = NULL;
1806 nt_printing_getsec(printername, &old_secdesc_ctr);
1808 /* Pick out correct owner and group sids */
1810 owner_sid = secdesc_ctr->sec->owner_sid ?
1811 secdesc_ctr->sec->owner_sid :
1812 old_secdesc_ctr->sec->owner_sid;
1814 group_sid = secdesc_ctr->sec->grp_sid ?
1815 secdesc_ctr->sec->grp_sid :
1816 old_secdesc_ctr->sec->grp_sid;
1818 /* Make a deep copy of the security descriptor */
1820 psd = make_sec_desc(secdesc_ctr->sec->revision,
1821 secdesc_ctr->sec->type,
1822 owner_sid, group_sid,
1823 secdesc_ctr->sec->sacl,
1824 secdesc_ctr->sec->dacl,
1827 new_secdesc_ctr = make_sec_desc_buf(size, psd);
1829 /* Free up memory */
1831 free_sec_desc(&psd);
1832 free_sec_desc_buf(&old_secdesc_ctr);
1835 if (!new_secdesc_ctr) {
1836 new_secdesc_ctr = secdesc_ctr;
1839 /* Store the security descriptor in a tdb */
1841 prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
1842 sizeof(SEC_DESC_BUF), 4, MARSHALL);
1844 if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
1846 status = ERROR_INVALID_FUNCTION;
1850 slprintf(key, sizeof(key), "SECDESC/%s", printername);
1852 if (tdb_prs_store(tdb, key, &ps)==0) {
1855 DEBUG(1,("Failed to store secdesc for %s\n", printername));
1856 status = ERROR_INVALID_FUNCTION;
1859 /* Free mallocated memory */
1862 free_sec_desc_buf(&old_secdesc_ctr);
1864 if (new_secdesc_ctr != secdesc_ctr) {
1865 free_sec_desc_buf(&new_secdesc_ctr);
1872 /****************************************************************************
1873 Construct a default security descriptor buffer for a printer.
1874 ****************************************************************************/
1876 static SEC_DESC_BUF *construct_default_printer_sdb(void)
1880 SEC_ACL *psa = NULL;
1881 SEC_DESC_BUF *sdb = NULL;
1882 SEC_DESC *psd = NULL;
1887 /* Create an ACE where Everyone is allowed to print */
1889 init_sec_access(&sa, PRINTER_ACE_PRINT);
1890 init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
1891 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
1894 /* Make the security descriptor owned by the Administrators group
1895 on the PDC of the domain. */
1897 if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
1898 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
1901 /* Backup plan - make printer owned by world. This should
1902 emulate a lanman printer as security settings can't be
1905 sid_copy(&owner_sid, &global_sid_World);
1908 /* The ACL revision number in rpc_secdesc.h differs from the one
1909 created by NT when setting ACE entries in printer
1910 descriptors. NT4 complains about the property being edited by a
1913 #define NT4_ACL_REVISION 0x2
1915 if ((psa = make_sec_acl(NT4_ACL_REVISION, 1, &ace)) != NULL) {
1916 psd = make_sec_desc(SEC_DESC_REVISION,
1917 SEC_DESC_SELF_RELATIVE |
1918 SEC_DESC_DACL_PRESENT,
1920 NULL, psa, &sd_size);
1925 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
1929 sdb = make_sec_desc_buf(sd_size, psd);
1931 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
1932 (unsigned int)sd_size));
1934 free_sec_desc(&psd);
1938 /****************************************************************************
1939 Get a security desc for a printer.
1940 ****************************************************************************/
1942 BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr)
1947 /* Fetch security descriptor from tdb */
1949 slprintf(key, sizeof(key), "SECDESC/%s", printername);
1951 if (tdb_prs_fetch(tdb, key, &ps)!=0 ||
1952 !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
1954 DEBUG(4,("using default secdesc for %s\n", printername));
1956 if (!(*secdesc_ctr = construct_default_printer_sdb()))
1962 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
1963 this security descriptor has been created when winbindd was
1964 down. Take ownership of security descriptor. */
1966 if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
1970 /* Change sd owner to workgroup administrator */
1972 if (winbind_lookup_name(lp_workgroup(), &owner_sid,
1974 SEC_DESC_BUF *new_secdesc_ctr = NULL;
1975 SEC_DESC *psd = NULL;
1980 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
1982 psd = make_sec_desc((*secdesc_ctr)->sec->revision,
1983 (*secdesc_ctr)->sec->type,
1985 (*secdesc_ctr)->sec->grp_sid,
1986 (*secdesc_ctr)->sec->sacl,
1987 (*secdesc_ctr)->sec->dacl,
1990 new_secdesc_ctr = make_sec_desc_buf(size, psd);
1992 free_sec_desc(&psd);
1994 /* Swap with other one */
1996 free_sec_desc_buf(secdesc_ctr);
1997 *secdesc_ctr = new_secdesc_ctr;
2001 nt_printing_setsec(printername, *secdesc_ctr);
2011 1: level not implemented
2012 2: file doesn't exist
2013 3: can't allocate memory
2014 4: can't free memory
2015 5: non existant struct
2019 A printer and a printer driver are 2 different things.
2020 NT manages them separatelly, Samba does the same.
2021 Why ? Simply because it's easier and it makes sense !
2023 Now explanation: You have 3 printers behind your samba server,
2024 2 of them are the same make and model (laser A and B). But laser B
2025 has an 3000 sheet feeder and laser A doesn't such an option.
2026 Your third printer is an old dot-matrix model for the accounting :-).
2028 If the /usr/local/samba/lib directory (default dir), you will have
2029 5 files to describe all of this.
2031 3 files for the printers (1 by printer):
2034 NTprinter_accounting
2035 2 files for the drivers (1 for the laser and 1 for the dot matrix)
2036 NTdriver_printer model X
2037 NTdriver_printer model Y
2039 jfm: I should use this comment for the text file to explain
2040 same thing for the forms BTW.
2041 Je devrais mettre mes commentaires en francais, ca serait mieux :-)
2045 /* Check a user has permissions to perform the given operation */
2047 BOOL print_access_check(struct current_user *user, int snum,
2048 uint32 required_access)
2050 SEC_DESC_BUF *secdesc = NULL;
2051 uint32 access_granted, status;
2056 /* Get printer name */
2058 pname = PRINTERNAME(snum);
2059 if (!pname || !*pname) pname = SERVICE(snum);
2061 /* Get printer security descriptor */
2063 nt_printing_getsec(pname, &secdesc);
2065 /* The ACE for Full Control in a printer security descriptor
2066 doesn't seem to map properly to the access checking model. For
2067 it to work properly it should be the logical OR of all the other
2068 values, i.e PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT.
2069 This would cause the access check to simply fall out when we
2070 check against any subset of these bits. To get things to work,
2071 change every ACE mask of PRINTER_ACE_FULL_CONTROL to
2072 PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT before
2073 performing the access check. I'm sure there is a better way to
2076 if (secdesc && secdesc->sec && secdesc->sec->dacl &&
2077 secdesc->sec->dacl->ace) {
2078 for(i = 0; i < secdesc->sec->dacl->num_aces; i++) {
2079 if (secdesc->sec->dacl->ace[i].info.mask ==
2080 PRINTER_ACE_FULL_CONTROL) {
2081 secdesc->sec->dacl->ace[i].info.mask =
2082 PRINTER_ACE_MANAGE_DOCUMENTS |
2090 result = se_access_check(secdesc->sec, user, required_access,
2091 &access_granted, &status);
2093 DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
2095 /* Free mallocated memory */
2097 free_sec_desc_buf(&secdesc);