~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to source3/winbindd/winbindd_rpc.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 implementation.
3
 
 
4
 
   Winbind rpc backend functions
5
 
 
6
 
   Copyright (C) Tim Potter 2000-2001,2003
7
 
   Copyright (C) Andrew Tridgell 2001
8
 
   Copyright (C) Volker Lendecke 2005
9
 
   Copyright (C) Guenther Deschner 2008 (pidl conversion)
10
 
 
11
 
   This program is free software; you can redistribute it and/or modify
12
 
   it under the terms of the GNU General Public License as published by
13
 
   the Free Software Foundation; either version 3 of the License, or
14
 
   (at your option) any later version.
15
 
 
16
 
   This program is distributed in the hope that it will be useful,
17
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 
   GNU General Public License for more details.
20
 
 
21
 
   You should have received a copy of the GNU General Public License
22
 
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
 
*/
 
1
/*
 
2
 * Unix SMB/CIFS implementation.
 
3
 *
 
4
 * Winbind rpc backend functions
 
5
 *
 
6
 * Copyright (c) 2000-2003 Tim Potter
 
7
 * Copyright (c) 2001      Andrew Tridgell
 
8
 * Copyright (c) 2005      Volker Lendecke
 
9
 * Copyright (c) 2008      Guenther Deschner (pidl conversion)
 
10
 * Copyright (c) 2010      Andreas Schneider <asn@samba.org>
 
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
 */
24
25
 
25
26
#include "includes.h"
26
27
#include "winbindd.h"
27
 
#include "../librpc/gen_ndr/cli_samr.h"
28
 
#include "../librpc/gen_ndr/cli_lsa.h"
29
 
 
30
 
#undef DBGC_CLASS
31
 
#define DBGC_CLASS DBGC_WINBIND
32
 
 
33
 
 
34
 
/* Query display info for a domain.  This returns enough information plus a
35
 
   bit extra to give an overview of domain users for the User Manager
36
 
   application. */
37
 
static NTSTATUS query_user_list(struct winbindd_domain *domain,
38
 
                               TALLOC_CTX *mem_ctx,
39
 
                               uint32 *num_entries, 
40
 
                               struct wbint_userinfo **info)
 
28
#include "winbindd_rpc.h"
 
29
#include "rpc_client/rpc_client.h"
 
30
#include "librpc/gen_ndr/ndr_samr_c.h"
 
31
#include "librpc/gen_ndr/ndr_lsa_c.h"
 
32
#include "rpc_client/cli_samr.h"
 
33
#include "rpc_client/cli_lsarpc.h"
 
34
#include "../libcli/security/security.h"
 
35
 
 
36
/* Query display info for a domain */
 
37
NTSTATUS rpc_query_user_list(TALLOC_CTX *mem_ctx,
 
38
                             struct rpc_pipe_client *samr_pipe,
 
39
                             struct policy_handle *samr_policy,
 
40
                             const struct dom_sid *domain_sid,
 
41
                             uint32_t *pnum_info,
 
42
                             struct wbint_userinfo **pinfo)
41
43
{
42
 
        NTSTATUS result;
43
 
        struct policy_handle dom_pol;
44
 
        unsigned int i, start_idx;
45
 
        uint32 loop_count;
46
 
        struct rpc_pipe_client *cli;
47
 
 
48
 
        DEBUG(3,("rpc: query_user_list\n"));
49
 
 
50
 
        *num_entries = 0;
51
 
        *info = NULL;
52
 
 
53
 
        if ( !winbindd_can_contact_domain( domain ) ) {
54
 
                DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
55
 
                          domain->name));
56
 
                return NT_STATUS_OK;
57
 
        }
58
 
 
59
 
        result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
60
 
        if (!NT_STATUS_IS_OK(result))
61
 
                return result;
62
 
 
63
 
        i = start_idx = 0;
64
 
        loop_count = 0;
 
44
        struct wbint_userinfo *info = NULL;
 
45
        uint32_t num_info = 0;
 
46
        uint32_t loop_count = 0;
 
47
        uint32_t start_idx = 0;
 
48
        uint32_t i = 0;
 
49
        NTSTATUS status, result;
 
50
        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
 
51
 
 
52
        *pnum_info = 0;
65
53
 
66
54
        do {
67
 
                uint32 num_dom_users, j;
68
 
                uint32 max_entries, max_size;
 
55
                uint32_t j;
 
56
                uint32_t num_dom_users;
 
57
                uint32_t max_entries, max_size;
69
58
                uint32_t total_size, returned_size;
70
 
 
71
59
                union samr_DispInfo disp_info;
72
60
 
73
 
                /* this next bit is copied from net_user_list_internal() */
74
 
 
75
 
                get_query_dispinfo_params(loop_count, &max_entries,
76
 
                                          &max_size);
77
 
 
78
 
                result = rpccli_samr_QueryDisplayInfo(cli, mem_ctx,
79
 
                                                      &dom_pol,
80
 
                                                      1,
 
61
                dcerpc_get_query_dispinfo_params(loop_count,
 
62
                                                 &max_entries,
 
63
                                                 &max_size);
 
64
 
 
65
                status = dcerpc_samr_QueryDisplayInfo(b,
 
66
                                                      mem_ctx,
 
67
                                                      samr_policy,
 
68
                                                      1, /* level */
81
69
                                                      start_idx,
82
70
                                                      max_entries,
83
71
                                                      max_size,
84
72
                                                      &total_size,
85
73
                                                      &returned_size,
86
 
                                                      &disp_info);
87
 
 
 
74
                                                      &disp_info,
 
75
                                                      &result);
 
76
                if (!NT_STATUS_IS_OK(status)) {
 
77
                        return status;
 
78
                }
88
79
                if (!NT_STATUS_IS_OK(result)) {
89
 
                        if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
90
 
                                return result;
91
 
                        }
 
80
                        if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
 
81
                                return result;
 
82
                        }
92
83
                }
93
84
 
94
 
                num_dom_users = disp_info.info1.count;
 
85
                /* increment required start query values */
95
86
                start_idx += disp_info.info1.count;
96
87
                loop_count++;
97
 
 
98
 
                *num_entries += num_dom_users;
99
 
 
100
 
                *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
101
 
                                             struct wbint_userinfo,
102
 
                                             *num_entries);
103
 
 
104
 
                if (!(*info)) {
 
88
                num_dom_users = disp_info.info1.count;
 
89
 
 
90
                num_info += num_dom_users;
 
91
 
 
92
                info = TALLOC_REALLOC_ARRAY(mem_ctx,
 
93
                                            info,
 
94
                                            struct wbint_userinfo,
 
95
                                            num_info);
 
96
                if (info == NULL) {
105
97
                        return NT_STATUS_NO_MEMORY;
106
98
                }
107
99
 
108
100
                for (j = 0; j < num_dom_users; i++, j++) {
109
 
 
110
101
                        uint32_t rid = disp_info.info1.entries[j].rid;
111
 
 
112
 
                        (*info)[i].acct_name = talloc_strdup(mem_ctx,
113
 
                                disp_info.info1.entries[j].account_name.string);
114
 
                        (*info)[i].full_name = talloc_strdup(mem_ctx,
115
 
                                disp_info.info1.entries[j].full_name.string);
116
 
                        (*info)[i].homedir = NULL;
117
 
                        (*info)[i].shell = NULL;
118
 
                        sid_compose(&(*info)[i].user_sid, &domain->sid, rid);
 
102
                        struct samr_DispEntryGeneral *src;
 
103
                        struct wbint_userinfo *dst;
 
104
 
 
105
                        src = &(disp_info.info1.entries[j]);
 
106
                        dst = &(info[i]);
 
107
 
 
108
                        dst->acct_name = talloc_strdup(info,
 
109
                                                       src->account_name.string);
 
110
                        if (dst->acct_name == NULL) {
 
111
                                return NT_STATUS_NO_MEMORY;
 
112
                        }
 
113
 
 
114
                        dst->full_name = talloc_strdup(info, src->full_name.string);
 
115
                        if ((src->full_name.string != NULL) &&
 
116
                            (dst->full_name == NULL))
 
117
                        {
 
118
                                return NT_STATUS_NO_MEMORY;
 
119
                        }
 
120
 
 
121
                        dst->homedir = NULL;
 
122
                        dst->shell = NULL;
 
123
 
 
124
                        sid_compose(&dst->user_sid, domain_sid, rid);
119
125
 
120
126
                        /* For the moment we set the primary group for
121
127
                           every user to be the Domain Users group.
124
130
                           This should really be made into a 'winbind
125
131
                           force group' smb.conf parameter or
126
132
                           something like that. */
127
 
 
128
 
                        sid_compose(&(*info)[i].group_sid, &domain->sid, 
129
 
                                    DOMAIN_GROUP_RID_USERS);
 
133
                        sid_compose(&dst->group_sid, domain_sid,
 
134
                                    DOMAIN_RID_USERS);
130
135
                }
131
 
 
132
136
        } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
133
137
 
134
 
        return result;
 
138
        *pnum_info = num_info;
 
139
        *pinfo = info;
 
140
 
 
141
        return NT_STATUS_OK;
135
142
}
136
143
 
137
 
/* list all domain groups */
138
 
static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
139
 
                                TALLOC_CTX *mem_ctx,
140
 
                                uint32 *num_entries, 
141
 
                                struct acct_info **info)
 
144
/* List all domain groups */
 
145
NTSTATUS rpc_enum_dom_groups(TALLOC_CTX *mem_ctx,
 
146
                             struct rpc_pipe_client *samr_pipe,
 
147
                             struct policy_handle *samr_policy,
 
148
                             uint32_t *pnum_info,
 
149
                             struct wb_acct_info **pinfo)
142
150
{
143
 
        struct policy_handle dom_pol;
144
 
        NTSTATUS status;
145
 
        uint32 start = 0;
146
 
        struct rpc_pipe_client *cli;
147
 
 
148
 
        *num_entries = 0;
149
 
        *info = NULL;
150
 
 
151
 
        DEBUG(3,("rpc: enum_dom_groups\n"));
152
 
 
153
 
        if ( !winbindd_can_contact_domain( domain ) ) {
154
 
                DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
155
 
                          domain->name));
156
 
                return NT_STATUS_OK;
157
 
        }
158
 
 
159
 
        status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
160
 
        if (!NT_STATUS_IS_OK(status))
161
 
                return status;
 
151
        struct wb_acct_info *info = NULL;
 
152
        uint32_t start = 0;
 
153
        uint32_t num_info = 0;
 
154
        NTSTATUS status, result;
 
155
        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
 
156
 
 
157
        *pnum_info = 0;
162
158
 
