~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/lib/netapi/user.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Unix SMB/CIFS implementation.
 
3
 *  NetApi User Support
 
4
 *  Copyright (C) Guenther Deschner 2008
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 3 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  This program is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
#include "includes.h"
 
21
 
 
22
#include "librpc/gen_ndr/libnetapi.h"
 
23
#include "lib/netapi/netapi.h"
 
24
#include "lib/netapi/netapi_private.h"
 
25
#include "lib/netapi/libnetapi.h"
 
26
 
 
27
/****************************************************************
 
28
****************************************************************/
 
29
 
 
30
static void convert_USER_INFO_X_to_samr_user_info21(struct USER_INFO_X *infoX,
 
31
                                                    struct samr_UserInfo21 *info21)
 
32
{
 
33
        uint32_t fields_present = 0;
 
34
        struct samr_LogonHours zero_logon_hours;
 
35
        struct lsa_BinaryString zero_parameters;
 
36
        NTTIME password_age;
 
37
 
 
38
        ZERO_STRUCTP(info21);
 
39
        ZERO_STRUCT(zero_logon_hours);
 
40
        ZERO_STRUCT(zero_parameters);
 
41
 
 
42
        if (infoX->usriX_flags) {
 
43
                fields_present |= SAMR_FIELD_ACCT_FLAGS;
 
44
        }
 
45
        if (infoX->usriX_name) {
 
46
                fields_present |= SAMR_FIELD_ACCOUNT_NAME;
 
47
        }
 
48
        if (infoX->usriX_password) {
 
49
                fields_present |= SAMR_FIELD_NT_PASSWORD_PRESENT;
 
50
        }
 
51
        if (infoX->usriX_flags) {
 
52
                fields_present |= SAMR_FIELD_ACCT_FLAGS;
 
53
        }
 
54
        if (infoX->usriX_name) {
 
55
                fields_present |= SAMR_FIELD_FULL_NAME;
 
56
        }
 
57
        if (infoX->usriX_home_dir) {
 
58
                fields_present |= SAMR_FIELD_HOME_DIRECTORY;
 
59
        }
 
60
        if (infoX->usriX_script_path) {
 
61
                fields_present |= SAMR_FIELD_LOGON_SCRIPT;
 
62
        }
 
63
        if (infoX->usriX_comment) {
 
64
                fields_present |= SAMR_FIELD_DESCRIPTION;
 
65
        }
 
66
        if (infoX->usriX_password_age) {
 
67
                fields_present |= SAMR_FIELD_FORCE_PWD_CHANGE;
 
68
        }
 
69
        if (infoX->usriX_full_name) {
 
70
                fields_present |= SAMR_FIELD_FULL_NAME;
 
71
        }
 
72
        if (infoX->usriX_usr_comment) {
 
73
                fields_present |= SAMR_FIELD_COMMENT;
 
74
        }
 
75
        if (infoX->usriX_profile) {
 
76
                fields_present |= SAMR_FIELD_PROFILE_PATH;
 
77
        }
 
78
        if (infoX->usriX_home_dir_drive) {
 
79
                fields_present |= SAMR_FIELD_HOME_DRIVE;
 
80
        }
 
81
        if (infoX->usriX_primary_group_id) {
 
82
                fields_present |= SAMR_FIELD_PRIMARY_GID;
 
83
        }
 
84
        if (infoX->usriX_country_code) {
 
85
                fields_present |= SAMR_FIELD_COUNTRY_CODE;
 
86
        }
 
87
        if (infoX->usriX_workstations) {
 
88
                fields_present |= SAMR_FIELD_WORKSTATIONS;
 
89
        }
 
90
 
 
91
        unix_to_nt_time_abs(&password_age, infoX->usriX_password_age);
 
92
 
 
93
        /* TODO: infoX->usriX_priv */
 
94
 
 
95
        info21->last_logon              = 0;
 
96
        info21->last_logoff             = 0;
 
97
        info21->last_password_change    = 0;
 
98
        info21->acct_expiry             = 0;
 
99
        info21->allow_password_change   = 0;
 
100
        info21->force_password_change   = 0;
 
101
        info21->account_name.string     = infoX->usriX_name;
 
102
        info21->full_name.string        = infoX->usriX_full_name;
 
103
        info21->home_directory.string   = infoX->usriX_home_dir;
 
104
        info21->home_drive.string       = infoX->usriX_home_dir_drive;
 
105
        info21->logon_script.string     = infoX->usriX_script_path;
 
106
        info21->profile_path.string     = infoX->usriX_profile;
 
107
        info21->description.string      = infoX->usriX_comment;
 
108
        info21->workstations.string     = infoX->usriX_workstations;
 
109
        info21->comment.string          = infoX->usriX_usr_comment;
 
110
        info21->parameters              = zero_parameters;
 
111
        info21->lm_owf_password         = zero_parameters;
 
112
        info21->nt_owf_password         = zero_parameters;
 
113
        info21->unknown3.string         = NULL;
 
114
        info21->buf_count               = 0;
 
115
        info21->buffer                  = NULL;
 
116
        info21->rid                     = infoX->usriX_user_id;
 
117
        info21->primary_gid             = infoX->usriX_primary_group_id;
 
118
        info21->acct_flags              = infoX->usriX_flags;
 
119
        info21->fields_present          = fields_present;
 
120
        info21->logon_hours             = zero_logon_hours;
 
121
        info21->bad_password_count      = infoX->usriX_bad_pw_count;
 
122
        info21->logon_count             = infoX->usriX_num_logons;
 
123
        info21->country_code            = infoX->usriX_country_code;
 
124
        info21->code_page               = infoX->usriX_code_page;
 
125
        info21->lm_password_set         = 0;
 
126
        info21->nt_password_set         = 0;
 
127
        info21->password_expired        = infoX->usriX_password_expired;
 
128
        info21->unknown4                = 0;
 
129
}
 
130
 
 
131
/****************************************************************
 
132
****************************************************************/
 
133
 
 
134
static NTSTATUS construct_USER_INFO_X(uint32_t level,
 
135
                                      uint8_t *buffer,
 
136
                                      struct USER_INFO_X *uX)
 
137
{
 
138
        struct USER_INFO_0 *u0 = NULL;
 
139
        struct USER_INFO_1 *u1 = NULL;
 
140
        struct USER_INFO_2 *u2 = NULL;
 
141
        struct USER_INFO_3 *u3 = NULL;
 
142
        struct USER_INFO_1003 *u1003 = NULL;
 
143
        struct USER_INFO_1006 *u1006 = NULL;
 
144
        struct USER_INFO_1007 *u1007 = NULL;
 
145
        struct USER_INFO_1009 *u1009 = NULL;
 
146
        struct USER_INFO_1011 *u1011 = NULL;
 
147
        struct USER_INFO_1012 *u1012 = NULL;
 
148
        struct USER_INFO_1014 *u1014 = NULL;
 
149
        struct USER_INFO_1024 *u1024 = NULL;
 
150
        struct USER_INFO_1051 *u1051 = NULL;
 
151
        struct USER_INFO_1052 *u1052 = NULL;
 
152
        struct USER_INFO_1053 *u1053 = NULL;
 
153
 
 
154
        if (!buffer || !uX) {
 
155
                return NT_STATUS_INVALID_PARAMETER;
 
156
        }
 
157
 
 
158
        ZERO_STRUCTP(uX);
 
159
 
 
160
        switch (level) {
 
161
                case 0:
 
162
                        u0 = (struct USER_INFO_0 *)buffer;
 
163
                        uX->usriX_name          = u0->usri0_name;
 
164
                        break;
 
165
                case 1:
 
166
                        u1 = (struct USER_INFO_1 *)buffer;
 
167
                        uX->usriX_name          = u1->usri1_name;
 
168
                        uX->usriX_password      = u1->usri1_password;
 
169
                        uX->usriX_password_age  = u1->usri1_password_age;
 
170
                        uX->usriX_priv          = u1->usri1_priv;
 
171
                        uX->usriX_home_dir      = u1->usri1_home_dir;
 
172
                        uX->usriX_comment       = u1->usri1_comment;
 
173
                        uX->usriX_flags         = u1->usri1_flags;
 
174
                        uX->usriX_script_path   = u1->usri1_script_path;
 
175
                        break;
 
176
                case 2:
 
177
                        u2 = (struct USER_INFO_2 *)buffer;
 
178
                        uX->usriX_name          = u2->usri2_name;
 
179
                        uX->usriX_password      = u2->usri2_password;
 
180
                        uX->usriX_password_age  = u2->usri2_password_age;
 
181
                        uX->usriX_priv          = u2->usri2_priv;
 
182
                        uX->usriX_home_dir      = u2->usri2_home_dir;
 
183
                        uX->usriX_comment       = u2->usri2_comment;
 
184
                        uX->usriX_flags         = u2->usri2_flags;
 
185
                        uX->usriX_script_path   = u2->usri2_script_path;
 
186
                        uX->usriX_auth_flags    = u2->usri2_auth_flags;
 
187
                        uX->usriX_full_name     = u2->usri2_full_name;
 
188
                        uX->usriX_usr_comment   = u2->usri2_usr_comment;
 
189
                        uX->usriX_parms         = u2->usri2_parms;
 
190
                        uX->usriX_workstations  = u2->usri2_workstations;
 
191
                        uX->usriX_last_logon    = u2->usri2_last_logon;
 
192
                        uX->usriX_last_logoff   = u2->usri2_last_logoff;
 
193
                        uX->usriX_acct_expires  = u2->usri2_acct_expires;
 
194
                        uX->usriX_max_storage   = u2->usri2_max_storage;
 
195
                        uX->usriX_units_per_week= u2->usri2_units_per_week;
 
196
                        uX->usriX_logon_hours   = u2->usri2_logon_hours;
 
197
                        uX->usriX_bad_pw_count  = u2->usri2_bad_pw_count;
 
198
                        uX->usriX_num_logons    = u2->usri2_num_logons;
 
199
                        uX->usriX_logon_server  = u2->usri2_logon_server;
 
200
                        uX->usriX_country_code  = u2->usri2_country_code;
 
201
                        uX->usriX_code_page     = u2->usri2_code_page;
 
202
                        break;
 
203
                case 3:
 
204
                        u3 = (struct USER_INFO_3 *)buffer;
 
205
                        uX->usriX_name          = u3->usri3_name;
 
206
                        uX->usriX_password_age  = u3->usri3_password_age;
 
207
                        uX->usriX_priv          = u3->usri3_priv;
 
208
                        uX->usriX_home_dir      = u3->usri3_home_dir;
 
209
                        uX->usriX_comment       = u3->usri3_comment;
 
210
                        uX->usriX_flags         = u3->usri3_flags;
 
211
                        uX->usriX_script_path   = u3->usri3_script_path;
 
212
                        uX->usriX_auth_flags    = u3->usri3_auth_flags;
 
213
                        uX->usriX_full_name     = u3->usri3_full_name;
 
214
                        uX->usriX_usr_comment   = u3->usri3_usr_comment;
 
215
                        uX->usriX_parms         = u3->usri3_parms;
 
216
                        uX->usriX_workstations  = u3->usri3_workstations;
 
217
                        uX->usriX_last_logon    = u3->usri3_last_logon;
 
218
                        uX->usriX_last_logoff   = u3->usri3_last_logoff;
 
219
                        uX->usriX_acct_expires  = u3->usri3_acct_expires;
 
220
                        uX->usriX_max_storage   = u3->usri3_max_storage;
 
221
                        uX->usriX_units_per_week= u3->usri3_units_per_week;
 
222
                        uX->usriX_logon_hours   = u3->usri3_logon_hours;
 
223
                        uX->usriX_bad_pw_count  = u3->usri3_bad_pw_count;
 
224
                        uX->usriX_num_logons    = u3->usri3_num_logons;
 
225
                        uX->usriX_logon_server  = u3->usri3_logon_server;
 
226
                        uX->usriX_country_code  = u3->usri3_country_code;
 
227
                        uX->usriX_code_page     = u3->usri3_code_page;
 
228
                        uX->usriX_user_id       = u3->usri3_user_id;
 
229
                        uX->usriX_primary_group_id = u3->usri3_primary_group_id;
 
230
                        uX->usriX_profile       = u3->usri3_profile;
 
231
                        uX->usriX_home_dir_drive = u3->usri3_home_dir_drive;
 
232
                        uX->usriX_password_expired = u3->usri3_password_expired;
 
233
                        break;
 
234
                case 1003:
 
235
                        u1003 = (struct USER_INFO_1003 *)buffer;
 
236
                        uX->usriX_password      = u1003->usri1003_password;
 
237
                        break;
 
238
                case 1006:
 
239
                        u1006 = (struct USER_INFO_1006 *)buffer;
 
240
                        uX->usriX_home_dir      = u1006->usri1006_home_dir;
 
241
                        break;
 
242
                case 1007:
 
243
                        u1007 = (struct USER_INFO_1007 *)buffer;
 
244
                        uX->usriX_comment       = u1007->usri1007_comment;
 
245
                        break;
 
246
                case 1009:
 
247
                        u1009 = (struct USER_INFO_1009 *)buffer;
 
248
                        uX->usriX_script_path   = u1009->usri1009_script_path;
 
249
                        break;
 
250
                case 1011:
 
251
                        u1011 = (struct USER_INFO_1011 *)buffer;
 
252
                        uX->usriX_full_name     = u1011->usri1011_full_name;
 
253
                        break;
 
254
                case 1012:
 
255
                        u1012 = (struct USER_INFO_1012 *)buffer;
 
256
                        uX->usriX_usr_comment   = u1012->usri1012_usr_comment;
 
257
                        break;
 
258
                case 1014:
 
259
                        u1014 = (struct USER_INFO_1014 *)buffer;
 
260
                        uX->usriX_workstations  = u1014->usri1014_workstations;
 
261
                        break;
 
262
                case 1024:
 
263
                        u1024 = (struct USER_INFO_1024 *)buffer;
 
264
                        uX->usriX_country_code  = u1024->usri1024_country_code;
 
265
                        break;
 
266
                case 1051:
 
267
                        u1051 = (struct USER_INFO_1051 *)buffer;
 
268
                        uX->usriX_primary_group_id = u1051->usri1051_primary_group_id;
 
269
                        break;
 
270
                case 1052:
 
271
                        u1052 = (struct USER_INFO_1052 *)buffer;
 
272
                        uX->usriX_profile       = u1052->usri1052_profile;
 
273
                        break;
 
274
                case 1053:
 
275
                        u1053 = (struct USER_INFO_1053 *)buffer;
 
276
                        uX->usriX_home_dir_drive = u1053->usri1053_home_dir_drive;
 
277
                        break;
 
278
                case 4:
 
279
                default:
 
280
                        return NT_STATUS_INVALID_INFO_CLASS;
 
281
        }
 
282
 
 
283
        return NT_STATUS_OK;
 
284
}
 
285
 
 
286
/****************************************************************
 
287
****************************************************************/
 
288
 
 
289
static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx,
 
290
                                          struct rpc_pipe_client *pipe_cli,
 
291
                                          DATA_BLOB *session_key,
 
292
                                          struct policy_handle *user_handle,
 
293
                                          struct USER_INFO_X *uX)
 
294
{
 
295
        union samr_UserInfo user_info;
 
296
        struct samr_UserInfo21 info21;
 
297
        NTSTATUS status;
 
298
 
 
299
        if (!uX) {
 
300
                return NT_STATUS_INVALID_PARAMETER;
 
301
        }
 
302
 
 
303
        convert_USER_INFO_X_to_samr_user_info21(uX, &info21);
 
304
 
 
305
        ZERO_STRUCT(user_info);
 
306
 
 
307
        if (uX->usriX_password) {
 
308
 
 
309
                user_info.info25.info = info21;
 
310
 
 
311
                init_samr_CryptPasswordEx(uX->usriX_password,
 
312
                                          session_key,
 
313
                                          &user_info.info25.password);
 
314
 
 
315
                status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
 
316
                                                  user_handle,
 
317
                                                  25,
 
318
                                                  &user_info);
 
319
 
 
320
                if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) {
 
321
 
 
322
                        user_info.info23.info = info21;
 
323
 
 
324
                        init_samr_CryptPassword(uX->usriX_password,
 
325
                                                session_key,
 
326
                                                &user_info.info23.password);
 
327
 
 
328
                        status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
 
329
                                                          user_handle,
 
330
                                                          23,
 
331
                                                          &user_info);
 
332
                }
 
333
        } else {
 
334
 
 
335
                user_info.info21 = info21;
 
336
 
 
337
                status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
 
338
                                                 user_handle,
 
339
                                                 21,
 
340
                                                 &user_info);
 
341
        }
 
342
 
 
343
        return status;
 
344
}
 
345
 
 
346
/****************************************************************
 
347
****************************************************************/
 
348
 
 
349
WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
 
350
                    struct NetUserAdd *r)
 
