mirror of
https://github.com/samba-team/samba.git
synced 2024-12-28 07:21:54 +03:00
This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.
This commit is contained in:
commit
9653595609
215
source/libsmb/trustdom_cache.c
Normal file
215
source/libsmb/trustdom_cache.c
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
Trusted domain names cache on top of gencache.
|
||||
|
||||
Copyright (C) Rafal Szczesniak 2002
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#undef DBGC_CLASS
|
||||
#define DBGC_CLASS DBGC_ALL /* there's no proper class yet */
|
||||
|
||||
#define TDOMKEY_FMT "TDOM/%s"
|
||||
|
||||
|
||||
/**
|
||||
* @file trustdom_cache.c
|
||||
*
|
||||
* Implementation of trusted domain names cache useful when
|
||||
* samba acts as domain member server. In such case, caching
|
||||
* domain names currently trusted gives a performance gain
|
||||
* because there's no need to query PDC each time we need
|
||||
* list of trusted domains
|
||||
**/
|
||||
|
||||
|
||||
/**
|
||||
* Initialise trustdom name caching system. Call gencache
|
||||
* initialisation routine to perform necessary activities.
|
||||
*
|
||||
* @return true upon successful cache initialisation or
|
||||
* false if cache init failed
|
||||
**/
|
||||
|
||||
BOOL trustdom_cache_enable(void)
|
||||
{
|
||||
/* Init trustdom cache by calling gencache initialisation */
|
||||
if (!gencache_init()) {
|
||||
DEBUG(2, ("trustdomcache_enable: Couldn't initialise trustdom cache on top of gencache.\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shutdown trustdom name caching system. Calls gencache
|
||||
* shutdown function.
|
||||
*
|
||||
* @return true upon successful cache close or
|
||||
* false if it failed
|
||||
**/
|
||||
|
||||
BOOL trustdom_cache_shutdown(void)
|
||||
{
|
||||
/* Close trustdom cache by calling gencache shutdown */
|
||||
if (!gencache_shutdown()) {
|
||||
DEBUG(2, ("trustdomcache_shutdown: Couldn't shutdown trustdom cache on top of gencache.\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Form up trustdom name key. It is based only
|
||||
* on domain name now.
|
||||
*
|
||||
* @param name trusted domain name
|
||||
* @return cache key for use in gencache mechanism
|
||||
**/
|
||||
|
||||
static char* trustdom_cache_key(const char* name)
|
||||
{
|
||||
char* keystr;
|
||||
asprintf(&keystr, TDOMKEY_FMT, strupper_static(name));
|
||||
|
||||
return keystr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Store trusted domain in gencache as the domain name (key)
|
||||
* and ip address of domain controller (value)
|
||||
*
|
||||
* @param name trusted domain name
|
||||
* @param alt_name alternative trusted domain name (used in ADS domains)
|
||||
* @param sid trusted domain's SID
|
||||
* @param timeout cache entry expiration time
|
||||
* @return true upon successful value storing or
|
||||
* false if store attempt failed
|
||||
**/
|
||||
|
||||
BOOL trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid,
|
||||
time_t timeout)
|
||||
{
|
||||
char *key, *alt_key;
|
||||
fstring sid_string;
|
||||
|
||||
/*
|
||||
* we use gecache call to avoid annoying debug messages
|
||||
* about initialised trustdom
|
||||
*/
|
||||
if (!gencache_init()) return False;
|
||||
|
||||
DEBUG(5, ("trustdom_store: storing SID %s of domain %s\n",
|
||||
sid_string_static(sid), name));
|
||||
|
||||
key = trustdom_cache_key(name);
|
||||
alt_key = alt_name ? trustdom_cache_key(alt_name) : NULL;
|
||||
|
||||
/* Generate string representation domain SID */
|
||||
sid_to_string(sid_string, sid);
|
||||
|
||||
/*
|
||||
* try to put the names in the cache
|
||||
*/
|
||||
if (alt_key) {
|
||||
return (gencache_set(alt_key, sid_string, timeout)
|
||||
&& gencache_set(key, sid_string, timeout));
|
||||
}
|
||||
|
||||
return gencache_set(key, sid_string, timeout);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetch trusted domain's dc from the gencache.
|
||||
* This routine can also be used to check whether given
|
||||
* domain is currently trusted one.
|
||||
*
|
||||
* @param name trusted domain name
|
||||
* @param sid trusted domain's SID to be returned
|
||||
* @return true if entry is found or
|
||||
* false if has expired/doesn't exist
|
||||
**/
|
||||
|
||||
BOOL trustdom_cache_fetch(const char* name, DOM_SID* sid)
|
||||
{
|
||||
char *key, *value;
|
||||
time_t timeout;
|
||||
|
||||
/* init the cache */
|
||||
if (!gencache_init()) return False;
|
||||
|
||||
/* exit now if null pointers were passed as they're required further */
|
||||
if (!sid) return False;
|
||||
|
||||
/* prepare a key and get the value */
|
||||
key = trustdom_cache_key(name);
|
||||
|
||||
if (!gencache_get(key, &value, &timeout)) {
|
||||
DEBUG(5, ("no entry for trusted domain %s found.\n", name));
|
||||
return False;
|
||||
} else {
|
||||
DEBUG(5, ("trusted domain %s found (%s)\n", name, value));
|
||||
}
|
||||
|
||||
/* convert ip string representation into in_addr structure */
|
||||
if(! string_to_sid(sid, value)) {
|
||||
sid = NULL;
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete single trustdom entry. Look at the
|
||||
* gencache_iterate definition.
|
||||
*
|
||||
**/
|
||||
|
||||
static void flush_trustdom_name(const char* key, const char *value, time_t timeout, void* dptr)
|
||||
{
|
||||
gencache_del(key);
|
||||
DEBUG(5, ("Deleting entry %s\n", key));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Flush all the trusted domains entries from the cache.
|
||||
**/
|
||||
|
||||
void trustdom_cache_flush(void)
|
||||
{
|
||||
if (!gencache_init())
|
||||
return;
|
||||
|
||||
/*
|
||||
* iterate through each TDOM cache's entry and flush it
|
||||
* by flush_trustdom_name function
|
||||
*/
|
||||
gencache_iterate(flush_trustdom_name, NULL, trustdom_cache_key("*"));
|
||||
DEBUG(5, ("Trusted domains cache flushed\n"));
|
||||
}
|
||||
|
204
source/printing/printing_db.c
Normal file
204
source/printing/printing_db.c
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 3.0
|
||||
printing backend routines
|
||||
Copyright (C) Andrew Tridgell 1992-2000
|
||||
Copyright (C) Jeremy Allison 2002
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "printing.h"
|
||||
|
||||
static struct tdb_print_db *print_db_head;
|
||||
|
||||
/****************************************************************************
|
||||
Function to find or create the printer specific job tdb given a printername.
|
||||
Limits the number of tdb's open to MAX_PRINT_DBS_OPEN.
|
||||
****************************************************************************/
|
||||
|
||||
struct tdb_print_db *get_print_db_byname(const char *printername)
|
||||
{
|
||||
struct tdb_print_db *p = NULL, *last_entry = NULL;
|
||||
int num_open = 0;
|
||||
pstring printdb_path;
|
||||
BOOL done_become_root = False;
|
||||
|
||||
for (p = print_db_head, last_entry = print_db_head; p; p = p->next) {
|
||||
/* Ensure the list terminates... JRA. */
|
||||
SMB_ASSERT(p->next != print_db_head);
|
||||
|
||||
if (p->tdb && strequal(p->printer_name, printername)) {
|
||||
DLIST_PROMOTE(print_db_head, p);
|
||||
p->ref_count++;
|
||||
return p;
|
||||
}
|
||||
num_open++;
|
||||
last_entry = p;
|
||||
}
|
||||
|
||||
/* Not found. */
|
||||
if (num_open >= MAX_PRINT_DBS_OPEN) {
|
||||
/* Try and recycle the last entry. */
|
||||
DLIST_PROMOTE(print_db_head, last_entry);
|
||||
|
||||
for (p = print_db_head; p; p = p->next) {
|
||||
if (p->ref_count)
|
||||
continue;
|
||||
if (p->tdb) {
|
||||
if (tdb_close(print_db_head->tdb)) {
|
||||
DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n",
|
||||
print_db_head->printer_name ));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
p->tdb = NULL;
|
||||
p->ref_count = 0;
|
||||
memset(p->printer_name, '\0', sizeof(p->printer_name));
|
||||
break;
|
||||
}
|
||||
if (p) {
|
||||
DLIST_PROMOTE(print_db_head, p);
|
||||
p = print_db_head;
|
||||
}
|
||||
}
|
||||
|
||||
if (!p) {
|
||||
/* Create one. */
|
||||
p = (struct tdb_print_db *)malloc(sizeof(struct tdb_print_db));
|
||||
if (!p) {
|
||||
DEBUG(0,("get_print_db: malloc fail !\n"));
|
||||
return NULL;
|
||||
}
|
||||
ZERO_STRUCTP(p);
|
||||
DLIST_ADD(print_db_head, p);
|
||||
}
|
||||
|
||||
pstrcpy(printdb_path, lock_path("printing/"));
|
||||
pstrcat(printdb_path, printername);
|
||||
pstrcat(printdb_path, ".tdb");
|
||||
|
||||
if (geteuid() != 0) {
|
||||
become_root();
|
||||
done_become_root = True;
|
||||
}
|
||||
|
||||
p->tdb = tdb_open_log(printdb_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
|
||||
|
||||
if (done_become_root)
|
||||
unbecome_root();
|
||||
|
||||
if (!p->tdb) {
|
||||
DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n",
|
||||
printdb_path ));
|
||||
DLIST_REMOVE(print_db_head, p);
|
||||
SAFE_FREE(p);
|
||||
return NULL;
|
||||
}
|
||||
fstrcpy(p->printer_name, printername);
|
||||
p->ref_count++;
|
||||
return p;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
Remove a reference count.
|
||||
****************************************************************************/
|
||||
|
||||
void release_print_db( struct tdb_print_db *pdb)
|
||||
{
|
||||
pdb->ref_count--;
|
||||
SMB_ASSERT(pdb->ref_count >= 0);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
Close all open print db entries.
|
||||
****************************************************************************/
|
||||
|
||||
void close_all_print_db(void)
|
||||
{
|
||||
struct tdb_print_db *p = NULL, *next_p = NULL;
|
||||
|
||||
for (p = print_db_head; p; p = next_p) {
|
||||
next_p = p->next;
|
||||
|
||||
if (p->tdb)
|
||||
tdb_close(p->tdb);
|
||||
DLIST_REMOVE(print_db_head, p);
|
||||
ZERO_STRUCTP(p);
|
||||
SAFE_FREE(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Fetch and clean the pid_t record list for all pids interested in notify
|
||||
messages. data needs freeing on exit.
|
||||
****************************************************************************/
|
||||
|
||||
TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT *tdb, const char *printer_name, BOOL cleanlist)
|
||||
{
|
||||
TDB_DATA data;
|
||||
size_t i;
|
||||
|
||||
ZERO_STRUCT(data);
|
||||
|
||||
data = tdb_fetch_by_string( tdb, NOTIFY_PID_LIST_KEY );
|
||||
|
||||
if (!data.dptr) {
|
||||
ZERO_STRUCT(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
if (data.dsize % 8) {
|
||||
DEBUG(0,("get_printer_notify_pid_list: Size of record for printer %s not a multiple of 8 !\n", printer_name ));
|
||||
tdb_delete_by_string(tdb, NOTIFY_PID_LIST_KEY );
|
||||
SAFE_FREE(data.dptr);
|
||||
ZERO_STRUCT(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
if (!cleanlist)
|
||||
return data;
|
||||
|
||||
/*
|
||||
* Weed out all dead entries.
|
||||
*/
|
||||
|
||||
for( i = 0; i < data.dsize; i += 8) {
|
||||
pid_t pid = (pid_t)IVAL(data.dptr, i);
|
||||
|
||||
if (pid == sys_getpid())
|
||||
continue;
|
||||
|
||||
/* Entry is dead if process doesn't exist or refcount is zero. */
|
||||
|
||||
while ((i < data.dsize) && ((IVAL(data.dptr, i + 4) == 0) || !process_exists(pid))) {
|
||||
|
||||
/* Refcount == zero is a logic error and should never happen. */
|
||||
if (IVAL(data.dptr, i + 4) == 0) {
|
||||
DEBUG(0,("get_printer_notify_pid_list: Refcount == 0 for pid = %u printer %s !\n",
|
||||
(unsigned int)pid, printer_name ));
|
||||
}
|
||||
|
||||
if (data.dsize - i > 8)
|
||||
memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
|
||||
data.dsize -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user