163
159
        do {
164
160
                struct samr_SamArray *sam_array = NULL;
165
 
                uint32 count = 0;
166
 
                TALLOC_CTX *mem_ctx2;
167
 
                int g;
168
 
 
169
 
                mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
 
161
                uint32_t count = 0;
 
162
                uint32_t g;
170
163
 
171
164
                /* start is updated by this call. */
172
 
                status = rpccli_samr_EnumDomainGroups(cli, mem_ctx2,
173
 
                                                      &dom_pol,
 
165
                status = dcerpc_samr_EnumDomainGroups(b,
 
166
                                                      mem_ctx,
 
167
                                                      samr_policy,
174
168
                                                      &start,
175
169
                                                      &sam_array,
176
170
                                                      0xFFFF, /* buffer size? */
177
 
                                                      &count);
178
 
 
179
 
                if (!NT_STATUS_IS_OK(status) &&
180
 
                    !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
181
 
                        talloc_destroy(mem_ctx2);
182
 
                        break;
183
 
                }
184
 
 
185
 
                (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
186
 
                                               struct acct_info,
187
 
                                               (*num_entries) + count);
188
 
                if (! *info) {
189
 
                        talloc_destroy(mem_ctx2);
 
171
                                                      &count,
 
172
                                                      &result);
 
173
                if (!NT_STATUS_IS_OK(status)) {
 
174
                        return status;
 
175
                }
 
176
                if (!NT_STATUS_IS_OK(result)) {
 
177
                        if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
 
178
                                DEBUG(2,("query_user_list: failed to enum domain groups: %s\n",
 
179
                                         nt_errstr(result)));
 
180
                                return result;
 
181
                        }
 
182
                }
 
183
 
 
184
                info = TALLOC_REALLOC_ARRAY(mem_ctx,
 
185
                                            info,
 
186
                                            struct wb_acct_info,
 
187
                                            num_info + count);
 
188
                if (info == NULL) {
190
189
                        return NT_STATUS_NO_MEMORY;
191
190
                }
192
191
 
193
 
                for (g=0; g < count; g++) {
194
 
 
195
 
                        fstrcpy((*info)[*num_entries + g].acct_name,
 
192
                for (g = 0; g < count; g++) {
 
193
                        fstrcpy(info[num_info + g].acct_name,
196
194
                                sam_array->entries[g].name.string);
197
 
                        (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
 
195
 
 
196
                        info[num_info + g].rid = sam_array->entries[g].idx;
198
197
                }
199
198
 
200
 
                (*num_entries) += count;
201
 
                talloc_destroy(mem_ctx2);
202
 
        } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
203
 
 
204
 
        return status;
 
199
                num_info += count;
 
200
        } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
 
201
 
 
202
        *pnum_info = num_info;
 
203
        *pinfo = info;
 
204
 
 
205
        return NT_STATUS_OK;
205
206
}
206
207
 
207
 
/* List all domain groups */
208
 
 
209
 
static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
210
 
                                TALLOC_CTX *mem_ctx,
211
 
                                uint32 *num_entries, 
212
 
                                struct acct_info **info)
 
208
NTSTATUS rpc_enum_local_groups(TALLOC_CTX *mem_ctx,
 
209
                               struct rpc_pipe_client *samr_pipe,
 
210
                               struct policy_handle *samr_policy,
 
211
                               uint32_t *pnum_info,
 
212
                               struct wb_acct_info **pinfo)
213
213
{
214
 
        struct policy_handle dom_pol;
215
 
        NTSTATUS result;
216
 
        struct rpc_pipe_client *cli;
217
 
 
218
 
        *num_entries = 0;
219
 
        *info = NULL;
220
 
 
221
 
        DEBUG(3,("rpc: enum_local_groups\n"));
222
 
 
223
 
        if ( !winbindd_can_contact_domain( domain ) ) {
224
 
                DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
225
 
                          domain->name));
226
 
                return NT_STATUS_OK;
227
 
        }
228
 
 
229
 
        result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
230
 
        if (!NT_STATUS_IS_OK(result))
231
 
                return result;
 
214
        struct wb_acct_info *info = NULL;
 
215
        uint32_t num_info = 0;
 
216
        NTSTATUS status, result;
 
217
        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
 
218
 
 
219
        *pnum_info = 0;
232
220
 
233
221
        do {
234
222
                struct samr_SamArray *sam_array = NULL;
235
 
                uint32 count = 0, start = *num_entries;
236
 
                TALLOC_CTX *mem_ctx2;
237
 
                int g;
238
 
 
239
 
                mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
240
 
 
241
 
                result = rpccli_samr_EnumDomainAliases(cli, mem_ctx2,
242
 
                                                       &dom_pol,
 
223
                uint32_t count = 0;
 
224
                uint32_t start = num_info;
 
225
                uint32_t g;
 
226
 
 
227
                status = dcerpc_samr_EnumDomainAliases(b,
 
228
                                                       mem_ctx,
 
229
                                                       samr_policy,
243
230
                                                       &start,
244
231
                                                       &sam_array,
245
232
                                                       0xFFFF, /* buffer size? */
246
 
                                                       &count);
247
 
                if (!NT_STATUS_IS_OK(result) &&
248
 
                    !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
249
 
                {
250
 
                        talloc_destroy(mem_ctx2);
251
 
                        return result;
252
 
                }
253
 
 
254
 
                (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
255
 
                                               struct acct_info,
256
 
                                               (*num_entries) + count);
257
 
                if (! *info) {
258
 
                        talloc_destroy(mem_ctx2);
259
 
                        return NT_STATUS_NO_MEMORY;
260
 
                }
261
 
 
262
 
                for (g=0; g < count; g++) {
263
 
 
264
 
                        fstrcpy((*info)[*num_entries + g].acct_name,
 
233
                                                       &count,
 
234
                                                       &result);
 
235
                if (!NT_STATUS_IS_OK(status)) {
 
236
                        return status;
 
237
                }
 
238
                if (!NT_STATUS_IS_OK(result)) {
 
239
                        if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
 
240
                                return result;
 
241
                        }
 
242
                }
 
243
 
 
244
                info = TALLOC_REALLOC_ARRAY(mem_ctx,
 
245
                                            info,
 
246
                                            struct wb_acct_info,
 
247
                                            num_info + count);
 
248
                if (info == NULL) {
 
249
                        return  NT_STATUS_NO_MEMORY;
 
250
                }
 
251
 
 
252
                for (g = 0; g < count; g++) {
 
253
                        fstrcpy(info[num_info + g].acct_name,
265
254
                                sam_array->entries[g].name.string);
266
 
                        (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
 
255
                        info[num_info + g].rid = sam_array->entries[g].idx;
267
256
                }
268
257
 
269
 
                (*num_entries) += count;
270
 
                talloc_destroy(mem_ctx2);
271
 
 
 
258
                num_info += count;
272
259
        } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
273
260
 
274
 
        return result;
 
261
        *pnum_info = num_info;
 
262
        *pinfo = info;
 
263
 
 
264
        return NT_STATUS_OK;
275
265
}
276
266
 
277
267
/* convert a single name to a sid in a domain */
278
 
static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
279
 
                                  TALLOC_CTX *mem_ctx,
280
 
                                  const char *domain_name,
281
 
                                  const char *name,
282
 
                                  uint32_t flags,
283
 
                                  DOM_SID *sid,
284
 
                                  enum lsa_SidType *type)
 
268
NTSTATUS rpc_name_to_sid(TALLOC_CTX *mem_ctx,
 
269
                         struct rpc_pipe_client *lsa_pipe,
 
270
                         struct policy_handle *lsa_policy,
 
271
                         const char *domain_name,
 
272
                         const char *name,
 
273
                         uint32_t flags,
 
274
                         struct dom_sid *sid,
 
275
                         enum lsa_SidType *type)
285
276
{
286
 
        NTSTATUS result;
287
 
        DOM_SID *sids = NULL;
288
277
        enum lsa_SidType *types = NULL;
 
278
        struct dom_sid *sids = NULL;
289
279
        char *full_name = NULL;
290
 
        NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
291
280
        char *mapped_name = NULL;
 
281
        NTSTATUS status;
292
282
 
293
 
        if (name == NULL || *name=='\0') {
 
283
        if (name == NULL || name[0] == '\0') {
294
284
                full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
295
 
        } else if (domain_name == NULL || *domain_name == '\0') {
 
285
        } else if (domain_name == NULL || domain_name[0] == '\0') {
296
286
                full_name = talloc_asprintf(mem_ctx, "%s", name);
297
287
        } else {
298
288
                full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
299
289
        }
300
 
        if (!full_name) {
301
 
                DEBUG(0, ("talloc_asprintf failed!\n"));
 
290
 
 
291
        if (full_name == NULL) {
302
292
                return NT_STATUS_NO_MEMORY;
303
293
        }
304
294
 
305
 
        DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
306
 
 
307
 
        name_map_status = normalize_name_unmap(mem_ctx, full_name,
308
 
                                               &mapped_name);
309
 
 
310
 
        /* Reset the full_name pointer if we mapped anytthing */
311
 
 
312
 
        if (NT_STATUS_IS_OK(name_map_status) ||
313
 
            NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
314
 
        {
 
295
        status = normalize_name_unmap(mem_ctx, full_name, &mapped_name);
 
296
        /* Reset the full_name pointer if we mapped anything */
 
297
        if (NT_STATUS_IS_OK(status) ||
 
298
            NT_STATUS_EQUAL(status, NT_STATUS_FILE_RENAMED)) {
315
299
                full_name = mapped_name;
316
300
        }
317
301
 
318
 
        DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
319
 
                 full_name?full_name:"", domain_name ));
320
 
 
321
 
        result = winbindd_lookup_names(mem_ctx, domain, 1,
322
 
                                       (const char **)&full_name, NULL,
323
 
                                       &sids, &types);
324
 
        if (!NT_STATUS_IS_OK(result))
325
 
                return result;
326
 
 
327
 
        /* Return rid and type if lookup successful */
 
302
        DEBUG(3,("name_to_sid: %s for domain %s\n",
 
303
                 full_name ? full_name : "", domain_name ));
 
304
 
 
305
        /*
 
306
         * We don't run into deadlocks here, cause winbind_off() is
 
307
         * called in the main function.
 
308
         */
 
309
        status = rpccli_lsa_lookup_names(lsa_pipe,
 
310
                                         mem_ctx,
 
311
                                         lsa_policy,
 
312
                                         1, /* num_names */
 
313
                                         (const char **) &full_name,
 
314
                                         NULL, /* domains */
 
315
                                         1, /* level */
 
316
                                         &sids,
 
317
                                         &types);
 
318
        if (!NT_STATUS_IS_OK(status)) {
 
319
                DEBUG(2,("name_to_sid: failed to lookup name: %s\n",
 
320
                        nt_errstr(status)));
 
321
                return status;
 
322
        }
328
323
 
329
324
        sid_copy(sid, &sids[0]);
330
325
        *type = types[0];
332
327
        return NT_STATUS_OK;
333
328
}
334
329
 
335
 
/*
336
 
  convert a domain SID to a user or group name
337
 
*/
338
 
static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
339
 
                                  TALLOC_CTX *mem_ctx,
340
 
                                  const DOM_SID *sid,
341
 
                                  char **domain_name,
342
 
                                  char **name,
343
 
                                  enum lsa_SidType *type)
 
330
/* Convert a domain SID to a user or group name */
 
331
NTSTATUS rpc_sid_to_name(TALLOC_CTX *mem_ctx,
 
332
                         struct rpc_pipe_client *lsa_pipe,
 
333
                         struct policy_handle *lsa_policy,
 
334
                         struct winbindd_domain *domain,
 
335
                         const struct dom_sid *sid,
 
336
                         char **pdomain_name,
 
337
                         char **pname,
 
338
                         enum lsa_SidType *ptype)
344
339
{
345
 
        char **domains;
346
 
        char **names;
347
 
        enum lsa_SidType *types = NULL;
348
 
        NTSTATUS result;
349
 
        NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
350
340
        char *mapped_name = NULL;
351
 
 
352
 
        DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
353
 
                 domain->name ));
354
 
 
355
 
        result = winbindd_lookup_sids(mem_ctx,
356
 
                                      domain,
357
 
                                      1,
358
 
                                      sid,
359
 
                                      &domains,
360
 
                                      &names,
361
 
                                      &types);
362
 
        if (!NT_STATUS_IS_OK(result)) {
363
 
                DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
364
 
                        nt_errstr(result)));
