diff --git a/source/passdb/pdb_tdb.c b/source/passdb/pdb_tdb.c index 9928768..2ff70f2 100644 --- a/source/passdb/pdb_tdb.c +++ b/source/passdb/pdb_tdb.c @@ -777,30 +777,50 @@ static int tdbsam_convert_one(struct db_record *rec, void *priv) *********************************************************************/ struct tdbsam_backup_state { - struct db_context *new_db; + void *db_ptr; bool success; }; -static int backup_copy_fn(struct db_record *orig_rec, void *state) +static int backup_copy_delete_fn(struct db_record *orig_rec, void *state) { struct tdbsam_backup_state *bs = (struct tdbsam_backup_state *)state; - struct db_record *new_rec; + struct tdb_context *tmp_tdb = (struct tdb_context *)bs->db_ptr; NTSTATUS status; - new_rec = bs->new_db->fetch_locked(bs->new_db, talloc_tos(), orig_rec->key); - if (new_rec == NULL) { + if (tdb_store(tmp_tdb, orig_rec->key, orig_rec->value, TDB_INSERT) != 0) { bs->success = false; - return 1; + return 1; } - status = new_rec->store(new_rec, orig_rec->value, TDB_INSERT); + status = orig_rec->delete_rec(orig_rec); + if (!NT_STATUS_IS_OK(status)) { + bs->success = false; + return 1; + } - TALLOC_FREE(new_rec); + return 0; +} +static int copy_back_fn(TDB_CONTEXT *tmp_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + struct tdbsam_backup_state *bs = (struct tdbsam_backup_state *)state; + struct db_context *db = (struct db_context *)bs->db_ptr; + struct db_record *new_rec = NULL; + NTSTATUS status; + + new_rec = db->fetch_locked(db, talloc_tos(), key); + if (new_rec == NULL) { + bs->success = false; + return 1; + } + status = new_rec->store(new_rec, dbuf, TDB_INSERT); if (!NT_STATUS_IS_OK(status)) { bs->success = false; + TALLOC_FREE(new_rec); return 1; - } + } + + TALLOC_FREE(new_rec); return 0; } @@ -812,12 +832,11 @@ static int backup_copy_fn(struct db_record *orig_rec, void *state) existing records to replace in the tdbsam_convert_one() function. JRA. *********************************************************************/ -static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db) +static bool tdbsam_convert_backup(const char *dbname, struct db_context *db) { TALLOC_CTX *frame = talloc_stackframe(); const char *tmp_fname = NULL; - struct db_context *tmp_db = NULL; - struct db_context *orig_db = *pp_db; + struct tdb_context *tmp_tdb = NULL; struct tdbsam_backup_state bs; int ret; @@ -832,35 +851,49 @@ static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db) /* Remember to open this on the NULL context. We need * it to stay around after we return from here. */ - tmp_db = db_open_trans(NULL, tmp_fname, 0, - TDB_DEFAULT, O_CREAT|O_RDWR, 0600); - if (tmp_db == NULL) { + tmp_tdb = tdb_open(tmp_fname, 0, TDB_DEFAULT, O_CREAT|O_RDWR, 0600); + if (tmp_tdb == NULL) { DEBUG(0, ("tdbsam_convert_backup: Failed to create backup TDB passwd " "[%s]\n", tmp_fname)); TALLOC_FREE(frame); return false; } - if (orig_db->transaction_start(orig_db) != 0) { + if (db->transaction_start(db) != 0) { DEBUG(0, ("tdbsam_convert_backup: Could not start transaction (1)\n")); unlink(tmp_fname); - TALLOC_FREE(tmp_db); + tdb_close(tmp_tdb); TALLOC_FREE(frame); return false; } - if (tmp_db->transaction_start(tmp_db) != 0) { + if (tdb_transaction_start(tmp_tdb) != 0) { DEBUG(0, ("tdbsam_convert_backup: Could not start transaction (2)\n")); - orig_db->transaction_cancel(orig_db); + db->transaction_cancel(db); unlink(tmp_fname); - TALLOC_FREE(tmp_db); + tdb_close(tmp_tdb); TALLOC_FREE(frame); return false; } - bs.new_db = tmp_db; + bs.db_ptr = (void *)tmp_tdb; bs.success = true; - ret = orig_db->traverse(orig_db, backup_copy_fn, (void *)&bs); + /* First copy the records into the tmp_tdb, deleting as we go. */ + ret = db->traverse(db, backup_copy_delete_fn, (void *)&bs); + if (ret < 0) { + DEBUG(0, ("tdbsam_convert_backup: traverse failed\n")); + goto cancel; + } + + if (!bs.success) { + DEBUG(0, ("tdbsam_convert_backup: Copy and delete records failed\n")); + goto cancel; + } + + /* Now traverse the backup tdb and copy back the records. */ + bs.db_ptr = (void *)db; + bs.success = true; + ret = tdb_traverse(tmp_tdb, copy_back_fn, (void *)&bs); if (ret < 0) { DEBUG(0, ("tdbsam_convert_backup: traverse failed\n")); goto cancel; @@ -871,62 +904,57 @@ static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db) goto cancel; } - if (orig_db->transaction_commit(orig_db) != 0) { + + if (db->transaction_commit(db) != 0) { smb_panic("tdbsam_convert_backup: orig commit failed\n"); } - if (tmp_db->transaction_commit(tmp_db) != 0) { + if (tdb_transaction_commit(tmp_tdb) != 0) { smb_panic("tdbsam_convert_backup: orig commit failed\n"); } /* This is safe from other users as we know we're * under a mutex here. */ - if (rename(tmp_fname, dbname) == -1) { - DEBUG(0, ("tdbsam_convert_backup: rename of %s to %s failed %s\n", + if (unlink(tmp_fname) == -1) { + DEBUG(0, ("tdbsam_convert_backup: unlink of %s failed %s\n", tmp_fname, - dbname, strerror(errno))); - smb_panic("tdbsam_convert_backup: replace passdb failed\n"); } + tdb_close(tmp_tdb); TALLOC_FREE(frame); - TALLOC_FREE(orig_db); DEBUG(1, ("tdbsam_convert_backup: updated %s file.\n", dbname )); - /* Replace the global db pointer. */ - *pp_db = tmp_db; return true; cancel: - if (orig_db->transaction_cancel(orig_db) != 0) { + if (db->transaction_cancel(db) != 0) { smb_panic("tdbsam_convert: transaction_cancel failed"); } - if (tmp_db->transaction_cancel(tmp_db) != 0) { - smb_panic("tdbsam_convert: transaction_cancel failed"); + if (tdb_transaction_cancel(tmp_tdb) != 0) { + smb_panic("tdbsam_convert: transaction_cancel [2] failed"); } unlink(tmp_fname); - TALLOC_FREE(tmp_db); + tdb_close(tmp_tdb); TALLOC_FREE(frame); return false; } -static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32 from) +static bool tdbsam_convert(struct db_context *db, const char *name, int32 from) { struct tdbsam_convert_state state; - struct db_context *db = NULL; int ret; - if (!tdbsam_convert_backup(name, pp_db)) { + if (!tdbsam_convert_backup(name, db)) { DEBUG(0, ("tdbsam_convert: Could not backup %s\n", name)); return false; } - db = *pp_db; state.from = from; state.success = true; @@ -1043,7 +1071,7 @@ static bool tdbsam_open( const char *name ) DEBUG(1, ("tdbsam_open: Converting version %d database to " "version %d.\n", version, TDBSAM_VERSION)); - if ( !tdbsam_convert(&db_sam, name, version) ) { + if ( !tdbsam_convert(db_sam, name, version) ) { DEBUG(0, ("tdbsam_open: Error when trying to convert " "tdbsam [%s]\n",name)); TALLOC_FREE(db_sam); diff --git a/source/printing/notify.c b/source/printing/notify.c index 23df17c..70a72f1 100644 --- a/source/printing/notify.c +++ b/source/printing/notify.c @@ -368,9 +368,10 @@ static void send_notify_field_buffer(const char *sharename, uint32 type, void notify_printer_status_byname(const char *sharename, uint32 status) { /* Printer status stored in value1 */ + int snum = print_queue_snum(sharename); send_notify_field_values(sharename, PRINTER_NOTIFY_TYPE, - PRINTER_NOTIFY_STATUS, 0, + PRINTER_NOTIFY_STATUS, snum, status, 0, 0); }