351
{
 
352
        struct rpc_pipe_client *pipe_cli = NULL;
 
353
        NTSTATUS status;
 
354
        WERROR werr;
 
355
        struct policy_handle connect_handle, domain_handle, user_handle;
 
356
        struct lsa_String lsa_account_name;
 
357
        struct dom_sid2 *domain_sid = NULL;
 
358
        union samr_UserInfo *user_info = NULL;
 
359
        struct samr_PwInfo pw_info;
 
360
        uint32_t access_granted = 0;
 
361
        uint32_t rid = 0;
 
362
        struct USER_INFO_X uX;
 
363
 
 
364
        ZERO_STRUCT(connect_handle);
 
365
        ZERO_STRUCT(domain_handle);
 
366
        ZERO_STRUCT(user_handle);
 
367
 
 
368
        if (!r->in.buffer) {
 
369
                return WERR_INVALID_PARAM;
 
370
        }
 
371
 
 
372
        switch (r->in.level) {
 
373
                case 1:
 
374
                        break;
 
375
                case 2:
 
376
                case 3:
 
377
                case 4:
 
378
                default:
 
379
                        werr = WERR_NOT_SUPPORTED;
 
380
                        goto done;
 
381
        }
 
382
 
 
383
        werr = libnetapi_open_pipe(ctx, r->in.server_name,
 
384
                                   &ndr_table_samr.syntax_id,
 
385
                                   &pipe_cli);
 
386
        if (!W_ERROR_IS_OK(werr)) {
 
387
                goto done;
 
388
        }
 
389
 
 
390
        status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
 
391
        if (!NT_STATUS_IS_OK(status)) {
 
392
                werr = ntstatus_to_werror(status);
 
393
                goto done;
 
394
        }
 
395
 
 
396
        werr = libnetapi_samr_open_domain(ctx, pipe_cli,
 
397
                                          SAMR_ACCESS_ENUM_DOMAINS |
 
398
                                          SAMR_ACCESS_LOOKUP_DOMAIN,
 
399
                                          SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
 
400
                                          SAMR_DOMAIN_ACCESS_CREATE_USER |
 
401
                                          SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
 
402
                                          &connect_handle,
 
403
                                          &domain_handle,
 
404
                                          &domain_sid);
 
405
        if (!W_ERROR_IS_OK(werr)) {
 
406
                goto done;
 
407
        }
 
408
 
 
409
        init_lsa_String(&lsa_account_name, uX.usriX_name);
 
410
 
 
411
        status = rpccli_samr_CreateUser2(pipe_cli, ctx,
 
412
                                         &domain_handle,
 
413
                                         &lsa_account_name,
 
414
                                         ACB_NORMAL,
 
415
                                         SEC_STD_WRITE_DAC |
 
416
                                         SEC_STD_DELETE |
 
417
                                         SAMR_USER_ACCESS_SET_PASSWORD |
 
418
                                         SAMR_USER_ACCESS_SET_ATTRIBUTES |
 
419
                                         SAMR_USER_ACCESS_GET_ATTRIBUTES,
 
420
                                         &user_handle,
 
421
                                         &access_granted,
 
422
                                         &rid);
 
423
        if (!NT_STATUS_IS_OK(status)) {
 
424
                werr = ntstatus_to_werror(status);
 
425
                goto done;
 
426
        }
 
427
 
 
428
        status = rpccli_samr_QueryUserInfo(pipe_cli, ctx,
 
429
                                           &user_handle,
 
430
                                           16,
 
431
                                           &user_info);
 
432
        if (!NT_STATUS_IS_OK(status)) {
 
433
                werr = ntstatus_to_werror(status);
 
434
                goto done;
 
435
        }
 
436
 
 
437
        if (!(user_info->info16.acct_flags & ACB_NORMAL)) {
 
438
                werr = WERR_INVALID_PARAM;
 
439
                goto done;
 
440
        }
 
441
 
 
442
        status = rpccli_samr_GetUserPwInfo(pipe_cli, ctx,
 
443
                                           &user_handle,
 
444
                                           &pw_info);
 
445
        if (!NT_STATUS_IS_OK(status)) {
 
446
                werr = ntstatus_to_werror(status);
 
447
                goto done;
 
448
        }
 
449
 
 
450
        uX.usriX_flags |= ACB_NORMAL;
 
451
 
 
452
        status = set_user_info_USER_INFO_X(ctx, pipe_cli,
 
453
                                           &pipe_cli->auth->user_session_key,
 
454
                                           &user_handle,
 
455
                                           &uX);
 
456
        if (!NT_STATUS_IS_OK(status)) {
 
457
                werr = ntstatus_to_werror(status);
 
458
                goto failed;
 
459
        }
 
460
 
 
461
        werr = WERR_OK;
 
462
        goto done;
 
463
 
 
464
 failed:
 
465
        rpccli_samr_DeleteUser(pipe_cli, ctx,
 
466
                               &user_handle);
 
467
 
 
468
 done:
 
469
        if (is_valid_policy_hnd(&user_handle)) {
 
470
                rpccli_samr_Close(pipe_cli, ctx, &user_handle);
 
471
        }
 
472
 
 
473
        if (ctx->disable_policy_handle_cache) {
 
474
                libnetapi_samr_close_domain_handle(ctx, &domain_handle);
 
475
                libnetapi_samr_close_connect_handle(ctx, &connect_handle);
 
476
        }
 
477
 
 
478
        return werr;
 
479
}
 
480
 
 
481
/****************************************************************
 
482
****************************************************************/
 
483
 
 
484
WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
 
485
                    struct NetUserAdd *r)
 
486
{
 
487
        LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserAdd);
 
488
}
 
489
 
 
490
/****************************************************************
 
491
****************************************************************/
 
492
 
 
493
WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
 
494
                    struct NetUserDel *r)
 
495
{
 
496
        struct rpc_pipe_client *pipe_cli = NULL;
 
497
        NTSTATUS status;
 
498
        WERROR werr;
 
499
        struct policy_handle connect_handle, builtin_handle, domain_handle, user_handle;
 
500
        struct lsa_String lsa_account_name;
 
501
        struct samr_Ids user_rids, name_types;
 
502
        struct dom_sid2 *domain_sid = NULL;
 
503
        struct dom_sid2 user_sid;
 
504
 
 
505
        ZERO_STRUCT(connect_handle);
 
506
        ZERO_STRUCT(builtin_handle);
 
507
        ZERO_STRUCT(domain_handle);
 
508
        ZERO_STRUCT(user_handle);
 
509
 
 
510
        werr = libnetapi_open_pipe(ctx, r->in.server_name,
 
511
                                   &ndr_table_samr.syntax_id,
 
512
                                   &pipe_cli);
 
513
 
 
514
        if (!W_ERROR_IS_OK(werr)) {
 
515
                goto done;
 
516
        }
 
517
 
 
518
        werr = libnetapi_samr_open_domain(ctx, pipe_cli,
 
519
                                          SAMR_ACCESS_ENUM_DOMAINS |
 
520
                                          SAMR_ACCESS_LOOKUP_DOMAIN,
 
521
                                          SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
 
522
                                          &connect_handle,
 
523
                                          &domain_handle,
 
524
                                          &domain_sid);
 
525
        if (!W_ERROR_IS_OK(werr)) {
 
526
                goto done;
 
527
        }
 
528
 
 
529
        status = rpccli_samr_OpenDomain(pipe_cli, ctx,
 
530
                                        &connect_handle,
 
531
                                        SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
 
532
                                        CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
 
533
                                        &builtin_handle);
 
534
        if (!NT_STATUS_IS_OK(status)) {
 
535
                werr = ntstatus_to_werror(status);
 
536
                goto done;
 
537
        }
 
538
 
 
539
        init_lsa_String(&lsa_account_name, r->in.user_name);
 
540
 
 
541
        status = rpccli_samr_LookupNames(pipe_cli, ctx,
 
542
                                         &domain_handle,
 
543
                                         1,
 
544
                                         &lsa_account_name,
 
545
                                         &user_rids,
 
546
                                         &name_types);
 
547
        if (!NT_STATUS_IS_OK(status)) {
 
548
                werr = ntstatus_to_werror(status);
 
549
                goto done;
 
550
        }
 
551
 
 
552
        status = rpccli_samr_OpenUser(pipe_cli, ctx,
 
553
                                      &domain_handle,
 
554
                                      SEC_STD_DELETE,
 
555
                                      user_rids.ids[0],
 
556
                                      &user_handle);
 
557
        if (!NT_STATUS_IS_OK(status)) {
 
558
                werr = ntstatus_to_werror(status);
 
559
                goto done;
 
560
        }
 
561
 
 
562
        sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
 
563
 
 
564
        status = rpccli_samr_RemoveMemberFromForeignDomain(pipe_cli, ctx,
 
565
                                                           &builtin_handle,
 
566
                                                           &user_sid);
 
567
        if (!NT_STATUS_IS_OK(status)) {
 
568
                werr = ntstatus_to_werror(status);
 
569
                goto done;
 
570
        }
 
571
 
 
572
        status = rpccli_samr_DeleteUser(pipe_cli, ctx,
 
573
                                        &user_handle);
 
574
        if (!NT_STATUS_IS_OK(status)) {
 
575
                werr = ntstatus_to_werror(status);
 
576
                goto done;
 
577
        }
 
578
 
 
579
        werr = WERR_OK;
 
580
 
 
581
 done:
 
582
        if (is_valid_policy_hnd(&user_handle)) {
 
583
                rpccli_samr_Close(pipe_cli, ctx, &user_handle);
 
584
        }
 
585
 
 
586
        if (ctx->disable_policy_handle_cache) {
 
587
                libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
 
588
                libnetapi_samr_close_domain_handle(ctx, &domain_handle);
 
589
                libnetapi_samr_close_connect_handle(ctx, &connect_handle);
 
590
        }
 
591
 
 
592
        return werr;
 
593
}
 
594
 
 
595
/****************************************************************
 
596
****************************************************************/
 
597
 
 
598
WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
 
599
                    struct NetUserDel *r)
 
600
{
 
601
        LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserDel);
 
602
}
 
603
 
 
604
/****************************************************************
 
605
****************************************************************/
 
606
 
 
607
static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
 
608
                                           struct rpc_pipe_client *pipe_cli,
 
609
                                           struct policy_handle *domain_handle,
 
610
                                           struct policy_handle *builtin_handle,
 
611
                                           const char *user_name,
 
612
                                           const struct dom_sid *domain_sid,
 
613
                                           uint32_t rid,
 
614
                                           uint32_t level,
 
615
                                           struct samr_UserInfo21 **info21,
 
616
                                           struct sec_desc_buf **sec_desc,
 
617
                                           uint32_t *auth_flag_p)
 
618
{
 
619
        NTSTATUS status;
 
620
 
 
621
        struct policy_handle user_handle;
 
622
        union samr_UserInfo *user_info = NULL;
 
623
        struct samr_RidWithAttributeArray *rid_array = NULL;
 
624
        uint32_t access_mask = SEC_STD_READ_CONTROL |
 
625
                               SAMR_USER_ACCESS_GET_ATTRIBUTES |
 
626
                               SAMR_USER_ACCESS_GET_NAME_ETC;
 
627
 
 
628
        ZERO_STRUCT(user_handle);
 
629
 
 
630
        switch (level) {
 
631
                case 0:
 
632
                        break;
 
633
                case 1:
 
634
                        access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
 
635
                                       SAMR_USER_ACCESS_GET_GROUPS;
 
636
                        break;
 
637
                case 2:
 
638
                case 3:
 
639
                case 4:
 
640
                case 11:
 
641
                        access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
 
642
                                       SAMR_USER_ACCESS_GET_GROUPS |
 
643
                                       SAMR_USER_ACCESS_GET_LOCALE;
 
644
                        break;
 
645
                case 10:
 
646
                case 20:
 
647
                case 23:
 
648
                        break;
 
649
                default:
 
650
                        return NT_STATUS_INVALID_LEVEL;
 
651
        }
 
652
 
 
653
        if (level == 0) {
 
654
                return NT_STATUS_OK;
 
655
        }
 
656
 
 
657
        status = rpccli_samr_OpenUser(pipe_cli, mem_ctx,
 
658
                                      domain_handle,
 
659
                                      access_mask,
 
660
                                      rid,
 
661
                                      &user_handle);
 
662
        if (!NT_STATUS_IS_OK(status)) {
 
663
                goto done;
 
664
        }
 
665
 
 
666
        status = rpccli_samr_QueryUserInfo(pipe_cli, mem_ctx,
 
667
                                           &user_handle,
 
668
                                           21,
 
669
                                           &user_info);
 
670
        if (!NT_STATUS_IS_OK(status)) {
 
671
                goto done;
 
672
        }
 
673
 
 
674
        status = rpccli_samr_QuerySecurity(pipe_cli, mem_ctx,
 
675
                                           &user_handle,
 
676
                                           SECINFO_DACL,
 
677
                                           sec_desc);
 
678
        if (!NT_STATUS_IS_OK(status)) {
 
679
                goto done;
 
680
        }
 
681
 
 
682
        if (access_mask & SAMR_USER_ACCESS_GET_GROUPS) {
 
683
 
 
684
                struct lsa_SidArray sid_array;
 
685
                struct samr_Ids alias_rids;
 
686
                int i;
 
687
                uint32_t auth_flag = 0;
 
688
                struct dom_sid sid;
 
689
 
 
690
                status = rpccli_samr_GetGroupsForUser(pipe_cli, mem_ctx,
 
691
                                                      &user_handle,
 
692
                                                      &rid_array);
 
693
                if (!NT_STATUS_IS_OK(status)) {
 
694
                        goto done;
 
695
                }
 
696
 
 
697
                sid_array.num_sids = rid_array->count + 1;
 
698
                sid_array.sids = talloc_array(mem_ctx, struct lsa_SidPtr,
 
699
                                              sid_array.num_sids);
 
700
                NT_STATUS_HAVE_NO_MEMORY(sid_array.sids);
 
701
 
 
702
                for (i=0; i<rid_array->count; i++) {
 
703
                        sid_compose(&sid, domain_sid, rid_array->rids[i].rid);
 
704
                        sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
 
705
                        NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
 
706
                }
 
707
 
 
708
                sid_compose(&sid, domain_sid, rid);
 
709
                sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
 
710
                NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
 
711
 
 
712
                status = rpccli_samr_GetAliasMembership(pipe_cli, mem_ctx,
 
713
                                                        builtin_handle,
 
714
                                                        &sid_array,
 
715
                                                        &alias_rids);
 
716
                if (!NT_STATUS_IS_OK(status)) {
 
717
                        goto done;
 
718
                }
 
719
 
 
720
                for (i=0; i<alias_rids.count; i++) {
 
721
                        switch (alias_rids.ids[i]) {
 
722
                                case 550: /* Print Operators */
 
723
                                        auth_flag |= AF_OP_PRINT;
 
724
                                        break;
 
725
                                case 549: /* Server Operators */
 
726
                                        auth_flag |= AF_OP_SERVER;
 
727
                                        break;
 
728
                                case 548: /* Account Operators */
 
729
                                        auth_flag |= AF_OP_ACCOUNTS;
 
730
                                        break;
 
731
                                default:
 
732
                                        break;
 
733
                        }
 
734
                }
 
735
 
 
736
                if (auth_flag_p) {
 
737
                        *auth_flag_p = auth_flag;
 
738
                }
 
739
        }
 
740
 
 
741
        *info21 = &user_info->info21;
 
742
 
 
743
 done:
 
744
        if (is_valid_policy_hnd(&user_handle)) {
 
745
                rpccli_samr_Close(pipe_cli, mem_ctx, &user_handle);
 
746
        }
 
747
 
 
748
        return status;
 
749
}
 
750
 
 
751
/****************************************************************
 
752
****************************************************************/
 
753
 
 
754
static uint32_t samr_rid_to_priv_level(uint32_t rid)
 
755
{
 
756
        switch (rid) {
 
757
                case DOMAIN_RID_ADMINISTRATOR:
 
758
                        return USER_PRIV_ADMIN;
 
759
                case DOMAIN_RID_GUEST:
 
760
                        return USER_PRIV_GUEST;
 
761
                default:
 
762
                        return USER_PRIV_USER;
 
763
        }
 
764
}
 
765
 
 
766
/****************************************************************
 
767
****************************************************************/
 
768
 
 
769
static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb)
 
770
{
 
771
        uint32_t fl = UF_SCRIPT; /* god knows why */
 
772
 
 
773
        fl |= ads_acb2uf(acb);
 
774
 
 
775
        return fl;
 
776
}
 
777
 
 
778
/****************************************************************
 
779
****************************************************************/
 
780
 
 
781
static NTSTATUS info21_to_USER_INFO_1(TALLOC_CTX *mem_ctx,
 
782
                                      const struct samr_UserInfo21 *i21,
 
783
                                      struct USER_INFO_1 *i)
 
784
{
 
785
        ZERO_STRUCTP(i);
 
786
        i->usri1_name           = talloc_strdup(mem_ctx, i21->account_name.string);
 
787
        NT_STATUS_HAVE_NO_MEMORY(i->usri1_name);
 
788
        i->usri1_password       = NULL;
 
789
        i->usri1_password_age   = time(NULL) - nt_time_to_unix(i21->last_password_change);
 
790
        i->usri1_priv           = samr_rid_to_priv_level(i21->rid);
 
791
        i->usri1_home_dir       = talloc_strdup(mem_ctx, i21->home_directory.string);
 
792
        i->usri1_comment        = talloc_strdup(mem_ctx, i21->description.string);
 
793
        i->usri1_flags          = samr_acb_flags_to_netapi_flags(i21->acct_flags);
 
794
        i->usri1_script_path    = talloc_strdup(mem_ctx, i21->logon_script.string);
 
795
 
 
796
        return NT_STATUS_OK;
 
797
}
 
798
 
 
799
/****************************************************************
 
800
****************************************************************/
 
801
 
 
802
static NTSTATUS info21_to_USER_INFO_2(TALLOC_CTX *mem_ctx,
 
803
                                      const struct samr_UserInfo21 *i21,
 
804
                                      uint32_t auth_flag,
 
805
                                      struct USER_INFO_2 *i)
 
806
{
 
807
        ZERO_STRUCTP(i);
 
808
 
 
809
        i->usri2_name           = talloc_strdup(mem_ctx, i21->account_name.string);
 
810
        NT_STATUS_HAVE_NO_MEMORY(i->usri2_name);
 
811
        i->usri2_password       = NULL;
 
812
        i->usri2_password_age   = time(NULL) - nt_time_to_unix(i21->last_password_change);
 
813
        i->usri2_priv           = samr_rid_to_priv_level(i21->rid);
 
814
        i->usri2_home_dir       = talloc_strdup(mem_ctx, i21->home_directory.string);
 
815
        i->usri2_comment        = talloc_strdup(mem_ctx, i21->description.string);
 
816
        i->usri2_flags          = samr_acb_flags_to_netapi_flags(i21->acct_flags);
 
817
        i->usri2_script_path    = talloc_strdup(mem_ctx, i21->logon_script.string);
 
818
        i->usri2_auth_flags     = auth_flag;
 
819
        i->usri2_full_name      = talloc_strdup(mem_ctx, i21->full_name.string);
 
820
        i->usri2_usr_comment    = talloc_strdup(mem_ctx, i21->comment.string);
 
821
        i->usri2_parms          = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
 
822
        i->usri2_workstations   = talloc_strdup(mem_ctx, i21->workstations.string);
 
823
        i->usri2_last_logon     = nt_time_to_unix(i21->last_logon);
 
824
        i->usri2_last_logoff    = nt_time_to_unix(i21->last_logoff);
 
825
        i->usri2_acct_expires   = nt_time_to_unix(i21->acct_expiry);
 
826
        i->usri2_max_storage    = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
 
827
        i->usri2_units_per_week = i21->logon_hours.units_per_week;
 
828
        i->usri2_logon_hours    = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
 
829
        i->usri2_bad_pw_count   = i21->bad_password_count;
 
830
        i->usri2_num_logons     = i21->logon_count;
 
831
        i->usri2_logon_server   = talloc_strdup(mem_ctx, "\\\\*");
 
832
        i->usri2_country_code   = i21->country_code;
 
833
        i->usri2_code_page      = i21->code_page;
 
834
 
 
835
        return NT_STATUS_OK;
 
836
}
 