365
 
                return result;
366
 
        }
367
 
 
368
 
 
369
 
        *type = (enum lsa_SidType)types[0];
370
 
        *domain_name = domains[0];
371
 
        *name = names[0];
372
 
 
373
 
        DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
374
 
 
375
 
        name_map_status = normalize_name_map(mem_ctx, domain, *name,
376
 
                                             &mapped_name);
377
 
        if (NT_STATUS_IS_OK(name_map_status) ||
378
 
            NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
379
 
        {
380
 
                *name = mapped_name;
381
 
                DEBUG(5,("returning mapped name -- %s\n", *name));
 
341
        char **domains = NULL;
 
342
        char **names = NULL;
 
343
        enum lsa_SidType *types = NULL;
 
344
        NTSTATUS map_status;
 
345
        NTSTATUS status;
 
346
 
 
347
        status = rpccli_lsa_lookup_sids(lsa_pipe,
 
348
                                        mem_ctx,
 
349
                                        lsa_policy,
 
350
                                        1, /* num_sids */
 
351
                                        sid,
 
352
                                        &domains,
 
353
                                        &names,
 
354
                                        &types);
 
355
        if (!NT_STATUS_IS_OK(status)) {
 
356
                DEBUG(2,("sid_to_name: failed to lookup sids: %s\n",
 
357
                        nt_errstr(status)));
 
358
                return status;
 
359
        }
 
360
 
 
361
        *ptype = (enum lsa_SidType) types[0];
 
362
 
 
363
        map_status = normalize_name_map(mem_ctx,
 
364
                                        domain,
 
365
                                        *pname,
 
366
                                        &mapped_name);
 
367
        if (NT_STATUS_IS_OK(map_status) ||
 
368
            NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) {
 
369
                *pname = talloc_strdup(mem_ctx, mapped_name);
 
370
                DEBUG(5,("returning mapped name -- %s\n", *pname));
 
371
        } else {
 
372
                *pname = talloc_strdup(mem_ctx, names[0]);
 
373
        }
 
374
        if (*pname == NULL) {
 
375
                return NT_STATUS_NO_MEMORY;
 
376
        }
 
377
 
 
378
        *pdomain_name = talloc_strdup(mem_ctx, domains[0]);
 
379
        if (*pdomain_name == NULL) {
 
380
                return NT_STATUS_NO_MEMORY;
382
381
        }
383
382
 
384
383
        return NT_STATUS_OK;
385
384
}
386
385
 
387
 
static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
388
 
                                    TALLOC_CTX *mem_ctx,
389
 
                                    const DOM_SID *sid,
390
 
                                    uint32 *rids,
391
 
                                    size_t num_rids,
392
 
                                    char **domain_name,
393
 
                                    char ***names,
394
 
                                    enum lsa_SidType **types)
 
386
/* Convert a bunch of rids to user or group names */
 
387
NTSTATUS rpc_rids_to_names(TALLOC_CTX *mem_ctx,
 
388
                           struct rpc_pipe_client *lsa_pipe,
 
389
                           struct policy_handle *lsa_policy,
 
390
                           struct winbindd_domain *domain,
 
391
                           const struct dom_sid *sid,
 
392
                           uint32_t *rids,
 
393
                           size_t num_rids,
 
394
                           char **pdomain_name,
 
395
                           char ***pnames,
 
396
                           enum lsa_SidType **ptypes)
