s3-id_cache: Move id caches mgmt out of smbd
authorAndreas Schneider <asn@samba.org>
Fri, 19 Aug 2011 15:28:37 +0000 (17:28 +0200)
committerSimo Sorce <idra@samba.org>
Sun, 21 Aug 2011 13:08:25 +0000 (09:08 -0400)
We must leave the MSG_IDMAP_KILL operation in SMBD as it uses smbd
specific internal globals and makes sense only in the context of a smbd
daemon.
The rest is moved under lib/ as we need to deal with id cache cleanups
in other daemons too (like lsasd).

Signed-off-by: Simo Sorce <idra@samba.org>
source3/Makefile.in
source3/lib/id_cache.c [new file with mode: 0644]
source3/lib/id_cache.h [new file with mode: 0644]
source3/passdb/lookup_sid.c
source3/passdb/lookup_sid.h
source3/smbd/msg_idmap.c
source3/smbd/proto.h
source3/smbd/server.c
source3/wscript_build

index 4937f3003ec23ecd946f60052240a5334ae358d0..39e62cce39960065e6b00458ee3c8288fd73933c 100644 (file)
@@ -431,6 +431,7 @@ CRYPTO_OBJ = ../lib/crypto/crc32.o ../lib/crypto/md5.o \
 LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) $(LIBTSOCKET_OBJ) \
          lib/messages.o librpc/gen_ndr/ndr_messaging.o lib/messages_local.o \
          lib/messages_ctdbd.o lib/ctdb_packet.o lib/ctdbd_conn.o \
+         lib/id_cache.o \
          ../lib/socket/interfaces.o lib/memcache.o \
          lib/talloc_dict.o \
          lib/serverid.o \
