summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs-xml/manpages-3/smbclient.1.xml24
-rwxr-xr-xexamples/perfcounter/perfcountd.init10
-rw-r--r--nsswitch/winbind_struct_protocol.h27
-rw-r--r--source3/Makefile.in3
-rw-r--r--source3/client/client.c5
-rw-r--r--source3/configure.in10
-rw-r--r--source3/include/event.h26
-rw-r--r--source3/include/includes.h3
-rw-r--r--source3/include/proto.h41
-rw-r--r--source3/include/smb.h3
-rw-r--r--source3/lib/async_req.c13
-rw-r--r--source3/lib/ctdbd_conn.c3
-rw-r--r--source3/lib/events.c356
-rw-r--r--source3/lib/smbldap.c12
-rw-r--r--source3/lib/util.c3
-rw-r--r--source3/modules/vfs_aio_fork.c6
-rw-r--r--source3/nmbd/asyncdns.c3
-rw-r--r--source3/nmbd/nmbd.c3
-rw-r--r--source3/nmbd/nmbd_processlogon.c3
-rw-r--r--source3/printing/notify.c3
-rw-r--r--source3/printing/print_cups.c3
-rw-r--r--source3/printing/printing.c3
-rw-r--r--source3/rpc_server/srv_samr_nt.c3
-rw-r--r--source3/smbd/blocking.c4
-rw-r--r--source3/smbd/dnsregister.c1
-rw-r--r--source3/smbd/fileio.c3
-rw-r--r--source3/smbd/oplock.c3
-rw-r--r--source3/smbd/process.c27
-rw-r--r--source3/smbd/server.c7
-rw-r--r--source3/utils/net_lua.c4
-rw-r--r--source3/utils/smbcontrol.c7
-rw-r--r--source3/winbindd/winbindd.c38
-rw-r--r--source3/winbindd/winbindd.h43
-rw-r--r--source3/winbindd/winbindd_cm.c52
-rw-r--r--source3/winbindd/winbindd_cred_cache.c318
-rw-r--r--source3/winbindd/winbindd_dual.c82
-rw-r--r--source3/winbindd/winbindd_proto.h10
37 files changed, 706 insertions, 459 deletions
diff --git a/docs-xml/manpages-3/smbclient.1.xml b/docs-xml/manpages-3/smbclient.1.xml
index e2662cc08d..188ff11bb0 100644
--- a/docs-xml/manpages-3/smbclient.1.xml
+++ b/docs-xml/manpages-3/smbclient.1.xml
@@ -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
diff --git a/examples/perfcounter/perfcountd.init b/examples/perfcounter/perfcountd.init
index 683e91395b..0beff96227 100755
--- a/examples/perfcounter/perfcountd.init
+++ b/examples/perfcounter/perfcountd.init
@@ -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
diff --git a/nsswitch/winbind_struct_protocol.h b/nsswitch/winbind_struct_protocol.h
index fe3da81791..0b3e74492c 100644
--- a/nsswitch/winbind_struct_protocol.h
+++ b/nsswitch/winbind_struct_protocol.h
@@ -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
diff --git a/source3/Makefile.in b/source3/Makefile.in
index c13f5ae20a..d938b94ee0 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -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
diff --git a/source3/client/client.c b/source3/client/client.c
index 529f21ab30..c40c04e9c6 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -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*",
diff --git a/source3/configure.in b/source3/configure.in
index fc3cb261d4..6727181e1c 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -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"
diff --git a/source3/include/event.h b/source3/include/event.h
index 0465fae471..93112a86fa 100644
--- a/source3/include/event.h
+++ b/source3/include/event.h
@@ -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);
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 64be27336d..8b0ff71c4e 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -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"
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 09f12ceb86..22183118e2 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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);
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 7fd4fbb553..9f6a6f02d7 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -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;
diff --git a/source3/lib/async_req.c b/source3/lib/async_req.c
index ac06df65a3..13b64ba79a 100644
--- a/source3/lib/async_req.c
+++ b/source3/lib/async_req.c
@@ -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) {
diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c
index 75a513312e..c94ef802c4 100644
--- a/source3/lib/ctdbd_conn.c
+++ b/source3/lib/ctdbd_conn.c
@@ -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) {
diff --git a/source3/lib/events.c b/source3/lib/events.c
index 8bbc9497ac..be2fdcb68f 100644
--- a/source3/lib/events.c
+++ b/source3/lib/events.c
@@ -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);
- }
- while (ev->timed_events != NULL) {
- ev->timed_events->event_ctx = NULL;
- DLIST_REMOVE(ev->timed_events, ev->timed_events);
- }
- return 0;
-}
+ int ret = 0;
-struct event_context *event_context_init(TALLOC_CTX *mem_ctx)
-{
- struct event_context *result;
-
- result = TALLOC_ZERO_P(mem_ctx, struct event_context);
- if (result == NULL) {
- return NULL;
+ while (ret == 0) {
+ ret = s3_event_loop_once(ev);
}
- talloc_set_destructor(result, event_context_destructor);
- return result;
+ return ret;
}
-int set_event_dispatch_time(struct event_context *event_ctx,
- const char *event_name, struct timeval when)
+static int s3_event_context_destructor(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) {
- DLIST_REMOVE(event_ctx->timed_events, te);
- te->when = when;
- add_event_by_time(te);
- return 1;
- }
+ 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;
}
-/* Returns 1 if event was found and cancelled, 0 otherwise. */
+void event_context_reinit(struct tevent_context *ev)
+{
+ s3_event_context_destructor(ev);
+ return;
+}
-int cancel_named_event(struct event_context *event_ctx,
- const char *event_name)
+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) {
- TALLOC_FREE(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;
}
-void dump_event_list(struct event_context *event_ctx)
+void dump_event_list(struct tevent_context *ev)
{
- 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");
+}
diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c
index f2161dc946..f0561a5081 100644
--- a/source3/lib/smbldap.c
+++ b/source3/lib/smbldap.c
@@ -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;
}
diff --git a/source3/lib/util.c b/source3/lib/util.c
index d00a764c1d..08ea5add7a 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -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;
}
diff --git a/source3/modules/vfs_aio_fork.c b/source3/modules/vfs_aio_fork.c
index 7914e8f401..30b14f280f 100644
--- a/source3/modules/vfs_aio_fork.c
+++ b/source3/modules/vfs_aio_fork.c
@@ -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);
diff --git a/source3/nmbd/asyncdns.c b/source3/nmbd/asyncdns.c
index ab9b1ed740..baa88bc44b 100644
--- a/source3/nmbd/asyncdns.c
+++ b/source3/nmbd/asyncdns.c
@@ -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");
}
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index d1ab3aaacb..659db85e69 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -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);
}
diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c
index 565d81f82d..a4ef528133 100644
--- a/source3/nmbd/nmbd_processlogon.c
+++ b/source3/nmbd/nmbd_processlogon.c
@@ -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 {
diff --git a/source3/printing/notify.c b/source3/printing/notify.c
index b24a8a52f5..860a400d64 100644
--- a/source3/printing/notify.c
+++ b/source3/printing/notify.c
@@ -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);
}
diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c
index 5fb1d379a6..d75d635779 100644
--- a/source3/printing/print_cups.c
+++ b/source3/printing/print_cups.c
@@ -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");
}
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index ba88f8ee56..0f38aeab80 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -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");
}
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 342f432c4e..24d14d720f 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -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);
}
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 2237a89ace..2b90d24c87 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -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;
}
diff --git a/source3/smbd/dnsregister.c b/source3/smbd/dnsregister.c
index 2319097ca5..c092251fee 100644
--- a/source3/smbd/dnsregister.c
+++ b/source3/smbd/dnsregister.c
@@ -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);
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index e67f926a04..30253d4466 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -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);
}
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index 261d8fd670..6efa3dcfc6 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -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) {
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 67e6067b26..cd9eaa6b1e 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -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;
}
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 254180ae1c..a84b58a052 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -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);
}
diff --git a/source3/utils/net_lua.c b/source3/utils/net_lua.c
index 3a5d1bdeb6..e4af9b5577 100644
--- a/source3/utils/net_lua.c
+++ b/source3/utils/net_lua.c
@@ -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) {
diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c
index 9d571f7ee3..330e7643cd 100644
--- a/source3/utils/smbcontrol.c
+++ b/source3/utils/smbcontrol.c
@@ -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;
}
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index e881ab412e..cf1dbf6f72 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -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);
}
diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h
index 04b0b39f81..d8e6ec4c7f 100644
--- a/source3/winbindd/winbindd.h
+++ b/source3/winbindd/winbindd.h
@@ -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
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index 3135b6a2a3..e5e3565604 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -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,6 +493,15 @@ void set_domain_online_request(struct winbindd_domain *domain)
because network manager seems to lie.
Wait at least 5 seconds. Heuristics suck... */
+
+ GetTimeOfDay(&tev);
+
+ /* Go into "startup" mode again. */
+ domain->startup_time = tev.tv_sec;
+ domain->startup = True;
+
+ tev.tv_sec += 5;
+
if (!domain->check_online_event) {
/* If we've come from being globally offline we
don't have a check online event handler set.
@@ -505,29 +510,20 @@ void set_domain_online_request(struct winbindd_domain *domain)
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);
-
- /* Go into "startup" mode again. */
- domain->startup_time = tev.tv_sec;
- domain->startup = True;
+ TALLOC_FREE(domain->check_online_event);
- tev.tv_sec += 5;
+ domain->check_online_event = event_add_timed(winbind_event_context(),
+ NULL,
+ tev,
+ check_domain_online_handler,
+ domain);
- set_event_dispatch_time(winbind_event_context(), "check_domain_online_handler", tev);
+ /* 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");
+ }
}
/****************************************************************
diff --git a/source3/winbindd/winbindd_cred_cache.c b/source3/winbindd/winbindd_cred_cache.c
index 311b1d1822..900f9acdfa 100644
--- a/source3/winbindd/winbindd_cred_cache.c
+++ b/source3/winbindd/winbindd_cred_cache.c
@@ -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 */
-
- if ((entry->renew_until < time(NULL)) && cred_ptr && cred_ptr->pass) {
-
- 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();
-
- if (ret) {
- DEBUG(3,("krb5_ticket_refresh_handler: "
- "could not re-kinit: %s\n",
- error_message(ret)));
- 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));
+ * tgt anymore
+ * NB
+ * This happens when machine are put to sleep for a very long time. */
+
+ if (entry->renew_until < time(NULL)) {
+rekinit:
+ if (cred_ptr && cred_ptr->pass) {
+
+ 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();
+
+ 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);
+
+ /* 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);
}
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index 4f1e92ed7c..1499141c34 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -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,33 +1242,34 @@ static bool fork_domain_child(struct winbindd_child *child)
messaging_register(winbind_messaging_context(), NULL,
MSG_DEBUG, debug_message);
+ primary_domain = find_our_domain();
+
+ if (primary_domain == NULL) {
+ smb_panic("no primary domain found");
+ }
+ /* 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);
- }
-
- /* 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);
+ /* 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);
+ }
}
}
- 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 might be in the idmap child...*/
if (child->domain && !(child->domain->internal) &&
lp_winbind_offline_logon()) {
@@ -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);
}
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 3869ac5771..32f057ad61 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -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,