837
 
 
838
/****************************************************************
 
839
****************************************************************/
 
840
 
 
841
static NTSTATUS info21_to_USER_INFO_3(TALLOC_CTX *mem_ctx,
 
842
                                      const struct samr_UserInfo21 *i21,
 
843
                                      uint32_t auth_flag,
 
844
                                      struct USER_INFO_3 *i)
 
845
{
 
846
        ZERO_STRUCTP(i);
 
847
 
 
848
        i->usri3_name           = talloc_strdup(mem_ctx, i21->account_name.string);
 
849
        NT_STATUS_HAVE_NO_MEMORY(i->usri3_name);
 
850
        i->usri3_password_age   = time(NULL) - nt_time_to_unix(i21->last_password_change);
 
851
        i->usri3_priv           = samr_rid_to_priv_level(i21->rid);
 
852
        i->usri3_home_dir       = talloc_strdup(mem_ctx, i21->home_directory.string);
 
853
        i->usri3_comment        = talloc_strdup(mem_ctx, i21->description.string);
 
854
        i->usri3_flags          = samr_acb_flags_to_netapi_flags(i21->acct_flags);
 
855
        i->usri3_script_path    = talloc_strdup(mem_ctx, i21->logon_script.string);
 
856
        i->usri3_auth_flags     = auth_flag;
 
857
        i->usri3_full_name      = talloc_strdup(mem_ctx, i21->full_name.string);
 
858
        i->usri3_usr_comment    = talloc_strdup(mem_ctx, i21->comment.string);
 
859
        i->usri3_parms          = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
 
860
        i->usri3_workstations   = talloc_strdup(mem_ctx, i21->workstations.string);
 
861
        i->usri3_last_logon     = nt_time_to_unix(i21->last_logon);
 
862
        i->usri3_last_logoff    = nt_time_to_unix(i21->last_logoff);
 
863
        i->usri3_acct_expires   = nt_time_to_unix(i21->acct_expiry);
 
864
        i->usri3_max_storage    = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
 
865
        i->usri3_units_per_week = i21->logon_hours.units_per_week;
 
866
        i->usri3_logon_hours    = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
 
867
        i->usri3_bad_pw_count   = i21->bad_password_count;
 
868
        i->usri3_num_logons     = i21->logon_count;
 
869
        i->usri3_logon_server   = talloc_strdup(mem_ctx, "\\\\*");
 
870
        i->usri3_country_code   = i21->country_code;
 
871
        i->usri3_code_page      = i21->code_page;
 
872
        i->usri3_user_id        = i21->rid;
 
873
        i->usri3_primary_group_id = i21->primary_gid;
 
874
        i->usri3_profile        = talloc_strdup(mem_ctx, i21->profile_path.string);
 
875
        i->usri3_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
 
876
        i->usri3_password_expired = i21->password_expired;
 
877
 
 
878
        return NT_STATUS_OK;
 
879
}
 
880
 
 
881
/****************************************************************
 
882
****************************************************************/
 
883
 
 
884
static NTSTATUS info21_to_USER_INFO_4(TALLOC_CTX *mem_ctx,
 
885
                                      const struct samr_UserInfo21 *i21,
 
886
                                      uint32_t auth_flag,
 
887
                                      struct dom_sid *domain_sid,
 
888
                                      struct USER_INFO_4 *i)
 
889
{
 
890
        struct dom_sid sid;
 
891
 
 
892
        ZERO_STRUCTP(i);
 
893
 
 
894
        i->usri4_name           = talloc_strdup(mem_ctx, i21->account_name.string);
 
895
        NT_STATUS_HAVE_NO_MEMORY(i->usri4_name);
 
896
        i->usri4_password_age   = time(NULL) - nt_time_to_unix(i21->last_password_change);
 
897
        i->usri4_password       = NULL;
 
898
        i->usri4_priv           = samr_rid_to_priv_level(i21->rid);
 
899
        i->usri4_home_dir       = talloc_strdup(mem_ctx, i21->home_directory.string);
 
900
        i->usri4_comment        = talloc_strdup(mem_ctx, i21->description.string);
 
901
        i->usri4_flags          = samr_acb_flags_to_netapi_flags(i21->acct_flags);
 
902
        i->usri4_script_path    = talloc_strdup(mem_ctx, i21->logon_script.string);
 
903
        i->usri4_auth_flags     = auth_flag;
 
904
        i->usri4_full_name      = talloc_strdup(mem_ctx, i21->full_name.string);
 
905
        i->usri4_usr_comment    = talloc_strdup(mem_ctx, i21->comment.string);
 
906
        i->usri4_parms          = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
 
907
        i->usri4_workstations   = talloc_strdup(mem_ctx, i21->workstations.string);
 
908
        i->usri4_last_logon     = nt_time_to_unix(i21->last_logon);
 
909
        i->usri4_last_logoff    = nt_time_to_unix(i21->last_logoff);
 
910
        i->usri4_acct_expires   = nt_time_to_unix(i21->acct_expiry);
 
911
        i->usri4_max_storage    = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
 
912
        i->usri4_units_per_week = i21->logon_hours.units_per_week;
 
913
        i->usri4_logon_hours    = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
 
914
        i->usri4_bad_pw_count   = i21->bad_password_count;
 
915
        i->usri4_num_logons     = i21->logon_count;
 
916
        i->usri4_logon_server   = talloc_strdup(mem_ctx, "\\\\*");
 
917
        i->usri4_country_code   = i21->country_code;
 
918
        i->usri4_code_page      = i21->code_page;
 
919
        if (!sid_compose(&sid, domain_sid, i21->rid)) {
 
920
                return NT_STATUS_NO_MEMORY;
 
921
        }
 
922
        i->usri4_user_sid       = (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
 
923
        i->usri4_primary_group_id = i21->primary_gid;
 
924
        i->usri4_profile        = talloc_strdup(mem_ctx, i21->profile_path.string);
 
925
        i->usri4_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
 
926
        i->usri4_password_expired = i21->password_expired;
 
927
 
 
928
        return NT_STATUS_OK;
 
929
}
 
930
 
 
931
/****************************************************************
 
932
****************************************************************/
 
933
 
 
934
static NTSTATUS info21_to_USER_INFO_10(TALLOC_CTX *mem_ctx,
 
935
                                       const struct samr_UserInfo21 *i21,
 
936
                                       struct USER_INFO_10 *i)
 
937
{
 
938
        ZERO_STRUCTP(i);
 
939
 
 
940
        i->usri10_name          = talloc_strdup(mem_ctx, i21->account_name.string);
 
941
        NT_STATUS_HAVE_NO_MEMORY(i->usri10_name);
 
942
        i->usri10_comment       = talloc_strdup(mem_ctx, i21->description.string);
 
943
        i->usri10_full_name     = talloc_strdup(mem_ctx, i21->full_name.string);
 
944
        i->usri10_usr_comment   = talloc_strdup(mem_ctx, i21->comment.string);
 
945
 
 
946
        return NT_STATUS_OK;
 
947
}
 
948
 
 
949
/****************************************************************
 
950
****************************************************************/
 
951
 
 
952
static NTSTATUS info21_to_USER_INFO_11(TALLOC_CTX *mem_ctx,
 
953
                                       const struct samr_UserInfo21 *i21,
 
954
                                       uint32_t auth_flag,
 
955
                                       struct USER_INFO_11 *i)
 
956
{
 
957
        ZERO_STRUCTP(i);
 
958
 
 
959
        i->usri11_name          = talloc_strdup(mem_ctx, i21->account_name.string);
 
960
        NT_STATUS_HAVE_NO_MEMORY(i->usri11_name);
 
961
        i->usri11_comment       = talloc_strdup(mem_ctx, i21->description.string);
 
962
        i->usri11_usr_comment   = talloc_strdup(mem_ctx, i21->comment.string);
 
963
        i->usri11_full_name     = talloc_strdup(mem_ctx, i21->full_name.string);
 
964
        i->usri11_priv          = samr_rid_to_priv_level(i21->rid);
 
965
        i->usri11_auth_flags    = auth_flag;
 
966
        i->usri11_password_age  = time(NULL) - nt_time_to_unix(i21->last_password_change);
 
967
        i->usri11_home_dir      = talloc_strdup(mem_ctx, i21->home_directory.string);
 
968
        i->usri11_parms         = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
 
969
        i->usri11_last_logon    = nt_time_to_unix(i21->last_logon);
 
970
        i->usri11_last_logoff   = nt_time_to_unix(i21->last_logoff);
 
971
        i->usri11_bad_pw_count  = i21->bad_password_count;
 
972
        i->usri11_num_logons    = i21->logon_count;
 
973
        i->usri11_logon_server  = talloc_strdup(mem_ctx, "\\\\*");
 
974
        i->usri11_country_code  = i21->country_code;
 
975
        i->usri11_workstations  = talloc_strdup(mem_ctx, i21->workstations.string);
 
976
        i->usri11_max_storage   = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
 
977
        i->usri11_units_per_week = i21->logon_hours.units_per_week;
 
978
        i->usri11_logon_hours   = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
 
979
        i->usri11_code_page     = i21->code_page;
 
980
 
 
981
        return NT_STATUS_OK;
 
982
}
 
983
 
 
984
/****************************************************************
 
985
****************************************************************/
 
986
 
 
987
static NTSTATUS info21_to_USER_INFO_20(TALLOC_CTX *mem_ctx,
 
988
                                       const struct samr_UserInfo21 *i21,
 
989
                                       struct USER_INFO_20 *i)
 
990
{
 
991
        ZERO_STRUCTP(i);
 
992
 
 
993
        i->usri20_name          = talloc_strdup(mem_ctx, i21->account_name.string);
 
994
        NT_STATUS_HAVE_NO_MEMORY(i->usri20_name);
 
995
        i->usri20_comment       = talloc_strdup(mem_ctx, i21->description.string);
 
996
        i->usri20_full_name     = talloc_strdup(mem_ctx, i21->full_name.string);
 
997
        i->usri20_flags         = samr_acb_flags_to_netapi_flags(i21->acct_flags);
 
998
        i->usri20_user_id       = i21->rid;
 
999
 
 
1000
        return NT_STATUS_OK;
 
1001
}
 
1002
 
 
1003
/****************************************************************
 
1004
****************************************************************/
 
1005
 
 
1006
static NTSTATUS info21_to_USER_INFO_23(TALLOC_CTX *mem_ctx,
 
1007
                                       const struct samr_UserInfo21 *i21,
 
1008
                                       struct dom_sid *domain_sid,
 
1009
                                       struct USER_INFO_23 *i)
 
1010
{
 
1011
        struct dom_sid sid;
 
1012
 
 
1013
        ZERO_STRUCTP(i);
 
1014
 
 
1015
        i->usri23_name          = talloc_strdup(mem_ctx, i21->account_name.string);
 
1016
        NT_STATUS_HAVE_NO_MEMORY(i->usri23_name);
 
1017
        i->usri23_comment       = talloc_strdup(mem_ctx, i21->description.string);
 
1018
        i->usri23_full_name     = talloc_strdup(mem_ctx, i21->full_name.string);
 
1019
        i->usri23_flags         = samr_acb_flags_to_netapi_flags(i21->acct_flags);
 
1020
        if (!sid_compose(&sid, domain_sid, i21->rid)) {
 
1021
                return NT_STATUS_NO_MEMORY;
 
1022
        }
 
1023
        i->usri23_user_sid      = (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
 
1024
 
 
1025
        return NT_STATUS_OK;
 
1026
}
 
1027
 
 
1028
/****************************************************************
 
1029
****************************************************************/
 
1030
 
 
1031
static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
 
1032
                                                         struct rpc_pipe_client *pipe_cli,
 
1033
                                                         struct dom_sid *domain_sid,
 
1034
                                                         struct policy_handle *domain_handle,
 
1035
                                                         struct policy_handle *builtin_handle,
 
1036
                                                         const char *user_name,
 
1037
                                                         uint32_t rid,
 
1038
                                                         uint32_t level,
 
1039
                                                         uint8_t **buffer,
 
1040
                                                         uint32_t *num_entries)
 
1041
{
 
1042
        NTSTATUS status;
 
1043
 
 
1044
        struct samr_UserInfo21 *info21 = NULL;
 
1045
        struct sec_desc_buf *sec_desc = NULL;
 
1046
        uint32_t auth_flag = 0;
 
1047
 
 
1048
        struct USER_INFO_0 info0;
 
1049
        struct USER_INFO_1 info1;
 
1050
        struct USER_INFO_2 info2;
 
1051
        struct USER_INFO_3 info3;
 
1052
        struct USER_INFO_4 info4;
 
1053
        struct USER_INFO_10 info10;
 
1054
        struct USER_INFO_11 info11;
 
1055
        struct USER_INFO_20 info20;
 
1056
        struct USER_INFO_23 info23;
 
1057
 
 
1058
        switch (level) {
 
1059
                case 0:
 
1060
                case 1:
 
1061
                case 2:
 
1062
                case 3:
 
1063
                case 4:
 
1064
                case 10:
 
1065
                case 11:
 
1066
                case 20:
 
1067
                case 23:
 
1068
                        break;
 
1069
                default:
 
1070
                        return NT_STATUS_INVALID_LEVEL;
 
1071
        }
 
1072
 
 
1073
        if (level == 0) {
 
1074
                info0.usri0_name = talloc_strdup(mem_ctx, user_name);
 
1075
                NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name);
 
1076
 
 
1077
                ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0,
 
1078
                             (struct USER_INFO_0 **)buffer, num_entries);
 
1079
 
 
1080
                return NT_STATUS_OK;
 
1081
        }
 
1082
 
 
1083
        status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli,
 
1084
                                            domain_handle,
 
1085
                                            builtin_handle,
 
1086
                                            user_name,
 
1087
                                            domain_sid,
 
1088
                                            rid,
 
1089
                                            level,
 
1090
                                            &info21,
 
1091
                                            &sec_desc,
 
1092
                                            &auth_flag);
 
1093
 
 
1094
        if (!NT_STATUS_IS_OK(status)) {
 
1095
                goto done;
 
1096
        }
 
1097
 
 
1098
        switch (level) {
 
1099
                case 0:
 
1100
                        /* already returned above */
 
1101
                        break;
 
1102
                case 1:
 
1103
                        status = info21_to_USER_INFO_1(mem_ctx, info21, &info1);
 
1104
                        NT_STATUS_NOT_OK_RETURN(status);
 
1105
 
 
1106
                        ADD_TO_ARRAY(mem_ctx, struct USER_INFO_1, info1,
 
1107
                                     (struct USER_INFO_1 **)buffer, num_entries);
 
1108
 
 
1109
                        break;
 
1110
                case 2:
 
1111
                        status = info21_to_USER_INFO_2(mem_ctx, info21, auth_flag, &info2);
 
1112
                        NT_STATUS_NOT_OK_RETURN(status);
 
1113
 
 
1114
                        ADD_TO_ARRAY(mem_ctx, struct USER_INFO_2, info2,
 
1115
                                     (struct USER_INFO_2 **)buffer, num_entries);
 
1116
 
 
1117
                        break;
 
1118
                case 3:
 
1119
                        status = info21_to_USER_INFO_3(mem_ctx, info21, auth_flag, &info3);
 
1120
                        NT_STATUS_NOT_OK_RETURN(status);
 
1121
 
 
1122
                        ADD_TO_ARRAY(mem_ctx, struct USER_INFO_3, info3,
 
1123
                                     (struct USER_INFO_3 **)buffer, num_entries);
 
1124
 
 
1125
                        break;
 
1126
                case 4:
 
1127
                        status = info21_to_USER_INFO_4(mem_ctx, info21, auth_flag, domain_sid, &info4);
 
1128
                        NT_STATUS_NOT_OK_RETURN(status);
 
1129
 
 
1130
                        ADD_TO_ARRAY(mem_ctx, struct USER_INFO_4, info4,
 
1131
                                     (struct USER_INFO_4 **)buffer, num_entries);
 
1132
 
 
1133
                        break;
 
1134
                case 10:
 
1135
                        status = info21_to_USER_INFO_10(mem_ctx, info21, &info10);
 
1136
                        NT_STATUS_NOT_OK_RETURN(status);
 
1137
 
 
1138
                        ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
 
1139
                                     (struct USER_INFO_10 **)buffer, num_entries);
 
1140
 
 
1141
                        break;
 
1142
                case 11:
 
1143
                        status = info21_to_USER_INFO_11(mem_ctx, info21, auth_flag, &info11);
 
1144
                        NT_STATUS_NOT_OK_RETURN(status);
 
1145
 
 
1146
                        ADD_TO_ARRAY(mem_ctx, struct USER_INFO_11, info11,
 
1147
                                     (struct USER_INFO_11 **)buffer, num_entries);
 
1148
 
 
1149
                        break;
 
1150
                case 20:
 
1151
                        status = info21_to_USER_INFO_20(mem_ctx, info21, &info20);
 
1152
                        NT_STATUS_NOT_OK_RETURN(status);
 
1153
 
 
1154
                        ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
 
1155
                                     (struct USER_INFO_20 **)buffer, num_entries);
 
1156
 
 
1157
                        break;
 
1158
                case 23:
 
1159
                        status = info21_to_USER_INFO_23(mem_ctx, info21, domain_sid, &info23);
 
1160
                        NT_STATUS_NOT_OK_RETURN(status);
 
1161
 
 
1162
                        ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
 
1163
                                     (struct USER_INFO_23 **)buffer, num_entries);
 
1164
                        break;
 
1165
                default:
 
1166
                        return NT_STATUS_INVALID_LEVEL;
 
1167
        }
 
1168
 
 
1169
 done:
 
1170
        return status;
 
1171
}
 
1172
 
 
1173
/****************************************************************
 
1174
****************************************************************/
 
1175
 
 
1176
WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
 
1177
                     struct NetUserEnum *r)
 
