~ubuntu-branches/ubuntu/vivid/samba/vivid

« back to all changes in this revision

Viewing changes to source4/dsdb/repl/drepl_extended.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Unix SMB/CIFS mplementation.
 
3
 
 
4
   DSDB replication service - extended operation code
 
5
 
 
6
   Copyright (C) Andrew Tridgell 2010
 
7
   Copyright (C) Andrew Bartlett 2010
 
8
   Copyright (C) Nadezhda Ivanova 2010
 
9
 
 
10
   based on drepl_notify.c
 
11
 
 
12
   This program is free software; you can redistribute it and/or modify
 
13
   it under the terms of the GNU General Public License as published by
 
14
   the Free Software Foundation; either version 3 of the License, or
 
15
   (at your option) any later version.
 
16
 
 
17
   This program is distributed in the hope that it will be useful,
 
18
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
20
   GNU General Public License for more details.
 
21
 
 
22
   You should have received a copy of the GNU General Public License
 
23
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
24
 
 
25
*/
 
26
 
 
27
#include "includes.h"
 
28
#include "ldb_module.h"
 
29
#include "dsdb/samdb/samdb.h"
 
30
#include "smbd/service.h"
 
31
#include "dsdb/repl/drepl_service.h"
 
32
#include "param/param.h"
 
33
 
 
34
 
 
35
/*
 
36
  create the role owner source dsa structure
 
37
 
 
38
  nc_dn: the DN of the subtree being replicated
 
39
  source_dsa_dn: the DN of the server that we are replicating from
 
40
 */
 
41
static WERROR drepl_create_extended_source_dsa(struct dreplsrv_service *service,
 
42
                                               struct ldb_dn *nc_dn,
 
43
                                               struct ldb_dn *source_dsa_dn,
 
44
                                               uint64_t min_usn,
 
45
                                               struct dreplsrv_partition_source_dsa **_sdsa)
 
46
{
 
47
        struct dreplsrv_partition_source_dsa *sdsa;
 
48
        struct ldb_context *ldb = service->samdb;
 
49
        int ret;
 
50
        WERROR werr;
 
51
        struct ldb_dn *nc_root;
 
52
        struct dreplsrv_partition *p;
 
53
 
 
54
        sdsa = talloc_zero(service, struct dreplsrv_partition_source_dsa);
 
55
        W_ERROR_HAVE_NO_MEMORY(sdsa);
 
56
 
 
57
        sdsa->partition = talloc_zero(sdsa, struct dreplsrv_partition);
 
58
        if (!sdsa->partition) {
 
59
                talloc_free(sdsa);
 
60
                return WERR_NOMEM;
 
61
        }
 
62
 
 
63
        sdsa->partition->dn = ldb_dn_copy(sdsa->partition, nc_dn);
 
64
        if (!sdsa->partition->dn) {
 
65
                talloc_free(sdsa);
 
66
                return WERR_NOMEM;
 
67
        }
 
68
        sdsa->partition->nc.dn = ldb_dn_alloc_linearized(sdsa->partition, nc_dn);
 
69
        if (!sdsa->partition->nc.dn) {
 
70
                talloc_free(sdsa);
 
71
                return WERR_NOMEM;
 
72
        }
 
73
        ret = dsdb_find_guid_by_dn(ldb, nc_dn, &sdsa->partition->nc.guid);
 
74
        if (ret != LDB_SUCCESS) {
 
75
                DEBUG(0,(__location__ ": Failed to find GUID for %s\n",
 
76
                         ldb_dn_get_linearized(nc_dn)));
 
77
                talloc_free(sdsa);
 
78
                return WERR_DS_DRA_INTERNAL_ERROR;
 
79
        }
 
80
 
 
81
        sdsa->repsFrom1 = &sdsa->_repsFromBlob.ctr.ctr1;
 
82
        ret = dsdb_find_guid_by_dn(ldb, source_dsa_dn, &sdsa->repsFrom1->source_dsa_obj_guid);
 
83
        if (ret != LDB_SUCCESS) {
 
84
                DEBUG(0,(__location__ ": Failed to find objectGUID for %s\n",
 
85
                         ldb_dn_get_linearized(source_dsa_dn)));
 
86
                talloc_free(sdsa);
 
87
                return WERR_DS_DRA_INTERNAL_ERROR;
 
88
        }
 
89
 
 
90
        sdsa->repsFrom1->other_info = talloc_zero(sdsa, struct repsFromTo1OtherInfo);
 
91
        if (!sdsa->repsFrom1->other_info) {
 
92
                talloc_free(sdsa);
 
93
                return WERR_NOMEM;
 
94
        }
 
95
 
 
96
        sdsa->repsFrom1->other_info->dns_name =
 
97
                talloc_asprintf(sdsa->repsFrom1->other_info, "%s._msdcs.%s",
 
98
                                GUID_string(sdsa->repsFrom1->other_info, &sdsa->repsFrom1->source_dsa_obj_guid),
 
99
                                lpcfg_dnsdomain(service->task->lp_ctx));
 
100
        if (!sdsa->repsFrom1->other_info->dns_name) {
 
101
                talloc_free(sdsa);
 
102
                return WERR_NOMEM;
 
103
        }
 
104
 
 
105
        werr = dreplsrv_out_connection_attach(service, sdsa->repsFrom1, &sdsa->conn);
 
106
        if (!W_ERROR_IS_OK(werr)) {
 
107
                DEBUG(0,(__location__ ": Failed to attach connection to %s\n",
 
108
                         ldb_dn_get_linearized(nc_dn)));
 
109
                talloc_free(sdsa);
 
110
                return werr;
 
111
        }
 
112
 
 
113
        ret = dsdb_find_nc_root(service->samdb, sdsa, nc_dn, &nc_root);
 
114
        if (ret != LDB_SUCCESS) {
 
115
                DEBUG(0,(__location__ ": Failed to find nc_root for %s\n",
 
116
                         ldb_dn_get_linearized(nc_dn)));
 
117
                talloc_free(sdsa);
 
118
                return WERR_DS_DRA_INTERNAL_ERROR;
 
119
        }
 
120
 
 
121
        /* use the partition uptodateness vector */
 
122
        ret = dsdb_load_udv_v2(service->samdb, nc_root, sdsa->partition,
 
123
                               &sdsa->partition->uptodatevector.cursors,
 
124
                               &sdsa->partition->uptodatevector.count);
 
125
        if (ret != LDB_SUCCESS) {
 
126
                DEBUG(0,(__location__ ": Failed to load UDV for %s\n",
 
127
                         ldb_dn_get_linearized(nc_root)));
 
128
                talloc_free(sdsa);
 
129
                return WERR_DS_DRA_INTERNAL_ERROR;
 
130
        }
 
131
 
 
132
        /* find the highwatermark from the partitions list */
 
133
        for (p=service->partitions; p; p=p->next) {
 
134
                if (ldb_dn_compare(p->dn, nc_root) == 0) {
 
135
                        struct dreplsrv_partition_source_dsa *s;
 
136
                        werr = dreplsrv_partition_source_dsa_by_guid(p,
 
137
                                                                     &sdsa->repsFrom1->source_dsa_obj_guid,
 
138
                                                                     &s);
 
139
                        if (W_ERROR_IS_OK(werr)) {
 
140
                                sdsa->repsFrom1->highwatermark = s->repsFrom1->highwatermark;
 
141
                                sdsa->repsFrom1->replica_flags = s->repsFrom1->replica_flags;
 
142
                        }
 
143
                }
 
144
        }
 
145
 
 
146
        if (!service->am_rodc) {
 
147
                sdsa->repsFrom1->replica_flags |= DRSUAPI_DRS_WRIT_REP;
 
148
        }
 
149
 
 
150
        *_sdsa = sdsa;
 
151
        return WERR_OK;
 
152
}
 