diff --git a/source3/lib/id_cache.c b/source3/lib/id_cache.c
new file mode 100644 (file)
index 0000000..50649dd
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Samba Unix/Linux SMB client library
+ *
+ * Copyright (C) Gregor Beck 2011
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @brief  Notify smbd about idmap changes
+ * @file   msg_idmap.c
+ * @author Gregor Beck <gb@sernet.de>
+ * @date   Feb 2011
+ *
+ */
+
+#include "includes.h"
+#include "messages.h"
+#include "lib/id_cache.h"
+#include "include/memcache.h"
+#include "idmap_cache.h"
+#include "../librpc/gen_ndr/ndr_security.h"
+#include "../libcli/security/dom_sid.h"
+
+bool id_cache_ref_parse(const char* str, struct id_cache_ref* id)
+{
+       struct dom_sid sid;
+       unsigned long ul;
+       char c, trash;
+
+       if (sscanf(str, "%cID %lu%c", &c, &ul, &trash) == 2) {
+               switch(c) {
+               case 'G':
+                       id->id.gid = ul;
+                       id->type = GID;
+                       return true;
+               case 'U':
+                       id->id.uid = ul;
+                       id->type = UID;
+                       return true;
+               default:
+                       break;
+               }
+       } else if (string_to_sid(&sid, str)) {
+               id->id.sid = sid;
+               id->type = SID;
+               return true;
+       }
+       return false;
+}
+
+static bool delete_uid_cache(uid_t puid)
+{
+       DATA_BLOB uid = data_blob_const(&puid, sizeof(puid));
+       DATA_BLOB sid;
+
+       if (!memcache_lookup(NULL, UID_SID_CACHE, uid, &sid)) {
+               DEBUG(3, ("UID %d is not memcached!\n", (int)puid));
+               return false;
+       }
+       DEBUG(3, ("Delete mapping UID %d <-> %s from memcache\n", (int)puid,
+                 sid_string_dbg((struct dom_sid*)sid.data)));
+       memcache_delete(NULL, SID_UID_CACHE, sid);
+       memcache_delete(NULL, UID_SID_CACHE, uid);
+       return true;
+}
+
+static bool delete_gid_cache(gid_t pgid)
+{
+       DATA_BLOB gid = data_blob_const(&pgid, sizeof(pgid));
+       DATA_BLOB sid;
+       if (!memcache_lookup(NULL, GID_SID_CACHE, gid, &sid)) {
+               DEBUG(3, ("GID %d is not memcached!\n", (int)pgid));
+               return false;
+       }
+       DEBUG(3, ("Delete mapping GID %d <-> %s from memcache\n", (int)pgid,
+                 sid_string_dbg((struct dom_sid*)sid.data)));
+       memcache_delete(NULL, SID_GID_CACHE, sid);
+       memcache_delete(NULL, GID_SID_CACHE, gid);
+       return true;
+}
+
+static bool delete_sid_cache(const struct dom_sid* psid)
+{
+       DATA_BLOB sid = data_blob_const(psid, ndr_size_dom_sid(psid, 0));
+       DATA_BLOB id;
+       if (memcache_lookup(NULL, SID_GID_CACHE, sid, &id)) {
+               DEBUG(3, ("Delete mapping %s <-> GID %d from memcache\n",
+                         sid_string_dbg(psid), *(int*)id.data));
+               memcache_delete(NULL, SID_GID_CACHE, sid);
+               memcache_delete(NULL, GID_SID_CACHE, id);
+       } else if (memcache_lookup(NULL, SID_UID_CACHE, sid, &id)) {
+               DEBUG(3, ("Delete mapping %s <-> UID %d from memcache\n",
+                         sid_string_dbg(psid), *(int*)id.data));
+               memcache_delete(NULL, SID_UID_CACHE, sid);
+               memcache_delete(NULL, UID_SID_CACHE, id);
+       } else {
+               DEBUG(3, ("SID %s is not memcached!\n", sid_string_dbg(psid)));
+               return false;
+       }
+       return true;
+}
+
+static void flush_gid_cache(void)
+{
+       DEBUG(3, ("Flush GID <-> SID memcache\n"));
+       memcache_flush(NULL, SID_GID_CACHE);
+       memcache_flush(NULL, GID_SID_CACHE);
+}
+
+static void flush_uid_cache(void)
+{
+       DEBUG(3, ("Flush UID <-> SID memcache\n"));
+       memcache_flush(NULL, SID_UID_CACHE);
+       memcache_flush(NULL, UID_SID_CACHE);
+}
+static void delete_from_cache(const struct id_cache_ref* id)
+{
+       switch(id->type) {
+       case UID:
+               delete_uid_cache(id->id.uid);
+               idmap_cache_del_uid(id->id.uid);
+               break;
+       case GID:
+               delete_gid_cache(id->id.gid);
+               idmap_cache_del_gid(id->id.gid);
+               break;
+       case SID:
+               delete_sid_cache(&id->id.sid);
+               idmap_cache_del_sid(&id->id.sid);
+               break;
+       default:
+               break;
+       }
+}
+
+
+static void message_idmap_flush(struct messaging_context *msg_ctx,
+                               void* private_data,
+                               uint32_t msg_type,
+                               struct server_id server_id,
+                               DATA_BLOB* data)
+{
+       const char *msg = data ? (const char *)data->data : NULL;
+
+       if ((msg == NULL) || (msg[0] == '\0')) {
+               flush_gid_cache();
+               flush_uid_cache();
+       } else if (strncmp(msg, "GID", 3)) {
+               flush_gid_cache();
+       } else if (strncmp(msg, "UID", 3)) {
+               flush_uid_cache();
+       } else {
+               DEBUG(0, ("Invalid argument: %s\n", msg));
+       }
+}
+
+static void message_idmap_delete(struct messaging_context *msg_ctx,
+                                void *private_data,
+                                uint32_t msg_type,
+                                struct server_id server_id,
+                                DATA_BLOB* data)
+{
+       const char *msg = (data && data->data) ? (const char *)data->data : "<NULL>";
+       struct id_cache_ref id;
+
+       if (!id_cache_ref_parse(msg, &id)) {
+               DEBUG(0, ("Invalid ?ID: %s\n", msg));
+               return;
+       }
+
+       delete_from_cache(&id);
+}
+
+void msg_idmap_register_msgs(struct messaging_context *ctx)
+{
+       messaging_register(ctx, NULL, MSG_IDMAP_FLUSH,  message_idmap_flush);
+       messaging_register(ctx, NULL, MSG_IDMAP_DELETE, message_idmap_delete);
+}
diff --git a/source3/lib/id_cache.h b/source3/lib/id_cache.h
new file mode 100644 (file)
index 0000000..fc78f75
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Samba Unix/Linux SMB client library
+ *
+ * Copyright (C) Gregor Beck 2011
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+struct id_cache_ref {
+       union {
+               uid_t uid;
+               gid_t gid;
+               struct dom_sid sid;
+               const char *name;
+       } id;
+       enum {UID, GID, SID, NAME} type;
+};
+
+bool id_cache_ref_parse(const char* str, struct id_cache_ref* id);
+
+void msg_idmap_register_msgs(struct messaging_context *ctx);
index 8b5330c097452827b3546a3ef309fe07057b4fa3..4c2e73befd64d50d1ba07db5298cb0c30eecfb1c 100644 (file)
@@ -1745,68 +1745,3 @@ done:
        return NT_STATUS_OK;
 }
 