1178
{
 
1179
        struct rpc_pipe_client *pipe_cli = NULL;
 
1180
        struct policy_handle connect_handle;
 
1181
        struct dom_sid2 *domain_sid = NULL;
 
1182
        struct policy_handle domain_handle, builtin_handle;
 
1183
        struct samr_SamArray *sam = NULL;
 
1184
        uint32_t filter = ACB_NORMAL;
 
1185
        int i;
 
1186
        uint32_t entries_read = 0;
 
1187
 
 
1188
        NTSTATUS status = NT_STATUS_OK;
 
1189
        WERROR werr;
 
1190
 
 
1191
        ZERO_STRUCT(connect_handle);
 
1192
        ZERO_STRUCT(domain_handle);
 
1193
        ZERO_STRUCT(builtin_handle);
 
1194
 
 
1195
        if (!r->out.buffer) {
 
1196
                return WERR_INVALID_PARAM;
 
1197
        }
 
1198
 
 
1199
        *r->out.buffer = NULL;
 
1200
        *r->out.entries_read = 0;
 
1201
 
 
1202
        switch (r->in.level) {
 
1203
                case 0:
 
1204
                case 1:
 
1205
                case 2:
 
1206
                case 3:
 
1207
                case 4:
 
1208
                case 10:
 
1209
                case 11:
 
1210
                case 20:
 
1211
                case 23:
 
1212
                        break;
 
1213
                default:
 
1214
                        return WERR_UNKNOWN_LEVEL;
 
1215
        }
 
1216
 
 
1217
        werr = libnetapi_open_pipe(ctx, r->in.server_name,
 
1218
                                   &ndr_table_samr.syntax_id,
 
1219
                                   &pipe_cli);
 
1220
        if (!W_ERROR_IS_OK(werr)) {
 
1221
                goto done;
 
1222
        }
 
1223
 
 
1224
        werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
 
1225
                                                  SAMR_ACCESS_ENUM_DOMAINS |
 
1226
                                                  SAMR_ACCESS_LOOKUP_DOMAIN,
 
1227
                                                  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
 
1228
                                                  SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
 
1229
                                                  &connect_handle,
 
1230
                                                  &builtin_handle);
 
1231
        if (!W_ERROR_IS_OK(werr)) {
 
1232
                goto done;
 
1233
        }
 
1234
 
 
1235
        werr = libnetapi_samr_open_domain(ctx, pipe_cli,
 
1236
                                          SAMR_ACCESS_ENUM_DOMAINS |
 
1237
                                          SAMR_ACCESS_LOOKUP_DOMAIN,
 
1238
                                          SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
 
1239
                                          SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
 
1240
                                          SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
 
1241
                                          &connect_handle,
 
1242
                                          &domain_handle,
 
1243
                                          &domain_sid);
 
1244
        if (!W_ERROR_IS_OK(werr)) {
 
1245
                goto done;
 
1246
        }
 
1247
 
 
1248
        switch (r->in.filter) {
 
1249
                case FILTER_NORMAL_ACCOUNT:
 
1250
                        filter = ACB_NORMAL;
 
1251
                        break;
 
1252
                case FILTER_TEMP_DUPLICATE_ACCOUNT:
 
1253
                        filter = ACB_TEMPDUP;
 
1254
                        break;
 
1255
                case FILTER_INTERDOMAIN_TRUST_ACCOUNT:
 
1256
                        filter = ACB_DOMTRUST;
 
1257
                        break;
 
1258
                case FILTER_WORKSTATION_TRUST_ACCOUNT:
 
1259
                        filter = ACB_WSTRUST;
 
1260
                        break;
 
1261
                case FILTER_SERVER_TRUST_ACCOUNT:
 
1262
                        filter = ACB_SVRTRUST;
 
1263
                        break;
 
1264
                default:
 
1265
                        break;
 
1266
        }
 
1267
 
 
1268
        status = rpccli_samr_EnumDomainUsers(pipe_cli,
 
1269
                                             ctx,
 
1270
                                             &domain_handle,
 
1271
                                             r->in.resume_handle,
 
1272
                                             filter,
 
1273
                                             &sam,
 
1274
                                             r->in.prefmaxlen,
 
1275
                                             &entries_read);
 
1276
        werr = ntstatus_to_werror(status);
 
1277
        if (NT_STATUS_IS_ERR(status)) {
 
1278
                goto done;
 
1279
        }
 
1280
 
 
1281
        for (i=0; i < sam->count; i++) {
 
1282
 
 
1283
                status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
 
1284
                                                                  domain_sid,
 
1285
                                                                  &domain_handle,
 
1286
                                                                  &builtin_handle,
 
1287
                                                                  sam->entries[i].name.string,
 
1288
                                                                  sam->entries[i].idx,
 
1289
                                                                  r->in.level,
 
1290
                                                                  r->out.buffer,
 
1291
                                                                  r->out.entries_read);
 
1292
                if (!NT_STATUS_IS_OK(status)) {
 
1293
                        werr = ntstatus_to_werror(status);
 
1294
                        goto done;
 
1295
                }
 
1296
        }
 
1297
 
 
1298
 done:
 
1299
        /* if last query */
 
1300
        if (NT_STATUS_IS_OK(status) ||
 
1301
            NT_STATUS_IS_ERR(status)) {
 
1302
 
 
1303
                if (ctx->disable_policy_handle_cache) {
 
1304
                        libnetapi_samr_close_domain_handle(ctx, &domain_handle);
 
1305
                        libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
 
1306
                        libnetapi_samr_close_connect_handle(ctx, &connect_handle);
 
1307
                }
 
1308
        }
 
1309
 
 
1310
        return werr;
 
1311
}
 
1312
 
 
1313
/****************************************************************
 
1314
****************************************************************/
 
1315
 
 
1316
WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
 
1317
                     struct NetUserEnum *r)
 
1318
{
 
1319
        LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserEnum);
 
1320
}
 
1321
 
 
1322
/****************************************************************
 
1323
****************************************************************/
 
1324
 
 
1325
static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
 
1326
                                                        struct samr_DispInfoGeneral *info,
 
1327
                                                        uint32_t *entries_read,
 
1328
                                                        void **buffer)
 
1329
{
 
1330
        struct NET_DISPLAY_USER *user = NULL;
 
1331
        int i;
 
1332
 
 
1333
        user = TALLOC_ZERO_ARRAY(mem_ctx,
 
1334
                                 struct NET_DISPLAY_USER,
 
1335
                                 info->count);
 
1336
        W_ERROR_HAVE_NO_MEMORY(user);
 
1337
 
 
1338
        for (i = 0; i < info->count; i++) {
 
1339
                user[i].usri1_name = talloc_strdup(mem_ctx,
 
1340
                        info->entries[i].account_name.string);
 
1341
                user[i].usri1_comment = talloc_strdup(mem_ctx,
 
1342
                        info->entries[i].description.string);
 
1343
                user[i].usri1_flags =
 
1344
                        info->entries[i].acct_flags;
 
1345
                user[i].usri1_full_name = talloc_strdup(mem_ctx,
 
1346
                        info->entries[i].full_name.string);
 
1347
                user[i].usri1_user_id =
 
1348
                        info->entries[i].rid;
 
1349
                user[i].usri1_next_index =
 
1350
                        info->entries[i].idx;
 
1351
 
 
1352
                if (!user[i].usri1_name) {
 
1353
                        return WERR_NOMEM;
 
1354
                }
 
1355
        }
 
1356
 
 
1357
        *buffer = talloc_memdup(mem_ctx, user,
 
1358
                sizeof(struct NET_DISPLAY_USER) * info->count);
 
1359
        W_ERROR_HAVE_NO_MEMORY(*buffer);
 
1360
 
 
1361
        *entries_read = info->count;
 
1362
 
 
1363
        return WERR_OK;
 
1364
}
 
1365
 
 
1366
/****************************************************************
 
1367
****************************************************************/
 
1368
 
 
1369
static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
 
1370
                                                           struct samr_DispInfoFull *info,
 
1371
                                                           uint32_t *entries_read,
 
1372
                                                           void **buffer)
 
1373
{
 
1374
        struct NET_DISPLAY_MACHINE *machine = NULL;
 
1375
        int i;
 
1376
 
 
1377
        machine = TALLOC_ZERO_ARRAY(mem_ctx,
 
1378
                                    struct NET_DISPLAY_MACHINE,
 
1379
                                    info->count);
 
1380
        W_ERROR_HAVE_NO_MEMORY(machine);
 
1381
 
 
1382
        for (i = 0; i < info->count; i++) {
 
1383
                machine[i].usri2_name = talloc_strdup(mem_ctx,
 
1384
                        info->entries[i].account_name.string);
 
1385
                machine[i].usri2_comment = talloc_strdup(mem_ctx,
 
1386
                        info->entries[i].description.string);
 
1387
                machine[i].usri2_flags =
 
1388
                        info->entries[i].acct_flags;
 
1389
                machine[i].usri2_user_id =
 
1390
                        info->entries[i].rid;
 
1391
                machine[i].usri2_next_index =
 
1392
                        info->entries[i].idx;
 
1393
 
 
1394
                if (!machine[i].usri2_name) {
 
1395
                        return WERR_NOMEM;
 
1396
                }
 
1397
        }
 
1398
 
 
1399
        *buffer = talloc_memdup(mem_ctx, machine,
 
1400
                sizeof(struct NET_DISPLAY_MACHINE) * info->count);
 
1401
        W_ERROR_HAVE_NO_MEMORY(*buffer);
 
1402
 
 
1403
        *entries_read = info->count;
 
1404
 
 
1405
        return WERR_OK;
 
1406
}
 
1407
 
 
1408
/****************************************************************
 
1409
****************************************************************/
 
1410
 
 
1411
static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
 
1412
                                                         struct samr_DispInfoFullGroups *info,
 
1413
                                                         uint32_t *entries_read,
 
1414
                                                         void **buffer)
 
1415
{
 
1416
        struct NET_DISPLAY_GROUP *group = NULL;
 
1417
        int i;
 
1418
 
 
1419
        group = TALLOC_ZERO_ARRAY(mem_ctx,
 
1420
                                  struct NET_DISPLAY_GROUP,
 
1421
                                  info->count);
 
1422
        W_ERROR_HAVE_NO_MEMORY(group);
 
1423
 
 
1424
        for (i = 0; i < info->count; i++) {
 
1425
                group[i].grpi3_name = talloc_strdup(mem_ctx,
 
1426
                        info->entries[i].account_name.string);
 
1427
                group[i].grpi3_comment = talloc_strdup(mem_ctx,
 
1428
                        info->entries[i].description.string);
 
1429
                group[i].grpi3_group_id =
 
1430
                        info->entries[i].rid;
 
1431
                group[i].grpi3_attributes =
 
1432
                        info->entries[i].acct_flags;
 
1433
                group[i].grpi3_next_index =
 
1434
                        info->entries[i].idx;
 
1435
 
 
1436
                if (!group[i].grpi3_name) {
 
1437
                        return WERR_NOMEM;
 
1438
                }
 
1439
        }
 
1440
 
 
1441
        *buffer = talloc_memdup(mem_ctx, group,
 
1442
                sizeof(struct NET_DISPLAY_GROUP) * info->count);
 
1443
        W_ERROR_HAVE_NO_MEMORY(*buffer);
 
1444
 
 
1445
        *entries_read = info->count;
 
1446
 
 
1447
        return WERR_OK;
 
1448
 
 
1449
}
 
1450
 
 
1451
/****************************************************************
 
1452
****************************************************************/
 
1453
 
 
1454
static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx,
 
1455
                                                   union samr_DispInfo *info,
 
1456
                                                   uint32_t level,
 
1457
                                                   uint32_t *entries_read,
 
1458
                                                   void **buffer)
 
1459
{
 
1460
        switch (level) {
 
1461
                case 1:
 
1462
                        return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx,
 
1463
                                                                         &info->info1,
 
1464
                                                                         entries_read,
 
1465
                                                                         buffer);
 
1466
                case 2:
 
1467
                        return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx,
 
1468
                                                                            &info->info2,
 
1469
                                                                            entries_read,
 
1470
                                                                            buffer);
 
1471
                case 3:
 
1472
                        return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx,
 
1473
                                                                          &info->info3,
 
1474
                                                                          entries_read,
 
1475
                                                                          buffer);
 
1476
                default:
 
1477
                        return WERR_UNKNOWN_LEVEL;
 
1478
        }
 
1479
 
 
1480
        return WERR_OK;
 
1481
}
 
1482
 
 
1483
/****************************************************************
 
1484
****************************************************************/
 
1485
 
 
1486
WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
 
1487
                                    struct NetQueryDisplayInformation *r)
 
1488
{
 
1489
        struct rpc_pipe_client *pipe_cli = NULL;
 
1490
        struct policy_handle connect_handle;
 
1491
        struct dom_sid2 *domain_sid = NULL;
 
1492
        struct policy_handle domain_handle;
 
1493
        union samr_DispInfo info;
 
1494
 
 
1495
        uint32_t total_size = 0;
 
1496
        uint32_t returned_size = 0;
 
1497
 
 
1498
        NTSTATUS status = NT_STATUS_OK;
 
1499
        WERROR werr;
 
1500
        WERROR werr_tmp;
 
1501
 
 
1502
        *r->out.entries_read = 0;
 
1503
 
 
1504
        ZERO_STRUCT(connect_handle);
 
1505
        ZERO_STRUCT(domain_handle);
 
1506
 
 
1507
        switch (r->in.level) {
 
1508
                case 1:
 
1509
                case 2:
 
1510
                case 3:
 
1511
                        break;
 
1512
                default:
 
1513
                        return WERR_UNKNOWN_LEVEL;
 
1514
        }
 
1515
 
 
1516
        werr = libnetapi_open_pipe(ctx, r->in.server_name,
 
1517
                                   &ndr_table_samr.syntax_id,
 
1518
                                   &pipe_cli);
 
1519
        if (!W_ERROR_IS_OK(werr)) {
 
1520
                goto done;
 
1521
        }
 
1522
 
 
1523
        werr = libnetapi_samr_open_domain(ctx, pipe_cli,
 
1524
                                          SAMR_ACCESS_ENUM_DOMAINS |
 
1525
                                          SAMR_ACCESS_LOOKUP_DOMAIN,
 
1526
                                          SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
 
1527
                                          SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
 
1528
                                          SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
 
1529
                                          &connect_handle,
 
1530
                                          &domain_handle,
 
1531
                                          &domain_sid);
 
1532
        if (!W_ERROR_IS_OK(werr)) {
 
1533
                goto done;
 
1534
        }
 
1535
 
 
1536
        status = rpccli_samr_QueryDisplayInfo2(pipe_cli,
 
1537
                                               ctx,
 
1538
                                               &domain_handle,
 
1539
                                               r->in.level,
 
1540
                                               r->in.idx,
 
1541
                                               r->in.entries_requested,
 
1542
                                               r->in.prefmaxlen,
 
1543
                                               &total_size,
 
1544
                                               &returned_size,
 
1545
                                               &info);
 
1546
        werr = ntstatus_to_werror(status);
 
1547
        if (NT_STATUS_IS_ERR(status)) {
 
1548
                goto done;
 
1549
        }
 
1550
 
 
1551
        werr_tmp = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
 
1552
                                                        r->in.level,
 
1553
                                                        r->out.entries_read,
 
1554
                                                        r->out.buffer);
 
1555
        if (!W_ERROR_IS_OK(werr_tmp)) {
 
1556
                werr = werr_tmp;
 
1557
        }
 
1558
 done:
 
1559
        /* if last query */
 
1560
        if (NT_STATUS_IS_OK(status) ||
 
1561
            NT_STATUS_IS_ERR(status)) {
 
1562
 
 
1563
                if (ctx->disable_policy_handle_cache) {
 
1564
                        libnetapi_samr_close_domain_handle(ctx, &domain_handle);
 
1565
                        libnetapi_samr_close_connect_handle(ctx, &connect_handle);
 
1566
                }
 
1567
        }
 
1568
 
 
1569
        return werr;
 
1570
 
 
1571
}
 
1572
 
 
1573
/****************************************************************
 
1574
****************************************************************/
 
1575
 
 
1576
 
 
1577
WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx,
 
1578
                                    struct NetQueryDisplayInformation *r)
 
1579
{
 
1580
        LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetQueryDisplayInformation);
 
1581
}
 
1582
 
 
1583
/****************************************************************
 
1584
****************************************************************/
 
1585
 
 
1586
WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx,
 
1587
                               struct NetUserChangePassword *r)
 
1588
{
 
1589
        return WERR_NOT_SUPPORTED;
 
1590
}
 
1591
 
 
1592
/****************************************************************
 
1593
****************************************************************/
 
1594
 
 
1595
WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx,
 
1596
                               struct NetUserChangePassword *r)
 
1597
{
 
1598
        return WERR_NOT_SUPPORTED;
 
1599
}
 
1600
 
 
1601
/****************************************************************
 
1602
****************************************************************/
 
1603
 
 
1604
WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
 
1605
                        struct NetUserGetInfo *r)
 
1606
{
 
1607
        struct rpc_pipe_client *pipe_cli = NULL;
 
1608
        NTSTATUS status;
 
1609
        WERROR werr;
 
1610
 
 
1611
        struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
 
1612
        struct lsa_String lsa_account_name;
 
1613
        struct dom_sid2 *domain_sid = NULL;
 
1614
        struct samr_Ids user_rids, name_types;
 
1615
        uint32_t num_entries = 0;
 
1616
 
 
1617
        ZERO_STRUCT(connect_handle);
 
1618
        ZERO_STRUCT(domain_handle);
 
1619
        ZERO_STRUCT(builtin_handle);
 
1620
        ZERO_STRUCT(user_handle);
 
1621
 
 
1622
        if (!r->out.buffer) {
 
1623
                return WERR_INVALID_PARAM;
 
1624
        }
 
1625
 
 
1626
        switch (r->in.level) {
 
1627
                case 0:
 
1628
                case 1:
 
1629
                case 2:
 
1630
                case 3:
 
1631
                case 4:
 
1632
                case 10:
 
1633
                case 11:
 
1634
                case 20:
 
1635
                case 23:
 
1636
                        break;
 
1637
                default:
 
1638
                        werr = WERR_UNKNOWN_LEVEL;
 
1639
                        goto done;
 
1640
        }
 
1641
 
 
1642
        werr = libnetapi_open_pipe(ctx, r->in.server_name,
 
1643
                                   &ndr_table_samr.syntax_id,
 
1644
                                   &pipe_cli);
 
1645
        if (!W_ERROR_IS_OK(werr)) {
 
1646
                goto done;
 
1647
        }
 
1648
 
 
1649
        werr = libnetapi_samr_open_domain(ctx, pipe_cli,
 
1650
                                          SAMR_ACCESS_ENUM_DOMAINS |
 
1651
                                          SAMR_ACCESS_LOOKUP_DOMAIN,
 
1652
                                          SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
 
1653
                                          &connect_handle,
 
1654
                                          &domain_handle,
 
1655
                                          &domain_sid);
 
1656
        if (!W_ERROR_IS_OK(werr)) {
 
1657
                goto done;
 
1658
        }
 
1659
 
 
1660
        werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
 
1661
                                                  SAMR_ACCESS_ENUM_DOMAINS |
 
1662
                                                  SAMR_ACCESS_LOOKUP_DOMAIN,
 
1663
                                                  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
 
1664
                                                  SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
 
1665
                                                  &connect_handle,
 
1666
                                                  &builtin_handle);
 