395
397
{
396
 
        char **domains;
397
 
        NTSTATUS result;
398
 
        DOM_SID *sids;
 
398
        enum lsa_SidType *types = NULL;
 
399
        char *domain_name = NULL;
 
400
        char **domains = NULL;
 
401
        char **names = NULL;
 
402
        struct dom_sid *sids;
399
403
        size_t i;
400
 
        char **ret_names;
401
 
 
402
 
        DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
403
 
 
404
 
        if (num_rids) {
405
 
                sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
 
404
        NTSTATUS status;
 
405
 
 
406
        if (num_rids > 0) {
 
407
                sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_rids);
406
408
                if (sids == NULL) {
407
409
                        return NT_STATUS_NO_MEMORY;
408
410
                }
410
412
                sids = NULL;
411
413
        }
412
414
 
413
 
        for (i=0; i<num_rids; i++) {
 
415
        for (i = 0; i < num_rids; i++) {
414
416
                if (!sid_compose(&sids[i], sid, rids[i])) {
415
417
                        return NT_STATUS_INTERNAL_ERROR;
416
418
                }
417
419
        }
418
420
 
419
 
        result = winbindd_lookup_sids(mem_ctx,
420
 
                                      domain,
421
 
                                      num_rids,
422
 
                                      sids,
423
 
                                      &domains,
424
 
                                      names,
425
 
                                      types);
426
 
 
427
 
        if (!NT_STATUS_IS_OK(result) &&
428
 
            !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
429
 
                return result;
 
421
        status = rpccli_lsa_lookup_sids(lsa_pipe,
 
422
                                        mem_ctx,
 
423
                                        lsa_policy,
 
424
                                        num_rids,
 
425
                                        sids,
 
426
                                        &domains,
 
427
                                        &names,
 
428
                                        &types);
 
429
        if (!NT_STATUS_IS_OK(status) &&
 
430
            !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
 
431
                DEBUG(2,("rids_to_names: failed to lookup sids: %s\n",
 
432
                        nt_errstr(status)));
 
433
                return status;
430
434
        }
431
435
 
432
 
        ret_names = *names;
433
 
        for (i=0; i<num_rids; i++) {
434
 
                NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
 
436
        for (i = 0; i < num_rids; i++) {
435
437
                char *mapped_name = NULL;
 
438
                NTSTATUS map_status;
436
439
 
437
 
                if ((*types)[i] != SID_NAME_UNKNOWN) {
438
 
                        name_map_status = normalize_name_map(mem_ctx,
439
 
                                                             domain,
440
 
                                                             ret_names[i],
441
 
                                                             &mapped_name);
442
 
                        if (NT_STATUS_IS_OK(name_map_status) ||
443
 
                            NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
444
 
                        {
445
 
                                ret_names[i] = mapped_name;
 
440
                if (types[i] != SID_NAME_UNKNOWN) {
 
441
                        map_status = normalize_name_map(mem_ctx,
 
442
                                                        domain,
 
443
                                                        names[i],
 
444
                                                        &mapped_name);
 
445
                        if (NT_STATUS_IS_OK(map_status) ||
 
446
                            NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) {
 
447
                                TALLOC_FREE(names[i]);
 
448
                                names[i] = talloc_strdup(names, mapped_name);
 
449
                                if (names[i] == NULL) {
 
450
                                        return NT_STATUS_NO_MEMORY;
 
451
                                }
446
452
                        }
447
453
 
448
 
                        *domain_name = domains[i];
 
454
                        domain_name = domains[i];
449
455
                }
450
456
        }
451
457
 
452
 
        return result;
 
458
        *pdomain_name = domain_name;
 
459
        *ptypes = types;
 
460
        *pnames = names;
 
461
 
 
462
        return NT_STATUS_OK;
453
463
}
454
464
 
455
465
/* Lookup user information from a rid or username. */
456
 
static NTSTATUS query_user(struct winbindd_domain *domain, 
457
 
                           TALLOC_CTX *mem_ctx, 
458
 
                           const DOM_SID *user_sid, 
459
 
                           struct wbint_userinfo *user_info)
 
466
NTSTATUS rpc_query_user(TALLOC_CTX *mem_ctx,
 
467
                        struct rpc_pipe_client *samr_pipe,
 
468
                        struct policy_handle *samr_policy,
 
469
                        const struct dom_sid *domain_sid,
 
470
                        const struct dom_sid *user_sid,
 
471
                        struct wbint_userinfo *user_info)
460
472
{
461
 
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
462
 
        struct policy_handle dom_pol, user_pol;
 
473
        struct policy_handle user_policy;
463
474
        union samr_UserInfo *info = NULL;
464
 
        uint32 user_rid;
465
 
        struct netr_SamInfo3 *user;
466
 
        struct rpc_pipe_client *cli;
467
 
 
468
 
        DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
469
 
 
470
 
        if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
 
475
        uint32_t user_rid;
 
476
        NTSTATUS status, result;
 
477
        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
 
478
 
 
479
        if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
471
480
                return NT_STATUS_UNSUCCESSFUL;
472
 
 
473
 
        user_info->homedir = NULL;
474
 
        user_info->shell = NULL;
475
 
        user_info->primary_gid = (gid_t)-1;
476
 
 
477
 
        /* try netsamlogon cache first */
478
 
 
479
 
        if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL ) 
480
 
        {
481
 
 
482
 
                DEBUG(5,("query_user: Cache lookup succeeded for %s\n", 
483
 
                        sid_string_dbg(user_sid)));
484
 
 
485
 
                sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
486
 
                sid_compose(&user_info->group_sid, &domain->sid,
487
 
                            user->base.primary_gid);
488
 
 
489
 
                user_info->acct_name = talloc_strdup(mem_ctx,
490
 
                                                     user->base.account_name.string);
491
 
                user_info->full_name = talloc_strdup(mem_ctx,
492
 
                                                     user->base.full_name.string);
493
 
 
494
 
                TALLOC_FREE(user);
495
 
 
496
 
                return NT_STATUS_OK;
497
 
        }
498
 
 
499
 
        if ( !winbindd_can_contact_domain( domain ) ) {
500
 
                DEBUG(10,("query_user: No incoming trust for domain %s\n",
501
 
                          domain->name));
502
 
                return NT_STATUS_OK;
503
 
        }
504
 
 
505
 
        /* no cache; hit the wire */
506
 
 
507
 
        result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
508
 
        if (!NT_STATUS_IS_OK(result))
509
 
                return result;
 
481
        }
510
482
 
511
483
        /* Get user handle */
512
 
        result = rpccli_samr_OpenUser(cli, mem_ctx,
513
 
                                      &dom_pol,
 
484
        status = dcerpc_samr_OpenUser(b,
 
485
                                      mem_ctx,
 
486
                                      samr_policy,
514
487
                                      SEC_FLAG_MAXIMUM_ALLOWED,
515
488
                                      user_rid,
516
 
                                      &user_pol);
517
 
 
518
 
        if (!NT_STATUS_IS_OK(result))
 
489
                                      &user_policy,
 
490
                                      &result);
 
491
        if (!NT_STATUS_IS_OK(status)) {
 
492
                return status;
 
493
        }
 
494
        if (!NT_STATUS_IS_OK(result)) {
519
495
                return result;
 
496
        }
520
497
 
521
498
        /* Get user info */
522
 
        result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
523
 
                                           &user_pol,
 
499
        status = dcerpc_samr_QueryUserInfo(b,
 
500
                                           mem_ctx,
 
501
                                           &user_policy,
524
502
                                           0x15,
525
 
                                           &info);
526
 
 
527
 
        rpccli_samr_Close(cli, mem_ctx, &user_pol);
528
 
 
529
 
        if (!NT_STATUS_IS_OK(result))
 
503
                                           &info,
 
504
                                           &result);
 
505
        {
 
506
                NTSTATUS _result;
 
507
                dcerpc_samr_Close(b, mem_ctx, &user_policy, &_result);
 
508
        }
 
509
        if (!NT_STATUS_IS_OK(status)) {
 
510
                return status;
 
511
        }
 
512
        if (!NT_STATUS_IS_OK(result)) {
530
513
                return result;
 
514
        }
531
515
 
532
 
        sid_compose(&user_info->user_sid, &domain->sid, user_rid);
533
 
        sid_compose(&user_info->group_sid, &domain->sid,
 
516
        sid_compose(&user_info->user_sid, domain_sid, user_rid);
 
517
        sid_compose(&user_info->group_sid, domain_sid,
534
518
                    info->info21.primary_gid);
535
 
        user_info->acct_name = talloc_strdup(mem_ctx,
536
 
                                             info->info21.account_name.string);
537
 
        user_info->full_name = talloc_strdup(mem_ctx,
538
 
                                             info->info21.full_name.string);
 
519
 
 
520
        user_info->acct_name = talloc_strdup(user_info,
 
521
                                        info->info21.account_name.string);
 
522
        if (user_info->acct_name == NULL) {
 
523
                return NT_STATUS_NO_MEMORY;
 
524
        }
 
525
 
 
526
        user_info->full_name = talloc_strdup(user_info,
 
527
                                        info->info21.full_name.string);
 
528
        if ((info->info21.full_name.string != NULL) &&
 
529
            (user_info->acct_name == NULL))
 
530
        {
 
531
                return NT_STATUS_NO_MEMORY;
 
532
        }
 
533
 
539
534
        user_info->homedir = NULL;
540
535
        user_info->shell = NULL;
541
536
        user_info->primary_gid = (gid_t)-1;
542
537
 
543
538
        return NT_STATUS_OK;
544
 
}                                   
 
539
}
545
540
 
546
 
/* Lookup groups a user is a member of.  I wish Unix had a call like this! */
547
 
static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
548
 
                                  TALLOC_CTX *mem_ctx,
549
 
                                  const DOM_SID *user_sid,
550
 
                                  uint32 *num_groups, DOM_SID **user_grpsids)
 
541
/* Lookup groups a user is a member of. */
 
542
NTSTATUS rpc_lookup_usergroups(TALLOC_CTX *mem_ctx,
 
543
                               struct rpc_pipe_client *samr_pipe,
 
544
                               struct policy_handle *samr_policy,
 
545
                               const struct dom_sid *domain_sid,
 
546
                               const struct dom_sid *user_sid,
 
547
                               uint32_t *pnum_groups,
 
548
                               struct dom_sid **puser_grpsids)
551
549
{
552
 
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
553
 
        struct policy_handle dom_pol, user_pol;
554
 
        uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
 
550
        struct policy_handle user_policy;
555
551
        struct samr_RidWithAttributeArray *rid_array = NULL;
556
 
        unsigned int i;
557
 
        uint32 user_rid;
558
 
        struct rpc_pipe_client *cli;
559
 
 
560
 
        DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
561
 
 
562
 
        if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
 
552
        struct dom_sid *user_grpsids = NULL;
 
553
        uint32_t num_groups = 0, i;
 
554
        uint32_t user_rid;
 
555
        NTSTATUS status, result;
 
556
        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
 
557
 
 
558
        if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
563
559
                return NT_STATUS_UNSUCCESSFUL;
564
 
 
565
 
        *num_groups = 0;
566
 
        *user_grpsids = NULL;
567
 
 
568
 
        /* so lets see if we have a cached user_info_3 */
569
 
        result = lookup_usergroups_cached(domain, mem_ctx, user_sid, 
570
 
                                          num_groups, user_grpsids);
571
 
 
572
 
        if (NT_STATUS_IS_OK(result)) {
573
 
                return NT_STATUS_OK;
574
 
        }
575
 
 
576
 
        if ( !winbindd_can_contact_domain( domain ) ) {
577
 
                DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
578
 
                          domain->name));
579
 
 
580
 
                /* Tell the cache manager not to remember this one */
581
 
 
582
 
                return NT_STATUS_SYNCHRONIZATION_REQUIRED;
583
 
        }
584
 
 
585
 
        /* no cache; hit the wire */
586
 
 
587
 
        result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
588
 
        if (!NT_STATUS_IS_OK(result))
589
 
                return result;
 
560
        }
590
561
 
591
562
        /* Get user handle */
592
 
        result = rpccli_samr_OpenUser(cli, mem_ctx,
593
 
                                      &dom_pol,
594
 
                                      des_access,
 
563
        status = dcerpc_samr_OpenUser(b,
 
564
                                      mem_ctx,
 
565
                                      samr_policy,
 
566
                                      SEC_FLAG_MAXIMUM_ALLOWED,
595
567
                                      user_rid,
596
 
                                      &user_pol);
597
 
 
598
 
        if (!NT_STATUS_IS_OK(result))
 
568
                                      &user_policy,
 
569
                                      &result);
 
570
        if (!NT_STATUS_IS_OK(status)) {
 
571
                return status;
 
572
        }
 
573
        if (!NT_STATUS_IS_OK(result)) {
599
574
                return result;
 
575
        }
600
576
 
601
577
        /* Query user rids */
602
 
        result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
603
 
                                              &user_pol,
604
 
                                              &rid_array);
605
 
        *num_groups = rid_array->count;
606
 
 
607
 
        rpccli_samr_Close(cli, mem_ctx, &user_pol);
608
 
 
609
 
        if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
 
578
        status = dcerpc_samr_GetGroupsForUser(b,
 
579
                                              mem_ctx,
 
580
                                              &user_policy,
 
581
                                              &rid_array,
 
582
                                              &result);
 
583
        num_groups = rid_array->count;
 
584
 
 
585
        {
 
586
                NTSTATUS _result;
 
587
                dcerpc_samr_Close(b, mem_ctx, &user_policy, &_result);
 
588
        }
 
589
 
 
590
        if (!NT_STATUS_IS_OK(status)) {
 
591
                return status;
 
592
        }
 
593
        if (!NT_STATUS_IS_OK(result) || num_groups == 0) {
610
594
                return result;
611
 
 
612
 
        (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
613
 
        if (!(*user_grpsids))
614
 
                return NT_STATUS_NO_MEMORY;
615
 
 
616
 
        for (i=0;i<(*num_groups);i++) {
617
 
                sid_copy(&((*user_grpsids)[i]), &domain->sid);
618
 
                sid_append_rid(&((*user_grpsids)[i]),
619
 
                                rid_array->rids[i].rid);
620
 
        }
 
595
        }
 
596
 
 
597
        user_grpsids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_groups);
 
598
        if (user_grpsids == NULL) {
 
599
                status = NT_STATUS_NO_MEMORY;
 
600
                return status;
 
601
        }
 
602
 
 
603
        for (i = 0; i < num_groups; i++) {
 
604
                sid_compose(&(user_grpsids[i]), domain_sid,
 
605
                            rid_array->rids[i].rid);
 
606
        }
 
607
 
 
608
        *pnum_groups = num_groups;
 
609
 
 
610
        *puser_grpsids = user_grpsids;
621
611
 
622
612
        return NT_STATUS_OK;
623
613
}
624
614
 
 
615
NTSTATUS rpc_lookup_useraliases(TALLOC_CTX *mem_ctx,
 
616
                                struct rpc_pipe_client *samr_pipe,
 
617
                                struct policy_handle *samr_policy,
 
618
                                uint32_t num_sids,
 
619
                                const struct dom_sid *sids,
 
620
                                uint32_t *pnum_aliases,
 
621
                                uint32_t **palias_rids)
 
622
{
625
623
#define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
626
 
 
627
 
static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
628
 
                                         TALLOC_CTX *mem_ctx,
629
 
                                         uint32 num_sids, const DOM_SID *sids,
630
 
                                         uint32 *num_aliases,
631
 
                                         uint32 **alias_rids)
632
 
