Only in samba-3.0.9/source: build-samba Only in samba-3.0.9/source/include: build_env.h Only in samba-3.0.9/source/include: stamp-h diff -ruBb --exclude-from=../../../samba-cvs/diff.excludes samba-3.0.9-orig/source/param/loadparm.c samba-3.0.9/source/param/loadparm.c --- samba-3.0.9-orig/source/param/loadparm.c 2004-11-15 21:03:16.000000000 -0600 +++ samba-3.0.9/source/param/loadparm.c 2004-12-07 18:09:53.773049300 -0600 @@ -1375,7 +1375,7 @@ /* Discovered by 2 days of pain by Don McCall @ HP :-). */ Globals.max_xmit = 0x4104; Globals.max_mux = 50; /* This is *needed* for profile support. */ - Globals.lpqcachetime = 10; + Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */ Globals.bDisableSpoolss = False; Globals.iMaxSmbdProcesses = 0;/* no limit specified */ Globals.pwordlevel = 0; diff -ruBb --exclude-from=../../../samba-cvs/diff.excludes samba-3.0.9-orig/source/printing/printing.c samba-3.0.9/source/printing/printing.c --- samba-3.0.9-orig/source/printing/printing.c 2004-11-15 21:03:15.000000000 -0600 +++ samba-3.0.9/source/printing/printing.c 2004-12-07 19:11:28.550472369 -0600 @@ -43,10 +43,12 @@ jobids are assigned when a job starts spooling. */ -/*************************************************************************** - Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32 - bit RPC jobids.... JRA. -***************************************************************************/ +struct print_queue_update_context { + char* sharename; + enum printing_types printing_type; + char* lpqcommand; +}; + static TDB_CONTEXT *rap_tdb; static uint16 next_rap_jobid; @@ -55,6 +57,11 @@ uint32 jobid; }; +/*************************************************************************** + Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32 + bit RPC jobids.... JRA. +***************************************************************************/ + uint16 pjobid_to_rap(const char* sharename, uint32 jobid) { uint16 rap_jobid; @@ -837,7 +844,7 @@ in the tdb. ****************************************************************************/ -static void set_updating_pid(const fstring sharename, BOOL delete) +static void set_updating_pid(const fstring sharename, BOOL updating) { fstring keystr; TDB_DATA key; @@ -854,7 +861,11 @@ key.dptr = keystr; key.dsize = strlen(keystr); - if (delete) { + DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n", + updating ? "" : "not ", + sharename )); + + if ( !updating ) { tdb_delete(pdb->tdb, key); release_print_db(pdb); return; @@ -978,11 +989,69 @@ } } -struct print_queue_update_context { - fstring sharename; - enum printing_types printing_type; - pstring lpqcommand; -}; +/**************************************************************************** + Check if the print queue has been updated recently enough. +****************************************************************************/ + +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; + + if (!pdb) + return False; + + snprintf(key, sizeof(key), "CACHE/%s", sharename); + last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key); + + /* + * Invalidate the queue for 3 reasons. + * (1). last queue scan time == -1. + * (2). Current time - last queue scan time > allowed cache time. + * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default). + * This last test picks up machines for which the clock has been moved + * forward, an lpq scan done and then the clock moved back. Otherwise + * that last lpq scan would stay around for a loooong loooong time... :-). JRA. + */ + + if (last_qscan_time == ((time_t)-1) + || (time_now - last_qscan_time) >= lp_lpqcachetime() + || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) + { + time_t msg_pending_time; + + DEBUG(4, ("print_cache_expired: cache expired for queue %s " + "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", + sharename, (int)last_qscan_time, (int)time_now, + (int)lp_lpqcachetime() )); + + /* check if another smbd has already sent a message to update the + queue. Give the pending message one minute to clear and + 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 ( check_pending + && tdb_fetch_uint32( pdb->tdb, key, (uint32*)&msg_pending_time ) + && 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)); + goto done; + } + + result = True; + } + +done: + release_print_db(pdb); + return result; +} /**************************************************************************** main work for updating the lpq cahe for a printer queue @@ -1003,6 +1072,14 @@ fstring keystr, cachestr; struct tdb_print_db *pdb = get_print_db_byname(sharename); + DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n", + sharename, current_printif->type, lpq_command)); + + if ( !print_cache_expired(sharename, False) ) { + DEBUG(5,("print_queue_update_internal: print cache for %s is still ok\n", sharename)); + return; + } + /* * Update the cache time FIRST ! Stops others even * attempting to get the lock and doing this @@ -1019,8 +1096,8 @@ current_printif->type, lpq_command, &queue, &status); - DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ? - "s" : "", sharename)); + DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n", + qcount, (qcount != 1) ? "s" : "", sharename)); /* Sort the queue by submission time otherwise they are displayed in hash order. */ @@ -1084,14 +1161,14 @@ SAFE_FREE(tstruct.queue); - DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n", + DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n", sharename, tstruct.total_jobs )); tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs); get_queue_status(sharename, &old_status); if (old_status.qcount != qcount) - DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n", + DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n", old_status.qcount, qcount, sharename)); /* store the new queue status structure */ @@ -1112,6 +1189,20 @@ slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename); tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL)); + /* clear the msg pending record for this queue */ + + snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename); + + if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) { + /* log a message but continue on */ + + DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n", + sharename)); + } + + release_print_db( pdb ); + + return; } /**************************************************************************** @@ -1128,6 +1219,8 @@ struct printif *current_printif = get_printer_fns( snum ); fstrcpy(sharename, lp_const_servicename(snum)); + + DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename)); pdb = get_print_db_byname(sharename); if (!pdb) return; @@ -1147,7 +1240,7 @@ slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename); /* Only wait 10 seconds for this. */ if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) { - DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", sharename)); + DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename)); release_print_db(pdb); return; } @@ -1172,7 +1265,7 @@ */ /* Tell others we're doing the update. */ - set_updating_pid(sharename, False); + set_updating_pid(sharename, True); /* * Allow others to enter and notice we're doing @@ -1192,26 +1285,38 @@ print_queue_update_internal( sharename, current_printif, lpq_command ); /* Delete our pid from the db. */ - set_updating_pid(sharename, True); + set_updating_pid(sharename, False); release_print_db(pdb); } /**************************************************************************** this is the receive function of the background lpq updater ****************************************************************************/ -static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len) +static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msglen) { - struct print_queue_update_context *ctx; + struct print_queue_update_context ctx; + fstring sharename; + pstring lpqcommand; + size_t len; - if (len != sizeof(struct print_queue_update_context)) { - DEBUG(1, ("Got invalid print queue update message\n")); + len = tdb_unpack( buf, msglen, "fdP", + sharename, + &ctx.printing_type, + lpqcommand ); + + if ( len == -1 ) { + DEBUG(0,("print_queue_receive: Got invalid print queue update message\n")); return; } - ctx = (struct print_queue_update_context*)buf; - print_queue_update_internal(ctx->sharename, - get_printer_fns_from_type(ctx->printing_type), - ctx->lpqcommand ); + ctx.sharename = sharename; + ctx.lpqcommand = lpqcommand; + + print_queue_update_internal(ctx.sharename, + get_printer_fns_from_type(ctx.printing_type), + ctx.lpqcommand ); + + return; } static pid_t background_lpq_updater_pid = -1; @@ -1277,27 +1382,84 @@ static void print_queue_update(int snum) { struct print_queue_update_context ctx; + fstring key; + fstring sharename; + pstring lpqcommand; + char *buffer = NULL; + size_t len = 0; + size_t newlen; + struct tdb_print_db *pdb; /* * Make sure that the background queue process exists. * Otherwise just do the update ourselves */ - if ( background_lpq_updater_pid != -1 ) { - fstrcpy(ctx.sharename, lp_const_servicename(snum)); + if ( background_lpq_updater_pid == -1 ) { + print_queue_update_with_lock( snum ); + return; + } + + fstrcpy( sharename, lp_const_servicename(snum)); + ctx.printing_type = lp_printing(snum); - pstrcpy(ctx.lpqcommand, lp_lpqcommand(snum)); - pstring_sub( ctx.lpqcommand, "%p", PRINTERNAME(snum) ); - standard_sub_snum( snum, ctx.lpqcommand, sizeof(ctx.lpqcommand) ); + pstrcpy( lpqcommand, lp_lpqcommand(snum)); + pstring_sub( lpqcommand, "%p", PRINTERNAME(snum) ); + standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) ); + + ctx.sharename = smb_xstrdup( sharename ); + ctx.lpqcommand = smb_xstrdup( lpqcommand ); + + /* get the length */ + + len = tdb_pack( buffer, len, "fdP", + ctx.sharename, + ctx.printing_type, + ctx.lpqcommand ); + + buffer = smb_xmalloc( sizeof(char)*len ); + + /* now pack the buffer */ + newlen = tdb_pack( buffer, len, "fdP", + ctx.sharename, + ctx.printing_type, + ctx.lpqcommand ); + + SMB_ASSERT( newlen == len ); + + DEBUG(10,("print_queue_update: Sending message -> printer = %s, " + "type = %d, lpq command = [%s]\n", + ctx.sharename, ctx.printing_type, ctx.lpqcommand )); + + /* here we set a msg pending record for other smbd processes + to throttle the number of duplicate print_queue_update msgs + sent. */ + + pdb = get_print_db_byname(sharename); + snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename); + + if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) { + /* log a message but continue on */ + + DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n", + sharename)); + } + + release_print_db( pdb ); + + /* finally send the message */ become_root(); message_send_pid(background_lpq_updater_pid, - MSG_PRINTER_UPDATE, &ctx, sizeof(ctx), - False); + MSG_PRINTER_UPDATE, buffer, len, False); unbecome_root(); - } else - print_queue_update_with_lock( snum ); + + SAFE_FREE( ctx.sharename ); + SAFE_FREE( ctx.lpqcommand ); + SAFE_FREE( buffer ); + + return; } /**************************************************************************** @@ -1897,45 +2059,6 @@ } /**************************************************************************** - Check if the print queue has been updated recently enough. -****************************************************************************/ - -static BOOL print_cache_expired(int snum) -{ - fstring key; - time_t last_qscan_time, time_now = time(NULL); - const char *printername = lp_const_servicename(snum); - struct tdb_print_db *pdb = get_print_db_byname(printername); - - if (!pdb) - return False; - - slprintf(key, sizeof(key), "CACHE/%s", printername); - last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key); - - /* - * Invalidate the queue for 3 reasons. - * (1). last queue scan time == -1. - * (2). Current time - last queue scan time > allowed cache time. - * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default). - * This last test picks up machines for which the clock has been moved - * forward, an lpq scan done and then the clock moved back. Otherwise - * that last lpq scan would stay around for a loooong loooong time... :-). JRA. - */ - - if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() || - last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) { - DEBUG(3, ("print cache expired for queue %s \ -(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername, - (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() )); - release_print_db(pdb); - return True; - } - release_print_db(pdb); - return False; -} - -/**************************************************************************** Get the queue status - do not update if db is out of date. ****************************************************************************/ @@ -1979,7 +2102,7 @@ int len; /* make sure the database is up to date */ - if (print_cache_expired(snum)) + if (print_cache_expired(lp_const_servicename(snum), True)) print_queue_update(snum); /* also fetch the queue status */ @@ -2294,7 +2417,7 @@ pjob_store(sharename, jobid, pjob); /* make sure the database is up to date */ - if (print_cache_expired(snum)) + if (print_cache_expired(lp_const_servicename(snum), True)) print_queue_update(snum); return True; @@ -2326,7 +2449,7 @@ const char* sharename = lp_servicename(snum); /* make sure the database is up to date */ - if (print_cache_expired(snum)) + if (print_cache_expired(lp_const_servicename(snum), True)) print_queue_update(snum); *pcount = 0; @@ -2447,7 +2570,7 @@ /* make sure the database is up to date */ - if (print_cache_expired(snum)) + if (print_cache_expired(lp_const_servicename(snum), True)) print_queue_update(snum); /* return if we are done */ @@ -2547,7 +2670,7 @@ } /* make sure the database is up to date */ - if (print_cache_expired(snum)) + if (print_cache_expired(lp_const_servicename(snum), True)) print_queue_update(snum); /* Send a printer notify message */ Only in samba-3.0.9/source/script: gen-8bit-gap.sh Only in samba-3.0.9/source: smbadduser diff -ruBb --exclude-from=../../../samba-cvs/diff.excludes samba-3.0.9-orig/source/smbd/lanman.c samba-3.0.9/source/smbd/lanman.c --- samba-3.0.9-orig/source/smbd/lanman.c 2004-11-15 21:03:14.000000000 -0600 +++ samba-3.0.9/source/smbd/lanman.c 2004-12-07 18:45:38.677852265 -0600 @@ -760,17 +760,9 @@ return(True); } - snum = lp_servicenumber(QueueName); - if (snum < 0 && pcap_printername_ok(QueueName,NULL)) { - int pnum = lp_servicenumber(PRINTERS_NAME); - if (pnum >= 0) { - lp_add_printer(QueueName,pnum); - snum = lp_servicenumber(QueueName); - } - } - - if (snum < 0 || !VALID_SNUM(snum)) - return(False); + snum = find_service(QueueName); + if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) ) + return False; if (uLevel==52) { count = get_printerdrivernumber(snum); @@ -1502,6 +1494,8 @@ data_len = fixed_len = string_len = 0; for (i=0;i 2) return False; /* defined only for uLevel 0,1,2 */ - if (!check_printjob_info(&desc,uLevel,str2)) return False; + if (strcmp(str1,"zWrLeh") != 0) + return False; - snum = lp_servicenumber(name); - if (snum < 0 && pcap_printername_ok(name,NULL)) { - int pnum = lp_servicenumber(PRINTERS_NAME); - if (pnum >= 0) { - lp_add_printer(name,pnum); - snum = lp_servicenumber(name); - } - } + if (uLevel > 2) + return False; /* defined only for uLevel 0,1,2 */ - if (snum < 0 || !VALID_SNUM(snum)) return(False); + if (!check_printjob_info(&desc,uLevel,str2)) + return False; + + snum = find_service(name); + if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) ) + return False; count = print_queue_status(snum,&queue,&status); if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt); @@ -3154,16 +3155,8 @@ if (strcmp(str1,"zWrLh") != 0) return False; if (!check_printdest_info(&desc,uLevel,str2)) return False; - snum = lp_servicenumber(PrinterName); - if (snum < 0 && pcap_printername_ok(PrinterName,NULL)) { - int pnum = lp_servicenumber(PRINTERS_NAME); - if (pnum >= 0) { - lp_add_printer(PrinterName,pnum); - snum = lp_servicenumber(PrinterName); - } - } - - if (snum < 0) { + snum = find_service(PrinterName); + if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) ) { *rdata_len = 0; desc.errcode = NERR_DestNotFound; desc.neededlen = 0;