The branch, master has been updated
via 7e938f3d233 printing: Fix use of time_t CID#1509005
via e3a6505f2b9 printing: Fix use of time_t CID#1509036
via 912c91cbcd4 printing: Fix use of time_t CID#1508987
via e9a7dce599e printing: Define and use methods to fetch/store time in
share cache
via 898efdc3233 printing: Update version for print database
via f89fc3c5f7b lib:util: Add APIs for fetch/store int64/uint64 values
to/from tdb
via fa160ebe8b4 s3:lib:util_tdb: Add format identifier for 64-bit
integer pack/unpack
from f3b380b8a38 lib:replace: Remove memset_s()
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 7e938f3d2330c3dc0bbfa62f66924d2a9951cf92
Author: Vinit Agnihotri <[email protected]>
Date: Tue Sep 16 11:30:57 2025 +0530
printing: Fix use of time_t CID#1509005
- This Fixes coverity issue Y2K38_SAFTY in print_queue_update(),
with use of fetch/store_share_cache_time helper function.
- Additional changes: Use helper functions fetch/store_share_cache_time
for tdb
key==MSG_PENDING for print_cache_expired()
Signed-off-by: Vinit Agnihotri <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
Reviewed-by: Anoop C S <[email protected]>
Autobuild-User(master): Anoop C S <[email protected]>
Autobuild-Date(master): Wed Nov 12 16:04:43 UTC 2025 on atb-devel-224
commit e3a6505f2b9fa09f16fa1ae8ac9f7a38167b9b86
Author: Vinit Agnihotri <[email protected]>
Date: Mon Sep 15 17:41:52 2025 +0530
printing: Fix use of time_t CID#1509036
- Use format specifier 'D' for time_t
- This fixes covery reported issue Y2K38_SAFTY for pjob_store()
Signed-off-by: Vinit Agnihotri <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
Reviewed-by: Anoop C S <[email protected]>
commit 912c91cbcd4f5b90623b9f435912dfcc349f9449
Author: Vinit Agnihotri <[email protected]>
Date: Mon Sep 15 18:38:32 2025 +0530
printing: Fix use of time_t CID#1508987
- This fixes coverity issue Y2K38_SAFTY for print_update_queue_internal()
Signed-off-by: Vinit Agnihotri <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
Reviewed-by: Anoop C S <[email protected]>
commit e9a7dce599eb12d7749783c1809c33313fc5d81e
Author: Vinit Agnihotri <[email protected]>
Date: Tue Sep 16 10:33:50 2025 +0530
printing: Define and use methods to fetch/store time in share cache
Signed-off-by: Vinit Agnihotri <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
Reviewed-by: Anoop C S <[email protected]>
commit 898efdc3233e6197235f2b6ef6cb3386c0622b9e
Author: Vinit Agnihotri <[email protected]>
Date: Tue Sep 16 14:25:40 2025 +0530
printing: Update version for print database
Updating version to change time_t related store/fetch from exisiting
uint32_t values to time_t (64-bit) values.
Signed-off-by: Vinit Agnihotri <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
Reviewed-by: Anoop C S <[email protected]>
commit f89fc3c5f7bc6e41de7a23ce2934ed8ff4dc0ac9
Author: Vinit Agnihotri <[email protected]>
Date: Wed Sep 24 12:44:07 2025 +0530
lib:util: Add APIs for fetch/store int64/uint64 values to/from tdb
Signed-off-by: Vinit Agnihotri <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
Reviewed-by: Anoop C S <[email protected]>
commit fa160ebe8b41b0eb0956849fcd5208c45159f812
Author: Vinit Agnihotri <[email protected]>
Date: Wed Sep 24 11:49:15 2025 +0530
s3:lib:util_tdb: Add format identifier for 64-bit integer pack/unpack
Signed-off-by: Vinit Agnihotri <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
Reviewed-by: Anoop C S <[email protected]>
-----------------------------------------------------------------------
Summary of changes:
lib/util/util_tdb.c | 97 +++++++++++++++++++++++++++++++
lib/util/util_tdb.h | 24 ++++++++
source3/include/printing.h | 2 +-
source3/lib/util_tdb.c | 15 +++++
source3/printing/printing.c | 136 +++++++++++++++++++++++++++++++-------------
5 files changed, 233 insertions(+), 41 deletions(-)
Changeset truncated at 500 lines:
diff --git a/lib/util/util_tdb.c b/lib/util/util_tdb.c
index d8672c35b9a..33de5c31b81 100644
--- a/lib/util/util_tdb.c
+++ b/lib/util/util_tdb.c
@@ -255,6 +255,103 @@ bool tdb_store_uint32(struct tdb_context *tdb, const char
*keystr, uint32_t valu
{
return tdb_store_uint32_byblob(tdb, string_term_tdb_data(keystr),
value);
}
+
+/****************************************************************************
+ Fetch a int64_t value by a arbitrary blob key, return -1 if not found.
+****************************************************************************/
+
+static int fetch_int64_parser(TDB_DATA key, TDB_DATA data, void *private_data)
+{
+ if (data.dsize == sizeof(int64_t)) {
+ *((int64_t *)private_data) = PULL_LE_I64(data.dptr, 0);
+ return 0;
+ }
+ return -1;
+}
+
+/****************************************************************************
+ Fetch a int64_t value by string key, return -1 if not found.
+****************************************************************************/
+
+int tdb_fetch_int64(struct tdb_context *tdb, const char *keystr, int64_t
*value)
+{
+ return tdb_parse_record(tdb, string_term_tdb_data(keystr),
fetch_int64_parser, value);
+}
+
+/****************************************************************************
+ Store a int64_t value by an arbitrary blob key, return 0 on success, -ve on
failure.
+ Input is int64_t in native byte order. Output in tdb is in little-endian.
+****************************************************************************/
+
+static int tdb_store_int64_byblob(struct tdb_context *tdb, TDB_DATA key,
+ int64_t v)
+{
+ int64_t v_store;
+ TDB_DATA data = { .dptr = (unsigned char *)&v_store, .dsize =
sizeof(v_store), };
+
+ PUSH_LE_I64(&v_store, 0, v);
+ return tdb_store(tdb, key, data, TDB_REPLACE);
+}
+
+/****************************************************************************
+ Store a int64_t value by string key, return 0 on success, -ve on failure.
+ Input is int64_t in native byte order. Output in tdb is in little-endian.
+****************************************************************************/
+
+int tdb_store_int64(struct tdb_context *tdb, const char *keystr, int64_t v)
+{
+ return tdb_store_int64_byblob(tdb, string_term_tdb_data(keystr), v);
+}
+
+/****************************************************************************
+ Fetch a uint64_t value by a arbitrary blob key, return -1 in case of error.
+ Output is uint64_t in native byte order.
+****************************************************************************/
+
+static int fetch_uint64_parser(TDB_DATA key, TDB_DATA data, void *private_data)
+{
+ if (data.dsize != sizeof(uint64_t)) {
+ return -1;
+ }
+ *((uint64_t *)private_data) = PULL_LE_U64(data.dptr, 0);
+ return 0;
+}
+
+/****************************************************************************
+ Fetch a uint64_t value by string key, return -1 if not found.
+ Output is uint64_t in native byte order.
+****************************************************************************/
+
+int tdb_fetch_uint64(struct tdb_context *tdb, const char *keystr, uint64_t
*value)
+{
+ return tdb_parse_record(tdb, string_term_tdb_data(keystr),
fetch_uint64_parser, value);
+}
+
+/****************************************************************************
+ Store a uint64_t value by an arbitrary blob key, return 0 on success, -1 on
failure.
+ Input is uint64_t in native byte order. Output in tdb is in little-endian.
+****************************************************************************/
+
+static int tdb_store_uint64_byblob(struct tdb_context *tdb, TDB_DATA key,
+ uint64_t value)
+{
+ uint64_t v_store;
+ TDB_DATA data = { .dptr = (unsigned char *)&v_store, .dsize =
sizeof(v_store), };
+
+ PUSH_LE_U64(&v_store, 0, value);
+ return tdb_store(tdb, key, data, TDB_REPLACE);
+}
+
+/****************************************************************************
+ Store a uint64_t value by string key, return 0 on success, -1 on failure.
+ Input is uint64_t in native byte order. Output in tdb is in little-endian.
+****************************************************************************/
+
+int tdb_store_uint64(struct tdb_context *tdb, const char *keystr, uint64_t
value)
+{
+ return tdb_store_uint64_byblob(tdb, string_term_tdb_data(keystr),
value);
+}
+
/****************************************************************************
Store a buffer by a null terminated string key. Return 0 on success, -ve
on failure.
diff --git a/lib/util/util_tdb.h b/lib/util/util_tdb.h
index 010521d9606..69926a12d10 100644
--- a/lib/util/util_tdb.h
+++ b/lib/util/util_tdb.h
@@ -80,6 +80,30 @@ bool tdb_fetch_uint32(struct tdb_context *tdb, const char
*keystr, uint32_t *val
****************************************************************************/
bool tdb_store_uint32(struct tdb_context *tdb, const char *keystr, uint32_t
value);
+/****************************************************************************
+ Fetch a int64_t value by string key, return -1 if not found.
+ Output is int64_t in native byte order.
+****************************************************************************/
+int tdb_fetch_int64(struct tdb_context *tdb, const char *keystr, int64_t *);
+
+/****************************************************************************
+ Store a int64_t value by string key, return 0 on success, -1 on failure.
+ Input is int64_t in native byte order. Output in tdb is in little-endian.
+****************************************************************************/
+int tdb_store_int64(struct tdb_context *tdb, const char *keystr, int64_t v);
+
+/****************************************************************************
+ Fetch a uint64_t value by string key, return -1 if not found.
+ Output is uint64_t in native byte order.
+****************************************************************************/
+int tdb_fetch_uint64(struct tdb_context *tdb, const char *keystr, uint64_t
*value);
+
+/****************************************************************************
+ Store a uint64_t value by string key, return 0 on success, -1 on failure.
+ Input is uint64_t in native byte order. Output in tdb is in little-endian.
+****************************************************************************/
+int tdb_store_uint64(struct tdb_context *tdb, const char *keystr, uint64_t
value);
+
/****************************************************************************
Store a buffer by a null terminated string key. Return 0 on success, -ve
on failure.
diff --git a/source3/include/printing.h b/source3/include/printing.h
index 20a2eb349d3..07db3790988 100644
--- a/source3/include/printing.h
+++ b/source3/include/printing.h
@@ -128,7 +128,7 @@ extern struct printif iprint_printif;
#ifndef PRINT_SPOOL_PREFIX
#define PRINT_SPOOL_PREFIX "smbprn."
#endif
-#define PRINT_DATABASE_VERSION 8
+#define PRINT_DATABASE_VERSION 9
#ifdef AIX
#define DEFAULT_PRINTING PRINT_AIX
diff --git a/source3/lib/util_tdb.c b/source3/lib/util_tdb.c
index 3c7c1945f58..f6fa1905ce1 100644
--- a/source3/lib/util_tdb.c
+++ b/source3/lib/util_tdb.c
@@ -39,6 +39,7 @@ static size_t tdb_pack_va(uint8_t *buf, int bufsize, const
char *fmt, va_list ap
uint8_t bt;
uint16_t w;
uint32_t d;
+ int64_t D;
int i;
void *p;
int len = 0;
@@ -67,6 +68,12 @@ static size_t tdb_pack_va(uint8_t *buf, int bufsize, const
char *fmt, va_list ap
if (bufsize && bufsize >= len)
SIVAL(buf, 0, d);
break;
+ case 'D': /* signed 64-bit integer*/
+ len = 8;
+ D = va_arg(ap, int64_t);
+ if (bufsize && bufsize >= len)
+ PUSH_LE_I64(buf, 0, D);
+ break;
case 'p': /* pointer */
len = 4;
p = va_arg(ap, void *);
@@ -140,6 +147,7 @@ int tdb_unpack(const uint8_t *buf, int in_bufsize, const
char *fmt, ...)
uint8_t *bt;
uint16_t *w;
uint32_t *d;
+ int64_t *D;
size_t bufsize = in_bufsize;
size_t len;
uint32_t *i;
@@ -174,6 +182,13 @@ int tdb_unpack(const uint8_t *buf, int in_bufsize, const
char *fmt, ...)
goto no_space;
*d = IVAL(buf, 0);
break;
+ case 'D': /* Signed 64-bit integer */
+ len = 8;
+ D = va_arg(ap, int64_t *);
+ if (bufsize < len)
+ goto no_space;
+ *D = PULL_LE_I64(buf, 0);
+ break;
case 'p': /* pointer */
len = 4;
p = va_arg(ap, void **);
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index 48d221de127..5fe9fcfcd5e 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -43,6 +43,9 @@
#include "source3/printing/rap_jobid.h"
#include "source3/lib/substitute.h"
+#define CACHE_LAST_SCAN_TIME "CACHE"
+#define MSG_PENDING_TIME "MSG_PENDING"
+
extern userdom_struct current_user_info;
/* Current printer interface */
@@ -50,6 +53,52 @@ static bool remove_from_jobs_added(const char* sharename,
uint32_t jobid);
static int get_queue_status(const char* sharename, print_status_struct *);
+static int fetch_share_cache_time(const char *key_name,
+ const char *sharename,
+ struct tdb_context *tdb,
+ time_t *curr_time)
+{
+ char *key = NULL;
+
+ key = talloc_asprintf(NULL, "%s/%s", key_name, sharename);
+ if (key == NULL) {
+ DBG_ERR("Failed to format key\n");
+ return -1;
+ }
+
+ if (tdb_fetch_int64(tdb, key, curr_time) != 0) {
+ DBG_ERR("No timing record found for[%s]!\n", sharename);
+ TALLOC_FREE(key);
+ return -1;
+ }
+
+ TALLOC_FREE(key);
+ return 0;
+}
+
+static int update_share_cache_time(const char *key_name,
+ const char *sharename,
+ struct tdb_context *tdb,
+ time_t curr_time)
+{
+ char *key = NULL;
+
+ key = talloc_asprintf(NULL, "%s/%s", key_name, sharename);
+ if (key == NULL) {
+ DBG_ERR("Failed to format key.\n");
+ return -1;
+ }
+
+ if (tdb_store_int64(tdb, key, (int64_t)curr_time) != 0) {
+ DBG_ERR("Unable to update print cache for %s\n", sharename);
+ TALLOC_FREE(key);
+ return -1;
+ }
+
+ TALLOC_FREE(key);
+ return 0;
+}
+
/****************************************************************************
Initialise the printing backend. Called once at startup before the fork().
****************************************************************************/
@@ -250,14 +299,15 @@ static int unpack_pjob(TALLOC_CTX *mem_ctx, uint8_t *buf,
int buflen,
{
int len = 0;
int used;
- uint32_t pjpid, pjjobid, pjsysjob, pjfd, pjstarttime, pjstatus;
+ uint32_t pjpid, pjjobid, pjsysjob, pjfd, pjstatus;
uint32_t pjsize, pjpage_count, pjspooled, pjsmbjob;
+ time_t pjstarttime;
if (!buf || !pjob) {
return -1;
}
- len += tdb_unpack(buf+len, buflen-len, "ddddddddddfffff",
+ len += tdb_unpack(buf+len, buflen-len, "ddddDdddddfffff",
&pjpid,
&pjjobid,
&pjsysjob,
@@ -674,12 +724,12 @@ static bool pjob_store(struct tevent_context *ev,
do {
len = 0;
buflen = newlen;
- len += tdb_pack(buf+len, buflen-len, "ddddddddddfffff",
+ len += tdb_pack(buf+len, buflen-len, "ddddDdddddfffff",
(uint32_t)pjob->pid,
(uint32_t)pjob->jobid,
(uint32_t)pjob->sysjob,
(uint32_t)pjob->fd,
- (uint32_t)pjob->starttime,
+ (int64_t)pjob->starttime,
(uint32_t)pjob->status,
(uint32_t)pjob->size,
(uint32_t)pjob->page_count,
@@ -1001,13 +1051,12 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA
key, TDB_DATA data, void
static void print_cache_flush(const char *sharename)
{
- fstring key;
struct tdb_print_db *pdb = get_print_db_byname(sharename);
if (!pdb)
return;
- slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
- tdb_store_int32(pdb->tdb, key, -1);
+
+ update_share_cache_time(CACHE_LAST_SCAN_TIME, sharename, pdb->tdb, -1);
release_print_db(pdb);
}
@@ -1131,13 +1180,13 @@ static void store_queue_struct(struct tdb_print_db
*pdb, struct traverse_struct
continue;
qcount++;
- data.dsize += tdb_pack(NULL, 0, "ddddddff",
+ data.dsize += tdb_pack(NULL, 0, "dddddDff",
(uint32_t)queue[i].sysjob,
(uint32_t)queue[i].size,
(uint32_t)queue[i].page_count,
(uint32_t)queue[i].status,
(uint32_t)queue[i].priority,
- (uint32_t)queue[i].time,
+ (int64_t)queue[i].time,
queue[i].fs_user,
queue[i].fs_file);
}
@@ -1151,13 +1200,13 @@ static void store_queue_struct(struct tdb_print_db
*pdb, struct traverse_struct
if ( queue[i].status == LPQ_DELETED )
continue;
- len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
+ len += tdb_pack(data.dptr + len, data.dsize - len, "dddddDff",
(uint32_t)queue[i].sysjob,
(uint32_t)queue[i].size,
(uint32_t)queue[i].page_count,
(uint32_t)queue[i].status,
(uint32_t)queue[i].priority,
- (uint32_t)queue[i].time,
+ (int64_t)queue[i].time,
queue[i].fs_user,
queue[i].fs_file);
}
@@ -1203,7 +1252,6 @@ static void check_job_added(const char *sharename,
TDB_DATA data, uint32_t jobid
static bool print_cache_expired(const char *sharename, bool check_pending)
{
- fstring key;
time_t last_qscan_time, time_now = time(NULL);
struct tdb_print_db *pdb = get_print_db_byname(sharename);
bool result = False;
@@ -1211,8 +1259,11 @@ static bool print_cache_expired(const char *sharename,
bool check_pending)
if (!pdb)
return False;
- snprintf(key, sizeof(key), "CACHE/%s", sharename);
- last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
+ if (fetch_share_cache_time(CACHE_LAST_SCAN_TIME, sharename,
+ pdb->tdb, &last_qscan_time) != 0) {
+ DBG_ERR("Unable to get last scan timing for %s\n", sharename);
+ goto done;
+ }
/*
* Invalidate the queue for 3 reasons.
@@ -1228,7 +1279,7 @@ static bool print_cache_expired(const char *sharename,
bool check_pending)
|| (time_now - last_qscan_time) >= lp_lpq_cache_time()
|| last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
{
- uint32_t u;
+ time_t u;
time_t msg_pending_time;
DBG_INFO("cache expired for queue %s "
@@ -1244,16 +1295,20 @@ static bool print_cache_expired(const char *sharename,
bool check_pending)
then send another message anyways. Make sure to check for
clocks that have been run forward and then back again. */
- snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
+ if (fetch_share_cache_time(MSG_PENDING_TIME, sharename,
pdb->tdb, &u) != 0) {
+ DBG_ERR("Unable to get updated scan time for %s\n",
sharename);
+ goto done;
+ }
+ msg_pending_time = u;
if ( check_pending
- && tdb_fetch_uint32( pdb->tdb, key, &u )
- && (msg_pending_time=u) > 0
+ && u
+ && msg_pending_time > 0
&& msg_pending_time <= time_now
&& (time_now - msg_pending_time) < 60 )
{
- DEBUG(4,("print_cache_expired: message already pending
for %s. Accepting cache\n",
- sharename));
+ DBG_INFO("Message already pending for %s. Accepting
cache\n",
+ sharename);
goto done;
}
@@ -1283,7 +1338,7 @@ static void print_queue_update_internal(struct
tevent_context *ev,
struct traverse_struct tstruct;
TDB_DATA data, key;
TDB_DATA jcdata;
- fstring keystr, cachestr;
+ fstring keystr;
struct tdb_print_db *pdb = get_print_db_byname(sharename);
TALLOC_CTX *tmp_ctx = talloc_new(ev);
@@ -1300,8 +1355,12 @@ static void print_queue_update_internal(struct
tevent_context *ev,
* if the lpq takes a long time.
*/
- slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
- tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
+ if (update_share_cache_time(CACHE_LAST_SCAN_TIME, sharename, pdb->tdb,
+ time(NULL)) != 0) {
+ DBG_ERR("Unable to update timing cache for %s\n", sharename);
+ talloc_free(tmp_ctx);
+ return;
+ }
/* get the current queue using the appropriate interface */
ZERO_STRUCT(status);
@@ -1416,19 +1475,18 @@ static void print_queue_update_internal(struct
tevent_context *ev,
* Update the cache time again. We want to do this call
* as little as possible...
*/
-
- slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
- tdb_store_int32(pdb->tdb, keystr, (int32_t)time(NULL));
+ if (update_share_cache_time(CACHE_LAST_SCAN_TIME, sharename, pdb->tdb,
+ time(NULL)) != 0) {
+ DBG_ERR("Unable to update timing cache for %s\n", sharename);
+ return;
+ }
/* clear the msg pending record for this queue */
-
- snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
-
- if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
+ if (update_share_cache_time(MSG_PENDING_TIME, sharename, pdb->tdb, 0)
!= 0) {
/* log a message but continue on */
- DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag
for [%s]!\n",
- sharename));
+ DBG_ERR("Failed to store MSG_PENDING flag for [%s]!\n",
+ sharename);
}
release_print_db( pdb );
@@ -1565,7 +1623,6 @@ update the internal database from the system print queue
for a queue
static void print_queue_update(struct messaging_context *msg_ctx,
int snum, bool force)
{
- char key[268];
fstring sharename;
char *lpqcommand = NULL;
char *lprmcommand = NULL;
@@ -1673,13 +1730,11 @@ static void print_queue_update(struct messaging_context
*msg_ctx,
return;
}
- snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
-
- if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
+ if (update_share_cache_time(MSG_PENDING_TIME, sharename, pdb->tdb,
time(NULL)) != 0) {
/* log a message but continue on */
- DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag
for [%s]!\n",
- sharename));
+ DBG_ERR("Failed to store MSG_PENDING flag for [%s]!\n",
+ sharename);
}
release_print_db( pdb );
@@ -2957,8 +3012,9 @@ static bool get_stored_queue_info(struct
messaging_context *msg_ctx,
/* Retrieve the linearised queue data. */
for(i = 0; i < qcount; i++) {
- uint32_t qjob, qsize, qpage_count, qstatus, qpriority, qtime;
- len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
+ uint32_t qjob, qsize, qpage_count, qstatus, qpriority;
+ time_t qtime;
+ len += tdb_unpack(data.dptr + len, data.dsize - len, "dddddDff",
&qjob,
&qsize,
&qpage_count,
--
Samba Shared Repository