1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

Merge branch 'master' of ssh://git.samba.org/data/git/samba

This commit is contained in:
Jelmer Vernooij 2009-01-05 18:01:04 +01:00
commit 37e6849d45
37 changed files with 708 additions and 461 deletions

View File

@ -13,7 +13,7 @@
<refnamediv>
<refname>smbclient</refname>
<refpurpose>ftp-like client to access SMB/CIFS resources
<refpurpose>ftp-like client to access SMB/CIFS resources
on servers</refpurpose>
</refnamediv>
@ -30,6 +30,7 @@
<arg choice="opt">-m maxprotocol</arg>
<arg choice="opt">-A authfile</arg>
<arg choice="opt">-N</arg>
<arg choice="opt">-g</arg>
<arg choice="opt">-i scope</arg>
<arg choice="opt">-O &lt;socket options&gt;</arg>
<arg choice="opt">-p port</arg>
@ -39,7 +40,7 @@
<arg choice="opt">-P</arg>
<arg choice="opt">-c &lt;command&gt;</arg>
</cmdsynopsis>
<cmdsynopsis>
<command>smbclient</command>
<arg choice="req">servicename</arg>
@ -54,6 +55,7 @@
<arg choice="opt">-m maxprotocol</arg>
<arg choice="opt">-A authfile</arg>
<arg choice="opt">-N</arg>
<arg choice="opt">-g</arg>
<arg choice="opt">-l log-basename</arg>
<arg choice="opt">-I destinationIP</arg>
<arg choice="opt">-E</arg>
@ -233,7 +235,7 @@
on your WfWg PCs if you want them to always be able to receive
messages. </para></listitem>
</varlistentry>
<varlistentry>
<term>-p port</term>
<listitem><para>This number is the TCP port number that will be used
@ -241,19 +243,27 @@
TCP port number for an SMB/CIFS server is 139, which is the
default. </para></listitem>
</varlistentry>
<varlistentry>
<term>-g</term>
<listitem><para>This parameter provides combined with
<parameter>-L</parameter> easy parseable output that allows processing
with utilities such as grep and cut.
</para></listitem>
</varlistentry>
<varlistentry>
<term>-P</term>
<listitem><para>
Make queries to the external server using the machine account of the local server.
</para></listitem>
</varlistentry>
&stdarg.help;
<varlistentry>
<term>-I IP-address</term>
<listitem><para><replaceable>IP address</replaceable> is the address of the server to connect to.
<listitem><para><replaceable>IP address</replaceable> is the address of the server to connect to.
It should be specified in standard "a.b.c.d" notation. </para>
<para>Normally the client would attempt to locate a named

View File

@ -21,17 +21,17 @@
PATH=/bin:/usr/bin:/sbin:/usr/sbin
killproc()
killproc()
{
pid=`ps aux | grep $1 | egrep -v '(grep|perfcountd)' | awk '{print $2}'`
if [ "$pid" != "" ]; then
if [ x"$pid" != "x" ]; then
kill $pid
fi
}
# Start/stop processes
# Start/stop processes
case "$1"
case "$1"
in
start)
/opt/samba/bin/perfcount -d -f /var/lib/samba/perfmon 2> /dev/null
@ -47,7 +47,7 @@ stop)
status)
pid=`ps aux | grep perfcount | egrep -v '(grep|perfcountd)' | awk '{print $2}'`
if [ "$pid" == "" ]; then
if [ x"$pid" = "x" ]; then
echo "Dead!"
exit 2;
fi

View File

@ -484,31 +484,4 @@ struct winbindd_response {
} extra_data;
};
struct WINBINDD_MEMORY_CREDS {
struct WINBINDD_MEMORY_CREDS *next, *prev;
const char *username; /* lookup key. */
uid_t uid;
int ref_count;
size_t len;
uint8_t *nt_hash; /* Base pointer for the following 2 */
uint8_t *lm_hash;
char *pass;
};
struct WINBINDD_CCACHE_ENTRY {
struct WINBINDD_CCACHE_ENTRY *next, *prev;
const char *principal_name;
const char *ccname;
const char *service;
const char *username;
const char *realm;
struct WINBINDD_MEMORY_CREDS *cred_ptr;
int ref_count;
uid_t uid;
time_t create_time;
time_t renew_until;
time_t refresh_time;
struct timed_event *event;
};
#endif

View File

@ -359,7 +359,8 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \
lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \
lib/iconv.o lib/pam_errors.o intl/lang_tdb.o lib/conn_tdb.o \
lib/adt_tree.o lib/gencache.o \
lib/module.o lib/events.o lib/ldap_escape.o @CHARSET_STATIC@ \
lib/module.o lib/events.o @LIBTEVENT_OBJ0@ \
lib/ldap_escape.o @CHARSET_STATIC@ \
lib/secdesc.o lib/util_seaccess.o lib/secace.o lib/secacl.o \
libads/krb5_errs.o lib/system_smbd.o lib/audit.o $(LIBNDR_OBJ) \
lib/file_id.o lib/idmap_cache.o

View File

@ -1353,6 +1353,11 @@ static int cmd_mget(void)
do_list(mget_mask, attribute, do_mget, false, true);
}
if (mget_mask == NULL) {
d_printf("nothing to mget\n");
return 0;
}
if (!*mget_mask) {
mget_mask = talloc_asprintf(ctx,
"%s*",

View File

@ -31,6 +31,15 @@ for obj in ${TALLOC_OBJ}; do
done
AC_SUBST(LIBTALLOC_OBJ0)
m4_include(../lib/tevent/libtevent.m4)
LIBTEVENT_OBJ0=""
for obj in ${TEVENT_OBJ}; do
LIBTEVENT_OBJ0="${LIBTEVENT_OBJ0} ${teventdir}/${obj}"
done
AC_SUBST(LIBTEVENT_OBJ0)
LIBS="${LIBS} ${TEVENT_LIBS}"
# TODO: These should come from m4_include(lib/tdb/libtdb.m4)
# but currently this fails: things have to get merged from s4.
tdbdir="../lib/tdb"
@ -50,6 +59,7 @@ AC_SUBST(LIBTDB_OBJ0)
SAMBA_CPPFLAGS="-Iinclude -I${srcdir-.}/include -I. -I${srcdir-.}"
SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/../lib/replace"
SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} ${TALLOC_CFLAGS}"
SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} ${TEVENT_CFLAGS}"
SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} ${TDB_CFLAGS}"
SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/libaddns"
SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/librpc"

View File

@ -18,7 +18,27 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* bits for file descriptor event flags */
#define EVENT_FD_READ 1
#define EVENT_FD_WRITE 2
#define TEVENT_COMPAT_DEFINES
#include <tevent.h>
#undef event_context_init
#define event_context_init(mem_ctx) s3_tevent_context_init(mem_ctx)
/* The following definitions come from lib/events.c */
void event_fd_set_writeable(struct fd_event *fde);
void event_fd_set_not_writeable(struct fd_event *fde);
void event_fd_set_readable(struct fd_event *fde);
void event_fd_set_not_readable(struct fd_event *fde);
bool event_add_to_select_args(struct event_context *event_ctx,
const struct timeval *now,
fd_set *read_fds, fd_set *write_fds,
struct timeval *timeout, int *maxfd);
bool run_events(struct event_context *event_ctx,
int selrtn, fd_set *read_fds, fd_set *write_fds);
struct timeval *get_timed_events_timeout(struct event_context *event_ctx,
struct timeval *to_ret);
void event_context_reinit(struct event_context *ev);
void dump_event_list(struct event_context *event_ctx);
struct tevent_context *s3_tevent_context_init(TALLOC_CTX *mem_ctx);

View File

@ -574,6 +574,8 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx);
#include "../talloc/talloc.h"
#include "event.h"
#include "../lib/util/data_blob.h"
#include "../lib/util/time.h"
#include "../lib/util/asn1.h"
@ -642,7 +644,6 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx);
#include "nsswitch/winbind_client.h"
#include "spnego.h"
#include "rpc_client.h"
#include "event.h"
#include "dbwrap.h"
#include "packet.h"
#include "ctdbd_conn.h"

View File