{
633
 
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
634
 
        struct policy_handle dom_pol;
635
 
        uint32 num_query_sids = 0;
636
 
        int i;
637
 
        struct rpc_pipe_client *cli;
 
624
        uint32_t num_query_sids = 0;
 
625
        uint32_t num_queries = 1;
 
626
        uint32_t num_aliases = 0;
 
627
        uint32_t total_sids = 0;
 
628
        uint32_t *alias_rids = NULL;
 
629
        uint32_t rangesize = MAX_SAM_ENTRIES_W2K;
 
630
        uint32_t i;
638
631
        struct samr_Ids alias_rids_query;
639
 
        int rangesize = MAX_SAM_ENTRIES_W2K;
640
 
        uint32 total_sids = 0;
641
 
        int num_queries = 1;
642
 
 
643
 
        *num_aliases = 0;
644
 
        *alias_rids = NULL;
645
 
 
646
 
        DEBUG(3,("rpc: lookup_useraliases\n"));
647
 
 
648
 
        if ( !winbindd_can_contact_domain( domain ) ) {
649
 
                DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
650
 
                          domain->name));
651
 
                return NT_STATUS_OK;
652
 
        }
653
 
 
654
 
        result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
655
 
        if (!NT_STATUS_IS_OK(result))
656
 
                return result;
 
632
        NTSTATUS status, result;
 
633
        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
657
634
 
658
635
        do {
659
636
                /* prepare query */
663
640
 
664
641
                num_query_sids = MIN(num_sids - total_sids, rangesize);
665
642
 
666
 
                DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n", 
667
 
                        num_queries, num_query_sids));  
 
643
                DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
 
644
                        num_queries, num_query_sids));
668
645
 
669
646
                if (num_query_sids) {
670
647
                        sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
675
652
                        sid_array.sids = NULL;
676
653
                }
677
654
 
678
 
                for (i=0; i<num_query_sids; i++) {
679
 
                        sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
680
 
                        if (!sid_array.sids[i].sid) {
681
 
                                TALLOC_FREE(sid_array.sids);
 
655
                for (i = 0; i < num_query_sids; i++) {
 
656
                        sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[total_sids++]);
 
657
                        if (sid_array.sids[i].sid == NULL) {
682
658
                                return NT_STATUS_NO_MEMORY;
683
659
                        }
684
660
                }
685
661
                sid_array.num_sids = num_query_sids;
686
662
 
687
663
                /* do request */
688
 
                result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
689
 
                                                        &dom_pol,
 
664
                status = dcerpc_samr_GetAliasMembership(b,
 
665
                                                        mem_ctx,
 
666
                                                        samr_policy,
690
667
                                                        &sid_array,
691
 
                                                        &alias_rids_query);
692
 
 
 
668
                                                        &alias_rids_query,
 
669
                                                        &result);
 
670
                if (!NT_STATUS_IS_OK(status)) {
 
671
                        return status;
 
672
                }
693
673
                if (!NT_STATUS_IS_OK(result)) {
694
 
                        *num_aliases = 0;
695
 
                        *alias_rids = NULL;
696
 
                        TALLOC_FREE(sid_array.sids);
697
 
                        goto done;
 
674
                        return result;
698
675
                }
699
676
 
700
677
                /* process output */
 
678
                for (i = 0; i < alias_rids_query.count; i++) {
 
679
                        size_t na = num_aliases;
701
680
 
702
 
                for (i=0; i<alias_rids_query.count; i++) {
703
 
                        size_t na = *num_aliases;
704
 
                        if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
705
 
                                                alias_rids, &na)) {
706
 
                                return NT_STATUS_NO_MEMORY;
707
 
                        }
708
 
                        *num_aliases = na;
 
681
                        if (!add_rid_to_array_unique(mem_ctx,
 
682
                                                     alias_rids_query.ids[i],
 
683
                                                     &alias_rids,
 
684
                                                     &na)) {
 
685
                                        return NT_STATUS_NO_MEMORY;
 
686
                                }
 
687
                                num_aliases = na;
709
688
                }
710
689
 
711
 
                TALLOC_FREE(sid_array.sids);
712
 
 
713
690
                num_queries++;
714
691
 
715
692
        } while (total_sids < num_sids);
716
693
 
717
 
 done:
718
 
        DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
719
 
                "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
720
 
 
721
 
        return result;
 
694
        DEBUG(10,("rpc: rpc_lookup_useraliases: got %d aliases in %d queries "
 
695
                  "(rangesize: %d)\n", num_aliases, num_queries, rangesize));
 
696
 
 
697
        *pnum_aliases = num_aliases;
 
698
        *palias_rids = alias_rids;
 
699
 
 
700
        return NT_STATUS_OK;
 
701
#undef MAX_SAM_ENTRIES_W2K
722
702
}
723
703
 
724
 
 
725
704
/* Lookup group membership given a rid.   */
726
 
static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
727
 
                                TALLOC_CTX *mem_ctx,
728
 
                                const DOM_SID *group_sid,
729
 
                                enum lsa_SidType type,
730
 
                                uint32 *num_names,
731
 
                                DOM_SID **sid_mem, char ***names, 
732
 
                                uint32 **name_types)
733
 
{
734
 
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
735
 
        uint32 i, total_names = 0;
736
 
        struct policy_handle dom_pol, group_pol;
737
 
        uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
738
 
        uint32 *rid_mem = NULL;
739
 
        uint32 group_rid;
740
 
        unsigned int j, r;
741
 
        struct rpc_pipe_client *cli;
742
 
        unsigned int orig_timeout;
743
 
        struct samr_RidTypeArray *rids = NULL;
744
 
 
745
 
        DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
746
 
                  sid_string_dbg(group_sid)));
747
 
 
748
 
        if ( !winbindd_can_contact_domain( domain ) ) {
749
 
                DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
750
 
                          domain->name));
751
 
                return NT_STATUS_OK;
752
 
        }
753
 
 
754
 
        if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
755
 
                return NT_STATUS_UNSUCCESSFUL;
756
 
 
757
 
        *num_names = 0;
758
 
 
759
 
        result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
760
 
        if (!NT_STATUS_IS_OK(result))
761
 
                return result;
762
 
 
763
 
        result = rpccli_samr_OpenGroup(cli, mem_ctx,
764
 
                                       &dom_pol,
765
 
                                       des_access,
766
 
                                       group_rid,
767
 
                                       &group_pol);
768
 
 
769
 
        if (!NT_STATUS_IS_OK(result))
770
 
                return result;
771
 
 
772
 
        /* Step #1: Get a list of user rids that are the members of the
773
 
           group. */
774
 
 
775
 
        /* This call can take a long time - allow the server to time out.
776
 
           35 seconds should do it. */
777
 
 
778
 
        orig_timeout = rpccli_set_timeout(cli, 35000);
779
 
 
780
 
        result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
781
 
                                              &group_pol,
782
 
                                              &rids);
783
 
 
784
 
        /* And restore our original timeout. */
785
 
        rpccli_set_timeout(cli, orig_timeout);
786
 
 
787
 
        rpccli_samr_Close(cli, mem_ctx, &group_pol);
788
 
 
789
 
        if (!NT_STATUS_IS_OK(result))
790
 
                return result;
791
 
 
792
 
        if (!rids || !rids->count) {
793
 
                names = NULL;
794
 
                name_types = NULL;
795
 
                sid_mem = NULL;
796
 
                return NT_STATUS_OK;
797
 
        }
798
 
 
799
 
        *num_names = rids->count;
800
 
        rid_mem = rids->rids;
801
 
 
802
 
        /* Step #2: Convert list of rids into list of usernames.  Do this
803
 
           in bunches of ~1000 to avoid crashing NT4.  It looks like there
804
 
           is a buffer overflow or something like that lurking around
805
 
           somewhere. */
806
 
 
807
 
#define MAX_LOOKUP_RIDS 900
808
 
 
809
 
        *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
810
 
        *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
811
 
        *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
812
 
 
813
 
        for (j=0;j<(*num_names);j++)
814
 
                sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
815
 
 
816
 
        if (*num_names>0 && (!*names || !*name_types))
817
 
                return NT_STATUS_NO_MEMORY;
818
 
 
819
 
        for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
820
 
                int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
821
 
                struct lsa_Strings tmp_names;
822
 
                struct samr_Ids tmp_types;
823
 
 
824
 
                /* Lookup a chunk of rids */
825
 
 
826
 
                result = rpccli_samr_LookupRids(cli, mem_ctx,
827
 
                                                &dom_pol,
828
 
                                                num_lookup_rids,
829
 
                                                &rid_mem[i],
830
 
                                                &tmp_names,
831
 
                                                &tmp_types);
832
 
 
833
 
                /* see if we have a real error (and yes the
834
 
                   STATUS_SOME_UNMAPPED is the one returned from 2k) */
835
 
 
836
 
                if (!NT_STATUS_IS_OK(result) &&
837
 
                    !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
838
 
                        return result;
839
 
 
840
 
                /* Copy result into array.  The talloc system will take
841
 
                   care of freeing the temporary arrays later on. */
842
 
 
843
 
                if (tmp_names.count != tmp_types.count) {
844
 
                        return NT_STATUS_UNSUCCESSFUL;
845
 
                }
846
 
 
847
 
                for (r=0; r<tmp_names.count; r++) {
848
 
                        if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
849
 
                                continue;
850
 
                        }
851
 
                        (*names)[total_names] = fill_domain_username_talloc(
852
 
                                mem_ctx, domain->name,
853
 
                                tmp_names.names[r].string, true);
854
 
                        (*name_types)[total_names] = tmp_types.ids[r];
855
 
                        total_names += 1;
856
 
                }
857
 
        }
858
 
 
859
 
        *num_names = total_names;
860
 
 
861
 
        return NT_STATUS_OK;
862
 
}
863
 
 
864
 
#ifdef HAVE_LDAP
865
 
 
866
 
#include <ldap.h>
867
 
 
868
 
static int get_ldap_seq(const char *server, int port, uint32 *seq)
869
 
{
870
 
        int ret = -1;
871
 
        struct timeval to;
872
 
        const char *attrs[] = {"highestCommittedUSN", NULL};
873
 
        LDAPMessage *res = NULL;
874
 
        char **values = NULL;
875
 
        LDAP *ldp = NULL;
876
 
 
877
 
        *seq = DOM_SEQUENCE_NONE;
 
705
NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx,
 
706
                             struct rpc_pipe_client *samr_pipe,
 
707
                             struct policy_handle *samr_policy,
 
708
                             const char *domain_name,
 
709
                             const struct dom_sid *domain_sid,
 
710
                             const struct dom_sid *group_sid,
 
711
                             enum lsa_SidType type,
 
712
                             uint32_t *pnum_names,
 
713
                             struct dom_sid **psid_mem,
 
714
                             char ***pnames,
 
715
                             uint32_t **pname_types)
 