1667
        if (!W_ERROR_IS_OK(werr)) {
 
1668
                goto done;
 
1669
        }
 
1670
 
 
1671
        init_lsa_String(&lsa_account_name, r->in.user_name);
 
1672
 
 
1673
        status = rpccli_samr_LookupNames(pipe_cli, ctx,
 
1674
                                         &domain_handle,
 
1675
                                         1,
 
1676
                                         &lsa_account_name,
 
1677
                                         &user_rids,
 
1678
                                         &name_types);
 
1679
        if (!NT_STATUS_IS_OK(status)) {
 
1680
                werr = ntstatus_to_werror(status);
 
1681
                goto done;
 
1682
        }
 
1683
 
 
1684
        status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
 
1685
                                                          domain_sid,
 
1686
                                                          &domain_handle,
 
1687
                                                          &builtin_handle,
 
1688
                                                          r->in.user_name,
 
1689
                                                          user_rids.ids[0],
 
1690
                                                          r->in.level,
 
1691
                                                          r->out.buffer,
 
1692
                                                          &num_entries);
 
1693
        if (!NT_STATUS_IS_OK(status)) {
 
1694
                werr = ntstatus_to_werror(status);
 
1695
                goto done;
 
1696
        }
 
1697
 
 
1698
 done:
 
1699
        if (is_valid_policy_hnd(&user_handle)) {
 
1700
                rpccli_samr_Close(pipe_cli, ctx, &user_handle);
 
1701
        }
 
1702
 
 
1703
        if (ctx->disable_policy_handle_cache) {
 
1704
                libnetapi_samr_close_domain_handle(ctx, &domain_handle);
 
1705
                libnetapi_samr_close_connect_handle(ctx, &connect_handle);
 
1706
        }
 
1707
 
 
1708
        return werr;
 
1709
}
 
1710
 
 
1711
/****************************************************************
 
1712
****************************************************************/
 
1713
 
 
1714
WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx,
 
1715
                        struct NetUserGetInfo *r)
 
1716
{
 
1717
        LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetInfo);
 
1718
}
 
1719
 
 
1720
/****************************************************************
 
1721
****************************************************************/
 
1722
 
 
1723
WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
 
1724
                        struct NetUserSetInfo *r)
 
1725
{
 
1726
        struct rpc_pipe_client *pipe_cli = NULL;
 
1727
        NTSTATUS status;
 
1728
        WERROR werr;
 
1729
 
 
1730
        struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
 
1731
        struct lsa_String lsa_account_name;
 
1732
        struct dom_sid2 *domain_sid = NULL;
 
1733
        struct samr_Ids user_rids, name_types;
 
1734
        uint32_t user_mask = 0;
 
1735
 
 
1736
        struct USER_INFO_X uX;
 
1737
 
 
1738
        ZERO_STRUCT(connect_handle);
 
1739
        ZERO_STRUCT(domain_handle);
 
1740
        ZERO_STRUCT(builtin_handle);
 
1741
        ZERO_STRUCT(user_handle);
 
1742
 
 
1743
        if (!r->in.buffer) {
 
1744
                return WERR_INVALID_PARAM;
 
1745
        }
 
1746
 
 
1747
        switch (r->in.level) {
 
1748
                case 0:
 
1749
                        user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
 
1750
                        break;
 
1751
                case 1003:
 
1752
                        user_mask = SAMR_USER_ACCESS_SET_PASSWORD;
 
1753
                        break;
 
1754
                case 1006:
 
1755
                case 1007:
 
1756
                case 1009:
 
1757
                case 1011:
 
1758
                case 1014:
 
1759
                case 1052:
 
1760
                case 1053:
 
1761
                        user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
 
1762
                        break;
 
1763
                case 1012:
 
1764
                case 1024:
 
1765
                        user_mask = SAMR_USER_ACCESS_SET_LOC_COM;
 
1766
                case 1051:
 
1767
                        user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES |
 
1768
                                    SAMR_USER_ACCESS_GET_GROUPS;
 
1769
                        break;
 
1770
                case 3:
 
1771
                        user_mask = STD_RIGHT_READ_CONTROL_ACCESS |
 
1772
                                    STD_RIGHT_WRITE_DAC_ACCESS |
 
1773
                                    SAMR_USER_ACCESS_GET_GROUPS |
 
1774
                                    SAMR_USER_ACCESS_SET_PASSWORD |
 
1775
                                    SAMR_USER_ACCESS_SET_ATTRIBUTES |
 
1776
                                    SAMR_USER_ACCESS_GET_ATTRIBUTES |
 
1777
                                    SAMR_USER_ACCESS_SET_LOC_COM;
 
1778
                        break;
 
1779
                case 1:
 
1780
                case 2:
 
1781
                case 4:
 
1782
                case 21:
 
1783
                case 22:
 
1784
                case 1005:
 
1785
                case 1008:
 
1786
                case 1010:
 
1787
                case 1017:
 
1788
                case 1020:
 
1789
                        werr = WERR_NOT_SUPPORTED;
 
1790
                        goto done;
 
1791
                default:
 
1792
                        werr = WERR_UNKNOWN_LEVEL;
 
1793
                        goto done;
 
1794
        }
 
1795
 
 
1796
        werr = libnetapi_open_pipe(ctx, r->in.server_name,
 
1797
                                   &ndr_table_samr.syntax_id,
 
1798
                                   &pipe_cli);
 
1799
        if (!W_ERROR_IS_OK(werr)) {
 
1800
                goto done;
 
1801
        }
 
1802
 
 
1803
        werr = libnetapi_samr_open_domain(ctx, pipe_cli,
 
1804
                                          SAMR_ACCESS_ENUM_DOMAINS |
 
1805
                                          SAMR_ACCESS_LOOKUP_DOMAIN,
 
1806
                                          SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
 
1807
                                          SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
 
1808
                                          &connect_handle,
 
1809
                                          &domain_handle,
 
1810
                                          &domain_sid);
 
1811
        if (!W_ERROR_IS_OK(werr)) {
 
1812
                goto done;
 
1813
        }
 
1814
 
 
1815
        werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
 
1816
                                                  SAMR_ACCESS_ENUM_DOMAINS |
 
1817
                                                  SAMR_ACCESS_LOOKUP_DOMAIN,
 
1818
                                                  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
 
1819
                                                  SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
 
1820
                                                  &connect_handle,
 
1821
                                                  &builtin_handle);
 
1822
        if (!W_ERROR_IS_OK(werr)) {
 
1823
                goto done;
 
1824
        }
 
1825
 
 
1826
        init_lsa_String(&lsa_account_name, r->in.user_name);
 
1827
 
 
1828
        status = rpccli_samr_LookupNames(pipe_cli, ctx,
 
1829
                                         &domain_handle,
 
1830
                                         1,
 
1831
                                         &lsa_account_name,
 
1832
                                         &user_rids,
 
1833
                                         &name_types);
 
1834
        if (!NT_STATUS_IS_OK(status)) {
 
1835
                werr = ntstatus_to_werror(status);
 
1836
                goto done;
 
1837
        }
 
1838
 
 
1839
        status = rpccli_samr_OpenUser(pipe_cli, ctx,
 
1840
                                      &domain_handle,
 
1841
                                      user_mask,
 
1842
                                      user_rids.ids[0],
 
1843
                                      &user_handle);
 
1844
        if (!NT_STATUS_IS_OK(status)) {
 
1845
                werr = ntstatus_to_werror(status);
 
1846
                goto done;
 
1847
        }
 
1848
 
 
1849
        status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
 
1850
        if (!NT_STATUS_IS_OK(status)) {
 
1851
                werr = ntstatus_to_werror(status);
 
1852
                goto done;
 
1853
        }
 
1854
 
 
1855
        status = set_user_info_USER_INFO_X(ctx, pipe_cli,
 
1856
                                           &pipe_cli->auth->user_session_key,
 
1857
                                           &user_handle,
 
1858
                                           &uX);
 
1859
        if (!NT_STATUS_IS_OK(status)) {
 
1860
                werr = ntstatus_to_werror(status);
 
1861
                goto done;
 
1862
        }
 
1863
 
 
1864
        werr = WERR_OK;
 
1865
 
 
1866
 done:
 
1867
        if (is_valid_policy_hnd(&user_handle)) {
 
1868
                rpccli_samr_Close(pipe_cli, ctx, &user_handle);
 
1869
        }
 
1870
 
 
1871
        if (ctx->disable_policy_handle_cache) {
 
1872
                libnetapi_samr_close_domain_handle(ctx, &domain_handle);
 
1873
                libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
 
1874
                libnetapi_samr_close_connect_handle(ctx, &connect_handle);
 
1875
        }
 
1876
 
 
1877
        return werr;
 
1878
}
 
1879
 
 
1880
/****************************************************************
 
1881
****************************************************************/
 
1882
 
 
1883
WERROR NetUserSetInfo_l(struct libnetapi_ctx *ctx,
 
1884
                        struct NetUserSetInfo *r)
 
1885
{
 
1886
        LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetInfo);
 
1887
}
 
1888
 
 
1889
/****************************************************************
 
1890
****************************************************************/
 
1891
 
 
1892
static NTSTATUS query_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
 
1893
                                           struct rpc_pipe_client *pipe_cli,
 
1894
                                           struct policy_handle *domain_handle,
 
1895
                                           struct samr_DomInfo1 *info1,
 
1896
                                           struct samr_DomInfo3 *info3,
 
1897
                                           struct samr_DomInfo5 *info5,
 
1898
                                           struct samr_DomInfo6 *info6,
 
1899
                                           struct samr_DomInfo7 *info7,
 
1900
                                           struct samr_DomInfo12 *info12)
 
1901
{
 
1902
        NTSTATUS status;
 
1903
        union samr_DomainInfo *dom_info = NULL;
 
1904
 
 
1905
        if (info1) {
 
1906
                status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
 
1907
                                                     domain_handle,
 
1908
                                                     1,
 
1909
                                                     &dom_info);
 
1910
                NT_STATUS_NOT_OK_RETURN(status);
 
1911
 
 
1912
                *info1 = dom_info->info1;
 
1913
        }
 
1914
 
 
1915
        if (info3) {
 
1916
                status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
 
1917
                                                     domain_handle,
 
1918
                                                     3,
 
1919
                                                     &dom_info);
 
1920
                NT_STATUS_NOT_OK_RETURN(status);
 
1921
 
 
1922
                *info3 = dom_info->info3;
 
1923
        }
 
1924
 
 
1925
        if (info5) {
 
1926
                status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
 
1927
                                                     domain_handle,
 
1928
                                                     5,
 
1929
                                                     &dom_info);
 
1930
                NT_STATUS_NOT_OK_RETURN(status);
 
1931
 
 
1932
                *info5 = dom_info->info5;
 
1933
        }
 
1934
 
 
1935
        if (info6) {
 
1936
                status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
 
1937
                                                     domain_handle,
 
1938
                                                     6,
 
1939
                                                     &dom_info);
 
1940
                NT_STATUS_NOT_OK_RETURN(status);
 
1941
 
 
1942
                *info6 = dom_info->info6;
 
1943
        }
 
1944
 
 
1945
        if (info7) {
 
1946
                status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
 
1947
                                                     domain_handle,
 
1948
                                                     7,
 
1949
                                                     &dom_info);
 
1950
                NT_STATUS_NOT_OK_RETURN(status);
 
1951
 
 
1952
                *info7 = dom_info->info7;
 
1953
        }
 
1954
 
 
1955
        if (info12) {
 
1956
                status = rpccli_samr_QueryDomainInfo2(pipe_cli, mem_ctx,
 
1957
                                                      domain_handle,
 
1958
                                                      12,
 
1959
                                                      &dom_info);
 
1960
                NT_STATUS_NOT_OK_RETURN(status);
 
1961
 
 
1962
                *info12 = dom_info->info12;
 
1963
        }
 
1964
 
 
1965
        return NT_STATUS_OK;
 
1966
}
 
1967
 
 
1968
/****************************************************************
 
1969
****************************************************************/
 
1970
 
 
1971
static NTSTATUS query_USER_MODALS_INFO_0(TALLOC_CTX *mem_ctx,
 
1972
                                         struct rpc_pipe_client *pipe_cli,
 
1973
                                         struct policy_handle *domain_handle,
 
1974
                                         struct USER_MODALS_INFO_0 *info0)
 
1975
{
 
1976
        NTSTATUS status;
 
1977
        struct samr_DomInfo1 dom_info1;
 
1978
        struct samr_DomInfo3 dom_info3;
 
1979
 
 
1980
        ZERO_STRUCTP(info0);
 
1981
 
 
1982
        status = query_USER_MODALS_INFO_rpc(mem_ctx,
 
1983
                                            pipe_cli,
 
1984
                                            domain_handle,
 
1985
                                            &dom_info1,
 
1986
                                            &dom_info3,
 
1987
                                            NULL,
 
1988
                                            NULL,
 
1989
                                            NULL,
 
1990
                                            NULL);
 
1991
        NT_STATUS_NOT_OK_RETURN(status);
 
1992
 
 
1993
        info0->usrmod0_min_passwd_len =
 
1994
                dom_info1.min_password_length;
 
1995
        info0->usrmod0_max_passwd_age =
 
1996
                nt_time_to_unix_abs((NTTIME *)&dom_info1.max_password_age);
 
1997
        info0->usrmod0_min_passwd_age =
 
1998
                nt_time_to_unix_abs((NTTIME *)&dom_info1.min_password_age);
 
1999
        info0->usrmod0_password_hist_len =
 
2000
                dom_info1.password_history_length;
 
2001
 
 
2002
        info0->usrmod0_force_logoff =
 
2003
                nt_time_to_unix_abs(&dom_info3.force_logoff_time);
 
2004
 
 
2005
        return NT_STATUS_OK;
 
2006
}
 
2007
 
 
2008
/****************************************************************
 
2009
****************************************************************/
 
2010
 
 
2011
static NTSTATUS query_USER_MODALS_INFO_1(TALLOC_CTX *mem_ctx,
 
2012
                                         struct rpc_pipe_client *pipe_cli,
 
2013
                                         struct policy_handle *domain_handle,
 
2014
                                         struct USER_MODALS_INFO_1 *info1)
 
2015
{
 
2016
        NTSTATUS status;
 
2017
        struct samr_DomInfo6 dom_info6;
 
2018
        struct samr_DomInfo7 dom_info7;
 
2019
 
 
2020
        status = query_USER_MODALS_INFO_rpc(mem_ctx,
 
2021
                                            pipe_cli,
 
2022
                                            domain_handle,
 
2023
                                            NULL,
 
2024
                                            NULL,
 
2025
                                            NULL,
 
2026
                                            &dom_info6,
 
2027
                                            &dom_info7,
 
2028
                                            NULL);
 
2029
        NT_STATUS_NOT_OK_RETURN(status);
 
2030
 
 
2031
        info1->usrmod1_primary =
 
2032
                talloc_strdup(mem_ctx, dom_info6.primary.string);
 
2033
 
 
2034
        info1->usrmod1_role = dom_info7.role;
 
2035
 
 
2036
        return NT_STATUS_OK;
 
2037
}
 
2038
 
 
2039
/****************************************************************
 
2040
****************************************************************/
 
2041
 
 
2042
static NTSTATUS query_USER_MODALS_INFO_2(TALLOC_CTX *mem_ctx,
 
2043
                                         struct rpc_pipe_client *pipe_cli,
 
2044
                                         struct policy_handle *domain_handle,
 
2045
                                         struct dom_sid *domain_sid,
 
2046
                                         struct USER_MODALS_INFO_2 *info2)
 
2047
{
 
2048
        NTSTATUS status;
 
2049
        struct samr_DomInfo5 dom_info5;
 
2050
 
 
2051
        status = query_USER_MODALS_INFO_rpc(mem_ctx,
 
2052
                                            pipe_cli,
 
2053
                                            domain_handle,
 
2054
                                            NULL,
 
2055
                                            NULL,
 
2056
                                            &dom_info5,
 
2057
                                            NULL,
 
2058
                                            NULL,
 
2059
                                            NULL);
 
2060
        NT_STATUS_NOT_OK_RETURN(status);
 
2061
 
 
2062
        info2->usrmod2_domain_name =
 
2063
                talloc_strdup(mem_ctx, dom_info5.domain_name.string);
 
2064
        info2->usrmod2_domain_id =
 
2065
                (struct domsid *)sid_dup_talloc(mem_ctx, domain_sid);
 
2066
 
 
2067
        NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_name);
 
2068
        NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_id);
 
2069
 
 
2070
        return NT_STATUS_OK;
 
2071
}
 
2072
 
 
2073
/****************************************************************
 
2074
****************************************************************/
 
2075
 
 
2076
static NTSTATUS query_USER_MODALS_INFO_3(TALLOC_CTX *mem_ctx,
 
2077
                                         struct rpc_pipe_client *pipe_cli,
 
2078
                                         struct policy_handle *domain_handle,
 
2079
                                         struct USER_MODALS_INFO_3 *info3)
 
2080
{
 
2081
        NTSTATUS status;
 
2082
        struct samr_DomInfo12 dom_info12;
 
2083
 
 
2084
        status = query_USER_MODALS_INFO_rpc(mem_ctx,
 
2085
                                            pipe_cli,
 
2086
                                            domain_handle,
 
2087
                                            NULL,
 
2088
                                            NULL,
 
2089
                                            NULL,
 
2090
                                            NULL,
 
2091
                                            NULL,
 
2092
                                            &dom_info12);
 
2093
        NT_STATUS_NOT_OK_RETURN(status);
 
2094
 
 
2095
        info3->usrmod3_lockout_duration =
 
2096
                nt_time_to_unix_abs(&dom_info12.lockout_duration);
 
2097
        info3->usrmod3_lockout_observation_window =
 
2098
                nt_time_to_unix_abs(&dom_info12.lockout_window);
 
2099
        info3->usrmod3_lockout_threshold =
 
2100
                dom_info12.lockout_threshold;
 
2101
 
 
2102
        return NT_STATUS_OK;
 
2103
}
 
