r23779: Change from v2 or later to v3 or later.
[samba.git] / source3 / groupdb / mapping_ldb.c
index c6ff6ca2af8d4464d21a9e6c9e4f875d5f75222d..21da363a530174f1a37a08352560bb2087fe8a7b 100644 (file)
@@ -9,7 +9,7 @@
  *  
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
+ *  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,
@@ -34,7 +34,7 @@ static BOOL mapping_upgrade(const char *tdb_path);
 /*
   connect to the group mapping ldb
 */
- BOOL init_group_mapping(void)
+static BOOL init_group_mapping(void)
 {
        BOOL existed;
        const char *init_ldif[] = 
@@ -44,7 +44,7 @@ static BOOL mapping_upgrade(const char *tdb_path);
                  "dn: @INDEXLIST\n" \
                  "@IDXATTR: gidNumber\n" \
                  "@IDXATTR: ntName\n" \
-                 "@IDXATTR: memberOf\n" };
+                 "@IDXATTR: member\n" };
        const char *db_path, *tdb_path;
        int ret;
        int flags = 0;
@@ -67,6 +67,10 @@ static BOOL mapping_upgrade(const char *tdb_path);
                flags |= LDB_FLG_NOSYNC;
        }
 
+       if (!lp_use_mmap()) {
+               flags |= LDB_FLG_NOMMAP;
+       }
+
        ret = ldb_connect(ldb, db_path, flags, NULL);
        if (ret != LDB_SUCCESS) {
                goto failed;
@@ -121,43 +125,39 @@ static struct ldb_dn *mapping_dn(TALLOC_CTX *mem_ctx, const DOM_SID *sid)
        }
        /* we split by domain and rid so we can do a subtree search
           when we only want one domain */
-       return ldb_dn_string_compose(mem_ctx, NULL, "domain=%s,rid=%u", 
-                                    string_sid, rid);
+       return ldb_dn_string_compose(mem_ctx, NULL, "rid=%u,domain=%s", 
+                                    rid, string_sid);
 }
 
 /*
   add a group mapping entry
  */
