Merge branch 'master' of ssh://git.samba.org/data/git/samba
authorJelmer Vernooij <jelmer@samba.org>
Mon, 5 Jan 2009 17:01:04 +0000 (18:01 +0100)
committerJelmer Vernooij <jelmer@samba.org>
Mon, 5 Jan 2009 17:01:04 +0000 (18:01 +0100)
37 files changed:
docs-xml/manpages-3/smbclient.1.xml
examples/perfcounter/perfcountd.init
nsswitch/winbind_struct_protocol.h
source3/Makefile.in
source3/client/client.c
source3/configure.in
source3/include/event.h
source3/include/includes.h
source3/include/proto.h
source3/include/smb.h
source3/lib/async_req.c
source3/lib/ctdbd_conn.c
source3/lib/events.c
source3/lib/smbldap.c
source3/lib/util.c
source3/modules/vfs_aio_fork.c
source3/nmbd/asyncdns.c
source3/nmbd/nmbd.c
source3/nmbd/nmbd_processlogon.c
source3/printing/notify.c
source3/printing/print_cups.c
source3/printing/printing.c
source3/rpc_server/srv_samr_nt.c
source3/smbd/blocking.c
source3/smbd/dnsregister.c
source3/smbd/fileio.c
source3/smbd/oplock.c
source3/smbd/process.c
source3/smbd/server.c
source3/utils/net_lua.c
source3/utils/smbcontrol.c
source3/winbindd/winbindd.c
source3/winbindd/winbindd.h
source3/winbindd/winbindd_cm.c
source3/winbindd/winbindd_cred_cache.c
source3/winbindd/winbindd_dual.c
source3/winbindd/winbindd_proto.h