2104
 
 
2105
/****************************************************************
 
2106
****************************************************************/
 
2107
 
 
2108
static NTSTATUS query_USER_MODALS_INFO_to_buffer(TALLOC_CTX *mem_ctx,
 
2109
                                                 struct rpc_pipe_client *pipe_cli,
 
2110
                                                 uint32_t level,
 
2111
                                                 struct policy_handle *domain_handle,
 
2112
                                                 struct dom_sid *domain_sid,
 
2113
                                                 uint8_t **buffer)
 
2114
{
 
2115
        NTSTATUS status;
 
2116
 
 
2117
        struct USER_MODALS_INFO_0 info0;
 
2118
        struct USER_MODALS_INFO_1 info1;
 
2119
        struct USER_MODALS_INFO_2 info2;
 
2120
        struct USER_MODALS_INFO_3 info3;
 
2121
 
 
2122
        if (!buffer) {
 
2123
                return ERROR_INSUFFICIENT_BUFFER;
 
2124
        }
 
2125
 
 
2126
        switch (level) {
 
2127
                case 0:
 
2128
                        status = query_USER_MODALS_INFO_0(mem_ctx,
 
2129
                                                          pipe_cli,
 
2130
                                                          domain_handle,
 
2131
                                                          &info0);
 
2132
                        NT_STATUS_NOT_OK_RETURN(status);
 
2133
 
 
2134
                        *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0,
 
2135
                                                           sizeof(info0));
 
2136
                        break;
 
2137
 
 
2138
                case 1:
 
2139
                        status = query_USER_MODALS_INFO_1(mem_ctx,
 
2140
                                                          pipe_cli,
 
2141
                                                          domain_handle,
 
2142
                                                          &info1);
 
2143
                        NT_STATUS_NOT_OK_RETURN(status);
 
2144
 
 
2145
                        *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1,
 
2146
                                                           sizeof(info1));
 
2147
                        break;
 
2148
                case 2:
 
2149
                        status = query_USER_MODALS_INFO_2(mem_ctx,
 
2150
                                                          pipe_cli,
 
2151
                                                          domain_handle,
 
2152
                                                          domain_sid,
 
2153
                                                          &info2);
 
2154
                        NT_STATUS_NOT_OK_RETURN(status);
 
2155
 
 
2156
                        *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2,
 
2157
                                                           sizeof(info2));
 
2158
                        break;
 
2159
                case 3:
 
2160
                        status = query_USER_MODALS_INFO_3(mem_ctx,
 
2161
                                                          pipe_cli,
 
2162
                                                          domain_handle,
 
2163
                                                          &info3);
 
2164
                        NT_STATUS_NOT_OK_RETURN(status);
 
2165
 
 
2166
                        *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3,
 
2167
                                                           sizeof(info3));
 
2168
                        break;
 
2169
                default:
 
2170
                        break;
 
2171
        }
 
2172
 
 
2173
        NT_STATUS_HAVE_NO_MEMORY(*buffer);
 
2174
 
 
2175
        return NT_STATUS_OK;
 
2176
}
 
2177
 
 
2178
/****************************************************************
 
2179
****************************************************************/
 
2180
 
 
2181
WERROR NetUserModalsGet_r(struct libnetapi_ctx *ctx,
 
2182
                          struct NetUserModalsGet *r)
 
2183
{
 
2184
        struct rpc_pipe_client *pipe_cli = NULL;
 
2185
        NTSTATUS status;
 
2186
        WERROR werr;
 
2187
 
 
2188
        struct policy_handle connect_handle, domain_handle;
 
2189
        struct dom_sid2 *domain_sid = NULL;
 
2190
        uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
 
2191
 
 
2192
        ZERO_STRUCT(connect_handle);
 
2193
        ZERO_STRUCT(domain_handle);
 
2194
 
 
2195
        if (!r->out.buffer) {
 
2196
                return WERR_INVALID_PARAM;
 
2197
        }
 
2198
 
 
2199
        switch (r->in.level) {
 
2200
                case 0:
 
2201
                        access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
 
2202
                                       SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
 
2203
                        break;
 
2204
                case 1:
 
2205
                case 2:
 
2206
                        access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
 
2207
                        break;
 
2208
                case 3:
 
2209
                        access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
 
2210
                        break;
 
2211
                default:
 
2212
                        werr = WERR_UNKNOWN_LEVEL;
 
2213
                        goto done;
 
2214
        }
 
2215
 
 
2216
        werr = libnetapi_open_pipe(ctx, r->in.server_name,
 
2217
                                   &ndr_table_samr.syntax_id,
 
2218
                                   &pipe_cli);
 
2219
        if (!W_ERROR_IS_OK(werr)) {
 
2220
                goto done;
 
2221
        }
 
2222
 
 
2223
        werr = libnetapi_samr_open_domain(ctx, pipe_cli,
 
2224
                                          SAMR_ACCESS_ENUM_DOMAINS |
 
2225
                                          SAMR_ACCESS_LOOKUP_DOMAIN,
 
2226
                                          access_mask,
 
2227
                                          &connect_handle,
 
2228
                                          &domain_handle,
 
2229
                                          &domain_sid);
 
2230
        if (!W_ERROR_IS_OK(werr)) {
 
2231
                goto done;
 
2232
        }
 
2233
 
 
2234
        /* 0:  1 + 3 */
 
2235
        /* 1:  6 + 7 */
 
2236
        /* 2:  5 */
 
2237
        /* 3: 12 (DomainInfo2) */
 
2238
 
 
2239
        status = query_USER_MODALS_INFO_to_buffer(ctx,
 
2240
                                                  pipe_cli,
 
2241
                                                  r->in.level,
 
2242
                                                  &domain_handle,
 
2243
                                                  domain_sid,
 
2244
                                                  r->out.buffer);
 
2245
        if (!NT_STATUS_IS_OK(status)) {
 
2246
                werr = ntstatus_to_werror(status);
 
2247
                goto done;
 
2248
        }
 
2249
 
 
2250
 done:
 
2251
        if (ctx->disable_policy_handle_cache) {
 
2252
                libnetapi_samr_close_domain_handle(ctx, &domain_handle);
 
2253
                libnetapi_samr_close_connect_handle(ctx, &connect_handle);
 
2254
        }
 
2255
 
 
2256
        return werr;
 
2257
}
 
2258
 
 
2259
/****************************************************************
 
2260
****************************************************************/
 
2261
 
 
2262
WERROR NetUserModalsGet_l(struct libnetapi_ctx *ctx,
 
2263
                          struct NetUserModalsGet *r)
 
2264
{
 
2265
        LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsGet);
 
2266
}
 
2267
 
 
2268
/****************************************************************
 
2269
****************************************************************/
 
2270
 
 
2271
static NTSTATUS set_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
 
2272
                                         struct rpc_pipe_client *pipe_cli,
 
2273
                                         struct policy_handle *domain_handle,
 
2274
                                         struct samr_DomInfo1 *info1,
 
2275
                                         struct samr_DomInfo3 *info3,
 
2276
                                         struct samr_DomInfo12 *info12)
 
2277
{
 
2278
        NTSTATUS status;
 
2279
        union samr_DomainInfo dom_info;
 
2280
 
 
2281
        if (info1) {
 
2282
 
 
2283
                ZERO_STRUCT(dom_info);
 
2284
 
 
2285
                dom_info.info1 = *info1;
 
2286
 
 
2287
                status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
 
2288
                                                   domain_handle,
 
2289
                                                   1,
 
2290
                                                   &dom_info);
 
2291
                NT_STATUS_NOT_OK_RETURN(status);
 
2292
        }
 
2293
 
 
2294
        if (info3) {
 
2295
 
 
2296
                ZERO_STRUCT(dom_info);
 
2297
 
 
2298
                dom_info.info3 = *info3;
 
2299
 
 
2300
                status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
 
2301
                                                   domain_handle,
 
2302
                                                   3,
 
2303
                                                   &dom_info);
 
2304
 
 
2305
                NT_STATUS_NOT_OK_RETURN(status);
 
2306
        }
 
2307
 
 
2308
        if (info12) {
 
2309
 
 
2310
                ZERO_STRUCT(dom_info);
 
2311
 
 
2312
                dom_info.info12 = *info12;
 
2313
 
 
2314
                status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
 
2315
                                                   domain_handle,
 
2316
                                                   12,
 
2317
                                                   &dom_info);
 
2318
 
 
2319
                NT_STATUS_NOT_OK_RETURN(status);
 
2320
        }
 
2321
 
 
2322
        return NT_STATUS_OK;
 
2323
}
 
2324
 
 
2325
/****************************************************************
 
2326
****************************************************************/
 
2327
 
 
2328
static NTSTATUS set_USER_MODALS_INFO_0_buffer(TALLOC_CTX *mem_ctx,
 
2329
                                              struct rpc_pipe_client *pipe_cli,
 
2330
                                              struct policy_handle *domain_handle,
 
2331
                                              struct USER_MODALS_INFO_0 *info0)
 
2332
{
 
2333
        NTSTATUS status;
 
2334
        struct samr_DomInfo1 dom_info_1;
 
2335
        struct samr_DomInfo3 dom_info_3;
 
2336
 
 
2337
        status = query_USER_MODALS_INFO_rpc(mem_ctx,
 
2338
                                            pipe_cli,
 
2339
                                            domain_handle,
 
2340
                                            &dom_info_1,
 
2341
                                            &dom_info_3,
 
2342
                                            NULL,
 
2343
                                            NULL,
 
2344
                                            NULL,
 
2345
                                            NULL);
 
2346
        NT_STATUS_NOT_OK_RETURN(status);
 
2347
 
 
2348
        dom_info_1.min_password_length =
 
2349
                info0->usrmod0_min_passwd_len;
 
2350
        dom_info_1.password_history_length =
 
2351
                info0->usrmod0_password_hist_len;
 
2352
 
 
2353
        unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
 
2354
                info0->usrmod0_max_passwd_age);
 
2355
        unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
 
2356
                info0->usrmod0_min_passwd_age);
 
2357
 
 
2358
        unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
 
2359
                info0->usrmod0_force_logoff);
 
2360
 
 
2361
        return set_USER_MODALS_INFO_rpc(mem_ctx,
 
2362
                                        pipe_cli,
 
2363
                                        domain_handle,
 
2364
                                        &dom_info_1,
 
2365
                                        &dom_info_3,
 
2366
                                        NULL);
 
2367
}
 
2368
 
 
2369
/****************************************************************
 
2370
****************************************************************/
 
2371
 
 
2372
static NTSTATUS set_USER_MODALS_INFO_3_buffer(TALLOC_CTX *mem_ctx,
 
2373
                                              struct rpc_pipe_client *pipe_cli,
 
2374
                                              struct policy_handle *domain_handle,
 
2375
                                              struct USER_MODALS_INFO_3 *info3)
 
2376
{
 
2377
        NTSTATUS status;
 
2378
        struct samr_DomInfo12 dom_info_12;
 
2379
 
 
2380
        status = query_USER_MODALS_INFO_rpc(mem_ctx,
 
2381
                                            pipe_cli,
 
2382
                                            domain_handle,
 
2383
                                            NULL,
 
2384
                                            NULL,
 
2385
                                            NULL,
 
2386
                                            NULL,
 
2387
                                            NULL,
 
2388
                                            &dom_info_12);
 
2389
        NT_STATUS_NOT_OK_RETURN(status);
 
2390
 
 
2391
        unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_duration,
 
2392
                info3->usrmod3_lockout_duration);
 
2393
        unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_window,
 
2394
                info3->usrmod3_lockout_observation_window);
 
2395
        dom_info_12.lockout_threshold = info3->usrmod3_lockout_threshold;
 
2396
 
 
2397
        return set_USER_MODALS_INFO_rpc(mem_ctx,
 
2398
                                        pipe_cli,
 
2399
                                        domain_handle,
 
2400
                                        NULL,
 
2401
                                        NULL,
 
2402
                                        &dom_info_12);
 
2403
}
 
2404
 
 
2405
/****************************************************************
 
2406
****************************************************************/
 
2407
 
 
2408
static NTSTATUS set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX *mem_ctx,
 
2409
                                                 struct rpc_pipe_client *pipe_cli,
 
2410
                                                 struct policy_handle *domain_handle,
 
2411
                                                 struct USER_MODALS_INFO_1001 *info1001)
 
2412
{
 
2413
        NTSTATUS status;
 
2414
        struct samr_DomInfo1 dom_info_1;
 
2415
 
 
2416
        status = query_USER_MODALS_INFO_rpc(mem_ctx,
 
2417
                                            pipe_cli,
 
2418
                                            domain_handle,
 
2419
                                            &dom_info_1,
 
2420
                                            NULL,
 
2421
                                            NULL,
 
2422
                                            NULL,
 
2423
                                            NULL,
 
2424
                                            NULL);
 
2425
        NT_STATUS_NOT_OK_RETURN(status);
 
2426
 
 
2427
        dom_info_1.min_password_length =
 
2428
                info1001->usrmod1001_min_passwd_len;
 
2429
 
 
2430
        return set_USER_MODALS_INFO_rpc(mem_ctx,
 
2431
                                        pipe_cli,
 
2432
                                        domain_handle,
 
2433
                                        &dom_info_1,
 
2434
                                        NULL,
 
2435
                                        NULL);
 
2436
}
 
2437
 
 
2438
/****************************************************************
 
2439
****************************************************************/
 
2440
 
 
2441
static NTSTATUS set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX *mem_ctx,
 
2442
                                                 struct rpc_pipe_client *pipe_cli,
 
2443
                                                 struct policy_handle *domain_handle,
 
2444
                                                 struct USER_MODALS_INFO_1002 *info1002)
 
2445
{
 
2446
        NTSTATUS status;
 
2447
        struct samr_DomInfo1 dom_info_1;
 
2448
 
 
2449
        status = query_USER_MODALS_INFO_rpc(mem_ctx,
 
2450
                                            pipe_cli,
 
2451
                                            domain_handle,
 
2452
                                            &dom_info_1,
 
2453
                                            NULL,
 
2454
                                            NULL,
 
2455
                                            NULL,
 
2456
                                            NULL,
 
2457
                                            NULL);
 
2458
        NT_STATUS_NOT_OK_RETURN(status);
 
2459
 
 
2460
        unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
 
2461
                info1002->usrmod1002_max_passwd_age);
 
2462
 
 
2463
        return set_USER_MODALS_INFO_rpc(mem_ctx,
 
2464
                                        pipe_cli,
 
2465
                                        domain_handle,
 
2466
                                        &dom_info_1,
 
2467
                                        NULL,
 
2468
                                        NULL);
 
2469
}
 
2470
 
 
2471
/****************************************************************
 
2472
****************************************************************/
 
2473
 
 
2474
static NTSTATUS set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX *mem_ctx,
 
2475
                                                 struct rpc_pipe_client *pipe_cli,
 
2476
                                                 struct policy_handle *domain_handle,
 
2477
                                                 struct USER_MODALS_INFO_1003 *info1003)
 
2478
{
 
2479
        NTSTATUS status;
 
2480
        struct samr_DomInfo1 dom_info_1;
 
2481
 
 
2482
        status = query_USER_MODALS_INFO_rpc(mem_ctx,
 
2483
                                            pipe_cli,
 
2484
                                            domain_handle,
 
2485
                                            &dom_info_1,
 
2486
                                            NULL,
 
2487
                                            NULL,
 
2488
                                            NULL,
 
2489
                                            NULL,
 
2490
                                            NULL);
 
2491
        NT_STATUS_NOT_OK_RETURN(status);
 
2492
 
 
2493
        unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
 
2494
                info1003->usrmod1003_min_passwd_age);
 
2495
 
 
2496
        return set_USER_MODALS_INFO_rpc(mem_ctx,
 
2497
                                        pipe_cli,
 
2498
                                        domain_handle,
 
2499
                                        &dom_info_1,
 
2500
                                        NULL,
 
2501
                                        NULL);
 
2502
}
 
2503
 
 
2504
/****************************************************************
 
2505
****************************************************************/
 
2506
 
 
2507
static NTSTATUS set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX *mem_ctx,
 
2508
                                                 struct rpc_pipe_client *pipe_cli,
 
2509
                                                 struct policy_handle *domain_handle,
 
2510
                                                 struct USER_MODALS_INFO_1004 *info1004)
 
2511
{
 
2512
        NTSTATUS status;
 
2513
        struct samr_DomInfo3 dom_info_3;
 
2514
 
 
2515
        status = query_USER_MODALS_INFO_rpc(mem_ctx,
 
2516
                                            pipe_cli,
 
2517
                                            domain_handle,
 
2518
                                            NULL,
 
2519
                                            &dom_info_3,
 
2520
                                            NULL,
 
2521
                                            NULL,
 
2522
                                            NULL,
 
2523
                                            NULL);
 
2524
        NT_STATUS_NOT_OK_RETURN(status);
 
2525
 
 
2526
        unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
 
2527
                info1004->usrmod1004_force_logoff);
 
2528
 
 
2529
        return set_USER_MODALS_INFO_rpc(mem_ctx,
 
2530
                                        pipe_cli,
 
2531
                                        domain_handle,
 
2532
                                        NULL,
 
2533
                                        &dom_info_3,
 
2534
                                        NULL);
 
2535
}
 
2536
 
 
2537
/****************************************************************
 
2538
****************************************************************/
 
2539
 
 
2540
static NTSTATUS set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX *mem_ctx,
 
2541
                                                 struct rpc_pipe_client *pipe_cli,
 
2542
                                                 struct policy_handle *domain_handle,
 
2543
                                                 struct USER_MODALS_INFO_1005 *info1005)
 
