3 * Unix SMB/Netbios implementation.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-2000,
7 * Copyright (C) Jean François Micouleau 1998-2000.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern int DEBUGLEVEL;
27 extern pstring global_myname;
28 extern DOM_SID global_sid_World;
30 static TDB_CONTEXT *tdb; /* used for driver files */
32 #define FORMS_PREFIX "FORMS/"
33 #define DRIVERS_PREFIX "DRIVERS/"
34 #define PRINTERS_PREFIX "PRINTERS/"
36 #define DATABASE_VERSION 1
38 /* we need to have a small set of default forms to support our
40 static nt_forms_struct default_forms[] = {
41 {"Letter", 0x2, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367},
42 {"A4", 0x2, 0x3354f, 0x4884e, 0x0, 0x0, 0x3354f, 0x4884e}
46 /****************************************************************************
47 open the NT printing tdb
48 ****************************************************************************/
49 BOOL nt_printing_init(void)
51 static pid_t local_pid;
53 if (tdb && local_pid == sys_getpid()) return True;
54 tdb = tdb_open(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
56 DEBUG(0,("Failed to open nt drivers database\n"));
60 local_pid = sys_getpid();
62 /* handle a Samba upgrade */
64 if (tdb_fetch_int(tdb, "INFO/version") != DATABASE_VERSION) {
65 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
66 tdb_store_int(tdb, "INFO/version", DATABASE_VERSION);
74 /****************************************************************************
75 get a form struct list
76 ****************************************************************************/
77 int get_ntforms(nt_forms_struct **list)
79 TDB_DATA kbuf, newkey, dbuf;
84 for (kbuf = tdb_firstkey(tdb);
86 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
87 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
89 dbuf = tdb_fetch(tdb, kbuf);
90 if (!dbuf.dptr) continue;
92 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
93 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddddddd",
94 &form.flag, &form.width, &form.length, &form.left,
95 &form.top, &form.right, &form.bottom);
97 if (ret != dbuf.dsize) continue;
99 *list = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
104 /* we should never return a null forms list or NT gets unhappy */
106 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
107 n = sizeof(default_forms) / sizeof(default_forms[0]);
114 /****************************************************************************
115 write a form struct list
116 ****************************************************************************/
117 int write_ntforms(nt_forms_struct **list, int number)
124 for (i=0;i<number;i++) {
125 len = tdb_pack(buf, sizeof(buf), "ddddddd",
126 (*list)[i].flag, (*list)[i].width, (*list)[i].length,
127 (*list)[i].left, (*list)[i].top, (*list)[i].right,
129 if (len > sizeof(buf)) break;
130 slprintf(key, sizeof(key), "%s%s", FORMS_PREFIX, (*list)[i].name);
131 kbuf.dsize = strlen(key)+1;
135 if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) break;
141 /****************************************************************************
142 add a form struct at the end of the list
143 ****************************************************************************/
144 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
151 * NT tries to add forms even when
152 * they are already in the base
153 * only update the values if already present
158 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
159 for (n=0; n<*count && update==False; n++)
161 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
163 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
170 if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
172 unistr2_to_ascii((*list)[n].name, &(form->name), sizeof((*list)[n].name)-1);
176 (*list)[n].flag=form->flags;
177 (*list)[n].width=form->size_x;
178 (*list)[n].length=form->size_y;
179 (*list)[n].left=form->left;
180 (*list)[n].top=form->top;
181 (*list)[n].right=form->right;
182 (*list)[n].bottom=form->bottom;
187 /****************************************************************************
189 ****************************************************************************/
190 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
194 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
196 DEBUG(106, ("[%s]\n", form_name));
197 for (n=0; n<count; n++)
199 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
200 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
204 if (n==count) return;
206 (*list)[n].flag=form->flags;
207 (*list)[n].width=form->size_x;
208 (*list)[n].length=form->size_y;
209 (*list)[n].left=form->left;
210 (*list)[n].top=form->top;
211 (*list)[n].right=form->right;
212 (*list)[n].bottom=form->bottom;
215 /****************************************************************************
216 get the nt drivers list
218 traverse the database and look-up the matching names
219 ****************************************************************************/
220 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
225 TDB_DATA kbuf, newkey;
227 get_short_archi(short_archi, architecture);
228 slprintf(key, sizeof(key), "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
230 for (kbuf = tdb_firstkey(tdb);
232 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
233 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
235 if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
238 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
245 /****************************************************************************
246 function to do the mapping between the long architecture name and
248 ****************************************************************************/
249 BOOL get_short_archi(char *short_archi, char *long_archi)
256 struct table archi_table[]=
258 {"Windows 4.0", "WIN40" },
259 {"Windows NT x86", "W32X86" },
260 {"Windows NT R4000", "W32MIPS" },
261 {"Windows NT Alpha_AXP", "W32ALPHA" },
262 {"Windows NT PowerPC", "W32PPC" },
268 DEBUG(107,("Getting architecture dependant directory\n"));
271 } while ( (archi_table[i].long_archi!=NULL ) &&
272 StrCaseCmp(long_archi, archi_table[i].long_archi) );
274 if (archi_table[i].long_archi==NULL) {
275 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
279 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
281 DEBUGADD(108,("index: [%d]\n", i));
282 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
283 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
288 /****************************************************************************
289 ****************************************************************************/
290 static void clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
292 fstring architecture;
297 /* jfm:7/16/2000 the client always sends the cversion=0.
298 * The server should check which version the driver is by reading the PE header
299 * of driver->driverpath.
301 * For Windows 95/98 the version is 0 (so the value sent is correct)
302 * For Windows NT (the architecture doesn't matter)
304 * NT 3.5/3.51: cversion=1
309 get_short_archi(architecture, driver->environment);
311 /* if it's Windows 95/98, we keep the version at 0
312 * jfmxxx: I need to redo that more correctly for NT2K.
315 if (StrCaseCmp(driver->environment, "Windows 4.0")==0)
320 /* clean up the driver name.
321 * we can get .\driver.dll
322 * or worse c:\windows\system\driver.dll !
324 /* using an intermediate string to not have overlaping memcpy()'s */
325 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
326 fstrcpy(new_name, p+1);
327 fstrcpy(driver->driverpath, new_name);
330 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
331 fstrcpy(new_name, p+1);
332 fstrcpy(driver->datafile, new_name);
335 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
336 fstrcpy(new_name, p+1);
337 fstrcpy(driver->configfile, new_name);
340 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
341 fstrcpy(new_name, p+1);
342 fstrcpy(driver->helpfile, new_name);
345 if (driver->dependentfiles) {
346 for (i=0; *driver->dependentfiles[i]; i++) {
347 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
348 fstrcpy(new_name, p+1);
349 fstrcpy(driver->dependentfiles[i], new_name);
355 /****************************************************************************
356 ****************************************************************************/
357 static void clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
362 /****************************************************************************
363 ****************************************************************************/
364 void clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level)
369 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
370 driver=driver_abstract.info_3;
371 clean_up_driver_struct_level_3(driver);
376 NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
377 driver=driver_abstract.info_6;
378 clean_up_driver_struct_level_6(driver);
384 /****************************************************************************
385 ****************************************************************************/
386 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user)
388 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
389 fstring architecture;
390 fstring clean_driver_name;
396 connection_struct *conn;
399 struct smb_passwd *smb_pass;
405 driver=driver_abstract.info_3;
407 get_short_archi(architecture, driver->environment);
409 /* clean up the driver's name */
410 fstrcpy(clean_driver_name, driver->name);
411 all_string_sub(clean_driver_name, "/", "#", 0);
413 /* connect to the print$ share under the same account as the user connected to the rpc pipe */
414 fstrcpy(user_name, uidtoname(user->uid));
415 DEBUG(10,("move_driver_to_download_area: uid %d -> user %s\n", (int)user->uid, user_name));
418 smb_pass = getsmbpwnam(user_name);
419 if(smb_pass == NULL) {
420 DEBUG(0,("move_driver_to_download_area: Unable to get smbpasswd entry for user %s\n",
426 /* Null password is ok - we are already an authenticated user... */
428 conn = make_connection("print$", user_name, null_pw, 0, "A:", user->vuid, &ecode);
431 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
436 if (!become_user(conn, conn->vuid)) {
437 DEBUG(0,("move_driver_to_download_area: Can't become user %s\n", user_name ));
443 * make the directories version and version\driver_name
444 * under the architecture directory.
446 DEBUG(5,("Creating first directory\n"));
447 slprintf(new_dir, sizeof(new_dir), "%s\\%d", architecture, driver->cversion);
448 mkdir_internal(conn, inbuf, outbuf, new_dir);
450 slprintf(new_dir, sizeof(new_dir), "%s\\%d\\%s", architecture, driver->cversion, clean_driver_name);
451 mkdir_internal(conn, inbuf, outbuf, new_dir);
453 /* move all the files, one by one,
454 * from archi\filexxx.yyy to
455 * archi\version\driver name\filexxx.yyy
458 DEBUG(5,("Moving file now !\n"));
459 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->driverpath);
460 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->driverpath);
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 ));
464 close_cnum(conn, user->vuid);
469 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->datafile);
470 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->datafile);
471 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False)) != 0) {
472 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
473 old_name, new_name ));
474 close_cnum(conn, user->vuid);
479 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->configfile);
480 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->configfile);
481 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False)) != 0) {
482 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
483 old_name, new_name ));
484 close_cnum(conn, user->vuid);
489 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->helpfile);
490 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->helpfile);
491 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False)) != 0) {
492 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
493 old_name, new_name ));
494 close_cnum(conn, user->vuid);
499 if (driver->dependentfiles) {
500 for (i=0; *driver->dependentfiles[i]; i++) {
501 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->dependentfiles[i]);
502 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->dependentfiles[i]);
504 * We don't check the error returns here as several of these
505 * files may have already been moved in the list above...
507 rename_internals(conn, inbuf, outbuf, old_name, new_name, False);
511 close_cnum(conn, user->vuid);
517 /****************************************************************************
518 ****************************************************************************/
519 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
522 fstring architecture;
524 fstring clean_driver_name;
531 get_short_archi(architecture, driver->environment);
533 /* The names are relative. We store them in the form: \print$\arch\version\printer-name\driver.xxx
534 * \\server is added in the rpc server layer.
535 * It does make sense to NOT store the server's name in the printer TDB.
538 /* clean up the driver's name */
539 fstrcpy(clean_driver_name, driver->name);
540 all_string_sub(clean_driver_name, "/", "#", 0);
542 slprintf(directory, sizeof(directory), "\\print$\\%s\\%d\\%s\\", architecture, driver->cversion, clean_driver_name);
545 fstrcpy(temp_name, driver->driverpath);
546 slprintf(driver->driverpath, sizeof(driver->driverpath), "%s%s", directory, temp_name);
548 fstrcpy(temp_name, driver->datafile);
549 slprintf(driver->datafile, sizeof(driver->datafile), "%s%s", directory, temp_name);
551 fstrcpy(temp_name, driver->configfile);
552 slprintf(driver->configfile, sizeof(driver->configfile), "%s%s", directory, temp_name);
554 fstrcpy(temp_name, driver->helpfile);
555 slprintf(driver->helpfile, sizeof(driver->helpfile), "%s%s", directory, temp_name);
557 if (driver->dependentfiles) {
558 for (i=0; *driver->dependentfiles[i]; i++) {
559 fstrcpy(temp_name, driver->dependentfiles[i]);
560 slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i]), "%s%s", directory, temp_name);
564 slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
571 len += tdb_pack(buf+len, buflen-len, "dffffffff",
580 driver->defaultdatatype);
582 if (driver->dependentfiles) {
583 for (i=0; *driver->dependentfiles[i]; i++) {
584 len += tdb_pack(buf+len, buflen-len, "f",
585 driver->dependentfiles[i]);
590 buf = (char *)Realloc(buf, len);
597 kbuf.dsize = strlen(key)+1;
601 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
607 /****************************************************************************
608 ****************************************************************************/
609 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
611 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
614 info3.cversion = driver->version;
615 fstrcpy(info3.environment,driver->environment);
616 fstrcpy(info3.driverpath,driver->driverpath);
617 fstrcpy(info3.datafile,driver->datafile);
618 fstrcpy(info3.configfile,driver->configfile);
619 fstrcpy(info3.helpfile,driver->helpfile);
620 fstrcpy(info3.monitorname,driver->monitorname);
621 fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
622 info3.dependentfiles = driver->dependentfiles;
624 return add_a_printer_driver_3(&info3);
628 /****************************************************************************
629 ****************************************************************************/
630 static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
632 NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
636 fstrcpy(info.name, in_prt);
637 fstrcpy(info.defaultdatatype, "RAW");
639 fstrcpy(info.driverpath, "");
640 fstrcpy(info.datafile, "");
641 fstrcpy(info.configfile, "");
642 fstrcpy(info.helpfile, "");
644 if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
645 return ERROR_NOT_ENOUGH_MEMORY;
647 memset(info.dependentfiles, '\0', 2*sizeof(fstring));
648 fstrcpy(info.dependentfiles[0], "");
650 *info_ptr = memdup(&info, sizeof(info));
655 /****************************************************************************
656 ****************************************************************************/
657 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
659 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
661 fstring architecture;
668 get_short_archi(architecture, in_arch);
670 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
672 slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
675 kbuf.dsize = strlen(key)+1;
677 dbuf = tdb_fetch(tdb, kbuf);
679 if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
681 if (!dbuf.dptr) return 5;
683 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
692 driver.defaultdatatype);
695 while (len < dbuf.dsize) {
696 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
697 sizeof(fstring)*(i+2));
698 if (driver.dependentfiles == NULL)
701 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
702 &driver.dependentfiles[i]);
705 if (driver.dependentfiles != NULL)
706 fstrcpy(driver.dependentfiles[i], "");
708 safe_free(dbuf.dptr);
710 if (len != dbuf.dsize) {
711 if (driver.dependentfiles != NULL)
712 safe_free(driver.dependentfiles);
714 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
717 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
722 /****************************************************************************
723 ****************************************************************************/
724 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
726 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
732 slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
733 DEBUG(10,("driver key: [%s]\n", key));
736 kbuf.dsize = strlen(key)+1;
737 if (!tdb_exists(tdb, kbuf)) return False;
740 get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
742 DEBUGADD(10,("info3->name [%s]\n", info3->name));
743 DEBUGADD(10,("info3->datafile [%s]\n", info3->datafile));
744 DEBUGADD(10,("info3->helpfile [%s]\n", info3->helpfile));
745 DEBUGADD(10,("info3->monitorname [%s]\n", info3->monitorname));
746 DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
747 for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
748 DEBUGADD(10,("info3->dependentfiles [%s]\n", info3->dependentfiles[i]));
750 DEBUGADD(10,("info3->environment [%s]\n", info3->environment));
751 DEBUGADD(10,("info3->driverpath [%s]\n", info3->driverpath));
752 DEBUGADD(10,("info3->configfile [%s]\n", info3->configfile));
754 /*pstrcat(line, info3->name); pstrcat(line, ":");*/
755 pstrcat(line, info3->configfile);
757 pstrcat(line, info3->datafile);
759 pstrcat(line, info3->helpfile);
761 pstrcat(line, info3->monitorname);
763 pstrcat(line, "RAW"); /*info3->defaultdatatype);*/
766 for (i=0; info3->dependentfiles &&
767 *info3->dependentfiles[i]; i++) {
768 if (i) pstrcat(line, ","); /* don't end in a "," */
769 pstrcat(line, info3->dependentfiles[i]);
777 /****************************************************************************
778 debugging function, dump at level 6 the struct in the logs
779 ****************************************************************************/
780 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
783 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
786 DEBUG(106,("Dumping printer driver at level [%d]\n", level));
792 if (driver.info_3 == NULL)
797 DEBUGADD(106,("version:[%d]\n", info3->cversion));
798 DEBUGADD(106,("name:[%s]\n", info3->name));
799 DEBUGADD(106,("environment:[%s]\n", info3->environment));
800 DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
801 DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
802 DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
803 DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
804 DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
805 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
807 for (i=0; info3->dependentfiles &&
808 *info3->dependentfiles[i]; i++) {
809 DEBUGADD(106,("dependentfile:[%s]\n",
810 info3->dependentfiles[i]));
817 DEBUGADD(1,("Level not implemented\n"));
825 /****************************************************************************
826 ****************************************************************************/
827 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
831 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
833 if (!nt_devmode) return len;
835 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
836 nt_devmode->devicename,
837 nt_devmode->formname,
839 nt_devmode->specversion,
840 nt_devmode->driverversion,
842 nt_devmode->driverextra,
843 nt_devmode->orientation,
844 nt_devmode->papersize,
845 nt_devmode->paperlength,
846 nt_devmode->paperwidth,
849 nt_devmode->defaultsource,
850 nt_devmode->printquality,
853 nt_devmode->yresolution,
854 nt_devmode->ttoption,
856 nt_devmode->logpixels,
859 nt_devmode->bitsperpel,
860 nt_devmode->pelswidth,
861 nt_devmode->pelsheight,
862 nt_devmode->displayflags,
863 nt_devmode->displayfrequency,
864 nt_devmode->icmmethod,
865 nt_devmode->icmintent,
866 nt_devmode->mediatype,
867 nt_devmode->dithertype,
868 nt_devmode->reserved1,
869 nt_devmode->reserved2,
870 nt_devmode->panningwidth,
871 nt_devmode->panningheight,
872 nt_devmode->private);
875 if (nt_devmode->private) {
876 len += tdb_pack(buf+len, buflen-len, "B",
877 nt_devmode->driverextra,
878 nt_devmode->private);
881 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
886 /****************************************************************************
887 ****************************************************************************/
888 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
892 while (param != NULL) {
893 len += tdb_pack(buf+len, buflen-len, "pfdB",
902 len += tdb_pack(buf+len, buflen-len, "p", param);
908 /****************************************************************************
909 delete a printer - this just deletes the printer info file, any open
910 handles are not affected
911 ****************************************************************************/
912 uint32 del_a_printer(char *sharename)
917 slprintf(key, sizeof(key), "%s%s",
918 PRINTERS_PREFIX, sharename);
921 kbuf.dsize=strlen(key)+1;
923 tdb_delete(tdb, kbuf);
927 /****************************************************************************
928 ****************************************************************************/
929 static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
933 int buflen, len, ret;
936 time_t time_unix = time(NULL);
939 * in addprinter: no servername and the printer is the name
940 * in setprinter: servername is \\server
941 * and printer is \\server\\printer
943 * Samba manages only local printers.
944 * we currently don't support things like path=\\other_server\printer
947 if (info->servername[0]!='\0') {
948 trim_string(info->printername, info->servername, NULL);
949 trim_string(info->printername, "\\", NULL);
950 info->servername[0]='\0';
954 * JFM: one day I'll forget.
955 * below that's info->portname because that's the SAMBA sharename
956 * and I made NT 'thinks' it's the portname
957 * the info->sharename is the thing you can name when you add a printer
958 * that's the short-name when you create shared printer for 95/98
959 * So I've made a limitation in SAMBA: you can only have 1 printer model
960 * behind a SAMBA share.
963 unix_to_nt_time(&time_nt, time_unix);
964 info->changeid=time_nt.low;
965 info->c_setprinter++;
972 len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffffffff",
975 info->default_priority,
992 info->printprocessor,
996 len += pack_devicemode(info->devmode, buf+len, buflen-len);
997 len += pack_specifics(info->specific, buf+len, buflen-len);
1000 buf = (char *)Realloc(buf, len);
1006 slprintf(key, sizeof(key), "%s%s",
1007 PRINTERS_PREFIX, info->sharename);
1010 kbuf.dsize = strlen(key)+1;
1014 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
1017 DEBUG(8, ("error updating printer to tdb on disk\n"));
1021 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
1022 info->sharename, info->drivername, info->portname, len));
1028 /****************************************************************************
1029 ****************************************************************************/
1030 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1032 NT_PRINTER_PARAM *current;
1034 DEBUG(108,("add_a_specific_param\n"));
1038 if (info_2->specific == NULL)
1040 info_2->specific=param;
1044 current=info_2->specific;
1045 while (current->next != NULL) {
1046 current=current->next;
1048 current->next=param;
1053 /****************************************************************************
1054 ****************************************************************************/
1055 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1057 NT_PRINTER_PARAM *current;
1058 NT_PRINTER_PARAM *previous;
1060 current=info_2->specific;
1063 if (current==NULL) return (False);
1065 if ( !strcmp(current->value, param->value) &&
1066 (strlen(current->value)==strlen(param->value)) ) {
1067 DEBUG(109,("deleting first value\n"));
1068 info_2->specific=current->next;
1069 safe_free(current->data);
1071 DEBUG(109,("deleted first value\n"));
1075 current=previous->next;
1077 while ( current!=NULL ) {
1078 if (!strcmp(current->value, param->value) &&
1079 strlen(current->value)==strlen(param->value) ) {
1080 DEBUG(109,("deleting current value\n"));
1081 previous->next=current->next;
1082 safe_free(current->data);
1084 DEBUG(109,("deleted current value\n"));
1088 previous=previous->next;
1089 current=current->next;
1094 /****************************************************************************
1095 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
1096 ****************************************************************************/
1097 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
1099 NT_PRINTER_PARAM *param = *param_ptr;
1104 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
1107 safe_free(param->data);
1113 /****************************************************************************
1114 Malloc and return an NT devicemode.
1115 ****************************************************************************/
1117 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
1120 * should I init this ones ???
1121 nt_devmode->devicename
1125 NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
1127 if (nt_devmode == NULL) {
1128 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
1132 ZERO_STRUCTP(nt_devmode);
1134 snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, default_devicename);
1135 fstrcpy(nt_devmode->devicename, adevice);
1138 fstrcpy(nt_devmode->formname, "Letter");
1140 nt_devmode->specversion = 0x0401;
1141 nt_devmode->driverversion = 0x0400;
1142 nt_devmode->size = 0x00DC;
1143 nt_devmode->driverextra = 0x0000;
1144 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
1145 DEFAULTSOURCE | COPIES | SCALE |
1146 PAPERSIZE | ORIENTATION;
1147 nt_devmode->orientation = 1;
1148 nt_devmode->papersize = PAPER_LETTER;
1149 nt_devmode->paperlength = 0;
1150 nt_devmode->paperwidth = 0;
1151 nt_devmode->scale = 0x64;
1152 nt_devmode->copies = 01;
1153 nt_devmode->defaultsource = BIN_FORMSOURCE;
1154 nt_devmode->printquality = 0x0258;
1155 nt_devmode->color = COLOR_MONOCHROME;
1156 nt_devmode->duplex = DUP_SIMPLEX;
1157 nt_devmode->yresolution = 0;
1158 nt_devmode->ttoption = TT_SUBDEV;
1159 nt_devmode->collate = COLLATE_FALSE;
1160 nt_devmode->icmmethod = 0;
1161 nt_devmode->icmintent = 0;
1162 nt_devmode->mediatype = 0;
1163 nt_devmode->dithertype = 0;
1165 /* non utilisés par un driver d'imprimante */
1166 nt_devmode->logpixels = 0;
1167 nt_devmode->bitsperpel = 0;
1168 nt_devmode->pelswidth = 0;
1169 nt_devmode->pelsheight = 0;
1170 nt_devmode->displayflags = 0;
1171 nt_devmode->displayfrequency = 0;
1172 nt_devmode->reserved1 = 0;
1173 nt_devmode->reserved2 = 0;
1174 nt_devmode->panningwidth = 0;
1175 nt_devmode->panningheight = 0;
1177 nt_devmode->private=NULL;
1182 /****************************************************************************
1183 Deepcopy an NT devicemode.
1184 ****************************************************************************/
1186 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
1188 NT_DEVICEMODE *new_nt_devicemode = NULL;
1190 if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
1191 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
1195 new_nt_devicemode->private = NULL;
1196 if (nt_devicemode->private != NULL) {
1197 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
1198 safe_free(new_nt_devicemode);
1199 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
1204 return new_nt_devicemode;
1207 /****************************************************************************
1208 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
1209 ****************************************************************************/
1211 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
1213 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
1215 if(nt_devmode == NULL)
1218 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
1220 if(nt_devmode->private)
1221 safe_free(nt_devmode->private);
1223 safe_free(nt_devmode);
1224 *devmode_ptr = NULL;
1227 /****************************************************************************
1228 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
1229 ****************************************************************************/
1230 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
1232 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
1233 NT_PRINTER_PARAM *param_ptr;
1238 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
1240 free_nt_devicemode(&info->devmode);
1241 free_sec_desc_buf(&info->secdesc_buf);
1243 for(param_ptr = info->specific; param_ptr; ) {
1244 NT_PRINTER_PARAM *tofree = param_ptr;
1246 param_ptr = param_ptr->next;
1247 free_nt_printer_param(&tofree);
1250 safe_free(*info_ptr);
1255 /****************************************************************************
1256 ****************************************************************************/
1257 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
1260 NT_DEVICEMODE devmode;
1262 ZERO_STRUCT(devmode);
1264 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
1266 if (!*nt_devmode) return len;
1268 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1272 &devmode.specversion,
1273 &devmode.driverversion,
1275 &devmode.driverextra,
1276 &devmode.orientation,
1278 &devmode.paperlength,
1279 &devmode.paperwidth,
1282 &devmode.defaultsource,
1283 &devmode.printquality,
1286 &devmode.yresolution,
1292 &devmode.bitsperpel,
1294 &devmode.pelsheight,
1295 &devmode.displayflags,
1296 &devmode.displayfrequency,
1300 &devmode.dithertype,
1303 &devmode.panningwidth,
1304 &devmode.panningheight,
1307 if (devmode.private)
1308 len += tdb_unpack(buf+len, buflen-len, "B", &devmode.driverextra, &devmode.private);
1310 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
1312 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
1313 if (devmode.private)
1314 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
1319 /****************************************************************************
1320 ****************************************************************************/
1321 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
1324 NT_PRINTER_PARAM param, *p;
1329 len += tdb_unpack(buf+len, buflen-len, "p", &p);
1332 len += tdb_unpack(buf+len, buflen-len, "fdB",
1338 *list = memdup(¶m, sizeof(param));
1340 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
1347 /****************************************************************************
1348 get a default printer info 2 struct
1349 ****************************************************************************/
1350 static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1352 extern pstring global_myname;
1354 NT_PRINTER_INFO_LEVEL_2 info;
1358 snum = lp_servicenumber(sharename);
1360 fstrcpy(info.servername, global_myname);
1361 fstrcpy(info.printername, sharename);
1362 fstrcpy(info.portname, sharename);
1363 fstrcpy(info.drivername, lp_printerdriver(snum));
1364 fstrcpy(info.comment, "");
1365 fstrcpy(info.printprocessor, "winprint");
1366 fstrcpy(info.datatype, "RAW");
1368 info.attributes = PRINTER_ATTRIBUTE_SHARED \
1369 | PRINTER_ATTRIBUTE_LOCAL \
1370 | PRINTER_ATTRIBUTE_RAW_ONLY ; /* attributes */
1372 info.starttime = 0; /* Minutes since 12:00am GMT */
1373 info.untiltime = 0; /* Minutes since 12:00am GMT */
1375 info.default_priority = 1;
1377 if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
1381 if (!nt_printing_getsec(sharename, &info.secdesc_buf))
1385 *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
1387 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
1396 free_nt_devicemode(&info.devmode);
1397 if (info.secdesc_buf)
1398 free_sec_desc_buf(&info.secdesc_buf);
1402 /****************************************************************************
1403 ****************************************************************************/
1404 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1407 NT_PRINTER_INFO_LEVEL_2 info;
1409 TDB_DATA kbuf, dbuf;
1413 slprintf(key, sizeof(key), "%s%s", PRINTERS_PREFIX, sharename);
1416 kbuf.dsize = strlen(key)+1;
1418 dbuf = tdb_fetch(tdb, kbuf);
1420 if (!dbuf.dptr) return get_a_printer_2_default(info_ptr, sharename);
1422 if (!dbuf.dptr) return 1;
1425 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffffffff",
1428 &info.default_priority,
1445 info.printprocessor,
1449 /* Samba has to have shared raw drivers. */
1450 info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
1452 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
1453 len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
1456 nt_printing_getsec(sharename, &info.secdesc_buf);
1457 #endif /* JRATEST */
1459 safe_free(dbuf.dptr);
1460 *info_ptr=memdup(&info, sizeof(info));
1462 DEBUG(9,("Unpacked printer [%s] running driver [%s]\n",
1463 sharename, info.drivername));
1469 /****************************************************************************
1470 debugging function, dump at level 6 the struct in the logs
1471 ****************************************************************************/
1472 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1475 NT_PRINTER_INFO_LEVEL_2 *info2;
1477 DEBUG(106,("Dumping printer at level [%d]\n", level));
1483 if (printer.info_2 == NULL)
1487 info2=printer.info_2;
1489 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
1490 DEBUGADD(106,("priority:[%d]\n", info2->priority));
1491 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
1492 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
1493 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
1494 DEBUGADD(106,("status:[%d]\n", info2->status));
1495 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
1496 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
1497 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
1498 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
1499 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
1501 DEBUGADD(106,("servername:[%s]\n", info2->servername));
1502 DEBUGADD(106,("printername:[%s]\n", info2->printername));
1503 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
1504 DEBUGADD(106,("portname:[%s]\n", info2->portname));
1505 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
1506 DEBUGADD(106,("comment:[%s]\n", info2->comment));
1507 DEBUGADD(106,("location:[%s]\n", info2->location));
1508 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
1509 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
1510 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
1511 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
1517 DEBUGADD(1,("Level not implemented\n"));
1526 * The function below are the high level ones.
1527 * only those ones must be called from the spoolss code.
1532 /****************************************************************************
1533 ****************************************************************************/
1534 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1538 dump_a_printer(printer, level);
1544 success=add_a_printer_2(printer.info_2);
1555 /****************************************************************************
1556 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
1557 ****************************************************************************/
1559 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
1562 NT_PRINTER_INFO_LEVEL *printer = NULL;
1566 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1572 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
1573 DEBUG(0,("get_a_printer: malloc fail.\n"));
1576 ZERO_STRUCTP(printer);
1577 success=get_a_printer_2(&printer->info_2, sharename);
1579 dump_a_printer(*printer, level);
1580 *pp_printer = printer;
1591 DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1596 /****************************************************************************
1597 Deletes a NT_PRINTER_INFO_LEVEL struct.
1598 ****************************************************************************/
1600 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
1603 NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
1605 DEBUG(104,("freeing a printer at level [%d]\n", level));
1607 if (printer == NULL)
1614 if (printer->info_2 != NULL)
1616 free_nt_printer_info_level_2(&printer->info_2);
1635 /****************************************************************************
1636 ****************************************************************************/
1637 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1640 DEBUG(104,("adding a printer at level [%d]\n", level));
1641 dump_a_printer_driver(driver, level);
1647 success=add_a_printer_driver_3(driver.info_3);
1653 success=add_a_printer_driver_6(driver.info_6);
1663 /****************************************************************************
1664 ****************************************************************************/
1665 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
1666 fstring printername, fstring architecture, uint32 version)
1674 success=get_a_printer_driver_3(&(driver->info_3),
1676 architecture, version);
1684 if (success == 0) dump_a_printer_driver(*driver, level);
1688 /****************************************************************************
1689 ****************************************************************************/
1690 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1698 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1699 if (driver.info_3 != NULL)
1701 info3=driver.info_3;
1702 safe_free(info3->dependentfiles);
1703 ZERO_STRUCTP(info3);
1715 NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
1716 if (driver.info_6 != NULL)
1718 info6=driver.info_6;
1719 safe_free(info6->dependentfiles);
1720 safe_free(info6->previousnames);
1721 ZERO_STRUCTP(info6);
1738 /****************************************************************************
1739 ****************************************************************************/
1740 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
1741 fstring value, uint8 **data, uint32 *type, uint32 *len)
1743 /* right now that's enough ! */
1744 NT_PRINTER_PARAM *param;
1747 param=printer.info_2->specific;
1749 while (param != NULL && i < param_index) {
1757 /* exited because it exist */
1759 StrnCpy(value, param->value, sizeof(fstring)-1);
1760 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1763 ZERO_STRUCTP(*data);
1764 memcpy(*data, param->data, param->data_len);
1765 *len=param->data_len;
1769 /****************************************************************************
1770 ****************************************************************************/
1771 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
1772 fstring value, uint8 **data, uint32 *type, uint32 *len)
1774 /* right now that's enough ! */
1775 NT_PRINTER_PARAM *param;
1777 DEBUG(105, ("get_specific_param\n"));
1779 param=printer.info_2->specific;
1781 while (param != NULL)
1783 if ( !strcmp(value, param->value)
1784 && strlen(value)==strlen(param->value))
1790 DEBUG(106, ("found one param\n"));
1793 /* exited because it exist */
1796 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1799 memcpy(*data, param->data, param->data_len);
1800 *len=param->data_len;
1802 DEBUG(106, ("exit of get_specific_param:true\n"));
1805 DEBUG(106, ("exit of get_specific_param:false\n"));
1810 /****************************************************************************
1811 store a security desc for a printer
1812 ****************************************************************************/
1813 uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
1815 SEC_DESC_BUF *new_secdesc_ctr = NULL;
1816 SEC_DESC_BUF *old_secdesc_ctr = NULL;
1818 TALLOC_CTX *mem_ctx = NULL;
1822 mem_ctx = talloc_init();
1823 if (mem_ctx == NULL)
1826 /* The old owner and group sids of the security descriptor are not
1827 present when new ACEs are added or removed by changing printer
1828 permissions through NT. If they are NULL in the new security
1829 descriptor then copy them over from the old one. */
1831 if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
1832 DOM_SID *owner_sid, *group_sid;
1833 SEC_DESC *psd = NULL;
1836 nt_printing_getsec(printername, &old_secdesc_ctr);
1838 /* Pick out correct owner and group sids */
1840 owner_sid = secdesc_ctr->sec->owner_sid ?
1841 secdesc_ctr->sec->owner_sid :
1842 old_secdesc_ctr->sec->owner_sid;
1844 group_sid = secdesc_ctr->sec->grp_sid ?
1845 secdesc_ctr->sec->grp_sid :
1846 old_secdesc_ctr->sec->grp_sid;
1848 /* Make a deep copy of the security descriptor */
1850 psd = make_sec_desc(secdesc_ctr->sec->revision,
1851 secdesc_ctr->sec->type,
1852 owner_sid, group_sid,
1853 secdesc_ctr->sec->sacl,
1854 secdesc_ctr->sec->dacl,
1857 new_secdesc_ctr = make_sec_desc_buf(size, psd);
1859 /* Free up memory */
1861 free_sec_desc(&psd);
1862 free_sec_desc_buf(&old_secdesc_ctr);
1865 if (!new_secdesc_ctr) {
1866 new_secdesc_ctr = secdesc_ctr;
1869 /* Store the security descriptor in a tdb */
1871 prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
1872 sizeof(SEC_DESC_BUF), 4, mem_ctx, MARSHALL);
1874 if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
1876 status = ERROR_INVALID_FUNCTION;
1880 slprintf(key, sizeof(key), "SECDESC/%s", printername);
1882 if (tdb_prs_store(tdb, key, &ps)==0) {
1885 DEBUG(1,("Failed to store secdesc for %s\n", printername));
1886 status = ERROR_INVALID_FUNCTION;
1889 /* Free mallocated memory */
1892 free_sec_desc_buf(&old_secdesc_ctr);
1894 if (new_secdesc_ctr != secdesc_ctr) {
1895 free_sec_desc_buf(&new_secdesc_ctr);
1900 talloc_destroy(mem_ctx);
1904 /****************************************************************************
1905 Construct a default security descriptor buffer for a printer.
1906 ****************************************************************************/
1908 static SEC_DESC_BUF *construct_default_printer_sdb(void)
1912 SEC_ACL *psa = NULL;
1913 SEC_DESC_BUF *sdb = NULL;
1914 SEC_DESC *psd = NULL;
1919 /* Create an ACE where Everyone is allowed to print */
1921 init_sec_access(&sa, PRINTER_ACE_PRINT);
1922 init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
1923 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
1926 /* Make the security descriptor owned by the Administrators group
1927 on the PDC of the domain. */
1929 if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
1930 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
1933 /* Backup plan - make printer owned by world. This should
1934 emulate a lanman printer as security settings can't be
1937 sid_copy(&owner_sid, &global_sid_World);
1940 /* The ACL revision number in rpc_secdesc.h differs from the one
1941 created by NT when setting ACE entries in printer
1942 descriptors. NT4 complains about the property being edited by a
1945 #define NT4_ACL_REVISION 0x2
1947 if ((psa = make_sec_acl(NT4_ACL_REVISION, 1, &ace)) != NULL) {
1948 psd = make_sec_desc(SEC_DESC_REVISION,
1949 SEC_DESC_SELF_RELATIVE |
1950 SEC_DESC_DACL_PRESENT,
1952 NULL, psa, &sd_size);
1957 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
1961 sdb = make_sec_desc_buf(sd_size, psd);
1963 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
1964 (unsigned int)sd_size));
1966 free_sec_desc(&psd);
1970 /****************************************************************************
1971 Get a security desc for a printer.
1972 ****************************************************************************/
1974 BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr)
1977 TALLOC_CTX *mem_ctx = NULL;
1980 mem_ctx = talloc_init();
1981 if (mem_ctx == NULL)
1984 /* Fetch security descriptor from tdb */
1986 slprintf(key, sizeof(key), "SECDESC/%s", printername);
1988 if (tdb_prs_fetch(tdb, key, &ps, mem_ctx)!=0 ||
1989 !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
1991 DEBUG(4,("using default secdesc for %s\n", printername));
1993 if (!(*secdesc_ctr = construct_default_printer_sdb())) {
1994 talloc_destroy(mem_ctx);
1998 talloc_destroy(mem_ctx);
2002 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
2003 this security descriptor has been created when winbindd was
2004 down. Take ownership of security descriptor. */
2006 if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
2010 /* Change sd owner to workgroup administrator */
2012 if (winbind_lookup_name(lp_workgroup(), &owner_sid,
2014 SEC_DESC_BUF *new_secdesc_ctr = NULL;
2015 SEC_DESC *psd = NULL;
2020 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
2022 psd = make_sec_desc((*secdesc_ctr)->sec->revision,
2023 (*secdesc_ctr)->sec->type,
2025 (*secdesc_ctr)->sec->grp_sid,
2026 (*secdesc_ctr)->sec->sacl,
2027 (*secdesc_ctr)->sec->dacl,
2030 new_secdesc_ctr = make_sec_desc_buf(size, psd);
2032 free_sec_desc(&psd);
2034 /* Swap with other one */
2036 free_sec_desc_buf(secdesc_ctr);
2037 *secdesc_ctr = new_secdesc_ctr;
2041 nt_printing_setsec(printername, *secdesc_ctr);
2046 talloc_destroy(mem_ctx);
2052 1: level not implemented
2053 2: file doesn't exist
2054 3: can't allocate memory
2055 4: can't free memory
2056 5: non existant struct
2060 A printer and a printer driver are 2 different things.
2061 NT manages them separatelly, Samba does the same.
2062 Why ? Simply because it's easier and it makes sense !
2064 Now explanation: You have 3 printers behind your samba server,
2065 2 of them are the same make and model (laser A and B). But laser B
2066 has an 3000 sheet feeder and laser A doesn't such an option.
2067 Your third printer is an old dot-matrix model for the accounting :-).
2069 If the /usr/local/samba/lib directory (default dir), you will have
2070 5 files to describe all of this.
2072 3 files for the printers (1 by printer):
2075 NTprinter_accounting
2076 2 files for the drivers (1 for the laser and 1 for the dot matrix)
2077 NTdriver_printer model X
2078 NTdriver_printer model Y
2080 jfm: I should use this comment for the text file to explain
2081 same thing for the forms BTW.
2082 Je devrais mettre mes commentaires en francais, ca serait mieux :-)
2086 /* Check a user has permissions to perform the given operation */
2088 BOOL print_access_check(struct current_user *user, int snum,
2089 uint32 required_access)
2091 SEC_DESC_BUF *secdesc = NULL;
2092 uint32 access_granted, status;
2097 /* Get printer name */
2099 pname = PRINTERNAME(snum);
2100 if (!pname || !*pname) pname = SERVICE(snum);
2102 /* Get printer security descriptor */
2104 nt_printing_getsec(pname, &secdesc);
2106 /* The ACE for Full Control in a printer security descriptor
2107 doesn't seem to map properly to the access checking model. For
2108 it to work properly it should be the logical OR of all the other
2109 values, i.e PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT.
2110 This would cause the access check to simply fall out when we
2111 check against any subset of these bits. To get things to work,
2112 change every ACE mask of PRINTER_ACE_FULL_CONTROL to
2113 PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT before
2114 performing the access check. I'm sure there is a better way to
2117 if (secdesc && secdesc->sec && secdesc->sec->dacl &&
2118 secdesc->sec->dacl->ace) {
2119 for(i = 0; i < secdesc->sec->dacl->num_aces; i++) {
2120 if (secdesc->sec->dacl->ace[i].info.mask ==
2121 PRINTER_ACE_FULL_CONTROL) {
2122 secdesc->sec->dacl->ace[i].info.mask =
2123 PRINTER_ACE_MANAGE_DOCUMENTS |
2131 result = se_access_check(secdesc->sec, user, required_access,
2132 &access_granted, &status);
2134 DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
2136 /* Free mallocated memory */
2138 free_sec_desc_buf(&secdesc);