index e2662cc08dc3c28e770ff7ac8e21d760dd1e6cb0..188ff11bb090ee02ccbb43fd73046c2c5383cab3 100644 (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>
                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 
                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 
index 683e91395b1558d6ae4f74305cc9a6404e4dd3ae..0beff9622760be78a72b5df2cd717fdfc9c6eaed 100755 (executable)
 
 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
index fe3da817910eb107c6dd8b5d686c4d3801b6e3bc..0b3e74492c5cdda5c209d75ee0f7873b0011af32 100644 (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
index c13f5ae20a8eddca80fa4e1064e43061a1d23d22..d938b94ee0e5ca8143e7199fb356addda42a9442 100644 (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
index 529f21ab302d649d9dc0d475d3f40d9d8f15b77f..c40c04e9c676b35051186cb727f5d08acc0d8e99 100644 (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*",
index fc3cb261d4331e2be49f524251e6aac1c5b7ea6e..6727181e1c3994a45bcb239ac18803f7ae7a9ef8 100644 (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"
index 0465fae471f4e3829ad99ec0cb617ff59e9de48f..93112a86fa3fa5d8e389de45e16d26c8f1099720 100644 (file)
    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);
 
index 64be27336d0e2f9d12d03fef6eddca817f1376a1..8b0ff71c4ec4a0ac236cfe8e36bb379c4d49f3d2 100644 (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"
index 09f12ceb86ef1cf44d0fe48f4fddfd91de227aae..22183118e26cda8240d5ff4f6b955383afe7c1cc 100644 (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);
index 7fd4fbb553cc2a9974d31b2f16946e306ff38097..9f6a6f02d788c573a8cc84ae135eb329d42bc01c 100644 (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;
index ac06df65a3ab92e400be12e3e4b425b7b8026a11..13b64ba79aa0b071247eaeb34108d7fc70607527 100644 (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) {
index 75a513312e21f27d93f35f7d6af4f894f6f87f65..c94ef802c4b68a5371df2d5027698d92dca645b9 100644 (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) {
index 8bbc9497ac7ec9642ca55d2c160820ac2050da47..be2fdcb68f3950c9b757631485878b43786e0606 100644 (file)
 */
 
 #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");
+}
index f2161dc946f4f15247782248494f9051442a9166..f0561a5081ef8d8812f315cf9d4faec764c84a8e 100644 (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;
        }
index d00a764c1d543dbb377cfdd13cdb4a4c51717b6e..08ea5add7a559a0bf83c02fae6ea99c5c7d7397e 100644 (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;
 }
 
index 7914e8f4014519e8392c7eca6ed755746005d34f..30b14f280f2a741201c0e16d15c59b55ad73b4c4 100644 (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);
index ab9b1ed740eeb1b324e4e506ecf8037a5fd60b74..baa88bc44b5be24d6a392329eb8cbef78f897d17 100644 (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");
        }
index d1ab3aaacbd9e43dfefa2e47b9d778137ebbcd3a..659db85e69f480da035444f952a7da387ec86b7b 100644 (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);
        }
index 565d81f82d46d409a13234a96a932bb561dba36a..a4ef528133b8b19293b3010e5d37bb13155f8852 100644 (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 {
index b24a8a52f599048961f88282669448b6631f8f8a..860a400d64902c60e9e28664c151a6ea17745706 100644 (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);
        }
 
index 5fb1d379a6322563759a33f79f263924ffe5ba95..d75d635779d05b915db495e5d5dd54aa82435fe7 100644 (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");
        }
index ba88f8ee566fe5f19559bed78f9a115e083bbbee..0f38aeab8063356041337b80300096ae6cfb67d8 100644 (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");
                }
index 342f432c4ef3d058c65766dacf2662e44e9ee86b..24d14d720fc23963f357c7488584a802c9043dec 100644 (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);
 }
 
index 2237a89ace6be3d9e8b9df1e369a1523843cfa46..2b90d24c878ec1e328e184cc58c296d4703c92ad 100644 (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;
        }
index 2319097ca564bd6371b4541c050b871c0070c7ec..c092251feec63169a86d09a8143ab7fd0d292d32 100644 (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);
 
index e67f926a049f5d4d5c3b5b44bc53ea42533e619f..30253d44664af9a9ed65382bfb67c87e2dcba75a 100644 (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);
 }
 
index 261d8fd6702def7e9dec90b875adaf2dc7832662..6efa3dcfc62e08d76a79e6f774c853e639581d9e 100644 (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) {
index 67e6067b260667e3c64e615cb184799396a14772..cd9eaa6b1ed87915b3059e1abcf24e8b37ef2869 100644 (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;
 }
 
index 254180ae1ca2603d47ba7f55401a76990a7ea220..a84b58a05287b72f4f828ede8b6bd7b1b65f486e 100644 (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);
        }
index 3a5d1bdeb676426fe681140469be716bfc62c49b..e4af9b55777bc2e6be2a2d7e2d8a08a96fca2fce 100644 (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) {
index 9d571f7ee39c7e62795fa5b62dcafd51b2be934e..330e7643cdf44323d9d6504d12b047aa5b714dc5 100644 (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;
        }
index e881ab412ecafac1ca22fe1f3e950efd810e2c05..cf1dbf6f7261d7bd543ca22fce69316cbc83c086 100644 (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);
        }
index 04b0b39f81a75342889ba60adc8cf5aee1064031..d8e6ec4c7fcd63cc2b26d4bd783ce35100a20bfb 100644 (file)
 
 #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
index 3135b6a2a3e31693ee6d785b7991b2c9b2b09f7e..e5e356560453d90fc9a94b2c40823af8fea8f247 100644 (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,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");
+       }
 }
 
 /****************************************************************
index 311b1d18228f7c6760dedf00e8e4c52768f99564..900f9acdfabe4d7499e2d6a86f3d3576a9b6a1e0 100644 (file)
 #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);
        }
index 4f1e92ed7c15a838e7bd8d557b300203ad8d2d22..1499141c34f74b837f90c20c6b89a2237cd3bfa4 100644 (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,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);
                }
index 3869ac57712b6c7423bf3a5bc67a40fad0be5ba8..32f057ad61e7b38d33727efeaf2b31810901eef1 100644 (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,