2544
{
 
2545
        NTSTATUS status;
 
2546
        struct samr_DomInfo1 dom_info_1;
 
2547
 
 
2548
        status = query_USER_MODALS_INFO_rpc(mem_ctx,
 
2549
                                            pipe_cli,
 
2550
                                            domain_handle,
 
2551
                                            &dom_info_1,
 
2552
                                            NULL,
 
2553
                                            NULL,
 
2554
                                            NULL,
 
2555
                                            NULL,
 
2556
                                            NULL);
 
2557
        NT_STATUS_NOT_OK_RETURN(status);
 
2558
 
 
2559
        dom_info_1.password_history_length =
 
2560
                info1005->usrmod1005_password_hist_len;
 
2561
 
 
2562
        return set_USER_MODALS_INFO_rpc(mem_ctx,
 
2563
                                        pipe_cli,
 
2564
                                        domain_handle,
 
2565
                                        &dom_info_1,
 
2566
                                        NULL,
 
2567
                                        NULL);
 
2568
}
 
2569
 
 
2570
/****************************************************************
 
2571
****************************************************************/
 
2572
 
 
2573
static NTSTATUS set_USER_MODALS_INFO_buffer(TALLOC_CTX *mem_ctx,
 
2574
                                            struct rpc_pipe_client *pipe_cli,
 
2575
                                            uint32_t level,
 
2576
                                            struct policy_handle *domain_handle,
 
2577
                                            struct dom_sid *domain_sid,
 
2578
                                            uint8_t *buffer)
 
2579
{
 
2580
        struct USER_MODALS_INFO_0 *info0;
 
2581
        struct USER_MODALS_INFO_3 *info3;
 
2582
        struct USER_MODALS_INFO_1001 *info1001;
 
2583
        struct USER_MODALS_INFO_1002 *info1002;
 
2584
        struct USER_MODALS_INFO_1003 *info1003;
 
2585
        struct USER_MODALS_INFO_1004 *info1004;
 
2586
        struct USER_MODALS_INFO_1005 *info1005;
 
2587
 
 
2588
        if (!buffer) {
 
2589
                return ERROR_INSUFFICIENT_BUFFER;
 
2590
        }
 
2591
 
 
2592
        switch (level) {
 
2593
                case 0:
 
2594
                        info0 = (struct USER_MODALS_INFO_0 *)buffer;
 
2595
                        return set_USER_MODALS_INFO_0_buffer(mem_ctx,
 
2596
                                                             pipe_cli,
 
2597
                                                             domain_handle,
 
2598
                                                             info0);
 
2599
                case 3:
 
2600
                        info3 = (struct USER_MODALS_INFO_3 *)buffer;
 
2601
                        return set_USER_MODALS_INFO_3_buffer(mem_ctx,
 
2602
                                                             pipe_cli,
 
2603
                                                             domain_handle,
 
2604
                                                             info3);
 
2605
                case 1001:
 
2606
                        info1001 = (struct USER_MODALS_INFO_1001 *)buffer;
 
2607
                        return set_USER_MODALS_INFO_1001_buffer(mem_ctx,
 
2608
                                                                pipe_cli,
 
2609
                                                                domain_handle,
 
2610
                                                                info1001);
 
2611
                case 1002:
 
2612
                        info1002 = (struct USER_MODALS_INFO_1002 *)buffer;
 
2613
                        return set_USER_MODALS_INFO_1002_buffer(mem_ctx,
 
2614
                                                                pipe_cli,
 
2615
                                                                domain_handle,
 
2616
                                                                info1002);
 
2617
                case 1003:
 
2618
                        info1003 = (struct USER_MODALS_INFO_1003 *)buffer;
 
2619
                        return set_USER_MODALS_INFO_1003_buffer(mem_ctx,
 
2620
                                                                pipe_cli,
 
2621
                                                                domain_handle,
 
2622
                                                                info1003);
 
2623
                case 1004:
 
2624
                        info1004 = (struct USER_MODALS_INFO_1004 *)buffer;
 
2625
                        return set_USER_MODALS_INFO_1004_buffer(mem_ctx,
 
2626
                                                                pipe_cli,
 
2627
                                                                domain_handle,
 
2628
                                                                info1004);
 
2629
                case 1005:
 
2630
                        info1005 = (struct USER_MODALS_INFO_1005 *)buffer;
 
2631
                        return set_USER_MODALS_INFO_1005_buffer(mem_ctx,
 
2632
                                                                pipe_cli,
 
2633
                                                                domain_handle,
 
2634
                                                                info1005);
 
2635
 
 
2636
                default:
 
2637
                        break;
 
2638
        }
 
2639
 
 
2640
        return NT_STATUS_OK;
 
2641
}
 
2642
 
 
2643
/****************************************************************
 
2644
****************************************************************/
 
2645
 
 
2646
WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx,
 
2647
                          struct NetUserModalsSet *r)
 
2648
{
 
2649
        struct rpc_pipe_client *pipe_cli = NULL;
 
2650
        NTSTATUS status;
 
2651
        WERROR werr;
 
2652
 
 
2653
        struct policy_handle connect_handle, domain_handle;
 
2654
        struct dom_sid2 *domain_sid = NULL;
 
2655
        uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
 
2656
 
 
2657
        ZERO_STRUCT(connect_handle);
 
2658
        ZERO_STRUCT(domain_handle);
 
2659
 
 
2660
        if (!r->in.buffer) {
 
2661
                return WERR_INVALID_PARAM;
 
2662
        }
 
2663
 
 
2664
        switch (r->in.level) {
 
2665
                case 0:
 
2666
                        access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
 
2667
                                       SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
 
2668
                                       SAMR_DOMAIN_ACCESS_SET_INFO_1 |
 
2669
                                       SAMR_DOMAIN_ACCESS_SET_INFO_2;
 
2670
                        break;
 
2671
                case 3:
 
2672
                case 1001:
 
2673
                case 1002:
 
2674
                case 1003:
 
2675
                case 1005:
 
2676
                        access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
 
2677
                                       SAMR_DOMAIN_ACCESS_SET_INFO_1;
 
2678
                        break;
 
2679
                case 1004:
 
2680
                        access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
 
2681
                                       SAMR_DOMAIN_ACCESS_SET_INFO_2;
 
2682
                        break;
 
2683
                case 1:
 
2684
                case 2:
 
2685
                case 1006:
 
2686
                case 1007:
 
2687
                        werr = WERR_NOT_SUPPORTED;
 
2688
                        break;
 
2689
                default:
 
2690
                        werr = WERR_UNKNOWN_LEVEL;
 
2691
                        goto done;
 
2692
        }
 
2693
 
 
2694
        werr = libnetapi_open_pipe(ctx, r->in.server_name,
 
2695
                                   &ndr_table_samr.syntax_id,
 
2696
                                   &pipe_cli);
 
2697
        if (!W_ERROR_IS_OK(werr)) {
 
2698
                goto done;
 
2699
        }
 
2700
 
 
2701
        werr = libnetapi_samr_open_domain(ctx, pipe_cli,
 
2702
                                          SAMR_ACCESS_ENUM_DOMAINS |
 
2703
                                          SAMR_ACCESS_LOOKUP_DOMAIN,
 
2704
                                          access_mask,
 
2705
                                          &connect_handle,
 
2706
                                          &domain_handle,
 
2707
                                          &domain_sid);
 
2708
        if (!W_ERROR_IS_OK(werr)) {
 
2709
                goto done;
 
2710
        }
 
2711
 
 
2712
        status = set_USER_MODALS_INFO_buffer(ctx,
 
2713
                                             pipe_cli,
 
2714
                                             r->in.level,
 
2715
                                             &domain_handle,
 
2716
                                             domain_sid,
 
2717
                                             r->in.buffer);
 
2718
        if (!NT_STATUS_IS_OK(status)) {
 
2719
                werr = ntstatus_to_werror(status);
 
2720
                goto done;
 
2721
        }
 
2722
 
 
2723
 done:
 
2724
        if (ctx->disable_policy_handle_cache) {
 
2725
                libnetapi_samr_close_domain_handle(ctx, &domain_handle);
 
2726
                libnetapi_samr_close_connect_handle(ctx, &connect_handle);
 
2727
        }
 
2728
 
 
2729
        return werr;
 
2730
}
 
2731
 
 
2732
/****************************************************************
 
2733
****************************************************************/
 
2734
 
 
2735
WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx,
 
2736
                          struct NetUserModalsSet *r)
 
2737
{
 
2738
        LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsSet);
 
2739
}
 
2740
 
 
2741
/****************************************************************
 
2742
****************************************************************/
 
2743
 
 
2744
NTSTATUS add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
 
2745
                                       uint32_t level,
 
2746
                                       const char *group_name,
 
2747
                                       uint32_t attributes,
 
2748
                                       uint8_t **buffer,
 
2749
                                       uint32_t *num_entries)
 
2750
{
 
2751
        struct GROUP_USERS_INFO_0 u0;
 
2752
        struct GROUP_USERS_INFO_1 u1;
 
2753
 
 
2754
        switch (level) {
 
2755
                case 0:
 
2756
                        if (group_name) {
 
2757
                                u0.grui0_name = talloc_strdup(mem_ctx, group_name);
 
2758
                                NT_STATUS_HAVE_NO_MEMORY(u0.grui0_name);
 
2759
                        } else {
 
2760
                                u0.grui0_name = NULL;
 
2761
                        }
 
2762
 
 
2763
                        ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_0, u0,
 
2764
                                     (struct GROUP_USERS_INFO_0 **)buffer, num_entries);
 
2765
                        break;
 
2766
                case 1:
 
2767
                        if (group_name) {
 
2768
                                u1.grui1_name = talloc_strdup(mem_ctx, group_name);
 
2769
                                NT_STATUS_HAVE_NO_MEMORY(u1.grui1_name);
 
2770
                        } else {
 
2771
                                u1.grui1_name = NULL;
 
2772
                        }
 
2773
 
 
2774
                        u1.grui1_attributes = attributes;
 
2775
 
 
2776
                        ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_1, u1,
 
2777
                                     (struct GROUP_USERS_INFO_1 **)buffer, num_entries);
 
2778
                        break;
 
2779
                default:
 
2780
                        return NT_STATUS_INVALID_INFO_CLASS;
 
2781
        }
 
2782
 
 
2783
        return NT_STATUS_OK;
 
2784
}
 
2785
 
 
2786
/****************************************************************
 
2787
****************************************************************/
 
2788
 
 
2789
WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
 
2790
                          struct NetUserGetGroups *r)
 
2791
{
 
2792
        struct rpc_pipe_client *pipe_cli = NULL;
 
2793
        struct policy_handle connect_handle, domain_handle, user_handle;
 
2794
        struct lsa_String lsa_account_name;
 
2795
        struct dom_sid2 *domain_sid = NULL;
 
2796
        struct samr_Ids user_rids, name_types;
 
2797
        struct samr_RidWithAttributeArray *rid_array = NULL;
 
2798
        struct lsa_Strings names;
 
2799
        struct samr_Ids types;
 
2800
        uint32_t *rids = NULL;
 
2801
 
 
2802
        int i;
 
2803
        uint32_t entries_read = 0;
 
2804
 
 
2805
        NTSTATUS status = NT_STATUS_OK;
 
2806
        WERROR werr;
 
2807
 
 
2808
        ZERO_STRUCT(connect_handle);
 
2809
        ZERO_STRUCT(domain_handle);
 
2810
 
 
2811
        if (!r->out.buffer) {
 
2812
                return WERR_INVALID_PARAM;
 
2813
        }
 
2814
 
 
2815
        *r->out.buffer = NULL;
 
2816
        *r->out.entries_read = 0;
 
2817
        *r->out.total_entries = 0;
 
2818
 
 
2819
        switch (r->in.level) {
 
2820
                case 0:
 
2821
                case 1:
 
2822
                        break;
 
2823
                default:
 
2824
                        return WERR_UNKNOWN_LEVEL;
 
2825
        }
 
2826
 
 
2827
        werr = libnetapi_open_pipe(ctx, r->in.server_name,
 
2828
                                   &ndr_table_samr.syntax_id,
 
2829
                                   &pipe_cli);
 
2830
        if (!W_ERROR_IS_OK(werr)) {
 
2831
                goto done;
 
2832
        }
 
2833
 
 
2834
        werr = libnetapi_samr_open_domain(ctx, pipe_cli,
 
2835
                                          SAMR_ACCESS_ENUM_DOMAINS |
 
2836
                                          SAMR_ACCESS_LOOKUP_DOMAIN,
 
2837
                                          SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
 
2838
                                          &connect_handle,
 
2839
                                          &domain_handle,
 
2840
                                          &domain_sid);
 
2841
        if (!W_ERROR_IS_OK(werr)) {
 
2842
                goto done;
 
2843
        }
 
2844
 
 
2845
        init_lsa_String(&lsa_account_name, r->in.user_name);
 
2846
 
 
2847
        status = rpccli_samr_LookupNames(pipe_cli, ctx,
 
2848
                                         &domain_handle,
 
2849
                                         1,
 
2850
                                         &lsa_account_name,
 
2851
                                         &user_rids,
 
2852
                                         &name_types);
 
2853
        if (!NT_STATUS_IS_OK(status)) {
 
2854
                werr = ntstatus_to_werror(status);
 
2855
                goto done;
 
2856
        }
 
2857
 
 
2858
        status = rpccli_samr_OpenUser(pipe_cli, ctx,
 
2859
                                      &domain_handle,
 
2860
                                      SAMR_USER_ACCESS_GET_GROUPS,
 
2861
                                      user_rids.ids[0],
 
2862
                                      &user_handle);
 
2863
        if (!NT_STATUS_IS_OK(status)) {
 
2864
                werr = ntstatus_to_werror(status);
 
2865
                goto done;
 
2866
        }
 
2867
 
 
2868
        status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
 
2869
                                              &user_handle,
 
2870
                                              &rid_array);
 
2871
        if (!NT_STATUS_IS_OK(status)) {
 
2872
                werr = ntstatus_to_werror(status);
 
2873
                goto done;
 
2874
        }
 
2875
 
 
2876
        rids = talloc_array(ctx, uint32_t, rid_array->count);
 
2877
        if (!rids) {
 
2878
                werr = WERR_NOMEM;
 
2879
                goto done;
 
2880
        }
 
2881
 
 
2882
        for (i=0; i < rid_array->count; i++) {
 
2883
                rids[i] = rid_array->rids[i].rid;
 
2884
        }
 
2885
 
 
2886
        status = rpccli_samr_LookupRids(pipe_cli, ctx,
 
2887
                                        &domain_handle,
 
2888
                                        rid_array->count,
 
2889
                                        rids,
 
2890
                                        &names,
 
2891
                                        &types);
 
2892
        if (!NT_STATUS_IS_OK(status) &&
 
2893
            !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
 
2894
                werr = ntstatus_to_werror(status);
 
2895
                goto done;
 
2896
        }
 
2897
 
 
2898
        for (i=0; i < names.count; i++) {
 
2899
                status = add_GROUP_USERS_INFO_X_buffer(ctx,
 
2900
                                                       r->in.level,
 
2901
                                                       names.names[i].string,
 
2902
                                                       rid_array->rids[i].attributes,
 
2903
                                                       r->out.buffer,
 
2904
                                                       &entries_read);
 
2905
                if (!NT_STATUS_IS_OK(status)) {
 
2906
                        werr = ntstatus_to_werror(status);
 
2907
                        goto done;
 
2908
                }
 
2909
        }
 
2910
 
 
2911
        *r->out.entries_read = entries_read;
 
2912
        *r->out.total_entries = entries_read;
 
2913
 
 
2914
 done:
 
2915
        if (ctx->disable_policy_handle_cache) {
 
2916
                libnetapi_samr_close_domain_handle(ctx, &domain_handle);
 
2917
                libnetapi_samr_close_connect_handle(ctx, &connect_handle);
 
2918
        }
 
2919
 
 
2920
        return werr;
 
2921
}
 
2922
 
 
2923
/****************************************************************
 
2924
****************************************************************/
 
2925
 
 
2926
WERROR NetUserGetGroups_l(struct libnetapi_ctx *ctx,
 
2927
                          struct NetUserGetGroups *r)
 
2928
{
 
2929
        LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetGroups);
 
2930
}
 
2931
 
 
2932
/****************************************************************
 
2933
****************************************************************/
 
2934
 
 
2935
WERROR NetUserSetGroups_r(struct libnetapi_ctx *ctx,
 
2936
                          struct NetUserSetGroups *r)
 