-bool delete_uid_cache(uid_t puid)
-{
-       DATA_BLOB uid = data_blob_const(&puid, sizeof(puid));
-       DATA_BLOB sid;
-
-       if (!memcache_lookup(NULL, UID_SID_CACHE, uid, &sid)) {
-               DEBUG(3, ("UID %d is not memcached!\n", (int)puid));
-               return false;
-       }
-       DEBUG(3, ("Delete mapping UID %d <-> %s from memcache\n", (int)puid,
-                 sid_string_dbg((struct dom_sid*)sid.data)));
-       memcache_delete(NULL, SID_UID_CACHE, sid);
-       memcache_delete(NULL, UID_SID_CACHE, uid);
-       return true;
-}
-
-bool delete_gid_cache(gid_t pgid)
-{
-       DATA_BLOB gid = data_blob_const(&pgid, sizeof(pgid));
-       DATA_BLOB sid;
-       if (!memcache_lookup(NULL, GID_SID_CACHE, gid, &sid)) {
-               DEBUG(3, ("GID %d is not memcached!\n", (int)pgid));
-               return false;
-       }
-       DEBUG(3, ("Delete mapping GID %d <-> %s from memcache\n", (int)pgid,
-                 sid_string_dbg((struct dom_sid*)sid.data)));
-       memcache_delete(NULL, SID_GID_CACHE, sid);
-       memcache_delete(NULL, GID_SID_CACHE, gid);
-       return true;
-}
-
-bool delete_sid_cache(const struct dom_sid* psid)
-{
-       DATA_BLOB sid = data_blob_const(psid, ndr_size_dom_sid(psid, 0));
-       DATA_BLOB id;
-       if (memcache_lookup(NULL, SID_GID_CACHE, sid, &id)) {
-               DEBUG(3, ("Delete mapping %s <-> GID %d from memcache\n",
-                         sid_string_dbg(psid), *(int*)id.data));
-               memcache_delete(NULL, SID_GID_CACHE, sid);
-               memcache_delete(NULL, GID_SID_CACHE, id);
-       } else if (memcache_lookup(NULL, SID_UID_CACHE, sid, &id)) {
-               DEBUG(3, ("Delete mapping %s <-> UID %d from memcache\n",
-                         sid_string_dbg(psid), *(int*)id.data));
-               memcache_delete(NULL, SID_UID_CACHE, sid);
-               memcache_delete(NULL, UID_SID_CACHE, id);
-       } else {
-               DEBUG(3, ("SID %s is not memcached!\n", sid_string_dbg(psid)));
-               return false;
-       }
-       return true;
-}
-
-void flush_gid_cache(void)
-{
-       DEBUG(3, ("Flush GID <-> SID memcache\n"));
-       memcache_flush(NULL, SID_GID_CACHE);
-       memcache_flush(NULL, GID_SID_CACHE);
-}
-
-void flush_uid_cache(void)
-{
-       DEBUG(3, ("Flush UID <-> SID memcache\n"));
-       memcache_flush(NULL, SID_UID_CACHE);
-       memcache_flush(NULL, UID_SID_CACHE);
-}
index b56aaba039586c58b7d09feafeb83aaa8752a049..5ce455d08bd90ae3e9633d151603d5ac0fefb8cc 100644 (file)
@@ -91,10 +91,5 @@ NTSTATUS get_primary_group_sid(TALLOC_CTX *mem_ctx,
                                const char *username,
                                struct passwd **_pwd,
                                struct dom_sid **_group_sid);
