#include "includes.h"
-extern pstring global_myname;
extern DOM_SID global_sid_World;
static TDB_CONTEXT *tdb_forms; /* used for forms files */
#define NTDRIVERS_DATABASE_VERSION_1 1
#define NTDRIVERS_DATABASE_VERSION_2 2
+#define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */
-#define NTDRIVERS_DATABASE_VERSION NTDRIVERS_DATABASE_VERSION_2
+#define NTDRIVERS_DATABASE_VERSION NTDRIVERS_DATABASE_VERSION_3
/* Map generic permissions to printer object specific permissions */
{"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
};
-static BOOL upgrade_to_version_2(void)
+static BOOL upgrade_to_version_3(void)
{
TDB_DATA kbuf, newkey, dbuf;
- DEBUG(0,("upgrade_to_version_2: upgrading print tdb's to version 2\n"));
+ DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
- newkey = tdb_nextkey(tdb_drivers, kbuf), SAFE_FREE(kbuf.dptr), kbuf=newkey) {
+ newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
dbuf = tdb_fetch(tdb_drivers, kbuf);
if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
- DEBUG(0,("upgrade_to_version_2:moving form\n"));
+ DEBUG(0,("upgrade_to_version_3:moving form\n"));
if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
- DEBUG(0,("upgrade_to_version_2: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
+ DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
return False;
}
if (tdb_delete(tdb_drivers, kbuf) != 0) {
- DEBUG(0,("upgrade_to_version_2: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
+ DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
return False;
}
}
if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
- DEBUG(0,("upgrade_to_version_2:moving printer\n"));
+ DEBUG(0,("upgrade_to_version_3:moving printer\n"));
if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
- DEBUG(0,("upgrade_to_version_2: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
+ DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
return False;
}
if (tdb_delete(tdb_drivers, kbuf) != 0) {
- DEBUG(0,("upgrade_to_version_2: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
+ DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
return False;
}
}
if (strncmp(kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
- DEBUG(0,("upgrade_to_version_2:moving secdesc\n"));
+ DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
- DEBUG(0,("upgrade_to_version_2: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
+ DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
return False;
}
if (tdb_delete(tdb_drivers, kbuf) != 0) {
- DEBUG(0,("upgrade_to_version_2: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
+ DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
return False;
}
}
}
/****************************************************************************
-open the NT printing tdb
+ Open the NT printing tdb.
****************************************************************************/
+
BOOL nt_printing_init(void)
{
static pid_t local_pid;
/* handle a Samba upgrade */
tdb_lock_bystring(tdb_drivers, vstring);
- if (tdb_fetch_int(tdb_drivers, vstring) != NTDRIVERS_DATABASE_VERSION) {
-
- if (tdb_fetch_int(tdb_drivers, vstring) == NTDRIVERS_DATABASE_VERSION_1) {
- if (!upgrade_to_version_2())
- return False;
- } else
- tdb_traverse(tdb_drivers, (tdb_traverse_func)tdb_delete, NULL);
+ {
+ int32 vers_id;
+
+ /* Cope with byte-reversed older versions of the db. */
+ vers_id = tdb_fetch_int32(tdb_drivers, vstring);
+ if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) {
+ /* Written on a bigendian machine with old fetch_int code. Save as le. */
+ /* The only upgrade between V2 and V3 is to save the version in little-endian. */
+ tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
+ vers_id = NTDRIVERS_DATABASE_VERSION;
+ }
+
+ if (vers_id != NTDRIVERS_DATABASE_VERSION) {
- tdb_store_int(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
+ if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) {
+ if (!upgrade_to_version_3())
+ return False;
+ } else
+ tdb_traverse(tdb_drivers, tdb_traverse_delete_fn, NULL);
+
+ tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
+ }
}
tdb_unlock_bystring(tdb_drivers, vstring);
for (kbuf = tdb_firstkey(tdb_forms);
kbuf.dptr;
- newkey = tdb_nextkey(tdb_forms, kbuf), SAFE_FREE(kbuf.dptr), kbuf=newkey) {
+ newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
dbuf = tdb_fetch(tdb_forms, kbuf);
for (kbuf = tdb_firstkey(tdb_drivers);
kbuf.dptr;
- newkey = tdb_nextkey(tdb_drivers, kbuf), SAFE_FREE(kbuf.dptr), kbuf=newkey) {
+ newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
}
/****************************************************************************
-Version information in Microsoft files is held in a VS_VERSION_INFO structure.
-There are two case to be covered here: PE (Portable Executable) and NE (New
-Executable) files. Both files support the same INFO structure, but PE files
-store the signature in unicode, and NE files store it as !unicode.
+ Version information in Microsoft files is held in a VS_VERSION_INFO structure.
+ There are two case to be covered here: PE (Portable Executable) and NE (New
+ Executable) files. Both files support the same INFO structure, but PE files
+ store the signature in unicode, and NE files store it as !unicode.
+ returns -1 on error, 1 on version info found, and 0 on no version info found.
****************************************************************************/
-static BOOL get_file_version(files_struct *fsp, char *fname,uint32 *major,
- uint32 *minor)
+
+static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
{
int i;
char *buf;
(*major>>16)&0xffff, *major&0xffff,
(*minor>>16)&0xffff, *minor&0xffff));
SAFE_FREE(buf);
- return True;
+ return 1;
}
}
}
/* Version info not found, fall back to origin date/time */
DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
SAFE_FREE(buf);
- return False;
+ return 0;
} else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
(*major>>16)&0xffff, *major&0xffff,
(*minor>>16)&0xffff, *minor&0xffff));
SAFE_FREE(buf);
- return True;
+ return 1;
}
}
}
/* Version info not found, fall back to origin date/time */
DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
SAFE_FREE(buf);
- return False;
+ return 0;
} else
/* Assume this isn't an error... the file just looks sort of like a PE/NE file */
no_version_info:
SAFE_FREE(buf);
- return False;
+ return 0;
error_exit:
SAFE_FREE(buf);
ZERO_STRUCT(st);
+ *perr = WERR_INVALID_PARAM;
+
/* If architecture is Windows 95/98/ME, the version is always 0. */
if (strcmp(architecture, "WIN40") == 0) {
DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
+ *perr = WERR_OK;
return 0;
}
close_file(fsp, True);
close_cnum(conn, user->vuid);
unbecome_user();
+ *perr = WERR_OK;
return cversion;
error_exit:
nt_devmode->paperlength = 0;
nt_devmode->paperwidth = 0;
nt_devmode->scale = 0x64;
- nt_devmode->copies = 01;
+ nt_devmode->copies = 1;
nt_devmode->defaultsource = BIN_FORMSOURCE;
nt_devmode->printquality = RES_HIGH; /* 0x0258 */
nt_devmode->color = COLOR_MONOCHROME;
****************************************************************************/
static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
{
- extern pstring global_myname;
int snum;
NT_PRINTER_INFO_LEVEL_2 info;
snum = lp_servicenumber(sharename);
- slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", global_myname);
+ slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s",
- global_myname, sharename);
+ get_called_name(), sharename);
fstrcpy(info.sharename, sharename);
fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
fstrcpy(info.drivername, lp_printerdriver(snum));
{
pstring key;
NT_PRINTER_INFO_LEVEL_2 info;
- int len = 0,
- devmode_length = 0;
+ int len = 0;
TDB_DATA kbuf, dbuf;
fstring printername;
info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
/* Restore the stripped strings. */
- slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", global_myname);
- slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", global_myname,
+ slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
+ slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", get_called_name(),
info.printername);
fstrcpy(info.printername, printername);
DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
- DEBUGADD(106,("status:[%s]\n", werror_str(info2->status)));
+ DEBUGADD(106,("status:[%d]\n", info2->status));
DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
free_a_printer(&printer, 2);
}
+/****************************************************************************
+ Update the changeid time.
+ This is SO NASTY as some drivers need this to change, others need it
+ static. This value will change every second, and I must hope that this
+ is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
+ UTAH ! JRA.
+****************************************************************************/
+
+static uint32 rev_changeid(void)
+{
+ struct timeval tv;
+
+ get_process_uptime(&tv);
+ /* This value is in ms * 100 */
+ return (((tv.tv_sec * 1000000) + tv.tv_usec)/100);
+}
+
/*
* The function below are the high level ones.
* only those ones must be called from the spoolss code.
{
case 2:
{
- printer.info_2->c_setprinter++;
+ /*
+ * Update the changestamp. Emperical tests show that the
+ * ChangeID is always updated,but c_setprinter is only
+ * incremented on a SetPrinter() call.
+ */
+
+ /* ChangeID **must** be increasing over the lifetime
+ of client's spoolss service in order for the
+ client's cache to show updates */
+
+ printer.info_2->changeid = rev_changeid();
+
+ /*
+ * Because one day someone will ask:
+ * NT->NT An admin connection to a remote
+ * printer show changes imeediately in
+ * the properities dialog
+ *
+ * A non-admin connection will only show the
+ * changes after viewing the properites page
+ * 2 times. Seems to be related to a
+ * race condition in the client between the spooler
+ * updating the local cache and the Explorer.exe GUI
+ * actually displaying the properties.
+ *
+ * This is fixed in Win2k. admin/non-admin
+ * connections both display changes immediately.
+ *
+ * 14/12/01 --jerry
+ */
+
result=update_a_printer_2(printer.info_2);
break;
}
case 2:
{
/*
- * Update the changestamp.
- * Note we must *not* do this in mod_a_printer().
+ * Update the changestamp. See comments in mod_a_printer()
+ * --jerry
*/
- NTTIME time_nt;
- time_t time_unix = time(NULL);
- unix_to_nt_time(&time_nt, time_unix);
- if (printer.info_2->changeid==time_nt.low)
- printer.info_2->changeid++;
- else
- printer.info_2->changeid=time_nt.low;
+ printer.info_2->changeid = rev_changeid();
printer.info_2->c_setprinter++;
result=update_a_printer_2(printer.info_2);
/* loop through the printers.tdb and check for the drivername */
for (kbuf = tdb_firstkey(tdb_printers); kbuf.dptr;
- newkey = tdb_nextkey(tdb_printers, kbuf), SAFE_FREE(kbuf.dptr), kbuf=newkey)
+ newkey = tdb_nextkey(tdb_printers, kbuf), safe_free(kbuf.dptr), kbuf=newkey)
{
dbuf = tdb_fetch(tdb_printers, kbuf);
}
if (!psd) {
- DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
+ DEBUG(0,("construct_default_printer_sdb: Failed to make SEC_DESC.\n"));
return NULL;
}
return False;
}
+ /* Save default security descriptor for later */
+
+ prs_init(&ps, (uint32)sec_desc_size((*secdesc_ctr)->sec) +
+ sizeof(SEC_DESC_BUF), ctx, MARSHALL);
+
+ if (sec_io_desc_buf("nt_printing_setsec", secdesc_ctr, &ps, 1))
+ tdb_prs_store(tdb_printers, key, &ps);
+
+ prs_mem_free(&ps);
+
return True;
}
for (i = 0; i < the_acl->num_aces; i++) {
fstring sid_str;
- sid_to_string(sid_str, &the_acl->ace[i].sid);
+ sid_to_string(sid_str, &the_acl->ace[i].trustee);
DEBUG(10, ("%s %d %d 0x%08x\n", sid_str,
the_acl->ace[i].type, the_acl->ace[i].flags,