@ -501,46 +501,6 @@ void display_set_stderr(void);
NTSTATUS map_nt_error_from_unix(int unix_error);
int map_errno_from_nt_status(NTSTATUS status);
/* The following definitions come from lib/events.c */
struct timed_event *event_add_timed(struct event_context *event_ctx,
TALLOC_CTX *mem_ctx,
struct timeval when,
const char *event_name,
void (*handler)(struct event_context *event_ctx,
struct timed_event *te,
const struct timeval *now,
void *private_data),
void *private_data);
struct fd_event *event_add_fd(struct event_context *event_ctx,
TALLOC_CTX *mem_ctx,
int fd, uint16_t flags,
void (*handler)(struct event_context *event_ctx,
struct fd_event *event,
uint16 flags,
void *private_data),
void *private_data);
void event_fd_set_writeable(struct fd_event *fde);
void event_fd_set_not_writeable(struct fd_event *fde);
void event_fd_set_readable(struct fd_event *fde);
void event_fd_set_not_readable(struct fd_event *fde);
bool event_add_to_select_args(struct event_context *event_ctx,
const struct timeval *now,
fd_set *read_fds, fd_set *write_fds,
struct timeval *timeout, int *maxfd);
bool events_pending(struct event_context *event_ctx);
bool run_events(struct event_context *event_ctx,
int selrtn, fd_set *read_fds, fd_set *write_fds);
struct timeval *get_timed_events_timeout(struct event_context *event_ctx,
struct timeval *to_ret);
int event_loop_once(struct event_context *ev);
struct event_context *event_context_init(TALLOC_CTX *mem_ctx);
int set_event_dispatch_time(struct event_context *event_ctx,
const char *event_name, struct timeval when);
int cancel_named_event(struct event_context *event_ctx,
const char *event_name);
void dump_event_list(struct event_context *event_ctx);
/* The following definitions come from lib/fault.c */
void fault_setup(void (*fn)(void *));
void dump_core_setup(const char *progname);
@ -1183,6 +1143,7 @@ int set_blocking(int fd, bool set);
void smb_msleep(unsigned int t);
void become_daemon(bool Fork, bool no_process_group);
bool reinit_after_fork(struct messaging_context *msg_ctx,
struct event_context *ev_ctx,
bool parent_longlived);
bool yesno(const char *p);
void *malloc_(size_t size);

View File

@ -361,9 +361,6 @@ struct fd_handle {
unsigned long gen_id;
};
struct event_context;
struct fd_event;
struct timed_event;
struct idle_event;
struct share_mode_entry;
struct uuid;

View File