153
 
 
154
struct extended_op_data {
 
155
        dreplsrv_extended_callback_t callback;
 
156
        void *callback_data;
 
157
        struct dreplsrv_partition_source_dsa *sdsa;
 
158
};
 
159
 
 
160
/*
 
161
  called when an extended op finishes
 
162
 */
 
163
static void extended_op_callback(struct dreplsrv_service *service,
 
164
                                 WERROR err,
 
165
                                 enum drsuapi_DsExtendedError exop_error,
 
166
                                 void *cb_data)
 
167
{
 
168
        struct extended_op_data *data = talloc_get_type_abort(cb_data, struct extended_op_data);
 
169
        talloc_free(data->sdsa);
 
170
        data->callback(service, err, exop_error, data->callback_data);
 
171
        talloc_free(data);
 
172
}
 
173
 
 
174
/*
 
175
  schedule a getncchanges request to the role owner for an extended operation
 
176
 */
 
177
WERROR drepl_request_extended_op(struct dreplsrv_service *service,
 
178
                                 struct ldb_dn *nc_dn,
 
179
                                 struct ldb_dn *source_dsa_dn,
 
180
                                 enum drsuapi_DsExtendedOperation extended_op,
 
181
                                 uint64_t fsmo_info,
 
182
                                 uint64_t min_usn,
 
183
                                 dreplsrv_extended_callback_t callback,
 
184
                                 void *callback_data)
 
185
{
 
186
        WERROR werr;
 
187
        struct extended_op_data *data;
 
188
        struct dreplsrv_partition_source_dsa *sdsa;
 
189
 
 
190
        werr = drepl_create_extended_source_dsa(service, nc_dn, source_dsa_dn, min_usn, &sdsa);
 
191
        W_ERROR_NOT_OK_RETURN(werr);
 
192
 
 
193
        data = talloc(service, struct extended_op_data);
 
194
        W_ERROR_HAVE_NO_MEMORY(data);
 
195
 
 
196
        data->callback = callback;
 
197
        data->callback_data = callback_data;
 
198
        data->sdsa = sdsa;
 
199
 
 
200
        werr = dreplsrv_schedule_partition_pull_source(service, sdsa,
 
201
                                                       0, extended_op, fsmo_info,
 
202
                                                       extended_op_callback, data);
 
203
        if (!W_ERROR_IS_OK(werr)) {
 
204
                talloc_free(sdsa);
 
205
                talloc_free(data);
 
206
        }
 
207
 
 
208
        dreplsrv_run_pending_ops(service);
 
209
 
 
210
        return werr;
 
211
}