Merge commit 'master/master'
authorAndrew Tridgell <tridge@samba.org>
Fri, 3 Oct 2008 19:23:00 +0000 (12:23 -0700)
committerAndrew Tridgell <tridge@samba.org>
Fri, 3 Oct 2008 19:23:00 +0000 (12:23 -0700)
source4/cldap_server/cldap_server.c
source4/cldap_server/netlogon.c
source4/dsdb/samdb/ldb_modules/partition.c
source4/dsdb/samdb/ldb_modules/proxy.c
source4/lib/charset/util_unistr.c
source4/librpc/idl/lsa.idl
source4/rpc_server/handles.c
source4/rpc_server/lsa/lsa_lookup.c
source4/torture/rpc/lsa.c

index 310fb564e0fc5068d8845bf158d09e20d44fcac9..240f2b1dc23d3cb5ba9ea5d94e2ed8d9ac3bf2db 100644 (file)
@@ -127,6 +127,7 @@ static NTSTATUS cldapd_startup_interfaces(struct cldapd_server *cldapd, struct l
        int num_interfaces;
        TALLOC_CTX *tmp_ctx = talloc_new(cldapd);
        NTSTATUS status;
+       int i;
 
        num_interfaces = iface_count(ifaces);
 
@@ -135,14 +136,14 @@ static NTSTATUS cldapd_startup_interfaces(struct cldapd_server *cldapd, struct l
        if (!lp_bind_interfaces_only(lp_ctx)) {
                status = cldapd_add_socket(cldapd, lp_ctx, "0.0.0.0");
                NT_STATUS_NOT_OK_RETURN(status);
-       } else {
-               int i;
-
-               for (i=0; i<num_interfaces; i++) {
-                       const char *address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i));
-                       status = cldapd_add_socket(cldapd, lp_ctx, address);
-                       NT_STATUS_NOT_OK_RETURN(status);
-               }
+       }
+
+       /* now we have to also listen on the specific interfaces,
+          so that replies always come from the right IP */
+       for (i=0; i<num_interfaces; i++) {
+               const char *address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i));
+               status = cldapd_add_socket(cldapd, lp_ctx, address);
+               NT_STATUS_NOT_OK_RETURN(status);
        }
 
        talloc_free(tmp_ctx);
index aac74f5d777be421bdd16d160886805e0b8cb3dd..1cb0d50d02befef0bc44d8d16d4ec5d941890c72 100644 (file)
@@ -301,7 +301,7 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
                server_type |= NBT_SERVER_KDC;
        }
 