-bool delete_uid_cache(uid_t uid);
-bool delete_gid_cache(gid_t gid);
-bool delete_sid_cache(const struct dom_sid* psid);
-void flush_uid_cache(void);
-void flush_gid_cache(void);
 
 #endif /* _PASSDB_LOOKUP_SID_H_ */
index e87b3134934a830bb3aa0e802e05e0dc84659ec0..0a24bb1626832cf275dc63a84297f05155518327 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-/**
- * @brief  Notify smbd about idmap changes
- * @file   msg_idmap.c
- * @author Gregor Beck <gb@sernet.de>
- * @date   Feb 2011
- *
- */
-
 #include "includes.h"
+#include "smbd/globals.h"
 #include "smbd/smbd.h"
-#include "globals.h"
 #include "../libcli/security/dom_sid.h"
 #include "idmap_cache.h"
 #include "passdb/lookup_sid.h"
 #include "auth.h"
 #include "messages.h"
-
-struct id {
-       union {
-               uid_t uid;
-               gid_t gid;
-               struct dom_sid sid;
-       } id;
-       enum {UID, GID, SID} type;
-};
-
-static bool parse_id(const char* str, struct id* id)
-{
-       struct dom_sid sid;
-       unsigned long ul;
-       char c, trash;
-
-       if (sscanf(str, "%cID %lu%c", &c, &ul, &trash) == 2) {
-               switch(c) {
-               case 'G':
-                       id->id.gid = ul;
-                       id->type = GID;
-                       return true;
-               case 'U':
-                       id->id.uid = ul;
-                       id->type = UID;
-                       return true;
-               default:
-                       break;
-               }
-       } else if (string_to_sid(&sid, str)) {
-               id->id.sid = sid;
-               id->type = SID;
-               return true;
-       }
-       return false;
-}
+#include "lib/id_cache.h"
 
 static bool uid_in_use(const struct user_struct* user, uid_t uid)
 {
@@ -113,8 +70,8 @@ static bool sid_in_use(const struct user_struct* user, const struct dom_sid* psi
        return false;
 }
 
-
-static bool id_in_use(const struct user_struct* user, const struct id* id)
+static bool id_in_use(const struct user_struct* user,
+                     const struct id_cache_ref* id)
 {
        switch(id->type) {
        case UID:
@@ -129,74 +86,27 @@ static bool id_in_use(const struct user_struct* user, const struct id* id)
        return false;
 }
 
-static void delete_from_cache(const struct id* id)
-{
-       switch(id->type) {
-       case UID:
-               delete_uid_cache(id->id.uid);
-               idmap_cache_del_uid(id->id.uid);
-               break;
-       case GID:
-               delete_gid_cache(id->id.gid);
-               idmap_cache_del_gid(id->id.gid);
-               break;
-       case SID:
-               delete_sid_cache(&id->id.sid);
-               idmap_cache_del_sid(&id->id.sid);
-               break;
-       default:
-               break;
-       }
-}
-
-
-static void message_idmap_flush(struct messaging_context *msg_ctx,
-                               void* private_data,
-                               uint32_t msg_type,
-                               struct server_id server_id,
-                               DATA_BLOB* data)
-{
-       const char *msg = data ? (const char *)data->data : NULL;
-
-       if ((msg == NULL) || (msg[0] == '\0')) {
-               flush_gid_cache();
-               flush_uid_cache();
-       } else if (strncmp(msg, "GID", 3)) {
-               flush_gid_cache();
-       } else if (strncmp(msg, "UID", 3)) {
-               flush_uid_cache();
-       } else {
-               DEBUG(0, ("Invalid argument: %s\n", msg));
-       }
-}
-
-
-static void message_idmap_delete(struct messaging_context *msg_ctx,
+static void message_idmap_kill(struct messaging_context *msg_ctx,
                                 void *private_data,
                                 uint32_t msg_type,
                                 struct server_id server_id,
                                 DATA_BLOB* data)
 {
        const char *msg = (data && data->data) ? (const char *)data->data : "<NULL>";
-       bool do_kill = (msg_type == MSG_IDMAP_KILL);
        struct user_struct *validated_users = smbd_server_conn->smb1.sessions.validated_users;
-       struct id id;
+       struct id_cache_ref id;
 
-       if (!parse_id(msg, &id)) {
+       if (!id_cache_ref_parse(msg, &id)) {
                DEBUG(0, ("Invalid ?ID: %s\n", msg));
                return;
        }
 
-       if (do_kill && id_in_use(validated_users, &id)) {
+       if (id_in_use(validated_users, &id)) {
                exit_server_cleanly(msg);
-       } else {
-               delete_from_cache(&id);
        }
 }
 
-void msg_idmap_register_msgs(struct messaging_context *ctx)
+void msg_idmap_register_kill_msg(struct messaging_context *ctx)
 {
-       messaging_register(ctx, NULL, MSG_IDMAP_FLUSH,  message_idmap_flush);
-       messaging_register(ctx, NULL, MSG_IDMAP_DELETE, message_idmap_delete);
-       messaging_register(ctx, NULL, MSG_IDMAP_KILL,   message_idmap_delete);
+       messaging_register(ctx, NULL, MSG_IDMAP_KILL, message_idmap_kill);
 }
index d1408134384f3061d49ab89b88782f16d33cfecd..554d907d896a9b2648fc99baabbcbb49dbed1f6d 100644 (file)
@@ -1182,6 +1182,6 @@ void *avahi_start_register(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 
 /* The following definitions come from smbd/msg_idmap.c */
 
-void msg_idmap_register_msgs(struct messaging_context *ctx);
+void msg_idmap_register_kill_msg(struct messaging_context *ctx);
 
 #endif /* _SMBD_PROTO_H_ */
index cc53f6962686df803e2ad310bddfa2d0a1616001..e547d38581b194a96d28d43bccd2d8dc592e66ff 100644 (file)
@@ -39,6 +39,7 @@
 #include "auth.h"
 #include "messages.h"
 #include "smbprofile.h"
+#include "lib/id_cache.h"
 
 extern void start_epmd(struct tevent_context *ev_ctx,
                       struct messaging_context *msg_ctx);
@@ -749,6 +750,7 @@ static bool open_sockets_smbd(struct smbd_parent_context *parent,
        brl_register_msgs(msg_ctx);
 
        msg_idmap_register_msgs(msg_ctx);
+       msg_idmap_register_kill_msg(msg_ctx);
 
 #ifdef CLUSTER_SUPPORT
        if (lp_clustering()) {
index 3d4e3b43ccb4e3c409043718214cae6ccfe9a9b6..46e9a853879943199450e85a88b4df6ac3bb84dd 100755 (executable)
@@ -55,6 +55,7 @@ REG_PARSE_PRS_SRC = '''registry/reg_parse_prs.c'''
 LIB_SRC = '''
           lib/messages.c lib/messages_local.c
           lib/messages_ctdbd.c lib/ctdb_packet.c lib/ctdbd_conn.c
+          lib/id_cache.c
           lib/talloc_dict.c
           lib/util_sconn.c
           lib/serverid.c