716
{
 
717
        struct policy_handle group_policy;
 
718
        uint32_t group_rid;
 
719
        uint32_t *rid_mem = NULL;
 
720
 
 
721
        uint32_t num_names = 0;
 
722
        uint32_t total_names = 0;
 
723
        struct dom_sid *sid_mem = NULL;
 
724
        char **names = NULL;
 
725
        uint32_t *name_types = NULL;
 
726
 
 
727
        struct lsa_Strings tmp_names;
 
728
        struct samr_Ids tmp_types;
 
729
 
 
730
        uint32_t j, r;
 
731
        NTSTATUS status, result;
 
732
        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
 
733
 
 
734
        if (!sid_peek_check_rid(domain_sid, group_sid, &group_rid)) {
 
735
                return NT_STATUS_UNSUCCESSFUL;
 
736
        }
 
737
 
 
738
        switch(type) {
 
739
        case SID_NAME_DOM_GRP:
 
740
        {
 
741
                struct samr_RidAttrArray *rids = NULL;
 
742
 
 
743
                status = dcerpc_samr_OpenGroup(b,
 
744
                                               mem_ctx,
 
745
                                               samr_policy,
 
746
                                               SEC_FLAG_MAXIMUM_ALLOWED,
 
747
                                               group_rid,
 
748
                                               &group_policy,
 
749
                                               &result);
 
750
                if (!NT_STATUS_IS_OK(status)) {
 
751
                        return status;
 
752
                }
 
753
                if (!NT_STATUS_IS_OK(result)) {
 
754
                        return result;
 
755
                }
 
756
 
 
757
                /*
 
758
                 * Step #1: Get a list of user rids that are the members of the group.
 
759
                 */
 
760
                status = dcerpc_samr_QueryGroupMember(b,
 
761
                                                      mem_ctx,
 
762
                                                      &group_policy,
 
763
                                                      &rids,
 
764
                                                      &result);
 
765
                {
 
766
                        NTSTATUS _result;
 
767
                        dcerpc_samr_Close(b, mem_ctx, &group_policy, &_result);
 
768
                }
 
769
 
 
770
                if (!NT_STATUS_IS_OK(status)) {
 
771
                        return status;
 
772
                }
 
773
                if (!NT_STATUS_IS_OK(result)) {
 
774
                        return result;
 
775
                }
 
776
 
 
777
 
 
778
                if (rids == NULL || rids->count == 0) {
 
779
                        pnum_names = 0;
 
780
                        pnames = NULL;
 
781
                        pname_types = NULL;
 
782
                        psid_mem = NULL;
 
783
 
 
784
                        return NT_STATUS_OK;
 
785
                }
 
786
 
 
787
                num_names = rids->count;
 
788
                rid_mem = rids->rids;
 
789
 
 
790
                break;
 
791
        }
 
792
        case SID_NAME_WKN_GRP:
 
793
        case SID_NAME_ALIAS:
 
794
        {
 
795
                struct lsa_SidArray sid_array;
 
796
                struct lsa_SidPtr sid_ptr;
 
797
                struct samr_Ids rids_query;
 
798
 
 
799
                sid_ptr.sid = dom_sid_dup(mem_ctx, group_sid);
 
800
                if (sid_ptr.sid == NULL) {
 
801
                        return NT_STATUS_NO_MEMORY;
 
802
                }
 
803
 
 
804
                sid_array.num_sids = 1;
 
805
                sid_array.sids = &sid_ptr;
 
806
 
 
807
                status = dcerpc_samr_GetAliasMembership(b,
 
808
                                                        mem_ctx,
 
809
                                                        samr_policy,
 
810
                                                        &sid_array,
 
811
                                                        &rids_query,
 
812
                                                        &result);
 
813
                if (!NT_STATUS_IS_OK(status)) {
 
814
                        return status;
 
815
                }
 
816
                if (!NT_STATUS_IS_OK(result)) {
 
817
                        return result;
 
818
                }
 
819
 
 
820
                if (rids_query.count == 0) {
 
821
                        pnum_names = 0;
 
822
                        pnames = NULL;
 
823
                        pname_types = NULL;
 
824
                        psid_mem = NULL;
 
825
 
 
826
                        return NT_STATUS_OK;
 
827
                }
 
828
 
 
829
                num_names = rids_query.count;
 
830
                rid_mem = rids_query.ids;
 
831
 
 
832
                break;
 
833
        }
 
834
        default:
 
835
                return NT_STATUS_UNSUCCESSFUL;
 
836
        }
878
837
 
879
838
        /*
880
 
         * Parameterised (5) second timeout on open. This is needed as the
881
 
         * search timeout doesn't seem to apply to doing an open as well. JRA.
 
839
         * Step #2: Convert list of rids into list of usernames.
882
840
         */
883
 
 
884
 
        ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
885
 
        if (ldp == NULL)
886
 
                return -1;
887
 
 
888
 
        /* Timeout if no response within 20 seconds. */
889
 
        to.tv_sec = 10;
890
 
        to.tv_usec = 0;
891
 
 
892
 
        if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
893
 
                           CONST_DISCARD(char **, attrs), 0, &to, &res))
894
 
                goto done;
895
 
 
896
 
        if (ldap_count_entries(ldp, res) != 1)
897
 
                goto done;
898
 
 
899
 
        values = ldap_get_values(ldp, res, "highestCommittedUSN");
900
 
        if (!values || !values[0])
901
 
                goto done;
902
 
 
903
 
        *seq = atoi(values[0]);
904
 
        ret = 0;
905
 
 
906
 
  done:
907
 
 
908
 
        if (values)
909
 
                ldap_value_free(values);
910
 
        if (res)
911
 
                ldap_msgfree(res);
912
 
        if (ldp)
913
 
                ldap_unbind(ldp);
914
 
        return ret;
915
 
}
916
 
 
917
 
/**********************************************************************
918
 
 Get the sequence number for a Windows AD native mode domain using
919
 
 LDAP queries.
920
 
**********************************************************************/
921
 
 
922
 
static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
923
 
{
924
 
        int ret = -1;
925
 
        char addr[INET6_ADDRSTRLEN];
926
 
 
927
 
        print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
928
 
        if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
929
 
                DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
930
 
                          "number for Domain (%s) from DC (%s)\n",
931
 
                        domain->name, addr));
932
 
        }
933
 
        return ret;
934
 
}
935
 
 
936
 
#endif /* HAVE_LDAP */
937
 
 
938
 
/* find the sequence number for a domain */
939
 
static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
940
 
{
941
 
        TALLOC_CTX *mem_ctx;
 
841
        if (num_names > 0) {
 
842
                names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_names);
 
843
                name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32_t, num_names);
 
844
                sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_names);
 
845
                if (names == NULL || name_types == NULL || sid_mem == NULL) {
 
846
                        return NT_STATUS_NO_MEMORY;
 
847
                }
 
848
        }
 
849
 
 
850
        for (j = 0; j < num_names; j++) {
 
851
                sid_compose(&sid_mem[j], domain_sid, rid_mem[j]);
 
852
        }
 
853
 
 
854
        status = dcerpc_samr_LookupRids(b,
 
855
                                        mem_ctx,
 
856
                                        samr_policy,
 
857
                                        num_names,
 
858
                                        rid_mem,
 
859
                                        &tmp_names,
 
860
                                        &tmp_types,
 
861
                                        &result);
 
862
        if (!NT_STATUS_IS_OK(status)) {
 
863
                return status;
 
864
        }
 
865
 
 
866
        if (!NT_STATUS_IS_OK(result)) {
 
867
                if (!NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
 
868
                        return result;
 
869
                }
 
870
        }
 
871
 
 
872
        /* Copy result into array.  The talloc system will take
 
873
           care of freeing the temporary arrays later on. */
 
874
        if (tmp_names.count != tmp_types.count) {
 
875
                return NT_STATUS_UNSUCCESSFUL;
 
876
        }
 
877
 
 
878
        for (r = 0; r < tmp_names.count; r++) {
 
879
                if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
 
880
                        continue;
 
881
                }
 
882
                names[total_names] = fill_domain_username_talloc(names,
 
883
                                                                 domain_name,
 
884
                                                                 tmp_names.names[r].string,
 
885
                                                                 true);
 
886
                if (names[total_names] == NULL) {
 
887
                        return NT_STATUS_NO_MEMORY;
 
888
                }
 
889
                name_types[total_names] = tmp_types.ids[r];
 
890
                total_names++;
 
891
        }
 
892
 
 
893
        *pnum_names = total_names;
 
894
        *pnames = names;
 
895
        *pname_types = name_types;
 
896
        *psid_mem = sid_mem;
 
897
 
 
898
        return NT_STATUS_OK;
 
899
}
 
900
 
 
901
/* Find the sequence number for a domain */
 
902
NTSTATUS rpc_sequence_number(TALLOC_CTX *mem_ctx,
 
903
                             struct rpc_pipe_client *samr_pipe,
 
904
                             struct policy_handle *samr_policy,
 
905
                             const char *domain_name,
 
906
                             uint32_t *pseq)
 
907
{
942
908
        union samr_DomainInfo *info = NULL;
943
 
        NTSTATUS result;
944
 
        struct policy_handle dom_pol;
945
 
        bool got_seq_num = False;
946
 
        struct rpc_pipe_client *cli;
947
 
 
948
 
        DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
949
 
 
950
 
        if ( !winbindd_can_contact_domain( domain ) ) {
951
 
                DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
952
 
                          domain->name));
953
 
                *seq = time(NULL);
954
 
                return NT_STATUS_OK;
955
 
        }
956
 
 
957
 
        *seq = DOM_SEQUENCE_NONE;
958
 
 
959
 
        if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
960
 
                return NT_STATUS_NO_MEMORY;
961
 
 
962
 
#ifdef HAVE_LDAP
963
 
        if ( domain->active_directory ) 
964
 
        {
965
 
                int res;
966
 
 
967
 
                DEBUG(8,("using get_ldap_seq() to retrieve the "
968
 
                         "sequence number\n"));
969
 
 
970
 
                res =  get_ldap_sequence_number( domain, seq );
971
 
                if (res == 0)
972
 
                {                       
973
 
                        result = NT_STATUS_OK;
974
 
                        DEBUG(10,("domain_sequence_number: LDAP for "
975
 
                                  "domain %s is %u\n",
976
 
                                  domain->name, *seq));
977
 
                        goto done;
978
 
                }
979
 
 
980
 
                DEBUG(10,("domain_sequence_number: failed to get LDAP "
981
 
                          "sequence number for domain %s\n",
982
 
                          domain->name ));
983
 
        }
984
 
#endif /* HAVE_LDAP */
985
 
 
986
 
        result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
987
 
        if (!NT_STATUS_IS_OK(result)) {
988
 
                goto done;
989
 
        }
990
 
 
991
 
        /* Query domain info */
992
 
 
993
 
        result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
994
 
                                             &dom_pol,
 