- BOOL add_mapping_entry(GROUP_MAP *map, int flag)
+static BOOL add_mapping_entry(GROUP_MAP *map, int flag)
 {
        struct ldb_message *msg;        
        int ret, i;
        fstring string_sid;
 
-       if (!init_group_mapping()) {
+       msg = ldb_msg_new(ldb);
+       if (msg == NULL) {
                return False;
        }
-       
-       msg = ldb_msg_new(ldb);
-       if (msg == NULL) return False;
 
        msg->dn = mapping_dn(msg, &map->sid);
-       if (msg->dn == NULL) goto failed;
+       if (msg->dn == NULL) {
+               goto failed;
+       }
 
        if (ldb_msg_add_string(msg, "objectClass", "groupMap") != LDB_SUCCESS ||
            ldb_msg_add_string(msg, "sid", 
                               sid_to_string(string_sid, &map->sid)) != LDB_SUCCESS ||
            ldb_msg_add_fmt(msg, "gidNumber", "%u", (unsigned)map->gid) != LDB_SUCCESS ||
            ldb_msg_add_fmt(msg, "sidNameUse", "%u", (unsigned)map->sid_name_use) != LDB_SUCCESS ||
+           ldb_msg_add_string(msg, "comment", map->comment) != LDB_SUCCESS ||
            ldb_msg_add_string(msg, "ntName", map->nt_name) != LDB_SUCCESS) {
                goto failed;
        }
 
-       if ((map->comment[0] != '\0') && 
-           (ldb_msg_add_string(msg, "ntName", map->nt_name) != LDB_SUCCESS)) {
-               goto failed;
-       }
-
        ret = ldb_add(ldb, msg);
 
        /* if it exists we update it. This is a hangover from the semantics the
@@ -204,16 +204,12 @@ static BOOL msg_to_group_map(struct ldb_message *msg, GROUP_MAP *map)
 /*
  return a group map entry for a given sid
 */
- BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map)
+static BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map)
 {
        int ret;
        struct ldb_dn *dn;
        struct ldb_result *res=NULL;
        
-       if (!init_group_mapping()) {
-               return False;
-       }
-
        dn = mapping_dn(ldb, &sid);
        if (dn == NULL) goto failed;
 
@@ -236,16 +232,12 @@ failed:
 /*
  return a group map entry for a given gid
 */
- BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map)
+static BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map)
 {
        int ret;
        char *expr;
        struct ldb_result *res=NULL;
 
-       if (!init_group_mapping()) {
-               return False;
-       }
-
        expr = talloc_asprintf(ldb, "(&(gidNumber=%u)(objectClass=groupMap))", 
                               (unsigned)gid);
        if (expr == NULL) goto failed;
@@ -267,16 +259,12 @@ failed:
 /*
   Return the sid and the type of the unix group.
 */
- BOOL get_group_map_from_ntname(const char *name, GROUP_MAP *map)
+static BOOL get_group_map_from_ntname(const char *name, GROUP_MAP *map)
 {
        int ret;
        char *expr;
        struct ldb_result *res=NULL;
 
-       if (!init_group_mapping()) {
-               return False;
-       }
-
        expr = talloc_asprintf(ldb, "(&(ntName=%s)(objectClass=groupMap))", name);
        if (expr == NULL) goto failed;
 
@@ -297,16 +285,15 @@ failed:
 /*
  Remove a group mapping entry.
 */
- BOOL group_map_remove(const DOM_SID *sid)
+static BOOL group_map_remove(const DOM_SID *sid)
 {
        struct ldb_dn *dn;
        int ret;
        
-       if (!init_group_mapping()) {
+       dn = mapping_dn(ldb, sid);
+       if (dn == NULL) {
                return False;
        }
-
-       dn = mapping_dn(ldb, sid);
        ret = ldb_delete(ldb, dn);
        talloc_free(dn);
 
@@ -317,9 +304,9 @@ failed:
 /*
   Enumerate the group mappings for a domain
 */
- BOOL enum_group_mapping(const DOM_SID *domsid, enum lsa_SidType sid_name_use, 
-                        GROUP_MAP **pp_rmap,
-                        size_t *p_num_entries, BOOL unix_only)
+static BOOL enum_group_mapping(const DOM_SID *domsid, enum lsa_SidType sid_name_use, 
+                              GROUP_MAP **pp_rmap,
+                              size_t *p_num_entries, BOOL unix_only)
 {
        int i, ret;
        char *expr;
@@ -328,10 +315,6 @@ failed:
        struct ldb_dn *basedn=NULL;
        TALLOC_CTX *tmp_ctx;
 
-       if (!init_group_mapping()) {
-               return False;
-       }
-
        tmp_ctx = talloc_new(ldb);
        if (tmp_ctx == NULL) goto failed;
 
@@ -380,8 +363,8 @@ failed:
    This operation happens on session setup, so it should better be fast. We
    store a list of aliases a SID is member of hanging off MEMBEROF/SID. 
 */
- NTSTATUS one_alias_membership(const DOM_SID *member,
-                              DOM_SID **sids, size_t *num)
+static NTSTATUS one_alias_membership(const DOM_SID *member,
+                                    DOM_SID **sids, size_t *num)
 {
        const char *attrs[] = {
                "sid",
@@ -393,19 +376,12 @@ failed:
        struct ldb_result *res=NULL;
        fstring string_sid;
        NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
-       
-       if (!init_group_mapping()) {
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
-       *sids = NULL;
-       *num = 0;
 
        if (!sid_to_string(string_sid, member)) {
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       expr = talloc_asprintf(ldb, "(&(memberOf=%s)(objectClass=groupMap))", 
+       expr = talloc_asprintf(ldb, "(&(member=%s)(objectClass=groupMap))", 
                               string_sid);
        if (expr == NULL) goto failed;
 
@@ -423,8 +399,7 @@ failed:
                        goto failed;
                }
                string_to_sid(&alias, (char *)el->values[0].data);
-               add_sid_to_array_unique(NULL, &alias, sids, num);
-               if (sids == NULL) {
+               if (!add_sid_to_array_unique(NULL, &alias, sids, num)) {
                        status = NT_STATUS_NO_MEMORY;
                        goto failed;
                }
@@ -439,7 +414,7 @@ failed:
 }
 
 /*
-  add/remove a memberOf field
+  add/remove a member field
 */
 static NTSTATUS modify_aliasmem(const DOM_SID *alias, const DOM_SID *member,
                                int operation)
@@ -452,10 +427,6 @@ static NTSTATUS modify_aliasmem(const DOM_SID *alias, const DOM_SID *member,
        TALLOC_CTX *tmp_ctx;
        GROUP_MAP map;
 
-       if (!init_group_mapping()) {
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
        if (!get_group_map_from_sid(*alias, &map)) {
                sid_to_string(string_sid, alias);
                return NT_STATUS_NO_SUCH_ALIAS;
@@ -473,10 +444,13 @@ static NTSTATUS modify_aliasmem(const DOM_SID *alias, const DOM_SID *member,
        }
 
        msg.dn = mapping_dn(tmp_ctx, alias);
+       if (msg.dn == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
        msg.num_elements = 1;
        msg.elements = ⪙
        el.flags = operation;
-       el.name = talloc_strdup(tmp_ctx, "memberOf");
+       el.name = talloc_strdup(tmp_ctx, "member");
        el.num_values = 1;
        el.values = &val;
        sid_to_string(string_sid, member);
@@ -498,24 +472,24 @@ static NTSTATUS modify_aliasmem(const DOM_SID *alias, const DOM_SID *member,
        return (ret == LDB_SUCCESS ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED);
 }
 
- NTSTATUS add_aliasmem(const DOM_SID *alias, const DOM_SID *member)
+static NTSTATUS add_aliasmem(const DOM_SID *alias, const DOM_SID *member)
 {
        return modify_aliasmem(alias, member, LDB_FLAG_MOD_ADD);
 }
 
- NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
+static NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
 {
        return modify_aliasmem(alias, member, LDB_FLAG_MOD_DELETE);
 }
 
 
 /*
-  enumerate sids that have the given alias set in memberOf
+  enumerate sids that have the given alias set in member
 */
- NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, size_t *num)
+static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, size_t *num)
 {
        const char *attrs[] = {
-               "memberOf",
+               "member",
                NULL
        };
        int ret, i;
@@ -523,14 +497,13 @@ static NTSTATUS modify_aliasmem(const DOM_SID *alias, const DOM_SID *member,
        struct ldb_dn *dn;
        struct ldb_message_element *el;
        
-       if (!init_group_mapping()) {
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
        *sids = NULL;
        *num = 0;
 
        dn = mapping_dn(ldb, alias);
+       if (dn == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
        ret = ldb_search(ldb, dn, LDB_SCOPE_BASE, NULL, attrs, &res);
        talloc_steal(dn, res);
@@ -543,7 +516,7 @@ static NTSTATUS modify_aliasmem(const DOM_SID *alias, const DOM_SID *member,
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
-       el = ldb_msg_find_element(res->msgs[0], "memberOf");
+       el = ldb_msg_find_element(res->msgs[0], "member");
        if (el == NULL) {
                talloc_free(dn);
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
@@ -552,8 +525,7 @@ static NTSTATUS modify_aliasmem(const DOM_SID *alias, const DOM_SID *member,
        for (i=0;i<el->num_values;i++) {
                DOM_SID sid;
                string_to_sid(&sid, (const char *)el->values[i].data);
-               add_sid_to_array_unique(NULL, &sid, sids, num);
-               if (sids == NULL) {
+               if (!add_sid_to_array_unique(NULL, &sid, sids, num)) {
                        talloc_free(dn);
                        return NT_STATUS_NO_MEMORY;
                }
@@ -572,7 +544,7 @@ static int upgrade_map_record(TDB_CONTEXT *tdb_ctx, TDB_DATA key,
        int ret;
        GROUP_MAP map;
 
-       if (strncmp(key.dptr, GROUP_PREFIX, 
+       if (strncmp((char *)key.dptr, GROUP_PREFIX, 
                    MIN(key.dsize, strlen(GROUP_PREFIX))) != 0) {
                return 0;
        }
@@ -606,11 +578,11 @@ static int upgrade_map_record(TDB_CONTEXT *tdb_ctx, TDB_DATA key,
 static int upgrade_alias_record(TDB_CONTEXT *tdb_ctx, TDB_DATA key, 
                                TDB_DATA data, void *state)
 {
-       const char *p = data.dptr;
+       const char *p = (const char *)data.dptr;
        fstring string_sid;
        DOM_SID member;
 
-       if (strncmp(key.dptr, MEMBEROF_PREFIX, 
+       if (strncmp((char *)key.dptr, MEMBEROF_PREFIX, 
                    MIN(key.dsize, strlen(MEMBEROF_PREFIX))) != 0) {
                return 0;
        }
@@ -661,7 +633,10 @@ static BOOL mapping_upgrade(const char *tdb_path)
        ret = tdb_traverse(tdb, upgrade_alias_record, &status);
        if (ret == -1 || status == -1) goto failed;
 
-       if (tdb) tdb_close(tdb);
+       if (tdb) {
+               tdb_close(tdb);
+               tdb = NULL;
+       }
 
        pstrcpy(old_path, tdb_path);
        pstrcpy(new_path, lock_path("group_mapping.tdb.upgraded"));
@@ -677,3 +652,31 @@ failed:
        if (tdb) tdb_close(tdb);
        return False;
 }
+
+
+
+static const struct mapping_backend ldb_backend = {
+       .add_mapping_entry         = add_mapping_entry,
+       .get_group_map_from_sid    = get_group_map_from_sid,
+       .get_group_map_from_gid    = get_group_map_from_gid,
+       .get_group_map_from_ntname = get_group_map_from_ntname,
+       .group_map_remove          = group_map_remove,
+       .enum_group_mapping        = enum_group_mapping,
+       .one_alias_membership      = one_alias_membership,
+       .add_aliasmem              = add_aliasmem,
+       .del_aliasmem              = del_aliasmem,
+       .enum_aliasmem             = enum_aliasmem      
+};
+
+/*
+  initialise the ldb mapping backend
+ */
+const struct mapping_backend *groupdb_ldb_init(void)
+{
+       if (!init_group_mapping()) {
+               DEBUG(0,("Failed to initialise ldb mapping backend\n"));
+               return NULL;
+       }
+
+       return &ldb_backend;
+}