-       if (!ldb_dn_compare_base(ldb_get_root_basedn(sam_ctx), ldb_get_default_basedn(sam_ctx))) {
+       if (ldb_dn_compare(ldb_get_root_basedn(sam_ctx), ldb_get_default_basedn(sam_ctx)) == 0) {
                server_type |= NBT_SERVER_DS_DNS_FOREST;
        }
 
index f600c727484362ca159ea32da36bc57f4576ce5a..8e4483a78e375c81a9db5bffba4118bd48320f04 100644 (file)
@@ -50,6 +50,7 @@ struct part_request {
 struct partition_context {
        struct ldb_module *module;
        struct ldb_request *req;
+       bool got_success;
 
        struct part_request *part_req;
        int num_requests;
@@ -170,7 +171,8 @@ static int partition_req_callback(struct ldb_request *req,
                return ldb_module_done(ac->req, NULL, NULL,
                                        LDB_ERR_OPERATIONS_ERROR);
        }
-       if (ares->error != LDB_SUCCESS) {
+
+       if (ares->error != LDB_SUCCESS && !ac->got_success) {
                return ldb_module_done(ac->req, ares->controls,
                                        ares->response, ares->error);
        }
@@ -191,6 +193,9 @@ static int partition_req_callback(struct ldb_request *req,
                return ldb_module_send_entry(ac->req, ares->message);
 
        case LDB_REPLY_DONE:
+               if (ares->error == LDB_SUCCESS) {
+                       ac->got_success = true;
+               }
                if (ac->req->operation == LDB_EXTENDED) {
                        /* FIXME: check for ares->response, replmd does not fill it ! */
                        if (ares->response) {
@@ -210,7 +215,8 @@ static int partition_req_callback(struct ldb_request *req,
                if (ac->finished_requests == ac->num_requests) {
                        /* this was the last one, call callback */
                        return ldb_module_done(ac->req, ares->controls,
-                                               ares->response, ares->error);
+                                              ares->response, 
+                                              ac->got_success?LDB_SUCCESS:ares->error);
                }
 
                /* not the last, now call the next one */
@@ -500,13 +506,41 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req)
                        return partition_send_all(module, ac, req);
                }
                for (i=0; data && data->partitions && data->partitions[i]; i++) {
-                       /* Find all partitions under the search base */
-                       if (ldb_dn_compare_base(req->op.search.base, data->partitions[i]->dn) == 0) {
+                       bool match = false, stop = false;
+                       /* Find all partitions under the search base 
+                          
+                          we match if:
+
+                             1) the DN we are looking for exactly matches the partition
+                            or
+                             2) the DN we are looking for is a parent of the partition and it isn't
+                                 a scope base search
+                             or
+                             3) the DN we are looking for is a child of the partition
+                        */
+                       if (ldb_dn_compare(data->partitions[i]->dn, req->op.search.base) == 0) {
+                               match = true;
+                               if (req->op.search.scope == LDB_SCOPE_BASE) {
+                                       stop = true;
+                               }
+                       }
+                       if (!match && 
+                           (ldb_dn_compare_base(req->op.search.base, data->partitions[i]->dn) == 0 &&
+                            req->op.search.scope != LDB_SCOPE_BASE)) {
+                               match = true;
+                       }
+                       if (!match &&
+                           ldb_dn_compare_base(data->partitions[i]->dn, req->op.search.base) == 0) {
+                               match = true;
+                               stop = true; /* note that this relies on partition ordering */
+                       }
+                       if (match) {
                                ret = partition_prep_request(ac, data->partitions[i]);
                                if (ret != LDB_SUCCESS) {
                                        return ret;
                                }
                        }
+                       if (stop) break;
                }
 
                /* Perhaps we didn't match any partitions.  Try the main partition, only */
@@ -586,7 +620,7 @@ static int partition_rename(struct ldb_module *module, struct ldb_request *req)
        }
 
        for (i=0; data && data->partitions && data->partitions[i]; i++) {
-               if (ldb_dn_compare_base(req->op.rename.olddn, data->partitions[i]->dn) == 0) {
+               if (ldb_dn_compare_base(data->partitions[i]->dn, req->op.rename.olddn) == 0) {
                        matched = i;
                }
        }
index 171832bbb46a9f8abb9a481baac9245e93d2721f..18b0649dda90a35d0fec7331a3302469b61c0c17 100644 (file)
@@ -233,7 +233,7 @@ static void proxy_convert_record(struct ldb_context *ldb,
        int attr, v;
 
        /* fix the message DN */
-       if (ldb_dn_compare_base(ldb, proxy->olddn, msg->dn) == 0) {
+       if (ldb_dn_compare_base(proxy->olddn, msg->dn) == 0) {
                ldb_dn_remove_base_components(msg->dn, ldb_dn_get_comp_num(proxy->olddn));
                ldb_dn_add_base(msg->dn, proxy->newdn);
        }
@@ -322,7 +322,7 @@ static int proxy_search_bytree(struct ldb_module *module, struct ldb_request *re
        }
 
        /* see if the dn is within olddn */
-       if (ldb_dn_compare_base(module->ldb, proxy->newdn, req->op.search.base) != 0) {
+       if (ldb_dn_compare_base(proxy->newdn, req->op.search.base) != 0) {
                goto passthru;
        }
 
index a8ff88423a27adce45101501ea1553bf479a7df0..5f3b2c53f120c9ebefde45211ecb7021dc52b983 100644 (file)
@@ -386,6 +386,9 @@ _PUBLIC_ size_t strlen_m_term(const char *s)
 **/
 _PUBLIC_ char *strchr_m(const char *s, char c)
 {
+       if (s == NULL) {
+               return NULL;
+       }
        /* characters below 0x3F are guaranteed to not appear in
           non-initial position in multi-byte charsets */
        if ((c & 0xC0) == 0) {
@@ -411,6 +414,10 @@ _PUBLIC_ char *strrchr_m(const char *s, char c)
 {
        char *ret = NULL;
 
+       if (s == NULL) {
+               return NULL;
+       }
+
        /* characters below 0x3F are guaranteed to not appear in
           non-initial position in multi-byte charsets */
        if ((c & 0xC0) == 0) {
index eed713f71cb9dfe4d4e7cf28c08e9bcb7be34601..e1c44990229420b9be5583814cac423f50e724bc 100644 (file)
@@ -1052,7 +1052,7 @@ import "misc.idl", "security.idl";
                lsa_SidType sid_type;
                dom_sid2 *sid;
                uint32 sid_index;
-               uint32 unknown;
+               uint32 flags;
        } lsa_TranslatedSid3;
 
        typedef struct {
index 47174b6eeb8b942eb253596eb8eb029a3ecf83f7..4831fb063da91551f847ac2af496fce4fe034f41 100644 (file)
@@ -29,7 +29,6 @@
 static int dcesrv_handle_destructor(struct dcesrv_handle *h)
 {
        DLIST_REMOVE(h->context->handles, h);
-       talloc_free(h);
        return 0;
 }
 
index a71bd575169e6f1470ddfe0e874542a90ab4a552..0ffb0572eec7c5643aaad41682090b5e6fec3d07 100644 (file)
@@ -620,6 +620,8 @@ NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call,
        NTSTATUS status;
        struct dcesrv_handle *h;
 
+       ZERO_STRUCT(r2);
+       
        /* No policy handle on the wire, so make one up here */
        r2.in.handle = talloc(mem_ctx, struct policy_handle);
        if (!r2.in.handle) {
@@ -649,9 +651,6 @@ NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call,
        r2.out.names   = r->out.names;
 
        status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2);
-       if (NT_STATUS_IS_ERR(status)) {
-               return status;
-       }
 
        r->out.domains = r2.out.domains;
        r->out.names   = r2.out.names;
@@ -671,6 +670,8 @@ NTSTATUS dcesrv_lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
        NTSTATUS status;
        int i;
 
+       ZERO_STRUCT(r2);
+
        r2.in.handle   = r->in.handle;
        r2.in.sids     = r->in.sids;
        r2.in.names    = NULL;
@@ -761,7 +762,7 @@ NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
                r->out.sids->sids[i].sid_type    = SID_NAME_UNKNOWN;
                r->out.sids->sids[i].sid         = NULL;
                r->out.sids->sids[i].sid_index   = 0xFFFFFFFF;
-               r->out.sids->sids[i].unknown     = 0;
+               r->out.sids->sids[i].flags       = 0;
 
                status2 = dcesrv_lsa_lookup_name(dce_call->event_ctx, lp_ctx, policy_state, mem_ctx, name, &authority_name, &sid, &rtype);
                if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
@@ -771,13 +772,13 @@ NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
                status2 = dcesrv_lsa_authority_list(policy_state, mem_ctx, rtype, authority_name, 
                                                    sid, r->out.domains, &sid_index);
                if (!NT_STATUS_IS_OK(status2)) {
-                       return status2;
+                       continue;
                }
 
                r->out.sids->sids[i].sid_type    = rtype;
                r->out.sids->sids[i].sid         = sid;
                r->out.sids->sids[i].sid_index   = sid_index;
-               r->out.sids->sids[i].unknown     = 0;
+               r->out.sids->sids[i].flags       = 0;
 
                (*r->out.count)++;
        }
@@ -806,6 +807,8 @@ NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX
        NTSTATUS status;
        struct dcesrv_handle *h;
 
+       ZERO_STRUCT(r2);
+
        /* No policy handle on the wire, so make one up here */
        r2.in.handle = talloc(mem_ctx, struct policy_handle);
        if (!r2.in.handle) {
@@ -836,9 +839,6 @@ NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX
        r2.out.count = r->out.count;
        
        status = dcesrv_lsa_LookupNames3(dce_call, mem_ctx, &r2);
-       if (NT_STATUS_IS_ERR(status)) {
-               return status;
-       }
        
        r->out.domains = r2.out.domains;
        r->out.sids = r2.out.sids;
@@ -913,7 +913,7 @@ NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
                status2 = dcesrv_lsa_authority_list(state, mem_ctx, rtype, authority_name, 
                                                    sid, r->out.domains, &sid_index);
                if (!NT_STATUS_IS_OK(status2)) {
-                       return status2;
+                       continue;
                }
 
                r->out.sids->sids[i].sid_type    = rtype;
@@ -944,6 +944,8 @@ NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *
        NTSTATUS status;
        int i;
 
+       ZERO_STRUCT(r2);
+
        r2.in.handle    = r->in.handle;
        r2.in.num_names = r->in.num_names;
        r2.in.names     = r->in.names;
@@ -955,7 +957,7 @@ NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *
        r2.out.count    = r->out.count;
 
        status = dcesrv_lsa_LookupNames2(dce_call, mem_ctx, &r2);
-       if (NT_STATUS_IS_ERR(status)) {
+       if (r2.out.sids == NULL) {
                return status;
        }
 
index af5ee4f6e1f423f10924d015968c272dcc737827..45f67afd699fd0583dd1e23e7131927aa440a9fc 100644 (file)
@@ -222,12 +222,13 @@ static bool test_LookupNames_bogus(struct dcerpc_pipe *p,
        NTSTATUS status;
        int i;
 
-       struct lsa_TranslatedName name;
+       struct lsa_TranslatedName name[2];
        struct lsa_TransNameArray tnames;
 
-       tnames.names = &name;
-       tnames.count = 1;
-       name.name.string = "NT AUTHORITY\\BOGUS";
+       tnames.names = name;
+       tnames.count = 2;
+       name[0].name.string = "NT AUTHORITY\\BOGUS";
+       name[1].name.string = NULL;
 
        printf("\nTesting LookupNames with bogus names\n");