909
        bool got_seq_num = false;
 
910
        NTSTATUS status, result;
 
911
        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
 
912
 
 
913
        /* query domain info */
 
914
        status = dcerpc_samr_QueryDomainInfo(b,
 
915
                                             mem_ctx,
 
916
                                             samr_policy,
995
917
                                             8,
996
 
                                             &info);
997
 
 
998
 
        if (NT_STATUS_IS_OK(result)) {
999
 
                *seq = info->info8.sequence_num;
1000
 
                got_seq_num = True;
 
918
                                             &info,
 
919
                                             &result);
 
920
        if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
 
921
                *pseq = info->info8.sequence_num;
 
922
                got_seq_num = true;
1001
923
                goto seq_num;
1002
924
        }
1003
925
 
1004
926
        /* retry with info-level 2 in case the dc does not support info-level 8
1005
927
         * (like all older samba2 and samba3 dc's) - Guenther */
1006
 
 
1007
 
        result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1008
 
                                             &dom_pol,
 
928
        status = dcerpc_samr_QueryDomainInfo(b,
 
929
                                             mem_ctx,
 
930
                                             samr_policy,
1009
931
                                             2,
1010
 
                                             &info);
1011
 
 
1012
 
        if (NT_STATUS_IS_OK(result)) {
1013
 
                *seq = info->general.sequence_num;
1014
 
                got_seq_num = True;
1015
 
        }
1016
 
 
1017
 
 seq_num:
 
932
                                             &info,
 
933
                                             &result);
 
934
        if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
 
935
                *pseq = info->general.sequence_num;
 
936
                got_seq_num = true;
 
937
                goto seq_num;
 
938
        }
 
939
 
 
940
        if (!NT_STATUS_IS_OK(status)) {
 
941
                goto seq_num;
 
942
        }
 
943
 
 
944
        status = result;
 
945
 
 
946
seq_num:
1018
947
        if (got_seq_num) {
1019
948
                DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1020
 
                          domain->name, (unsigned)*seq));
 
949
                          domain_name, (unsigned) *pseq));
1021
950
        } else {
1022
951
                DEBUG(10,("domain_sequence_number: failed to get sequence "
1023
952
                          "number (%u) for domain %s\n",
1024
 
                          (unsigned)*seq, domain->name ));
 
953
                          (unsigned) *pseq, domain_name ));
 
954
                status = NT_STATUS_OK;
1025
955
        }
1026
956
 
1027
 
  done:
1028
 
 
1029
 
        talloc_destroy(mem_ctx);
1030
 
 
1031
 
        return result;
 
957
        return status;
1032
958
}
1033
959
 
1034
 
/* get a list of trusted domains */
1035
 
static NTSTATUS trusted_domains(struct winbindd_domain *domain,
1036
 
                                TALLOC_CTX *mem_ctx,
1037
 
                                struct netr_DomainTrustList *trusts)
 
960
/* Get a list of trusted domains */
 
961
NTSTATUS rpc_trusted_domains(TALLOC_CTX *mem_ctx,
 
962
                             struct rpc_pipe_client *lsa_pipe,
 
963
                             struct policy_handle *lsa_policy,
 
964
                             uint32_t *pnum_trusts,
 
965
                             struct netr_DomainTrust **ptrusts)
1038
966
{
1039
 
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1040
 
        uint32 enum_ctx = 0;
1041
 
        struct rpc_pipe_client *cli;
1042
 
        struct policy_handle lsa_policy;
1043
 
 
1044
 
        DEBUG(3,("rpc: trusted_domains\n"));
1045
 
 
1046
 
        ZERO_STRUCTP(trusts);
1047
 
 
1048
 
        result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1049
 
        if (!NT_STATUS_IS_OK(result))
1050
 
                return result;
1051
 
 
1052
 
        result = STATUS_MORE_ENTRIES;
1053
 
 
1054
 
        while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1055
 
                uint32 start_idx;
1056
 
                int i;
 
967
        struct netr_DomainTrust *array = NULL;
 
968
        uint32_t enum_ctx = 0;
 
969
        uint32_t count = 0;
 
970
        NTSTATUS status, result;
 
971
        struct dcerpc_binding_handle *b = lsa_pipe->binding_handle;
 
972
 
 
973
        do {
1057
974
                struct lsa_DomainList dom_list;
 
975
                uint32_t start_idx;
 
976
                uint32_t i;
1058
977
 
1059
 
                result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
1060
 
                                                 &lsa_policy,
 
978
                /*
 
979
                 * We don't run into deadlocks here, cause winbind_off() is
 
980
                 * called in the main function.
 
981
                 */
 
982
                status = dcerpc_lsa_EnumTrustDom(b,
 
983
                                                 mem_ctx,
 
984
                                                 lsa_policy,
1061
985
                                                 &enum_ctx,
1062
986
                                                 &dom_list,
1063
 
                                                 (uint32_t)-1);
1064
 
 
1065
 
                if (!NT_STATUS_IS_OK(result) &&
1066
 
                    !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1067
 
                        break;
1068
 
 
1069
 
                start_idx = trusts->count;
1070
 
                trusts->count += dom_list.count;
1071
 
 
1072
 
                trusts->array = talloc_realloc(
1073
 
                        mem_ctx, trusts->array, struct netr_DomainTrust,
1074
 
                        trusts->count);
1075
 
                if (trusts->array == NULL) {
 
987
                                                 (uint32_t) -1,
 
988
                                                 &result);
 
989
                if (!NT_STATUS_IS_OK(status)) {
 
990
                        return status;
 
991
                }
 
992
                if (!NT_STATUS_IS_OK(result)) {
 
993
                        if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
 
994
                                return result;
 
995
                        }
 
996
                }
 
997
 
 
998
                start_idx = count;
 
999
                count += dom_list.count;
 
1000
 
 
1001
                array = talloc_realloc(mem_ctx,
 
1002
                                       array,
 
1003
                                       struct netr_DomainTrust,
 
1004
                                       count);
 
1005
                if (array == NULL) {
1076
1006
                        return NT_STATUS_NO_MEMORY;
1077
1007
                }
1078
1008
 
1079
 
                for (i=0; i<dom_list.count; i++) {
1080
 
                        struct netr_DomainTrust *trust = &trusts->array[i];
 
1009
                for (i = 0; i < dom_list.count; i++) {
 
1010
                        struct netr_DomainTrust *trust = &array[i];
1081
1011
                        struct dom_sid *sid;
1082
1012
 
1083
1013
                        ZERO_STRUCTP(trust);
1084
1014
 
1085
 
                        trust->netbios_name = talloc_move(
1086
 
                                trusts->array,
1087
 
                                &dom_list.domains[i].name.string);
 
1015
                        trust->netbios_name = talloc_move(array,
 
1016
                                                          &dom_list.domains[i].name.string);
1088
1017
                        trust->dns_name = NULL;
1089
1018
 
1090
 
                        sid = talloc(trusts->array, struct dom_sid);
 
1019
                        sid = talloc(array, struct dom_sid);
1091
1020
                        if (sid == NULL) {
1092
1021
                                return NT_STATUS_NO_MEMORY;
1093
1022
                        }
1094
1023
                        sid_copy(sid, dom_list.domains[i].sid);
1095
1024
                        trust->sid = sid;
1096
1025
                }
1097
 
        }
1098
 
        return result;
1099
 
}
1100
 
 
1101
 
/* find the lockout policy for a domain */
1102
 
static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1103
 
                                     TALLOC_CTX *mem_ctx,
1104
 
                                     struct samr_DomInfo12 *lockout_policy)
1105
 
{
1106
 
        NTSTATUS result;
1107
 
        struct rpc_pipe_client *cli;
1108
 
        struct policy_handle dom_pol;
1109
 
        union samr_DomainInfo *info = NULL;
1110
 
 
1111
 
        DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1112
 
 
1113
 
        if ( !winbindd_can_contact_domain( domain ) ) {
1114
 
                DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1115
 
                          domain->name));
1116
 
                return NT_STATUS_NOT_SUPPORTED;
1117
 
        }
1118
 
 
1119
 
        result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1120
 
        if (!NT_STATUS_IS_OK(result)) {
1121
 
                goto done;
1122
 
        }
1123
 
 
1124
 
        result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1125
 
                                             &dom_pol,
1126
 
                                             12,
1127
 
                                             &info);
1128
 
        if (!NT_STATUS_IS_OK(result)) {
1129
 
                goto done;
1130
 
        }
1131
 
 
1132
 
        *lockout_policy = info->info12;
1133
 
 
1134
 
        DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1135
 
                info->info12.lockout_threshold));
1136
 
 
1137
 
  done:
1138
 
 
1139
 
        return result;
1140
 
}
1141
 
 
1142
 
/* find the password policy for a domain */
1143
 
static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1144
 
                                      TALLOC_CTX *mem_ctx,
1145
 
                                      struct samr_DomInfo1 *password_policy)
1146
 
{
1147
 
        NTSTATUS result;
1148
 
        struct rpc_pipe_client *cli;
1149
 
        struct policy_handle dom_pol;
1150
 
        union samr_DomainInfo *info = NULL;
1151
 
 
1152
 
        DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1153
 
 
1154
 
        if ( !winbindd_can_contact_domain( domain ) ) {
1155
 
                DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1156
 
                          domain->name));
1157
 
                return NT_STATUS_NOT_SUPPORTED;
1158
 
        }
1159
 
 
1160
 
        result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1161
 
        if (!NT_STATUS_IS_OK(result)) {
1162
 
                goto done;
1163
 
        }
1164
 
 
1165
 
        result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1166
 
                                             &dom_pol,
1167
 
                                             1,
1168
 
                                             &info);
1169
 
        if (!NT_STATUS_IS_OK(result)) {
1170
 
                goto done;
1171
 
        }
1172
 
 
1173
 
        *password_policy = info->info1;
1174
 
 
1175
 
        DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1176
 
                info->info1.min_password_length));
1177
 
 
1178
 
  done:
1179
 
 
1180
 
        return result;
1181
 
}
1182
 
 
1183
 
typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
1184
 
                                     TALLOC_CTX *mem_ctx,
1185
 
                                     struct policy_handle *pol,
1186
 
                                     int num_sids,
1187
 
                                     const DOM_SID *sids,
1188
 
                                     char ***pdomains,
1189
 
                                     char ***pnames,
1190
 
                                     enum lsa_SidType **ptypes);
1191
 
 
1192
 
NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
1193
 
                              struct winbindd_domain *domain,
1194
 
                              uint32_t num_sids,
1195
 
                              const struct dom_sid *sids,
1196
 
                              char ***domains,
1197
 
                              char ***names,
