Fix include paths to new location of libutil.
[bbaumbach/samba-autobuild/.git] / source4 / dsdb / common / sidmap.c
index 70bf8f0ecb80d8890c70e1ab422c315c4ca2e302..31b56ea52f0418a1b988f976acfb9ab526bf9264 100644 (file)
@@ -7,7 +7,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,
@@ -16,8 +16,7 @@
    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, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "dsdb/common/flags.h"
 #include "dsdb/samdb/samdb.h"
 #include "auth/auth.h"
-#include "libcli/ldap/ldap.h"
-#include "db_wrap.h"
+#include "libcli/ldap/ldap_ndr.h"
+#include "lib/ldb/include/ldb.h"
+#include "../lib/util/util_ldb.h"
 #include "libcli/security/security.h"
+#include "param/param.h"
 
 /*
   these are used for the fallback local uid/gid to sid mapping
@@ -48,14 +49,15 @@ struct sidmap_context {
 /*
   open a sidmap context - use talloc_free to close
 */
-_PUBLIC_ struct sidmap_context *sidmap_open(TALLOC_CTX *mem_ctx)
+struct sidmap_context *sidmap_open(TALLOC_CTX *mem_ctx, struct event_context *ev_ctx, 
+                                  struct loadparm_context *lp_ctx)
 {
        struct sidmap_context *sidmap;
        sidmap = talloc(mem_ctx, struct sidmap_context);
        if (sidmap == NULL) {
                return NULL;
        }
-       sidmap->samctx = samdb_connect(sidmap, system_session(sidmap));
+       sidmap->samctx = samdb_connect(sidmap, ev_ctx, lp_ctx, system_session(sidmap, lp_ctx));
        if (sidmap->samctx == NULL) {
                talloc_free(sidmap);
                return NULL;
@@ -69,26 +71,26 @@ _PUBLIC_ struct sidmap_context *sidmap_open(TALLOC_CTX *mem_ctx)
   check the sAMAccountType field of a search result to see if
   the account is a user account
 */
-static BOOL is_user_account(struct ldb_message *res)
+static bool is_user_account(struct ldb_message *res)
 {
        uint_t atype = samdb_result_uint(res, "sAMAccountType", 0);
        if (atype && (!(atype & ATYPE_ACCOUNT))) {
-               return False;
+               return false;
        }
-       return True;
+       return true;
 }
 
 /*
   check the sAMAccountType field of a search result to see if
   the account is a group account
 */
-static BOOL is_group_account(struct ldb_message *res)
+static bool is_group_account(struct ldb_message *res)
 {
        uint_t atype = samdb_result_uint(res, "sAMAccountType", 0);
        if (atype && atype == ATYPE_NORMAL_ACCOUNT) {
-               return False;
+               return false;
        }
-       return True;
+       return true;
 }
 
 
@@ -122,11 +124,11 @@ static NTSTATUS sidmap_primary_domain_sid(struct sidmap_context *sidmap,
 /*
   map a sid to a unix uid
 */
-_PUBLIC_ NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, 
-                                       struct dom_sid *sid, uid_t *uid)
+NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap,
+                                       const struct dom_sid *sid, uid_t *uid)
 {
-       const char *attrs[] = { "sAMAccountName", "uidNumber", 
-                               "sAMAccountType", NULL };
+       const char *attrs[] = { "sAMAccountName", "uidNumber",
+                               "sAMAccountType", "unixName", NULL };
        int ret;
        const char *s;
        TALLOC_CTX *tmp_ctx;
@@ -136,15 +138,17 @@ _PUBLIC_ NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap,
 
        tmp_ctx = talloc_new(sidmap);
 
-       ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, 
-                          "objectSid=%s", ldap_encode_ndr_dom_sid(tmp_ctx, sid));
+       ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs,
+                          "objectSid=%s",
+                          ldap_encode_ndr_dom_sid(tmp_ctx, sid));
+
        if (ret != 1) {
                goto allocated_sid;
        }
 
        /* make sure its a user, not a group */
        if (!is_user_account(res[0])) {
-               DEBUG(0,("sid_to_unixuid: sid %s is not an account!\n", 
+               DEBUG(0,("sid_to_unixuid: sid %s is not an account!\n",
                         dom_sid_string(tmp_ctx, sid)));
                talloc_free(tmp_ctx);
                return NT_STATUS_INVALID_SID;
@@ -211,17 +215,58 @@ allocated_sid:
                 dom_sid_string(tmp_ctx, sid)));
 
        talloc_free(tmp_ctx);
-       return NT_STATUS_INVALID_SID;
+       return NT_STATUS_NONE_MAPPED;
 }
 
 
+/*
+  see if a sid is a group - very inefficient!
+*/
+bool sidmap_sid_is_group(struct sidmap_context *sidmap, struct dom_sid *sid)
+{
+       const char *attrs[] = { "sAMAccountType", NULL };
+       int ret;
+       TALLOC_CTX *tmp_ctx;
+       struct ldb_message **res;
+       NTSTATUS status;
+       struct dom_sid *domain_sid;
+       bool is_group;
+
+       tmp_ctx = talloc_new(sidmap);
+
+       ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, 
+                          "objectSid=%s", ldap_encode_ndr_dom_sid(tmp_ctx, sid));
+       if (ret == 1) {
+               is_group = is_group_account(res[0]);
+               talloc_free(tmp_ctx);
+               return is_group;
+       }
+
+       status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid);
+       if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(tmp_ctx);
+               return false;
+       }
+
+       if (dom_sid_in_domain(domain_sid, sid)) {
+               uint32_t rid = sid->sub_auths[sid->num_auths-1];
+               if (rid >= SIDMAP_LOCAL_GROUP_BASE) {
+                       talloc_free(tmp_ctx);
+                       return true;
+               }
+       }
+
+       talloc_free(tmp_ctx);
+       return false;
+}
+
 /*
   map a sid to a unix gid
 */