2937
{
 
2938
        struct rpc_pipe_client *pipe_cli = NULL;
 
2939
        struct policy_handle connect_handle, domain_handle, user_handle, group_handle;
 
2940
        struct lsa_String lsa_account_name;
 
2941
        struct dom_sid2 *domain_sid = NULL;
 
2942
        struct samr_Ids user_rids, name_types;
 
2943
        struct samr_Ids group_rids;
 
2944
        struct samr_RidWithAttributeArray *rid_array = NULL;
 
2945
        struct lsa_String *lsa_names = NULL;
 
2946
 
 
2947
        uint32_t *add_rids = NULL;
 
2948
        uint32_t *del_rids = NULL;
 
2949
        size_t num_add_rids = 0;
 
2950
        size_t num_del_rids = 0;
 
2951
 
 
2952
        uint32_t *member_rids = NULL;
 
2953
        size_t num_member_rids = 0;
 
2954
 
 
2955
        struct GROUP_USERS_INFO_0 *i0 = NULL;
 
2956
        struct GROUP_USERS_INFO_1 *i1 = NULL;
 
2957
 
 
2958
        int i, k;
 
2959
 
 
2960
        NTSTATUS status = NT_STATUS_OK;
 
2961
        WERROR werr;
 
2962
 
 
2963
        ZERO_STRUCT(connect_handle);
 
2964
        ZERO_STRUCT(domain_handle);
 
2965
 
 
2966
        if (!r->in.buffer) {
 
2967
                return WERR_INVALID_PARAM;
 
2968
        }
 
2969
 
 
2970
        switch (r->in.level) {
 
2971
                case 0:
 
2972
                case 1:
 
2973
                        break;
 
2974
                default:
 
2975
                        return WERR_UNKNOWN_LEVEL;
 
2976
        }
 
2977
 
 
2978
        werr = libnetapi_open_pipe(ctx, r->in.server_name,
 
2979
                                   &ndr_table_samr.syntax_id,
 
2980
                                   &pipe_cli);
 
2981
        if (!W_ERROR_IS_OK(werr)) {
 
2982
                goto done;
 
2983
        }
 
2984
 
 
2985
        werr = libnetapi_samr_open_domain(ctx, pipe_cli,
 
2986
                                          SAMR_ACCESS_ENUM_DOMAINS |
 
2987
                                          SAMR_ACCESS_LOOKUP_DOMAIN,
 
2988
                                          SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
 
2989
                                          &connect_handle,
 
2990
                                          &domain_handle,
 
2991
                                          &domain_sid);
 
2992
        if (!W_ERROR_IS_OK(werr)) {
 
2993
                goto done;
 
2994
        }
 
2995
 
 
2996
        init_lsa_String(&lsa_account_name, r->in.user_name);
 
2997
 
 
2998
        status = rpccli_samr_LookupNames(pipe_cli, ctx,
 
2999
                                         &domain_handle,
 
3000
                                         1,
 
3001
                                         &lsa_account_name,
 
3002
                                         &user_rids,
 
3003
                                         &name_types);
 
3004
        if (!NT_STATUS_IS_OK(status)) {
 
3005
                werr = ntstatus_to_werror(status);
 
3006
                goto done;
 
3007
        }
 
3008
 
 
3009
        status = rpccli_samr_OpenUser(pipe_cli, ctx,
 
3010
                                      &domain_handle,
 
3011
                                      SAMR_USER_ACCESS_GET_GROUPS,
 
3012
                                      user_rids.ids[0],
 
3013
                                      &user_handle);
 
3014
        if (!NT_STATUS_IS_OK(status)) {
 
3015
                werr = ntstatus_to_werror(status);
 
3016
                goto done;
 
3017
        }
 
3018
 
 
3019
        switch (r->in.level) {
 
3020
                case 0:
 
3021
                        i0 = (struct GROUP_USERS_INFO_0 *)r->in.buffer;
 
3022
                        break;
 
3023
                case 1:
 
3024
                        i1 = (struct GROUP_USERS_INFO_1 *)r->in.buffer;
 
3025
                        break;
 
3026
        }
 
3027
 
 
3028
        lsa_names = talloc_array(ctx, struct lsa_String, r->in.num_entries);
 
3029
        if (!lsa_names) {
 
3030
                werr = WERR_NOMEM;
 
3031
                goto done;
 
3032
        }
 
3033
 
 
3034
        for (i=0; i < r->in.num_entries; i++) {
 
3035
 
 
3036
                switch (r->in.level) {
 
3037
                        case 0:
 
3038
                                init_lsa_String(&lsa_names[i], i0->grui0_name);
 
3039
                                i0++;
 
3040
                                break;
 
3041
                        case 1:
 
3042
                                init_lsa_String(&lsa_names[i], i1->grui1_name);
 
3043
                                i1++;
 
3044
                                break;
 
3045
                }
 
3046
        }
 
3047
 
 
3048
        status = rpccli_samr_LookupNames(pipe_cli, ctx,
 
3049
                                         &domain_handle,
 
3050
                                         r->in.num_entries,
 
3051
                                         lsa_names,
 
3052
                                         &group_rids,
 
3053
                                         &name_types);
 
3054
        if (!NT_STATUS_IS_OK(status)) {
 
3055
                werr = ntstatus_to_werror(status);
 
3056
                goto done;
 
3057
        }
 
3058
 
 
3059
        member_rids = group_rids.ids;
 
3060
        num_member_rids = group_rids.count;
 
3061
 
 
3062
        status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
 
3063
                                              &user_handle,
 
3064
                                              &rid_array);
 
3065
        if (!NT_STATUS_IS_OK(status)) {
 
3066
                werr = ntstatus_to_werror(status);
 
3067
                goto done;
 
3068
        }
 
3069
 
 
3070
        /* add list */
 
3071
 
 
3072
        for (i=0; i < r->in.num_entries; i++) {
 
3073
                bool already_member = false;
 
3074
                for (k=0; k < rid_array->count; k++) {
 
3075
                        if (member_rids[i] == rid_array->rids[k].rid) {
 
3076
                                already_member = true;
 
3077
                                break;
 
3078
                        }
 
3079
                }
 
3080
                if (!already_member) {
 
3081
                        if (!add_rid_to_array_unique(ctx,
 
3082
                                                     member_rids[i],
 
3083
                                                     &add_rids, &num_add_rids)) {
 
3084
                                werr = WERR_GENERAL_FAILURE;
 
3085
                                goto done;
 
3086
                        }
 
3087
                }
 
3088
        }
 
3089
 
 
3090
        /* del list */
 
3091
 
 
3092
        for (k=0; k < rid_array->count; k++) {
 
3093
                bool keep_member = false;
 
3094
                for (i=0; i < r->in.num_entries; i++) {
 
3095
                        if (member_rids[i] == rid_array->rids[k].rid) {
 
3096
                                keep_member = true;
 
3097
                                break;
 
3098
                        }
 
3099
                }
 
3100
                if (!keep_member) {
 
3101
                        if (!add_rid_to_array_unique(ctx,
 
3102
                                                     rid_array->rids[k].rid,
 
3103
                                                     &del_rids, &num_del_rids)) {
 
3104
                                werr = WERR_GENERAL_FAILURE;
 
3105
                                goto done;
 
3106
                        }
 
3107
                }
 
3108
        }
 
3109
 
 
3110
        /* add list */
 
3111
 
 
3112
        for (i=0; i < num_add_rids; i++) {
 
3113
                status = rpccli_samr_OpenGroup(pipe_cli, ctx,
 
3114
                                               &domain_handle,
 
3115
                                               SAMR_GROUP_ACCESS_ADD_MEMBER,
 
3116
                                               add_rids[i],
 
3117
                                               &group_handle);
 
3118
                if (!NT_STATUS_IS_OK(status)) {
 
3119
                        werr = ntstatus_to_werror(status);
 
3120
                        goto done;
 
3121
                }
 
3122
 
 
3123
                status = rpccli_samr_AddGroupMember(pipe_cli, ctx,
 
3124
                                                    &group_handle,
 
3125
                                                    user_rids.ids[0],
 
3126
                                                    7 /* ? */);
 
3127
                if (!NT_STATUS_IS_OK(status)) {
 
3128
                        werr = ntstatus_to_werror(status);
 
3129
                        goto done;
 
3130
                }
 
3131
 
 
3132
                if (is_valid_policy_hnd(&group_handle)) {
 
3133
                        rpccli_samr_Close(pipe_cli, ctx, &group_handle);
 
3134
                }
 
3135
        }
 
3136
 
 
3137
        /* del list */
 
3138
 
 
3139
        for (i=0; i < num_del_rids; i++) {
 
3140
                status = rpccli_samr_OpenGroup(pipe_cli, ctx,
 
3141
                                               &domain_handle,
 
3142
                                               SAMR_GROUP_ACCESS_REMOVE_MEMBER,
 
3143
                                               del_rids[i],
 
3144
                                               &group_handle);
 
3145
                if (!NT_STATUS_IS_OK(status)) {
 
3146
                        werr = ntstatus_to_werror(status);
 
3147
                        goto done;
 
3148
                }
 
3149
 
 
3150
                status = rpccli_samr_DeleteGroupMember(pipe_cli, ctx,
 
3151
                                                       &group_handle,
 
3152
                                                       user_rids.ids[0]);
 
3153
                if (!NT_STATUS_IS_OK(status)) {
 
3154
                        werr = ntstatus_to_werror(status);
 
3155
                        goto done;
 
3156
                }
 
3157
 
 
3158
                if (is_valid_policy_hnd(&group_handle)) {
 
3159
                        rpccli_samr_Close(pipe_cli, ctx, &group_handle);
 
3160
                }
 
3161
        }
 
3162
 
 
3163
        werr = WERR_OK;
 
3164
 
 
3165
 done:
 
3166
        if (is_valid_policy_hnd(&group_handle)) {
 
3167
                rpccli_samr_Close(pipe_cli, ctx, &group_handle);
 
3168
        }
 
3169
 
 
3170
        if (ctx->disable_policy_handle_cache) {
 
3171
                libnetapi_samr_close_domain_handle(ctx, &domain_handle);
 
3172
                libnetapi_samr_close_connect_handle(ctx, &connect_handle);
 
3173
        }
 
3174
 
 
3175
        return werr;
 
3176
}
 
3177
 
 
3178
/****************************************************************
 
3179
****************************************************************/
 
3180
 
 
3181
WERROR NetUserSetGroups_l(struct libnetapi_ctx *ctx,
 
3182
                          struct NetUserSetGroups *r)
 
3183
{
 
3184
        LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetGroups);
 
3185
}
 
3186
 
 
3187
/****************************************************************
 
3188
****************************************************************/
 
3189
 
 
3190
static NTSTATUS add_LOCALGROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
 
3191
                                                   uint32_t level,
 
3192
                                                   const char *group_name,
 
3193
                                                   uint8_t **buffer,
 
3194
                                                   uint32_t *num_entries)
 
3195
{
 
3196
        struct LOCALGROUP_USERS_INFO_0 u0;
 
3197
 
 
3198
        switch (level) {
 
3199
                case 0:
 
3200
                        u0.lgrui0_name = talloc_strdup(mem_ctx, group_name);
 
3201
                        NT_STATUS_HAVE_NO_MEMORY(u0.lgrui0_name);
 
3202
 
 
3203
                        ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_USERS_INFO_0, u0,
 
3204
                                     (struct LOCALGROUP_USERS_INFO_0 **)buffer, num_entries);
 
3205
                        break;
 
3206
                default:
 
3207
                        return NT_STATUS_INVALID_INFO_CLASS;
 
3208
        }
 
3209
 
 
3210
        return NT_STATUS_OK;
 
3211
}
 
3212
 
 
3213
/****************************************************************
 
3214
****************************************************************/
 
3215
 
 
3216
WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
 
3217
                               struct NetUserGetLocalGroups *r)
 
3218
{
 
3219
        struct rpc_pipe_client *pipe_cli = NULL;
 
3220
        struct policy_handle connect_handle, domain_handle, user_handle,
 
3221
        builtin_handle;
 
3222
        struct lsa_String lsa_account_name;
 
3223
        struct dom_sid2 *domain_sid = NULL;
 
3224
        struct samr_Ids user_rids, name_types;
 
3225
        struct samr_RidWithAttributeArray *rid_array = NULL;
 
3226
        struct lsa_Strings names;
 
3227
        struct samr_Ids types;
 
3228
        uint32_t *rids = NULL;
 
3229
        size_t num_rids = 0;
 
3230
        struct dom_sid user_sid;
 
3231
        struct lsa_SidArray sid_array;
 
3232
        struct samr_Ids domain_rids;
 
3233
        struct samr_Ids builtin_rids;
 
3234
 
 
3235
        int i;
 
3236
        uint32_t entries_read = 0;
 
3237
 
 
3238
        NTSTATUS status = NT_STATUS_OK;
 
3239
        WERROR werr;
 
3240
 
 
3241
        ZERO_STRUCT(connect_handle);
 
3242
        ZERO_STRUCT(domain_handle);
 
3243
 
 
3244
        if (!r->out.buffer) {
 
3245
                return WERR_INVALID_PARAM;
 
3246
        }
 
3247
 
 
3248
        *r->out.buffer = NULL;
 
3249
        *r->out.entries_read = 0;
 
3250
        *r->out.total_entries = 0;
 
3251
 
 
3252
        switch (r->in.level) {
 
3253
                case 0:
 
3254
                case 1:
 
3255
                        break;
 
3256
                default:
 
3257
                        return WERR_UNKNOWN_LEVEL;
 
3258
        }
 
3259
 
 
3260
        werr = libnetapi_open_pipe(ctx, r->in.server_name,
 
3261
                                   &ndr_table_samr.syntax_id,
 
3262
                                   &pipe_cli);
 
3263
        if (!W_ERROR_IS_OK(werr)) {
 
3264
                goto done;
 
3265
        }
 
3266
 
 
3267
        werr = libnetapi_samr_open_domain(ctx, pipe_cli,
 
3268
                                          SAMR_ACCESS_ENUM_DOMAINS |
 
3269
                                          SAMR_ACCESS_LOOKUP_DOMAIN,
 
3270
                                          SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
 
3271
                                          SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
 
3272
                                          &connect_handle,
 
3273
                                          &domain_handle,
 
3274
                                          &domain_sid);
 
3275
        if (!W_ERROR_IS_OK(werr)) {
 
3276
                goto done;
 
3277
        }
 
3278
 
 
3279
        werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
 
3280
                                                  SAMR_ACCESS_ENUM_DOMAINS |
 
3281
                                                  SAMR_ACCESS_LOOKUP_DOMAIN,
 
3282
                                                  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
 
3283
                                                  SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
 
3284
                                                  &connect_handle,
 
3285
                                                  &builtin_handle);
 
3286
        if (!W_ERROR_IS_OK(werr)) {
 
3287
                goto done;
 
3288
        }
 
3289
 
 
3290
        init_lsa_String(&lsa_account_name, r->in.user_name);
 
3291
 
 
3292
        status = rpccli_samr_LookupNames(pipe_cli, ctx,
 
3293
                                         &domain_handle,
 
3294
                                         1,
 
3295
                                         &lsa_account_name,
 
3296
                                         &user_rids,
 
3297
                                         &name_types);
 
3298
        if (!NT_STATUS_IS_OK(status)) {
 
3299
                werr = ntstatus_to_werror(status);
 
3300
                goto done;
 
3301
        }
 
3302
 
 
3303
        status = rpccli_samr_OpenUser(pipe_cli, ctx,
 
3304
                                      &domain_handle,
 
3305
                                      SAMR_USER_ACCESS_GET_GROUPS,
 
3306
                                      user_rids.ids[0],
 
3307
                                      &user_handle);
 
3308
        if (!NT_STATUS_IS_OK(status)) {
 
3309
                werr = ntstatus_to_werror(status);
 
3310
                goto done;
 
3311
        }
 
3312
 
 
3313
        status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
 
3314
                                              &user_handle,
 
3315
                                              &rid_array);
 
3316
        if (!NT_STATUS_IS_OK(status)) {
 
3317
                werr = ntstatus_to_werror(status);
 
3318
                goto done;
 
3319
        }
 
3320
 
 
3321
        if (!sid_compose(&user_sid, domain_sid, user_rids.ids[0])) {
 
3322
                werr = WERR_NOMEM;
 
3323
                goto done;
 
3324
        }
 
3325
 
 
3326
        sid_array.num_sids = rid_array->count + 1;
 
3327
        sid_array.sids = TALLOC_ARRAY(ctx, struct lsa_SidPtr, sid_array.num_sids);
 
3328
        if (!sid_array.sids) {
 
3329
                werr = WERR_NOMEM;
 
3330
                goto done;
 
3331
        }
 
3332
 
 
3333
        sid_array.sids[0].sid = sid_dup_talloc(ctx, &user_sid);
 
3334
        if (!sid_array.sids[0].sid) {
 
3335
                werr = WERR_NOMEM;
 
3336
                goto done;
 
3337
        }
 
3338
 
 
3339
        for (i=0; i < rid_array->count; i++) {
 
3340
                struct dom_sid sid;
 
3341
 
 
3342
                if (!sid_compose(&sid, domain_sid, rid_array->rids[i].rid)) {
 
3343
                        werr = WERR_NOMEM;
 
3344
                        goto done;
 
3345
                }
 
3346
 
 
3347
                sid_array.sids[i+1].sid = sid_dup_talloc(ctx, &sid);
 
3348
                if (!sid_array.sids[i+1].sid) {
 
3349
                        werr = WERR_NOMEM;
 
3350
                        goto done;
 
3351
                }
 
3352
        }
 
3353
 
 
3354
        status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
 
3355
                                                &domain_handle,
 
3356
                                                &sid_array,
 
3357
                                                &domain_rids);
 
3358
        if (!NT_STATUS_IS_OK(status)) {
 
3359
                werr = ntstatus_to_werror(status);
 
3360
                goto done;
 
3361
        }
 
3362
 
 
3363
        for (i=0; i < domain_rids.count; i++) {
 
3364
                if (!add_rid_to_array_unique(ctx, domain_rids.ids[i],
 
3365
                                             &rids, &num_rids)) {
 
3366
                        werr = WERR_NOMEM;
 
3367
                        goto done;
 
3368
                }
 
3369
        }
 
3370
 
 
3371
        status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
 
3372
                                                &builtin_handle,
 
3373
                                                &sid_array,
 
3374
                                                &builtin_rids);
 
3375
        if (!NT_STATUS_IS_OK(status)) {
 
3376
                werr = ntstatus_to_werror(status);
 
3377
                goto done;
 
3378
        }
 
3379
 
 
3380
        for (i=0; i < builtin_rids.count; i++) {
 
3381
                if (!add_rid_to_array_unique(ctx, builtin_rids.ids[i],
 
3382
                                             &rids, &num_rids)) {
 
3383
                        werr = WERR_NOMEM;
 
3384
                        goto done;
 
3385
                }
 
3386
        }
 
3387
 
 
3388
        status = rpccli_samr_LookupRids(pipe_cli, ctx,
 
3389
                                        &builtin_handle,
 
3390
                                        num_rids,
 
3391
                                        rids,
 
3392
                                        &names,
 
3393
                                        &types);
 
3394
        if (!NT_STATUS_IS_OK(status)) {
 
3395
                werr = ntstatus_to_werror(status);
 
3396
                goto done;
 
3397
        }
 
3398
 
 
3399
        for (i=0; i < names.count; i++) {
 
3400
                status = add_LOCALGROUP_USERS_INFO_X_buffer(ctx,
 
3401
                                                            r->in.level,
 
3402
                                                            names.names[i].string,
 
3403
                                                            r->out.buffer,
 
3404
                                                            &entries_read);
 
3405
                if (!NT_STATUS_IS_OK(status)) {
 
3406
                        werr = ntstatus_to_werror(status);
 
3407
                        goto done;
 
3408
                }
 
3409
        }
 
3410
 
 
3411
        *r->out.entries_read = entries_read;
 
3412
        *r->out.total_entries = entries_read;
 
3413
 
 
3414
 done:
 
3415
        if (ctx->disable_policy_handle_cache) {
 
3416
                libnetapi_samr_close_domain_handle(ctx, &domain_handle);
 
3417
                libnetapi_samr_close_connect_handle(ctx, &connect_handle);
 
3418
        }
 
3419
 
 
3420
        return werr;
 
3421
}
 
3422
 
 
3423
/****************************************************************
 
3424
****************************************************************/
 
3425
 
 
3426
WERROR NetUserGetLocalGroups_l(struct libnetapi_ctx *ctx,
 
3427
                               struct NetUserGetLocalGroups *r)
 
3428
{
 
3429
        LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetLocalGroups);
 
3430
}