@ -103,12 +103,12 @@ void async_req_error(struct async_req *req, NTSTATUS status)
* @brief Timed event callback
* @param[in] ev Event context
* @param[in] te The timed event
* @param[in] now current time
* @param[in] now zero time
* @param[in] priv The async request to be finished
*/
static void async_trigger(struct event_context *ev, struct timed_event *te,
const struct timeval *now, void *priv)
struct timeval now, void *priv)
{
struct async_req *req = talloc_get_type_abort(priv, struct async_req);
@ -139,7 +139,7 @@ bool async_post_status(struct async_req *req, struct event_context *ev,
{
req->status = status;
if (event_add_timed(ev, req, timeval_zero(), "async_trigger",
if (event_add_timed(ev, req, timeval_zero(),
async_trigger, req) == NULL) {
return false;
}
@ -197,7 +197,7 @@ NTSTATUS async_req_simple_recv(struct async_req *req)
static void async_req_timedout(struct event_context *ev,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *priv)
{
struct async_req *req = talloc_get_type_abort(
@ -211,7 +211,7 @@ bool async_req_set_timeout(struct async_req *req, struct event_context *ev,
{
return (event_add_timed(ev, req,
timeval_current_ofs(to.tv_sec, to.tv_usec),
"async_req_timedout", async_req_timedout, req)
async_req_timedout, req)
!= NULL);
}
@ -268,7 +268,7 @@ static int async_queue_entry_destructor(struct async_queue_entry *e)
static void async_req_immediate_trigger(struct event_context *ev,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *priv)
{
struct async_queue_entry *e = talloc_get_type_abort(
@ -303,7 +303,6 @@ bool async_req_enqueue(struct async_req_queue *queue, struct event_context *ev,
struct timed_event *te;
te = event_add_timed(ev, e, timeval_zero(),
"async_req_immediate_trigger",
async_req_immediate_trigger,
e);
if (te == NULL) {

View File

@ -200,7 +200,7 @@ struct deferred_msg_state {
static void deferred_message_dispatch(struct event_context *event_ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data)
{
struct deferred_msg_state *state = talloc_get_type_abort(
@ -383,7 +383,6 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32 reqid,
evt = event_add_timed(conn->msg_ctx->event_ctx,
conn->msg_ctx->event_ctx,
timeval_zero(),
"deferred_message_dispatch",
deferred_message_dispatch,
msg_state);
if (evt == NULL) {

View File

@ -19,52 +19,19 @@
*/
#include "includes.h"
#include <tevent_internal.h>
struct timed_event {
struct timed_event *next, *prev;
struct event_context *event_ctx;
struct timeval when;
const char *event_name;
void (*handler)(struct event_context *event_ctx,
struct timed_event *te,
const struct timeval *now,
void *private_data);
void *private_data;
struct s3_event_context {
struct tevent_context *ev;
struct tevent_fd *fd_events;
};
struct fd_event {
struct fd_event *prev, *next;
struct event_context *event_ctx;
int fd;
uint16_t flags; /* see EVENT_FD_* flags */
void (*handler)(struct event_context *event_ctx,
struct fd_event *event,
uint16 flags,
void *private_data);
void *private_data;
};
#define EVENT_FD_WRITEABLE(fde) \
event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_WRITE)
#define EVENT_FD_READABLE(fde) \
event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_READ)
#define EVENT_FD_NOT_WRITEABLE(fde) \
event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_WRITE)
#define EVENT_FD_NOT_READABLE(fde) \
event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_READ)
struct event_context {
struct timed_event *timed_events;
struct fd_event *fd_events;
};
static int timed_event_destructor(struct timed_event *te)
static int s3_event_timer_destructor(struct tevent_timer *te)
{
DEBUG(10, ("Destroying timed event %lx \"%s\"\n", (unsigned long)te,
te->event_name));
DEBUG(10, ("Destroying timer event %p \"%s\"\n",
te, te->handler_name));
if (te->event_ctx != NULL) {
DLIST_REMOVE(te->event_ctx->timed_events, te);
DLIST_REMOVE(te->event_ctx->timer_events, te);
}
return 0;
}
@ -73,23 +40,23 @@ static int timed_event_destructor(struct timed_event *te)
Add te by time.
****************************************************************************/
static void add_event_by_time(struct timed_event *te)
static void add_event_by_time(struct tevent_timer *te)
{
struct event_context *ctx = te->event_ctx;
struct timed_event *last_te, *cur_te;
struct tevent_context *ctx = te->event_ctx;
struct tevent_timer *last_te, *cur_te;
/* Keep the list ordered by time. We must preserve this. */
last_te = NULL;
for (cur_te = ctx->timed_events; cur_te; cur_te = cur_te->next) {
for (cur_te = ctx->timer_events; cur_te; cur_te = cur_te->next) {
/* if the new event comes before the current one break */
if (!timeval_is_zero(&cur_te->when) &&
timeval_compare(&te->when, &cur_te->when) < 0) {
if (!timeval_is_zero(&cur_te->next_event) &&
timeval_compare(&te->next_event, &cur_te->next_event) < 0) {
break;
}
last_te = cur_te;
}
DLIST_ADD_AFTER(ctx->timed_events, te, last_te);
DLIST_ADD_AFTER(ctx->timer_events, te, last_te);
}
/****************************************************************************
@ -98,115 +65,128 @@ static void add_event_by_time(struct timed_event *te)
handed to it.
****************************************************************************/
struct timed_event *event_add_timed(struct event_context *event_ctx,
TALLOC_CTX *mem_ctx,
struct timeval when,
const char *event_name,
void (*handler)(struct event_context *event_ctx,
struct timed_event *te,
const struct timeval *now,
void *private_data),
void *private_data)
static struct tevent_timer *s3_event_add_timer(struct tevent_context *event_ctx,
TALLOC_CTX *mem_ctx,
struct timeval when,
tevent_timer_handler_t handler,
void *private_data,
const char *handler_name,
const char *location)
{
struct timed_event *te;
struct tevent_timer *te;
te = TALLOC_P(mem_ctx, struct timed_event);
te = TALLOC_P(mem_ctx, struct tevent_timer);
if (te == NULL) {
DEBUG(0, ("talloc failed\n"));
return NULL;
}
te->event_ctx = event_ctx;
te->when = when;
te->event_name = event_name;
te->next_event = when;
te->handler = handler;
te->private_data = private_data;
te->handler_name = handler_name;
te->location = location;
te->additional_data = NULL;
add_event_by_time(te);
talloc_set_destructor(te, timed_event_destructor);
talloc_set_destructor(te, s3_event_timer_destructor);
DEBUG(10, ("Added timed event \"%s\": %lx\n", event_name,
(unsigned long)te));
DEBUG(10, ("Added timed event \"%s\": %p\n", handler_name, te));
return te;
}
static int fd_event_destructor(struct fd_event *fde)
static int s3_event_fd_destructor(struct tevent_fd *fde)
{
if (fde->event_ctx != NULL) {
DLIST_REMOVE(fde->event_ctx->fd_events, fde);
struct s3_event_context *ev3;
ev3 = talloc_get_type(fde->event_ctx->additional_data,
struct s3_event_context);
DLIST_REMOVE(ev3->fd_events, fde);
}
if (fde->close_fn) {
fde->close_fn(fde->event_ctx, fde, fde->fd, fde->private_data);
fde->fd = -1;
}
return 0;
}
struct fd_event *event_add_fd(struct event_context *event_ctx,
TALLOC_CTX *mem_ctx,
int fd, uint16_t flags,
void (*handler)(struct event_context *event_ctx,
struct fd_event *event,
uint16 flags,
void *private_data),
void *private_data)
static struct tevent_fd *s3_event_add_fd(struct tevent_context *ev,
TALLOC_CTX *mem_ctx,
int fd,
uint16_t flags,
tevent_fd_handler_t handler,
void *private_data,
const char *handler_name,
const char *location)
{
struct fd_event *fde;
struct s3_event_context *ev3 = talloc_get_type(ev->additional_data,
struct s3_event_context);
struct tevent_fd *fde;
if (!(fde = TALLOC_P(mem_ctx, struct fd_event))) {
if (!(fde = TALLOC_P(mem_ctx, struct tevent_fd))) {
return NULL;
}
fde->event_ctx = event_ctx;
fde->event_ctx = ev;
fde->fd = fd;
fde->flags = flags;
fde->handler = handler;
fde->close_fn = NULL;
fde->private_data = private_data;
fde->handler_name = handler_name;
fde->location = location;
DLIST_ADD(event_ctx->fd_events, fde);
DLIST_ADD(ev3->fd_events, fde);
talloc_set_destructor(fde, fd_event_destructor);
talloc_set_destructor(fde, s3_event_fd_destructor);
return fde;
}
void event_fd_set_writeable(struct fd_event *fde)
void event_fd_set_writeable(struct tevent_fd *fde)
{
fde->flags |= EVENT_FD_WRITE;
TEVENT_FD_WRITEABLE(fde);
}
void event_fd_set_not_writeable(struct fd_event *fde)
void event_fd_set_not_writeable(struct tevent_fd *fde)
{
fde->flags &= ~EVENT_FD_WRITE;
TEVENT_FD_NOT_WRITEABLE(fde);
}
void event_fd_set_readable(struct fd_event *fde)
void event_fd_set_readable(struct tevent_fd *fde)
{
fde->flags |= EVENT_FD_READ;
TEVENT_FD_READABLE(fde);
}
void event_fd_set_not_readable(struct fd_event *fde)
void event_fd_set_not_readable(struct tevent_fd *fde)
{
fde->flags &= ~EVENT_FD_READ;
TEVENT_FD_NOT_READABLE(fde);
}
/*
* Return if there's something in the queue
*/
bool event_add_to_select_args(struct event_context *event_ctx,
bool event_add_to_select_args(struct tevent_context *ev,
const struct timeval *now,
fd_set *read_fds, fd_set *write_fds,
struct timeval *timeout, int *maxfd)
{
struct fd_event *fde;
struct s3_event_context *ev3 = talloc_get_type(ev->additional_data,
struct s3_event_context);
struct tevent_fd *fde;
struct timeval diff;
bool ret = False;
bool ret = false;
for (fde = event_ctx->fd_events; fde; fde = fde->next) {
for (fde = ev3->fd_events; fde; fde = fde->next) {
if (fde->flags & EVENT_FD_READ) {
FD_SET(fde->fd, read_fds);
ret = True;
ret = true;
}
if (fde->flags & EVENT_FD_WRITE) {
FD_SET(fde->fd, write_fds);
ret = True;
ret = true;
}
if ((fde->flags & (EVENT_FD_READ|EVENT_FD_WRITE))
@ -215,61 +195,48 @@ bool event_add_to_select_args(struct event_context *event_ctx,
}
}
if (event_ctx->timed_events == NULL) {
if (ev->timer_events == NULL) {
return ret;
}
diff = timeval_until(now, &event_ctx->timed_events->when);
diff = timeval_until(now, &ev->timer_events->next_event);
*timeout = timeval_min(timeout, &diff);
return True;
return true;
}
bool events_pending(struct event_context *event_ctx)
{
struct fd_event *fde;
if (event_ctx->timed_events != NULL) {
return True;
}
for (fde = event_ctx->fd_events; fde; fde = fde->next) {
if (fde->flags & (EVENT_FD_READ|EVENT_FD_WRITE)) {
return True;
}
}
return False;
}
bool run_events(struct event_context *event_ctx,
bool run_events(struct tevent_context *ev,
int selrtn, fd_set *read_fds, fd_set *write_fds)
{
bool fired = False;
struct fd_event *fde, *next;
struct s3_event_context *ev3 = talloc_get_type(ev->additional_data,
struct s3_event_context);
bool fired = false;
struct tevent_fd *fde, *next;
/* Run all events that are pending, not just one (as we
did previously. */
while (event_ctx->timed_events) {
while (ev->timer_events) {
struct timeval now;
GetTimeOfDay(&now);
if (timeval_compare(
&now, &event_ctx->timed_events->when) < 0) {
&now, &ev->timer_events->next_event) < 0) {
/* Nothing to do yet */
DEBUG(11, ("run_events: Nothing to do\n"));
break;
}
DEBUG(10, ("Running event \"%s\" %lx\n",
event_ctx->timed_events->event_name,
(unsigned long)event_ctx->timed_events));
DEBUG(10, ("Running event \"%s\" %p\n",
ev->timer_events->handler_name,
ev->timer_events));
event_ctx->timed_events->handler(
event_ctx,
event_ctx->timed_events, &now,
event_ctx->timed_events->private_data);
ev->timer_events->handler(
ev,
ev->timer_events, now,
ev->timer_events->private_data);
fired = True;
fired = true;
}
if (fired) {
@ -277,7 +244,7 @@ bool run_events(struct event_context *event_ctx,
* We might have changed the socket status during the timed
* events, return to run select again.
*/
return True;
return true;
}
if (selrtn == 0) {
@ -287,7 +254,7 @@ bool run_events(struct event_context *event_ctx,
return fired;
}
for (fde = event_ctx->fd_events; fde; fde = next) {
for (fde = ev3->fd_events; fde; fde = next) {
uint16 flags = 0;
next = fde->next;
@ -295,8 +262,8 @@ bool run_events(struct event_context *event_ctx,
if (FD_ISSET(fde->fd, write_fds)) flags |= EVENT_FD_WRITE;
if (flags & fde->flags) {
fde->handler(event_ctx, fde, flags, fde->private_data);
fired = True;
fde->handler(ev, fde, flags, fde->private_data);
fired = true;
}
}
@ -304,17 +271,17 @@ bool run_events(struct event_context *event_ctx,
}
struct timeval *get_timed_events_timeout(struct event_context *event_ctx,
struct timeval *get_timed_events_timeout(struct tevent_context *ev,
struct timeval *to_ret)
{
struct timeval now;
if (event_ctx->timed_events == NULL) {
if (ev->timer_events == NULL) {
return NULL;
}
now = timeval_current();
*to_ret = timeval_until(&now, &event_ctx->timed_events->when);
*to_ret = timeval_until(&now, &ev->timer_events->next_event);
DEBUG(10, ("timed_events_timeout: %d/%d\n", (int)to_ret->tv_sec,
(int)to_ret->tv_usec));
@ -322,7 +289,7 @@ struct timeval *get_timed_events_timeout(struct event_context *event_ctx,
return to_ret;
}
int event_loop_once(struct event_context *ev)
static int s3_event_loop_once(struct tevent_context *ev)
{
struct timeval now, to;
fd_set r_fds, w_fds;
@ -356,71 +323,60 @@ int event_loop_once(struct event_context *ev)
return 0;
}
static int event_context_destructor(struct event_context *ev)
static int s3_event_loop_wait(struct tevent_context *ev)
{
while (ev->fd_events != NULL) {
ev->fd_events->event_ctx = NULL;
DLIST_REMOVE(ev->fd_events, ev->fd_events);
int ret = 0;
while (ret == 0) {
ret = s3_event_loop_once(ev);
}
while (ev->timed_events != NULL) {
ev->timed_events->event_ctx = NULL;
DLIST_REMOVE(ev->timed_events, ev->timed_events);
return ret;
}
static int s3_event_context_destructor(struct tevent_context *ev)
{
struct s3_event_context *ev3 = talloc_get_type(ev->additional_data,
struct s3_event_context);
while (ev3->fd_events != NULL) {
ev3->fd_events->event_ctx = NULL;
DLIST_REMOVE(ev3->fd_events, ev3->fd_events);
}
while (ev->timer_events != NULL) {
ev->timer_events->event_ctx = NULL;
DLIST_REMOVE(ev->timer_events, ev3->ev->timer_events);
}
return 0;
}
struct event_context *event_context_init(TALLOC_CTX *mem_ctx)
void event_context_reinit(struct tevent_context *ev)
{
struct event_context *result;
result = TALLOC_ZERO_P(mem_ctx, struct event_context);
if (result == NULL) {
return NULL;
}
talloc_set_destructor(result, event_context_destructor);
return result;
s3_event_context_destructor(ev);
return;
}
int set_event_dispatch_time(struct event_context *event_ctx,
const char *event_name, struct timeval when)
static int s3_event_context_init(struct tevent_context *ev)
{
struct timed_event *te;
struct s3_event_context *ev3;
for (te = event_ctx->timed_events; te; te = te->next) {
if (strcmp(event_name, te->event_name) == 0) {
DLIST_REMOVE(event_ctx->timed_events, te);
te->when = when;
add_event_by_time(te);
return 1;
}
}
ev3 = talloc_zero(ev, struct s3_event_context);
if (!ev3) return -1;
ev3->ev = ev;
ev->additional_data = ev3;
talloc_set_destructor(ev, s3_event_context_destructor);
return 0;
}
/* Returns 1 if event was found and cancelled, 0 otherwise. */
int cancel_named_event(struct event_context *event_ctx,
const char *event_name)
void dump_event_list(struct tevent_context *ev)
{
struct timed_event *te;
for (te = event_ctx->timed_events; te; te = te->next) {
if (strcmp(event_name, te->event_name) == 0) {
TALLOC_FREE(te);
return 1;
}
}
return 0;
}
void dump_event_list(struct event_context *event_ctx)
{
struct timed_event *te;
struct fd_event *fe;
struct s3_event_context *ev3 = talloc_get_type(ev->additional_data,
struct s3_event_context);
struct tevent_timer *te;
struct tevent_fd *fe;
struct timeval evt, now;
if (!event_ctx) {
if (!ev) {
return;
}
@ -428,22 +384,50 @@ void dump_event_list(struct event_context *event_ctx)
DEBUG(10,("dump_event_list:\n"));
for (te = event_ctx->timed_events; te; te = te->next) {
for (te = ev->timer_events; te; te = te->next) {
evt = timeval_until(&now, &te->when);
evt = timeval_until(&now, &te->next_event);
DEBUGADD(10,("Timed Event \"%s\" %lx handled in %d seconds (at %s)\n",
te->event_name,
(unsigned long)te,
DEBUGADD(10,("Timed Event \"%s\" %p handled in %d seconds (at %s)\n",
te->handler_name,
te,
(int)evt.tv_sec,
http_timestring(talloc_tos(), te->when.tv_sec)));
http_timestring(talloc_tos(), te->next_event.tv_sec)));
}
for (fe = event_ctx->fd_events; fe; fe = fe->next) {
for (fe = ev3->fd_events; fe; fe = fe->next) {
DEBUGADD(10,("FD Event %d %lx, flags: 0x%04x\n",
DEBUGADD(10,("FD Event %d %p, flags: 0x%04x\n",
fe->fd,
(unsigned long)fe,
fe,
fe->flags));
}
}
static const struct tevent_ops s3_event_ops = {
.context_init = s3_event_context_init,
.add_fd = s3_event_add_fd,
.set_fd_close_fn= tevent_common_fd_set_close_fn,
.get_fd_flags = tevent_common_fd_get_flags,
.set_fd_flags = tevent_common_fd_set_flags,
.add_timer = s3_event_add_timer,
.loop_once = s3_event_loop_once,
.loop_wait = s3_event_loop_wait,
};
static bool s3_tevent_init(void)
{
static bool initialized;
if (initialized) {
return true;
}
initialized = tevent_register_backend("s3", &s3_event_ops);
tevent_set_default_backend("s3");
return initialized;
}
struct tevent_context *s3_tevent_context_init(TALLOC_CTX *mem_ctx)
{
s3_tevent_init();
return tevent_context_init_byname(mem_ctx, "s3");
}

View File

@ -1014,7 +1014,7 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_
static void smbldap_idle_fn(struct event_context *event_ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data);
/**********************************************************************
@ -1079,7 +1079,7 @@ static int smbldap_open(struct smbldap_state *ldap_state)
ldap_state->idle_event = event_add_timed(
ldap_state->event_context, NULL,
timeval_current_ofs(SMBLDAP_IDLE_TIME, 0),
"smbldap_idle_fn", smbldap_idle_fn, ldap_state);
smbldap_idle_fn, ldap_state);
}
DEBUG(4,("The LDAP server is successfully connected\n"));
@ -1572,7 +1572,7 @@ int smbldap_search_suffix (struct smbldap_state *ldap_state,
static void smbldap_idle_fn(struct event_context *event_ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data)
{
struct smbldap_state *state = (struct smbldap_state *)private_data;
@ -1584,13 +1584,13 @@ static void smbldap_idle_fn(struct event_context *event_ctx,
return;
}
if ((state->last_use+SMBLDAP_IDLE_TIME) > now->tv_sec) {
if ((state->last_use+SMBLDAP_IDLE_TIME) > now.tv_sec) {
DEBUG(10,("ldap connection not idle...\n"));
state->idle_event = event_add_timed(
event_ctx, NULL,
timeval_add(now, SMBLDAP_IDLE_TIME, 0),
"smbldap_idle_fn", smbldap_idle_fn,
timeval_add(&now, SMBLDAP_IDLE_TIME, 0),
smbldap_idle_fn,
private_data);
return;
}

View File

@ -949,6 +949,7 @@ void become_daemon(bool Fork, bool no_process_group)
}
bool reinit_after_fork(struct messaging_context *msg_ctx,
struct event_context *ev_ctx,
bool parent_longlived)
{
NTSTATUS status;
@ -976,6 +977,8 @@ bool reinit_after_fork(struct messaging_context *msg_ctx,
return false;
}
event_context_reinit(ev_ctx);
return true;
}

View File

@ -216,7 +216,7 @@ static ssize_t write_fd(int fd, void *ptr, size_t nbytes, int sendfd)
static void aio_child_cleanup(struct event_context *event_ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data)
{
struct aio_child_list *list = talloc_get_type_abort(
@ -252,8 +252,7 @@ static void aio_child_cleanup(struct event_context *event_ctx,
* Re-schedule the next cleanup round
*/
list->cleanup_event = event_add_timed(smbd_event_context(), list,
timeval_add(now, 30, 0),
"aio_child_cleanup",
timeval_add(&now, 30, 0),
aio_child_cleanup, list);
}
@ -284,7 +283,6 @@ static struct aio_child_list *init_aio_children(struct vfs_handle_struct *handle
if (data->cleanup_event == NULL) {
data->cleanup_event = event_add_timed(smbd_event_context(), data,
timeval_current_ofs(30, 0),
"aio_child_cleanup",
aio_child_cleanup, data);
if (data->cleanup_event == NULL) {
TALLOC_FREE(data);

View File

@ -164,7 +164,8 @@ void start_async_dns(void)
CatchSignal(SIGHUP, SIG_IGN);
CatchSignal(SIGTERM, SIGNAL_CAST sig_term );
if (!reinit_after_fork(nmbd_messaging_context(), true)) {
if (!reinit_after_fork(nmbd_messaging_context(),
nmbd_event_context(), true)) {
DEBUG(0,("reinit_after_fork() failed\n"));
smb_panic("reinit_after_fork() failed");
}

View File

@ -911,7 +911,8 @@ static bool open_sockets(bool isdaemon, int port)
pidfile_create("nmbd");
if (!reinit_after_fork(nmbd_messaging_context(), false)) {
if (!reinit_after_fork(nmbd_messaging_context(),
nmbd_event_context(), false)) {
DEBUG(0,("reinit_after_fork() failed\n"));
exit(1);
}

View File

@ -52,7 +52,7 @@ static bool delay_logon(const char *peer_name, const char *peer_addr)
static void delayed_init_logon_handler(struct event_context *event_ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data)
{
struct packet_struct *p = (struct packet_struct *)private_data;
@ -657,7 +657,6 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
event_add_timed(nmbd_event_context(),
NULL,
when,
"delayed_init_logon",
delayed_init_logon_handler,
p);
} else {

View File

@ -221,7 +221,7 @@ void print_notify_send_messages(struct messaging_context *msg_ctx,
static void print_notify_event_send_messages(struct event_context *event_ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data)
{
/* Remove this timed event handler. */
@ -326,7 +326,6 @@ to notify_queue_head\n", msg->type, msg->field, msg->printer));
/* Add an event for 1 second's time to send this queue. */
notify_event = event_add_timed(smbd_event_context(), NULL,
timeval_current_ofs(1,0),
"print_notify",
print_notify_event_send_messages, NULL);
}

View File

@ -425,7 +425,8 @@ static bool cups_pcap_load_async(int *pfd)
}
/* Child. */
if (!reinit_after_fork(smbd_messaging_context(), true)) {
if (!reinit_after_fork(smbd_messaging_context(),
smbd_event_context(), true)) {
DEBUG(0,("cups_pcap_load_async: reinit_after_fork() failed\n"));
smb_panic("cups_pcap_load_async: reinit_after_fork() failed");
}

View File

@ -1421,7 +1421,8 @@ void start_background_queue(void)
close(pause_pipe[0]);
pause_pipe[0] = -1;
if (!reinit_after_fork(smbd_messaging_context(), true)) {
if (!reinit_after_fork(smbd_messaging_context(),
smbd_event_context(), true)) {
DEBUG(0,("reinit_after_fork() failed\n"));
smb_panic("reinit_after_fork() failed");
}

View File

@ -457,7 +457,7 @@ static void free_samr_info(void *ptr)
static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data)
{
DISP_INFO *disp_info = (DISP_INFO *)private_data;
@ -486,7 +486,6 @@ static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromno
disp_info->cache_timeout_event = event_add_timed(
smbd_event_context(), NULL,
timeval_current_ofs(secs_fromnow, 0),
"disp_info_cache_idle_timeout_handler",
disp_info_cache_idle_timeout_handler, (void *)disp_info);
}

View File

@ -68,7 +68,7 @@ static void process_blocking_lock_queue(void);
static void brl_timeout_fn(struct event_context *event_ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data)
{
SMB_ASSERT(brl_timeout == te);
@ -123,7 +123,7 @@ static bool recalc_brl_timeout(void)
}
if (!(brl_timeout = event_add_timed(smbd_event_context(), NULL,
next_timeout, "brl_timeout",
next_timeout,
brl_timeout_fn, NULL))) {
return False;
}

View File

@ -85,7 +85,6 @@ static void schedule_dns_register_smbd_retry(struct dns_reg_state *dns_state,
event= event_add_timed(smbd_event_context(),
NULL,
timeval_current_ofs(DNS_REG_RETRY_INTERVAL, 0),
"DNS registration handler",
dns_register_smbd_retry,
dns_state);

View File

@ -173,7 +173,7 @@ static int wcp_file_size_change(files_struct *fsp)
static void update_write_time_handler(struct event_context *ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data)
{
files_struct *fsp = (files_struct *)private_data;
@ -221,7 +221,6 @@ void trigger_write_time_update(struct files_struct *fsp)
fsp->update_write_time_event =
event_add_timed(smbd_event_context(), NULL,
timeval_current_ofs(0, delay),
"update_write_time_handler",
update_write_time_handler, fsp);
}

View File

@ -346,7 +346,7 @@ static files_struct *initial_break_processing(struct file_id id, unsigned long f
static void oplock_timeout_handler(struct event_context *ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data)
{
files_struct *fsp = (files_struct *)private_data;
@ -373,7 +373,6 @@ static void add_oplock_timeout_handler(files_struct *fsp)
fsp->oplock_timeout =
event_add_timed(smbd_event_context(), NULL,
timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0),
"oplock_timeout_handler",
oplock_timeout_handler, fsp);
if (fsp->oplock_timeout == NULL) {

View File

@ -583,26 +583,33 @@ struct idle_event {
void *private_data;
};
static void idle_event_handler(struct event_context *ctx,
struct timed_event *te,
const struct timeval *now,
void *private_data)
static void smbd_idle_event_handler(struct event_context *ctx,
struct timed_event *te,
struct timeval now,
void *private_data)
{
struct idle_event *event =
talloc_get_type_abort(private_data, struct idle_event);
TALLOC_FREE(event->te);
if (!event->handler(now, event->private_data)) {
DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
event->name, event->te));
if (!event->handler(&now, event->private_data)) {
DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
event->name, event->te));
/* Don't repeat, delete ourselves */
TALLOC_FREE(event);
return;
}
DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
event->name, event->te));
event->te = event_add_timed(ctx, event,
timeval_sum(now, &event->interval),
event->name,
idle_event_handler, event);
timeval_sum(&now, &event->interval),
smbd_idle_event_handler, event);
/* We can't do much but fail here. */
SMB_ASSERT(event->te != NULL);
@ -637,14 +644,14 @@ struct idle_event *event_add_idle(struct event_context *event_ctx,
result->te = event_add_timed(event_ctx, result,
timeval_sum(&now, &interval),
result->name,
idle_event_handler, result);
smbd_idle_event_handler, result);
if (result->te == NULL) {
DEBUG(0, ("event_add_timed failed\n"));
TALLOC_FREE(result);
return NULL;
}
DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
return result;
}

View File

@ -753,7 +753,9 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
false);
if (!reinit_after_fork(
smbd_messaging_context(), true)) {
smbd_messaging_context(),
smbd_event_context(),
true)) {
DEBUG(0,("reinit_after_fork() failed\n"));
smb_panic("reinit_after_fork() failed");
}
@ -1327,7 +1329,8 @@ extern void build_options(bool screen);
if (is_daemon)
pidfile_create("smbd");
if (!reinit_after_fork(smbd_messaging_context(), false)) {
if (!reinit_after_fork(smbd_messaging_context(),
smbd_event_context(), false)) {
DEBUG(0,("reinit_after_fork() failed\n"));
exit(1);
}

View File

@ -248,7 +248,7 @@ static int evt_userdata_tostring(lua_State *L) {
static void evt_userdata_sleep_done(struct event_context *event_ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *priv)
{
struct thread_reference *ref = talloc_get_type_abort(
@ -279,7 +279,7 @@ static int evt_userdata_sleep(lua_State *L)
}
te = event_add_timed(p->ev, ref, timeval_current_ofs(0, usecs),
"evt_userdata_sleep", evt_userdata_sleep_done,
evt_userdata_sleep_done,
ref);
if (te == NULL) {

View File

@ -65,9 +65,9 @@ static bool send_message(struct messaging_context *msg_ctx,
return ret;
}
static void timeout_handler(struct event_context *event_ctx,
static void smbcontrol_timeout(struct event_context *event_ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data)
{
bool *timed_out = (bool *)private_data;
@ -85,8 +85,7 @@ static void wait_replies(struct messaging_context *msg_ctx,
if (!(te = event_add_timed(messaging_event_context(msg_ctx), NULL,
timeval_current_ofs(timeout, 0),
"smbcontrol_timeout",
timeout_handler, (void *)&timed_out))) {
smbcontrol_timeout, (void *)&timed_out))) {
DEBUG(0, ("event_add_timed failed\n"));
return;
}

View File

@ -415,16 +415,16 @@ static void process_request(struct winbindd_cli_state *state)
/*
* A list of file descriptors being monitored by select in the main processing
* loop. fd_event->handler is called whenever the socket is readable/writable.
* loop. winbindd_fd_event->handler is called whenever the socket is readable/writable.
*/
static struct fd_event *fd_events = NULL;
static struct winbindd_fd_event *fd_events = NULL;
void add_fd_event(struct fd_event *ev)
void add_fd_event(struct winbindd_fd_event *ev)
{
struct fd_event *match;
struct winbindd_fd_event *match;
/* only add unique fd_event structs */
/* only add unique winbindd_fd_event structs */
for (match=fd_events; match; match=match->next ) {
#ifdef DEVELOPER
@ -438,17 +438,17 @@ void add_fd_event(struct fd_event *ev)
DLIST_ADD(fd_events, ev);
}
void remove_fd_event(struct fd_event *ev)
void remove_fd_event(struct winbindd_fd_event *ev)
{
DLIST_REMOVE(fd_events, ev);
}
/*
* Handler for fd_events to complete a read/write request, set up by
* Handler for winbindd_fd_events to complete a read/write request, set up by
* setup_async_read/setup_async_write.
*/
static void rw_callback(struct fd_event *event, int flags)
static void rw_callback(struct winbindd_fd_event *event, int flags)
{
size_t todo;
ssize_t done = 0;
@ -489,11 +489,11 @@ static void rw_callback(struct fd_event *event, int flags)
}
/*
* Request an async read/write on a fd_event structure. (*finished) is called
* Request an async read/write on a winbindd_fd_event structure. (*finished) is called
* when the request is completed or an error had occurred.
*/
void setup_async_read(struct fd_event *event, void *data, size_t length,
void setup_async_read(struct winbindd_fd_event *event, void *data, size_t length,
void (*finished)(void *private_data, bool success),
void *private_data)
{
@ -507,7 +507,7 @@ void setup_async_read(struct fd_event *event, void *data, size_t length,
event->flags = EVENT_FD_READ;
}
void setup_async_write(struct fd_event *event, void *data, size_t length,
void setup_async_write(struct winbindd_fd_event *event, void *data, size_t length,
void (*finished)(void *private_data, bool success),
void *private_data)
{
@ -826,7 +826,7 @@ void winbind_check_sigterm(bool is_parent)
static void process_loop(void)
{
struct winbindd_cli_state *state;
struct fd_event *ev;
struct winbindd_fd_event *ev;
fd_set r_fds, w_fds;
int maxfd, listen_sock, listen_priv_sock, selret;
struct timeval timeout, ev_timeout;
@ -865,6 +865,13 @@ static void process_loop(void)
timeout.tv_usec = 0;
/* Check for any event timeouts. */
{
struct timeval now;
GetTimeOfDay(&now);
event_add_to_select_args(winbind_event_context(), &now,
&r_fds, &w_fds, &ev_timeout, &maxfd);
}
if (get_timed_events_timeout(winbind_event_context(), &ev_timeout)) {
timeout = timeval_min(&timeout, &ev_timeout);
}
@ -918,9 +925,11 @@ static void process_loop(void)
/* selret > 0 */
run_events(winbind_event_context(), selret, &r_fds, &w_fds);
ev = fd_events;
while (ev != NULL) {
struct fd_event *next = ev->next;
struct winbindd_fd_event *next = ev->next;
int flags = 0;
if (FD_ISSET(ev->fd, &r_fds))
flags |= EVENT_FD_READ;
@ -1191,7 +1200,8 @@ int main(int argc, char **argv, char **envp)
TimeInit();
if (!reinit_after_fork(winbind_messaging_context(), false)) {
if (!reinit_after_fork(winbind_messaging_context(),
winbind_event_context(), false)) {
DEBUG(0,("reinit_after_fork() failed\n"));
exit(1);
}

View File

@ -39,15 +39,11 @@
#define WB_REPLACE_CHAR '_'
/* bits for fd_event.flags */
#define EVENT_FD_READ 1
#define EVENT_FD_WRITE 2
struct fd_event {
struct fd_event *next, *prev;
struct winbindd_fd_event {
struct winbindd_fd_event *next, *prev;
int fd;
int flags; /* see EVENT_FD_* flags */
void (*handler)(struct fd_event *fde, int flags);
void (*handler)(struct winbindd_fd_event *fde, int flags);
void *data;
size_t length, done;
void (*finished)(void *private_data, bool success);
@ -65,7 +61,7 @@ struct sid_ctr {
struct winbindd_cli_state {
struct winbindd_cli_state *prev, *next; /* Linked list pointers */
int sock; /* Open socket from client */
struct fd_event fd_event;
struct winbindd_fd_event fd_event;
pid_t pid; /* pid of client */
bool finished; /* Can delete from list */
bool write_extra_data; /* Write extra_data field */
@ -151,7 +147,7 @@ struct winbindd_child {
struct winbindd_domain *domain;
char *logfilename;
struct fd_event event;
struct winbindd_fd_event event;
struct timed_event *lockout_policy_event;
struct timed_event *machine_password_change_event;
struct winbindd_async_request *requests;
@ -377,7 +373,34 @@ enum ent_type {
LIST_USERS = 0,
LIST_GROUPS,
};
struct WINBINDD_MEMORY_CREDS {
struct WINBINDD_MEMORY_CREDS *next, *prev;
const char *username; /* lookup key. */
uid_t uid;
int ref_count;
size_t len;
uint8_t *nt_hash; /* Base pointer for the following 2 */
uint8_t *lm_hash;
char *pass;
};
struct WINBINDD_CCACHE_ENTRY {
struct WINBINDD_CCACHE_ENTRY *next, *prev;
const char *principal_name;
const char *ccname;
const char *service;
const char *username;
const char *realm;
struct WINBINDD_MEMORY_CREDS *cred_ptr;
int ref_count;
uid_t uid;
time_t create_time;
time_t renew_until;
time_t refresh_time;
struct timed_event *event;
};
#include "winbindd/winbindd_proto.h"
#define WINBINDD_ESTABLISH_LOOP 30

View File

@ -212,7 +212,8 @@ static bool fork_child_dc_connect(struct winbindd_domain *domain)
/* Leave messages blocked - we will never process one. */
if (!reinit_after_fork(winbind_messaging_context(), true)) {
if (!reinit_after_fork(winbind_messaging_context(),
winbind_event_context(), true)) {
DEBUG(0,("reinit_after_fork() failed\n"));
messaging_send_buf(winbind_messaging_context(),
pid_to_procid(parent_pid),
@ -271,7 +272,7 @@ static bool fork_child_dc_connect(struct winbindd_domain *domain)
static void check_domain_online_handler(struct event_context *ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data)
{
struct winbindd_domain *domain =
@ -285,7 +286,7 @@ static void check_domain_online_handler(struct event_context *ctx,
/* Are we still in "startup" mode ? */
if (domain->startup && (now->tv_sec > domain->startup_time + 30)) {
if (domain->startup && (now.tv_sec > domain->startup_time + 30)) {
/* No longer in "startup" mode. */
DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n",
domain->name ));
@ -366,7 +367,6 @@ void set_domain_offline(struct winbindd_domain *domain)
domain->check_online_event = event_add_timed(winbind_event_context(),
NULL,
timeval_current_ofs(domain->check_online_timeout,0),
"check_domain_online_handler",
check_domain_online_handler,
domain);
@ -402,8 +402,6 @@ void set_domain_offline(struct winbindd_domain *domain)
static void set_domain_online(struct winbindd_domain *domain)
{
struct timeval now;
DEBUG(10,("set_domain_online: called for domain %s\n",
domain->name ));
@ -422,9 +420,7 @@ static void set_domain_online(struct winbindd_domain *domain)
winbindd_set_locator_kdc_envs(domain);
/* If we are waiting to get a krb5 ticket, trigger immediately. */
GetTimeOfDay(&now);
set_event_dispatch_time(winbind_event_context(),
"krb5_ticket_gain_handler", now);
ccache_regain_all_now();
/* Ok, we're out of any startup mode now... */
domain->startup = False;
@ -497,27 +493,6 @@ void set_domain_online_request(struct winbindd_domain *domain)
because network manager seems to lie.
Wait at least 5 seconds. Heuristics suck... */
if (!domain->check_online_event) {
/* If we've come from being globally offline we
don't have a check online event handler set.
We need to add one now we're trying to go
back online. */
DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
domain->name ));
domain->check_online_event = event_add_timed(winbind_event_context(),
NULL,
timeval_current_ofs(5, 0),
"check_domain_online_handler",
check_domain_online_handler,
domain);
/* The above *has* to succeed for winbindd to work. */
if (!domain->check_online_event) {
smb_panic("set_domain_online_request: failed to add online handler");
}
}
GetTimeOfDay(&tev);
@ -527,7 +502,28 @@ void set_domain_online_request(struct winbindd_domain *domain)
tev.tv_sec += 5;
set_event_dispatch_time(winbind_event_context(), "check_domain_online_handler", tev);
if (!domain->check_online_event) {
/* If we've come from being globally offline we
don't have a check online event handler set.
We need to add one now we're trying to go
back online. */
DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
domain->name ));
}
TALLOC_FREE(domain->check_online_event);
domain->check_online_event = event_add_timed(winbind_event_context(),
NULL,
tev,
check_domain_online_handler,
domain);
/* The above *has* to succeed for winbindd to work. */
if (!domain->check_online_event) {
smb_panic("set_domain_online_request: failed to add online handler");
}
}
/****************************************************************

View File

@ -34,6 +34,10 @@
#define MAX_CCACHES 100
static struct WINBINDD_CCACHE_ENTRY *ccache_list;
static void krb5_ticket_gain_handler(struct event_context *,
struct timed_event *,
struct timeval,
void *);
/* The Krb5 ticket refresh handler should be scheduled
at one-half of the period from now till the tkt
@ -71,13 +75,27 @@ static int ccache_entry_count(void)
return i;
}
void ccache_remove_all_after_fork(void)
{
struct WINBINDD_CCACHE_ENTRY *cur, *next;
for (cur = ccache_list; cur; cur = next) {
next = cur->next;
DLIST_REMOVE(ccache_list, cur);
TALLOC_FREE(cur->event);
TALLOC_FREE(cur);
}
return;
}
/****************************************************************
Do the work of refreshing the ticket.
****************************************************************/
static void krb5_ticket_refresh_handler(struct event_context *event_ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data)
{
struct WINBINDD_CCACHE_ENTRY *entry =
@ -85,6 +103,7 @@ static void krb5_ticket_refresh_handler(struct event_context *event_ctx,
#ifdef HAVE_KRB5
int ret;
time_t new_start;
time_t expire_time = 0;
struct WINBINDD_MEMORY_CREDS *cred_ptr = entry->cred_ptr;
#endif
@ -97,44 +116,83 @@ static void krb5_ticket_refresh_handler(struct event_context *event_ctx,
#ifdef HAVE_KRB5
/* Kinit again if we have the user password and we can't renew the old
* tgt anymore */
* tgt anymore
* NB
* This happens when machine are put to sleep for a very long time. */
if ((entry->renew_until < time(NULL)) && cred_ptr && cred_ptr->pass) {
if (entry->renew_until < time(NULL)) {
rekinit:
if (cred_ptr && cred_ptr->pass) {
set_effective_uid(entry->uid);
set_effective_uid(entry->uid);
ret = kerberos_kinit_password_ext(entry->principal_name,
cred_ptr->pass,
0, /* hm, can we do time correction here ? */
&entry->refresh_time,
&entry->renew_until,
entry->ccname,
False, /* no PAC required anymore */
True,
WINBINDD_PAM_AUTH_KRB5_RENEW_TIME,
NULL);
gain_root_privilege();
ret = kerberos_kinit_password_ext(entry->principal_name,
cred_ptr->pass,
0, /* hm, can we do time correction here ? */
&entry->refresh_time,
&entry->renew_until,
entry->ccname,
False, /* no PAC required anymore */
True,
WINBINDD_PAM_AUTH_KRB5_RENEW_TIME,
NULL);
gain_root_privilege();
if (ret) {
DEBUG(3,("krb5_ticket_refresh_handler: "
"could not re-kinit: %s\n",
error_message(ret)));
TALLOC_FREE(entry->event);
return;
}
if (ret) {
DEBUG(3,("krb5_ticket_refresh_handler: "
"could not re-kinit: %s\n",
error_message(ret)));
/* destroy the ticket because we cannot rekinit
* it, ignore error here */
ads_kdestroy(entry->ccname);
DEBUG(10,("krb5_ticket_refresh_handler: successful re-kinit "
"for: %s in ccache: %s\n",
entry->principal_name, entry->ccname));
/* Don't break the ticket refresh chain: retry
* refreshing ticket sometime later when KDC is
* unreachable -- BoYang
* */
if ((ret == KRB5_KDC_UNREACH)
|| (ret == KRB5_REALM_CANT_RESOLVE)) {
#if defined(DEBUG_KRB5_TKT_RENEWAL)
new_start = time(NULL) + 30;
#else
new_start = time(NULL) +
MAX(30, lp_winbind_cache_time());
#endif
/* try to regain ticket here */
entry->event = event_add_timed(winbind_event_context(),
entry,
timeval_set(new_start, 0),
krb5_ticket_gain_handler,
entry);
return;
}
TALLOC_FREE(entry->event);
return;
}
DEBUG(10,("krb5_ticket_refresh_handler: successful re-kinit "
"for: %s in ccache: %s\n",
entry->principal_name, entry->ccname));
#if defined(DEBUG_KRB5_TKT_RENEWAL)
new_start = time(NULL) + 30;
new_start = time(NULL) + 30;
#else
/* The tkt should be refreshed at one-half the period
from now to the expiration time */
new_start = KRB5_EVENT_REFRESH_TIME(entry->refresh_time);
/* The tkt should be refreshed at one-half the period
from now to the expiration time */
expire_time = entry->refresh_time;
new_start = KRB5_EVENT_REFRESH_TIME(entry->refresh_time);
#endif
goto done;
goto done;
} else {
/* can this happen?
* No cached credentials
* destroy ticket and refresh chain
* */
ads_kdestroy(entry->ccname);
TALLOC_FREE(entry->event);
return;
}
}
set_effective_uid(entry->uid);
@ -146,6 +204,7 @@ static void krb5_ticket_refresh_handler(struct event_context *event_ctx,
#if defined(DEBUG_KRB5_TKT_RENEWAL)
new_start = time(NULL) + 30;
#else
expire_time = new_start;
new_start = KRB5_EVENT_REFRESH_TIME(new_start);
#endif
@ -157,24 +216,73 @@ static void krb5_ticket_refresh_handler(struct event_context *event_ctx,
error_message(ret)));
/* maybe we are beyond the renewing window */
/* evil rises here, we refresh ticket failed,
* but the ticket might be expired. Therefore,
* When we refresh ticket failed, destory the
* ticket */
ads_kdestroy(entry->ccname);
/* avoid breaking the renewal chain: retry in
* lp_winbind_cache_time() seconds when the KDC was not
* available right now. */
* available right now.
* the return code can be KRB5_REALM_CANT_RESOLVE*/
if (ret == KRB5_KDC_UNREACH) {
if ((ret == KRB5_KDC_UNREACH)
|| (ret == KRB5_REALM_CANT_RESOLVE)) {
#if defined(DEBUG_KRB5_TKT_RENEWAL)
new_start = time(NULL) + 30;
#else
new_start = time(NULL) +
MAX(30, lp_winbind_cache_time());
goto done;
#endif
/* ticket is destroyed here, we have to regain it
* if it is possible */
entry->event = event_add_timed(winbind_event_context(),
entry,
timeval_set(new_start, 0),
krb5_ticket_gain_handler,
entry);
return;
}
/* This is evil, if the ticket was already expired.
* renew ticket function returns KRB5KRB_AP_ERR_TKT_EXPIRED.
* But there is still a chance that we can rekinit it.
*
* This happens when user login in online mode, and then network
* down or something cause winbind goes offline for a very long time,
* and then goes online again. ticket expired, renew failed.
* This happens when machine are put to sleep for a long time,
* but shorter than entry->renew_util.
* NB
* Looks like the KDC is reachable, we want to rekinit as soon as
* possible instead of waiting some time later. */
if ((ret == KRB5KRB_AP_ERR_TKT_EXPIRED)
|| (ret == KRB5_FCC_NOFILE)) goto rekinit;
return;
}
done:
/* in cases that ticket will be unrenewable soon, we don't try to renew ticket
* but try to regain ticket if it is possible */
if (entry->renew_until && expire_time
&& (entry->renew_until <= expire_time)) {
/* try to regain ticket 10 seconds beforre expiration */
expire_time -= 10;
entry->event = event_add_timed(winbind_event_context(), entry,
timeval_set(expire_time, 0),
krb5_ticket_gain_handler,
entry);
return;
}
if (entry->refresh_time == 0) {
entry->refresh_time = new_start;
}
entry->event = event_add_timed(winbind_event_context(), entry,
timeval_set(new_start, 0),
"krb5_ticket_refresh_handler",
krb5_ticket_refresh_handler,
entry);
@ -187,7 +295,7 @@ done:
static void krb5_ticket_gain_handler(struct event_context *event_ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data)
{
struct WINBINDD_CCACHE_ENTRY *entry =
@ -239,6 +347,9 @@ static void krb5_ticket_gain_handler(struct event_context *event_ctx,
DEBUG(3,("krb5_ticket_gain_handler: "
"could not kinit: %s\n",
error_message(ret)));
/* evil. If we cannot do it, destroy any the __maybe__
* __existing__ ticket */
ads_kdestroy(entry->ccname);
goto retry_later;
}
@ -249,13 +360,17 @@ static void krb5_ticket_gain_handler(struct event_context *event_ctx,
goto got_ticket;
retry_later:
#if defined(DEBUG_KRB5_TKT_REGAIN)
t = timeval_set(time(NULL) + 30, 0);
#else
t = timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0);
#endif
entry->refresh_time = 0;
entry->event = event_add_timed(winbind_event_context(),
entry,
t,
"krb5_ticket_gain_handler",
krb5_ticket_gain_handler,
entry);
@ -269,10 +384,12 @@ static void krb5_ticket_gain_handler(struct event_context *event_ctx,
t = timeval_set(KRB5_EVENT_REFRESH_TIME(entry->refresh_time), 0);
#endif
if (entry->refresh_time == 0) {
entry->refresh_time = t.tv_sec;
}
entry->event = event_add_timed(winbind_event_context(),
entry,
t,
"krb5_ticket_refresh_handler",
krb5_ticket_refresh_handler,
entry);
@ -280,6 +397,43 @@ static void krb5_ticket_gain_handler(struct event_context *event_ctx,
#endif
}
void ccache_regain_all_now(void)
{
struct WINBINDD_CCACHE_ENTRY *cur;
struct timeval t = timeval_current();
for (cur = ccache_list; cur; cur = cur->next) {
struct timed_event *new_event;
/*
* if refresh_time is 0, we know that the
* the event has the krb5_ticket_gain_handler
*/
if (cur->refresh_time == 0) {
new_event = event_add_timed(winbind_event_context(),
cur,
t,
krb5_ticket_gain_handler,
cur);
} else {
new_event = event_add_timed(winbind_event_context(),
cur,
t,
krb5_ticket_refresh_handler,
cur);
}
if (!new_event) {
continue;
}
TALLOC_FREE(cur->event);
cur->event = new_event;
}
return;
}
/****************************************************************
Check if an ccache entry exists.
****************************************************************/
@ -331,6 +485,10 @@ NTSTATUS add_ccache_to_list(const char *princ_name,
{
struct WINBINDD_CCACHE_ENTRY *entry = NULL;
struct timeval t;
NTSTATUS ntret;
#ifdef HAVE_KRB5
int ret;
#endif
if ((username == NULL && princ_name == NULL) ||
ccname == NULL || uid < 0) {
@ -343,6 +501,28 @@ NTSTATUS add_ccache_to_list(const char *princ_name,
return NT_STATUS_NO_MORE_ENTRIES;
}
/* If it is cached login, destroy krb5 ticket
* to avoid surprise. */
#ifdef HAVE_KRB5
if (postponed_request) {
/* ignore KRB5_FCC_NOFILE error here */
ret = ads_kdestroy(ccname);
if (ret == KRB5_FCC_NOFILE) {
ret = 0;
}
if (ret) {
DEBUG(0, ("add_ccache_to_list: failed to destroy "
"user krb5 ccache %s with %s\n", ccname,
error_message(ret)));
return krb5_to_nt_status(ret);
} else {
DEBUG(10, ("add_ccache_to_list: successfully destroyed "
"krb5 ccache %s for user %s\n", ccname,
username));
}
}
#endif
/* Reference count old entries */
entry = get_ccache_by_username(username);
if (entry) {
@ -355,7 +535,51 @@ NTSTATUS add_ccache_to_list(const char *princ_name,
"ref count on entry %s is now %d\n",
username, entry->ref_count));
/* FIXME: in this case we still might want to have a krb5 cred
* event handler created - gd*/
* event handler created - gd
* Add ticket refresh handler here */
if (!lp_winbind_refresh_tickets() || renew_until <= 0) {
return NT_STATUS_OK;
}
if (!entry->event) {
if (postponed_request) {
t = timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0);
entry->event = event_add_timed(winbind_event_context(),
entry,
t,
krb5_ticket_gain_handler,
entry);
} else {
/* Renew at 1/2 the ticket expiration time */
#if defined(DEBUG_KRB5_TKT_RENEWAL)
t = timeval_set(time(NULL)+30, 0);
#else
t = timeval_set(KRB5_EVENT_REFRESH_TIME(ticket_end), 0);
#endif
entry->event = event_add_timed(winbind_event_context(),
entry,
t,
krb5_ticket_refresh_handler,
entry);
}
if (!entry->event) {
ntret = remove_ccache(username);
if (!NT_STATUS_IS_OK(ntret)) {
DEBUG(0, ("add_ccache_to_list: Failed to remove krb5 "
"ccache %s for user %s\n", entry->ccname,
entry->username));
DEBUG(0, ("add_ccache_to_list: error is %s\n",
nt_errstr(ntret)));
return ntret;
}
return NT_STATUS_NO_MEMORY;
}
DEBUG(10,("add_ccache_to_list: added krb5_ticket handler\n"));
}
return NT_STATUS_OK;
}
@ -406,10 +630,10 @@ NTSTATUS add_ccache_to_list(const char *princ_name,
if (postponed_request) {
t = timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0);
entry->refresh_time = 0;
entry->event = event_add_timed(winbind_event_context(),
entry,
t,
"krb5_ticket_gain_handler",
krb5_ticket_gain_handler,
entry);
} else {
@ -419,10 +643,12 @@ NTSTATUS add_ccache_to_list(const char *princ_name,
#else
t = timeval_set(KRB5_EVENT_REFRESH_TIME(ticket_end), 0);
#endif
if (entry->refresh_time == 0) {
entry->refresh_time = t.tv_sec;
}
entry->event = event_add_timed(winbind_event_context(),
entry,
t,
"krb5_ticket_refresh_handler",
krb5_ticket_refresh_handler,
entry);
}

View File

@ -175,7 +175,7 @@ static void async_main_request_sent(void *private_data, bool success)
static void async_request_timeout_handler(struct event_context *ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data)
{
struct winbindd_async_request *state =
@ -247,7 +247,6 @@ static void async_request_sent(void *private_data_data, bool success)
state->reply_timeout_event = event_add_timed(winbind_event_context(),
NULL,
timeval_current_ofs(300,0),
"async_request_timeout",
async_request_timeout_handler,
state);
if (!state->reply_timeout_event) {
@ -827,7 +826,7 @@ void winbind_msg_dump_domain_list(struct messaging_context *msg_ctx,
static void account_lockout_policy_handler(struct event_context *ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data)
{
struct winbindd_child *child =
@ -866,7 +865,6 @@ static void account_lockout_policy_handler(struct event_context *ctx,
child->lockout_policy_event = event_add_timed(winbind_event_context(), NULL,
timeval_current_ofs(3600, 0),
"account_lockout_policy_handler",
account_lockout_policy_handler,
child);
}
@ -919,7 +917,7 @@ static bool calculate_next_machine_pwd_change(const char *domain,
static void machine_password_change_handler(struct event_context *ctx,
struct timed_event *te,
const struct timeval *now,
struct timeval now,
void *private_data)
{
struct winbindd_child *child =
@ -971,7 +969,6 @@ static void machine_password_change_handler(struct event_context *ctx,
child->machine_password_change_event = event_add_timed(winbind_event_context(), NULL,
next_change,
"machine_password_change_handler",
machine_password_change_handler,
child);
}
@ -985,6 +982,7 @@ static void child_msg_offline(struct messaging_context *msg,
DATA_BLOB *data)
{
struct winbindd_domain *domain;
struct winbindd_domain *primary_domain = NULL;
const char *domainname = (const char *)data->data;
if (data->data == NULL || data->length == 0) {
@ -998,6 +996,8 @@ static void child_msg_offline(struct messaging_context *msg,
return;
}
primary_domain = find_our_domain();
/* Mark the requested domain offline. */
for (domain = domain_list(); domain; domain = domain->next) {
@ -1007,6 +1007,11 @@ static void child_msg_offline(struct messaging_context *msg,
if (strequal(domain->name, domainname)) {
DEBUG(5,("child_msg_offline: marking %s offline.\n", domain->name));
set_domain_offline(domain);
/* we are in the trusted domain, set the primary domain
* offline too */
if (domain != primary_domain) {
set_domain_offline(primary_domain);
}
}
}
}
@ -1020,6 +1025,7 @@ static void child_msg_online(struct messaging_context *msg,
DATA_BLOB *data)
{
struct winbindd_domain *domain;
struct winbindd_domain *primary_domain = NULL;
const char *domainname = (const char *)data->data;
if (data->data == NULL || data->length == 0) {
@ -1033,6 +1039,8 @@ static void child_msg_online(struct messaging_context *msg,
return;
}
primary_domain = find_our_domain();
/* Set our global state as online. */
set_global_winbindd_state_online();
@ -1047,6 +1055,16 @@ static void child_msg_online(struct messaging_context *msg,
DEBUG(5,("child_msg_online: requesting %s to go online.\n", domain->name));
winbindd_flush_negative_conn_cache(domain);
set_domain_online_request(domain);
/* we can be in trusted domain, which will contact primary domain
* we have to bring primary domain online in trusted domain process
* see, winbindd_dual_pam_auth() --> winbindd_dual_pam_auth_samlogon()
* --> contact_domain = find_our_domain()
* */
if (domain != primary_domain) {
winbindd_flush_negative_conn_cache(primary_domain);
set_domain_online_request(primary_domain);
}
}
}
}
@ -1177,13 +1195,18 @@ static bool fork_domain_child(struct winbindd_child *child)
state.sock = fdpair[0];
close(fdpair[1]);
if (!reinit_after_fork(winbind_messaging_context(), true)) {
if (!reinit_after_fork(winbind_messaging_context(),
winbind_event_context(), true)) {
DEBUG(0,("reinit_after_fork() failed\n"));
_exit(0);
}
close_conns_after_fork();
/* Ensure we're not handling an event inherited from
our parent. */
ccache_remove_all_after_fork();
if (!override_logfile) {
lp_set_logfile(child->logfilename);
reopen_logs();
@ -1219,32 +1242,33 @@ static bool fork_domain_child(struct winbindd_child *child)
messaging_register(winbind_messaging_context(), NULL,
MSG_DEBUG, debug_message);
if ( child->domain ) {
child->domain->startup = True;
child->domain->startup_time = time(NULL);
}
/* Ensure we have no pending check_online events other
than one for this domain or the primary domain. */
for (domain = domain_list(); domain; domain = domain->next) {
if (domain->primary) {
primary_domain = domain;
}
if ((domain != child->domain) && !domain->primary) {
TALLOC_FREE(domain->check_online_event);
}
}
primary_domain = find_our_domain();
if (primary_domain == NULL) {
smb_panic("no primary domain found");
}
/* Ensure we're not handling an event inherited from
our parent. */
cancel_named_event(winbind_event_context(),
"krb5_ticket_refresh_handler");
/* we have destroy all time event in reinit_after_fork()
* set check_online_event to NULL */
for (domain = domain_list(); domain; domain = domain->next) {
domain->check_online_event = NULL;
}
/* It doesn't matter if we allow cache login,
* try to bring domain online after fork. */
if ( child->domain ) {
child->domain->startup = True;
child->domain->startup_time = time(NULL);
/* we can be in primary domain or in trusted domain
* If we are in trusted domain, set the primary domain
* in start-up mode */
if (!(child->domain->internal)) {
set_domain_online_request(child->domain);
if (!(child->domain->primary)) {
primary_domain->startup = True;
primary_domain->startup_time = time(NULL);
set_domain_online_request(primary_domain);
}
}
}
/* We might be in the idmap child...*/
if (child->domain && !(child->domain->internal) &&
@ -1266,7 +1290,6 @@ static bool fork_domain_child(struct winbindd_child *child)
child->lockout_policy_event = event_add_timed(
winbind_event_context(), NULL, timeval_zero(),
"account_lockout_policy_handler",
account_lockout_policy_handler,
child);
}
@ -1281,7 +1304,6 @@ static bool fork_domain_child(struct winbindd_child *child)
&next_change)) {
child->machine_password_change_event = event_add_timed(
winbind_event_context(), NULL, next_change,
"machine_password_change_handler",
machine_password_change_handler,
child);
}

View File

@ -53,12 +53,12 @@ bool register_message_flags(bool doreg, uint32 msg_flags);
struct event_context *winbind_event_context(void);
struct messaging_context *winbind_messaging_context(void);
void add_fd_event(struct fd_event *ev);
void remove_fd_event(struct fd_event *ev);
void setup_async_read(struct fd_event *event, void *data, size_t length,
void add_fd_event(struct winbindd_fd_event *ev);
void remove_fd_event(struct winbindd_fd_event *ev);
void setup_async_read(struct winbindd_fd_event *event, void *data, size_t length,
void (*finished)(void *private_data, bool success),
void *private_data);
void setup_async_write(struct fd_event *event, void *data, size_t length,
void setup_async_write(struct winbindd_fd_event *event, void *data, size_t length,
void (*finished)(void *private_data, bool success),
void *private_data);
void request_error(struct winbindd_cli_state *state);
@ -243,6 +243,8 @@ bool ccache_entry_exists(const char *username);
bool ccache_entry_identical(const char *username,
uid_t uid,
const char *ccname);
void ccache_remove_all_after_fork(void);
void ccache_regain_all_now(void);
NTSTATUS add_ccache_to_list(const char *princ_name,
const char *ccname,
const char *service,