-_PUBLIC_ NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap,
-                                       struct dom_sid *sid, gid_t *gid)
+NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap,
+                                       const struct dom_sid *sid, gid_t *gid)
 {
-       const char *attrs[] = { "sAMAccountName", "gidNumber", 
+       const char *attrs[] = { "sAMAccountName", "gidNumber",
                                "unixName", "sAMAccountType", NULL };
        int ret;
        const char *s;
@@ -303,7 +348,7 @@ allocated_sid:
                 dom_sid_string(tmp_ctx, sid)));
 
        talloc_free(tmp_ctx);
-       return NT_STATUS_INVALID_SID;
+       return NT_STATUS_NONE_MAPPED;
 }
 
 
@@ -311,9 +356,9 @@ allocated_sid:
   map a unix uid to a dom_sid
   the returned sid is allocated in the supplied mem_ctx
 */
-_PUBLIC_ NTSTATUS sidmap_uid_to_sid(struct sidmap_context *sidmap,
+NTSTATUS sidmap_uid_to_sid(struct sidmap_context *sidmap,
                                    TALLOC_CTX *mem_ctx,
-                                   uid_t uid, struct dom_sid **sid)
+                                   const uid_t uid, struct dom_sid **sid)
 {
        const char *attrs[] = { "sAMAccountName", "objectSid", "sAMAccountType", NULL };
        int ret, i;
@@ -385,7 +430,7 @@ _PUBLIC_ NTSTATUS sidmap_uid_to_sid(struct sidmap_context *sidmap,
        */
 allocate_sid:
        if (uid > SIDMAP_MAX_LOCAL_UID) {
-               return NT_STATUS_INVALID_SID;
+               return NT_STATUS_NONE_MAPPED;
        }
 
        status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid);
@@ -409,9 +454,9 @@ allocate_sid:
   map a unix gid to a dom_sid
   the returned sid is allocated in the supplied mem_ctx
 */
-_PUBLIC_ NTSTATUS sidmap_gid_to_sid(struct sidmap_context *sidmap,
+NTSTATUS sidmap_gid_to_sid(struct sidmap_context *sidmap,
                                    TALLOC_CTX *mem_ctx,
-                                   gid_t gid, struct dom_sid **sid)
+                                   const gid_t gid, struct dom_sid **sid)
 {
        const char *attrs[] = { "sAMAccountName", "objectSid", "sAMAccountType", NULL };
        int ret, i;
@@ -483,7 +528,7 @@ _PUBLIC_ NTSTATUS sidmap_gid_to_sid(struct sidmap_context *sidmap,
        */
 allocate_sid:
        if (gid > SIDMAP_MAX_LOCAL_GID) {
-               return NT_STATUS_INVALID_SID;
+               return NT_STATUS_NONE_MAPPED;
        }
 
        status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid);
@@ -506,17 +551,17 @@ allocate_sid:
   check if a sid is in the range of auto-allocated SIDs from our primary domain,
   and if it is, then return the name and atype
 */
-_PUBLIC_ NTSTATUS sidmap_allocated_sid_lookup(struct sidmap_context *sidmap, 
+NTSTATUS sidmap_allocated_sid_lookup(struct sidmap_context *sidmap, 
                                              TALLOC_CTX *mem_ctx, 
                                              const struct dom_sid *sid,
                                              const char **name,
-                                             uint32_t *atype)
+                                             enum lsa_SidType *rtype)
 {
        NTSTATUS status;
        struct dom_sid *domain_sid;
        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
-       uint32_t rid;
-
+       uint32_t rid, atype;
+       
        status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid);
        if (!NT_STATUS_IS_OK(status)) {
                return NT_STATUS_NO_SUCH_DOMAIN;
@@ -524,20 +569,22 @@ _PUBLIC_ NTSTATUS sidmap_allocated_sid_lookup(struct sidmap_context *sidmap,
 
        if (!dom_sid_in_domain(domain_sid, sid)) {
                talloc_free(tmp_ctx);
-               return NT_STATUS_INVALID_SID;
+               return NT_STATUS_NONE_MAPPED;
        }
 
        talloc_free(tmp_ctx);
 
        rid = sid->sub_auths[sid->num_auths-1];
        if (rid < SIDMAP_LOCAL_USER_BASE) {
-               return NT_STATUS_INVALID_SID;
+               return NT_STATUS_NONE_MAPPED;
        }
 
        if (rid < SIDMAP_LOCAL_GROUP_BASE) {
                struct passwd *pwd;
                uid_t uid = rid - SIDMAP_LOCAL_USER_BASE;
-               *atype = ATYPE_NORMAL_ACCOUNT;
+               atype = ATYPE_NORMAL_ACCOUNT;
+               *rtype = samdb_atype_map(atype);
+
                pwd = getpwuid(uid);
                if (pwd == NULL) {
                        *name = talloc_asprintf(mem_ctx, "uid%u", uid);
@@ -547,7 +594,8 @@ _PUBLIC_ NTSTATUS sidmap_allocated_sid_lookup(struct sidmap_context *sidmap,
        } else {
                struct group *grp;
                gid_t gid = rid - SIDMAP_LOCAL_GROUP_BASE;
-               *atype = ATYPE_LOCAL_GROUP;
+               atype = ATYPE_LOCAL_GROUP;
+               *rtype = samdb_atype_map(atype);
                grp = getgrgid(gid);
                if (grp == NULL) {
                        *name = talloc_asprintf(mem_ctx, "gid%u", gid);