1198
 
                              enum lsa_SidType **types)
1199
 
{
1200
 
        NTSTATUS status;
1201
 
        struct rpc_pipe_client *cli = NULL;
1202
 
        struct policy_handle lsa_policy;
1203
 
        unsigned int orig_timeout;
1204
 
        lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
1205
 
 
1206
 
        if (domain->can_do_ncacn_ip_tcp) {
1207
 
                status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1208
 
                if (NT_STATUS_IS_OK(status)) {
1209
 
                        lookup_sids_fn = rpccli_lsa_lookup_sids3;
1210
 
                        goto lookup;
1211
 
                }
1212
 
                domain->can_do_ncacn_ip_tcp = false;
1213
 
        }
1214
 
        status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1215
 
 
1216
 
        if (!NT_STATUS_IS_OK(status)) {
1217
 
                return status;
1218
 
        }
1219
 
 
1220
 
 lookup:
1221
 
        /*
1222
 
         * This call can take a long time
1223
 
         * allow the server to time out.
1224
 
         * 35 seconds should do it.
1225
 
         */
1226
 
        orig_timeout = rpccli_set_timeout(cli, 35000);
1227
 
 
1228
 
        status = lookup_sids_fn(cli,
1229
 
                                mem_ctx,
1230
 
                                &lsa_policy,
1231
 
                                num_sids,
1232
 
                                sids,
1233
 
                                domains,
1234
 
                                names,
1235
 
                                types);
1236
 
 
1237
 
        /* And restore our original timeout. */
1238
 
        rpccli_set_timeout(cli, orig_timeout);
1239
 
 
1240
 
        if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED ||
1241
 
            NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) {
1242
 
                /*
1243
 
                 * This can happen if the schannel key is not
1244
 
                 * valid anymore, we need to invalidate the
1245
 
                 * all connections to the dc and reestablish
1246
 
                 * a netlogon connection first.
1247
 
                 */
1248
 
                invalidate_cm_connection(&domain->conn);
1249
 
                status = NT_STATUS_ACCESS_DENIED;
1250
 
        }
1251
 
 
1252
 
        if (!NT_STATUS_IS_OK(status)) {
1253
 
                return status;
1254
 
        }
1255
 
 
1256
 
        return status;
1257
 
}
1258
 
 
1259
 
typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
1260
 
                                      TALLOC_CTX *mem_ctx,
1261
 
                                      struct policy_handle *pol,
1262
 
                                      int num_names,
1263
 
                                      const char **names,
1264
 
                                      const char ***dom_names,
1265
 
                                      int level,
1266
 
                                      struct dom_sid **sids,
1267
 
                                      enum lsa_SidType **types);
1268
 
 
1269
 
NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
1270
 
                               struct winbindd_domain *domain,
1271
 
                               uint32_t num_names,
1272
 
                               const char **names,
1273
 
                               const char ***domains,
1274
 
                               struct dom_sid **sids,
1275
 
                               enum lsa_SidType **types)
1276
 
{
1277
 
        NTSTATUS status;
1278
 
        struct rpc_pipe_client *cli = NULL;
1279
 
        struct policy_handle lsa_policy;
1280
 
        unsigned int orig_timeout = 0;
1281
 
        lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
1282
 
 
1283
 
        if (domain->can_do_ncacn_ip_tcp) {
1284
 
                status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1285
 
                if (NT_STATUS_IS_OK(status)) {
1286
 
                        lookup_names_fn = rpccli_lsa_lookup_names4;
1287
 
                        goto lookup;
1288
 
                }
1289
 
                domain->can_do_ncacn_ip_tcp = false;
1290
 
        }
1291
 
        status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1292
 
 
1293
 
        if (!NT_STATUS_IS_OK(status)) {
1294
 
                return status;
1295
 
        }
1296
 
 
1297
 
 lookup:
1298
 
 
1299
 
        /*
1300
 
         * This call can take a long time
1301
 
         * allow the server to time out.
1302
 
         * 35 seconds should do it.
1303
 
         */
1304
 
        orig_timeout = rpccli_set_timeout(cli, 35000);
1305
 
 
1306
 
        status = lookup_names_fn(cli,
1307
 
                                 mem_ctx,
1308
 
                                 &lsa_policy,
1309
 
                                 num_names,
1310
 
                                 (const char **) names,
1311
 
                                 domains,
1312
 
                                 1,
1313
 
                                 sids,
1314
 
                                 types);
1315
 
 
1316
 
        /* And restore our original timeout. */
1317
 
        rpccli_set_timeout(cli, orig_timeout);
1318
 
 
1319
 
        if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED ||
1320
 
            NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) {
1321
 
                /*
1322
 
                 * This can happen if the schannel key is not
1323
 
                 * valid anymore, we need to invalidate the
1324
 
                 * all connections to the dc and reestablish
1325
 
                 * a netlogon connection first.
1326
 
                 */
1327
 
                invalidate_cm_connection(&domain->conn);
1328
 
                status = NT_STATUS_ACCESS_DENIED;
1329
 
        }
1330
 
 
1331
 
        if (!NT_STATUS_IS_OK(status)) {
1332
 
                return status;
1333
 
        }
1334
 
 
1335
 
        return status;
1336
 
}
1337
 
 
1338
 
/* the rpc backend methods are exposed via this structure */
1339
 
struct winbindd_methods msrpc_methods = {
1340
 
        False,
1341
 
        query_user_list,
1342
 
        enum_dom_groups,
1343
 
        enum_local_groups,
1344
 
        msrpc_name_to_sid,
1345
 
        msrpc_sid_to_name,
1346
 
        msrpc_rids_to_names,
1347
 
        query_user,
1348
 
        lookup_usergroups,
1349
 
        msrpc_lookup_useraliases,
1350
 
        lookup_groupmem,
1351
 
        sequence_number,
1352
 
        msrpc_lockout_policy,
1353
 
        msrpc_password_policy,
1354
 
        trusted_domains,
1355
 
};
 
1026
        } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
 
1027
 
 
1028
        *pnum_trusts = count;
 
1029
        *ptrusts = array;
 
1030
 
 
1031
        return NT_STATUS_OK;
 
1032
}
 
1033
 
 
1034
static NTSTATUS rpc_try_lookup_sids3(TALLOC_CTX *mem_ctx,
 
1035
                                     struct winbindd_domain *domain,
 
1036
                                     struct lsa_SidArray *sids,
 
1037
                                     struct lsa_RefDomainList **pdomains,
 
1038
                                     struct lsa_TransNameArray **pnames)
 
1039
{
 
1040
        struct lsa_TransNameArray2 lsa_names2;
 
1041
        struct lsa_TransNameArray *names;
 
1042
        uint32_t i, count;
 
1043
        struct rpc_pipe_client *cli;
 
1044
        NTSTATUS status, result;
 
1045
 
 
1046
        status = cm_connect_lsa_tcp(domain, talloc_tos(), &cli);
 
1047
        if (!NT_STATUS_IS_OK(status)) {
 
1048
                domain->can_do_ncacn_ip_tcp = false;
 
1049
                return status;
 
1050
        }
 
1051
 
 
1052
        ZERO_STRUCT(lsa_names2);
 
1053
        status = dcerpc_lsa_LookupSids3(cli->binding_handle,
 
1054
                                        mem_ctx,
 
1055
                                        sids,
 
1056
                                        pdomains,
 
1057
                                        &lsa_names2,
 
1058
                                        LSA_LOOKUP_NAMES_ALL,
 
1059
                                        &count,
 
1060
                                        LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES,
 
1061
                                        LSA_CLIENT_REVISION_2,
 
1062
                                        &result);
 
1063
        if (!NT_STATUS_IS_OK(status)) {
 
1064
                return status;
 
1065
        }
 
1066
        if (NT_STATUS_IS_ERR(result)) {
 
1067
                return result;
 
1068
        }
 
1069
        names = TALLOC_ZERO_P(mem_ctx, struct lsa_TransNameArray);
 
1070
        if (names == NULL) {
 
1071
                return NT_STATUS_NO_MEMORY;
 
1072
        }
 
1073
        names->count = lsa_names2.count;
 
1074
        names->names = talloc_array(names, struct lsa_TranslatedName,
 
1075
                                    names->count);
 
1076
        if (names->names == NULL) {
 
1077
                return NT_STATUS_NO_MEMORY;
 
1078
        }
 
1079
        for (i=0; i<names->count; i++) {
 
1080
                names->names[i].sid_type = lsa_names2.names[i].sid_type;
 
1081
                names->names[i].name.string = talloc_move(
 
1082
                        names->names, &lsa_names2.names[i].name.string);
 
1083
                names->names[i].sid_index = lsa_names2.names[i].sid_index;
 
1084
        }
 
1085
        *pnames = names;
 
1086
        return result;
 
1087
}
 
1088
 
 
1089
NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx,
 
1090
                         struct winbindd_domain *domain,
 
1091
                         struct lsa_SidArray *sids,
 
1092
                         struct lsa_RefDomainList **pdomains,
 
1093
                         struct lsa_TransNameArray **pnames)
 
1094
{
 
1095
        struct lsa_TransNameArray *names;
 
1096
        struct rpc_pipe_client *cli = NULL;
 
1097
        struct policy_handle lsa_policy;
 
1098
        uint32_t count;
 
1099
        NTSTATUS status, result;
 
1100
 
 
1101
        if (domain->can_do_ncacn_ip_tcp) {
 
1102
                status = rpc_try_lookup_sids3(mem_ctx, domain, sids,
 
1103
                                              pdomains, pnames);
 
1104
                if (!NT_STATUS_IS_ERR(status)) {
 
1105
                        return status;
 
1106
                }
 
1107
        }
 
1108
 
 
1109
        status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
 
1110
        if (!NT_STATUS_IS_OK(status)) {
 
1111
                return status;
 
1112
        }
 
1113
 
 
1114
        names = TALLOC_ZERO_P(mem_ctx, struct lsa_TransNameArray);
 
1115
        if (names == NULL) {
 
1116
                return NT_STATUS_NO_MEMORY;
 
1117
        }
 
1118
        status = dcerpc_lsa_LookupSids(cli->binding_handle, mem_ctx,
 
1119
                                       &lsa_policy, sids, pdomains,
 
1120
                                       names, LSA_LOOKUP_NAMES_ALL,
 
1121
                                       &count, &result);
 
1122
        if (!NT_STATUS_IS_OK(status)) {
 
1123
                return status;
 
1124
        }
 
1125
        if (NT_STATUS_IS_ERR(result)) {
 
1126
                return result;
 
1127
        }
 
1128
        *pnames = names;
 
1129
        return result;
 
1130
}