Get rid of DISP_USER_INFO/DISP_GROUP_INFO as they serve no useful
[samba.git] / source / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison               2001-2002,
9  *  Copyright (C) Jean François Micouleau      1998-2001,
10  *  Copyright (C) Anthony Liguori                   2002,
11  *  Copyright (C) Jim McDonough                     2002.
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2 of the License, or
16  *  (at your option) any later version.
17  *
18  *  This program is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License
24  *  along with this program; if not, write to the Free Software
25  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26  */
27
28 /*
29  * This is the implementation of the SAMR code.
30  */
31
32 #include "includes.h"
33
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
36
37 extern DOM_SID global_sid_Builtin;
38
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
42
43
44 typedef struct _disp_info {
45         BOOL user_dbloaded;
46         uint32 num_user_account;
47         SAM_ACCOUNT *disp_user_info;
48         BOOL group_dbloaded;
49         uint32 num_group_account;
50         DOMAIN_GRP *disp_group_info;
51 } DISP_INFO;
52
53 struct samr_info {
54         /* for use by the \PIPE\samr policy */
55         DOM_SID sid;
56         uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
57         uint32 acc_granted;
58         uint16 acb_mask;
59         BOOL all_machines;
60         DISP_INFO disp_info;
61
62         TALLOC_CTX *mem_ctx;
63 };
64
65 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
70
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
72
73 /*******************************************************************
74  Checks if access to an object should be granted, and returns that
75  level of access for further checks.
76 ********************************************************************/
77
78 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access, 
79                                   uint32 *acc_granted, const char *debug) 
80 {
81         NTSTATUS status = NT_STATUS_ACCESS_DENIED;
82
83         if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
84                 *acc_granted = des_access;
85                 if (geteuid() == sec_initial_uid()) {
86                         DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n",
87                                 debug, des_access));
88                         DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
89                         status = NT_STATUS_OK;
90                 }
91                 else {
92                         DEBUG(2,("%s: ACCESS DENIED  (requested: %#010x)\n",
93                                 debug, des_access));
94                 }
95         }
96         return status;
97 }
98
99 /*******************************************************************
100  Checks if access to a function can be granted
101 ********************************************************************/
102
103 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
104 {
105         DEBUG(5,("%s: access check ((granted: %#010x;  required: %#010x)\n",
106                         debug, acc_granted, acc_required));
107         if ((acc_granted & acc_required) != acc_required) {
108                 if (geteuid() == sec_initial_uid()) {
109                         DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
110                                 debug, acc_granted, acc_required));
111                         DEBUGADD(4,("but overwritten by euid == 0\n"));
112                         return NT_STATUS_OK;
113                 }
114                 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x;  required: %#010x)\n",
115                         debug, acc_granted, acc_required));
116                 return NT_STATUS_ACCESS_DENIED;
117         }
118         return NT_STATUS_OK;
119 }
120
121
122 /*******************************************************************
123  Create a samr_info struct.
124 ********************************************************************/
125
126 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
127 {
128         struct samr_info *info;
129         fstring sid_str;
130         TALLOC_CTX *mem_ctx;
131         
132         if (psid) {
133                 sid_to_string(sid_str, psid);
134         } else {
135                 fstrcpy(sid_str,"(NULL)");
136         }
137
138         mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
139
140         if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
141                 return NULL;
142
143         ZERO_STRUCTP(info);
144         DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
145         if (psid) {
146                 sid_copy( &info->sid, psid);
147         } else {
148                 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
149         }
150         info->mem_ctx = mem_ctx;
151         return info;
152 }
153
154 /*******************************************************************
155  Function to free the per handle data.
156  ********************************************************************/
157
158 static void free_samr_users(struct samr_info *info) 
159 {
160         int i;
161
162         if (info->disp_info.user_dbloaded){
163                 for (i=0; i<info->disp_info.num_user_account; i++) {
164                         SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
165                         /* Not really a free, actually a 'clear' */
166                         pdb_free_sam(&sam);
167                 }
168         }
169         info->disp_info.user_dbloaded=False;
170         info->disp_info.num_user_account=0;
171 }
172
173 /*******************************************************************
174  Function to free the per handle data.
175  ********************************************************************/
176
177 static void free_samr_db(struct samr_info *info)
178 {
179         /* Groups are talloced */
180
181         free_samr_users(info);
182
183         info->disp_info.group_dbloaded=False;
184         info->disp_info.num_group_account=0;
185 }
186
187 static void free_samr_info(void *ptr)
188 {
189         struct samr_info *info=(struct samr_info *) ptr;
190
191         free_samr_db(info);
192         talloc_destroy(info->mem_ctx);
193 }
194
195 /*******************************************************************
196  Ensure password info is never given out. Paranioa... JRA.
197  ********************************************************************/
198
199 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
200 {
201         
202         if (!sam_pass)
203                 return;
204
205         /* These now zero out the old password */
206
207         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
208         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
209 }
210
211
212 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
213 {
214         SAM_ACCOUNT *pwd = NULL;
215         SAM_ACCOUNT *pwd_array = NULL;
216         NTSTATUS nt_status = NT_STATUS_OK;
217         TALLOC_CTX *mem_ctx = info->mem_ctx;
218
219         DEBUG(10,("load_sampwd_entries\n"));
220
221         /* if the snapshoot is already loaded, return */
222         if ((info->disp_info.user_dbloaded==True) 
223             && (info->acb_mask == acb_mask) 
224             && (info->all_machines == all_machines)) {
225                 DEBUG(10,("load_sampwd_entries: already in memory\n"));
226                 return NT_STATUS_OK;
227         }
228
229         free_samr_users(info);
230
231         if (!pdb_setsampwent(False)) {
232                 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
233                 return NT_STATUS_ACCESS_DENIED;
234         }
235
236         for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd))) 
237                      && pdb_getsampwent(pwd) == True; pwd=NULL) {
238                 
239                 if (all_machines) {
240                         if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST) 
241                               || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
242                                 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
243                                 pdb_free_sam(&pwd);
244                                 continue;
245                         }
246                 } else {
247                         if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
248                                 pdb_free_sam(&pwd);
249                                 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
250                                 continue;
251                         }
252                 }
253
254                 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
255                 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
256                 
257                         DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
258                         pwd_array=(SAM_ACCOUNT *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info, 
259                                           (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(SAM_ACCOUNT));
260
261                         if (pwd_array==NULL)
262                                 return NT_STATUS_NO_MEMORY;
263
264                         info->disp_info.disp_user_info=pwd_array;
265                 }
266         
267                 /* Copy the SAM_ACCOUNT into the array */
268                 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
269
270                 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
271
272                 info->disp_info.num_user_account++;     
273         }
274
275         pdb_endsampwent();
276
277         /* the snapshoot is in memory, we're ready to enumerate fast */
278
279         info->acb_mask = acb_mask;
280         info->all_machines = all_machines;
281         info->disp_info.user_dbloaded=True;
282
283         DEBUG(10,("load_sampwd_entries: done\n"));
284
285         return nt_status;
286 }
287
288 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
289 {
290         GROUP_MAP *map=NULL;
291         DOMAIN_GRP *grp_array = NULL;
292         uint32 group_entries = 0;
293         uint32 i;
294         TALLOC_CTX *mem_ctx = info->mem_ctx;
295
296         DEBUG(10,("load_group_domain_entries\n"));
297
298         /* if the snapshoot is already loaded, return */
299         if (info->disp_info.group_dbloaded==True) {
300                 DEBUG(10,("load_group_domain_entries: already in memory\n"));
301                 return NT_STATUS_OK;
302         }
303         
304
305         become_root();
306
307         if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED)) {
308                 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
309                 return NT_STATUS_NO_MEMORY;
310         }
311         
312         unbecome_root();
313
314         info->disp_info.num_group_account=group_entries;
315
316         grp_array=(DOMAIN_GRP *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DOMAIN_GRP));
317         if (group_entries!=0 && grp_array==NULL) {
318                 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
319                 SAFE_FREE(map);
320                 return NT_STATUS_NO_MEMORY;
321         }
322
323         info->disp_info.disp_group_info=grp_array;
324
325         for (i=0; i<group_entries; i++) {
326                 fstrcpy(grp_array[i].name, map[i].nt_name);
327                 fstrcpy(grp_array[i].comment, map[i].comment);
328                 sid_split_rid(&map[i].sid, &grp_array[i].rid);
329                 grp_array[i].attr=SID_NAME_DOM_GRP;
330         }
331
332         SAFE_FREE(map);
333
334         /* the snapshoot is in memory, we're ready to enumerate fast */
335
336         info->disp_info.group_dbloaded=True;
337
338         DEBUG(10,("load_group_domain_entries: done\n"));
339
340         return NT_STATUS_OK;
341 }
342
343
344 /*******************************************************************
345  _samr_close_hnd
346  ********************************************************************/
347
348 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
349 {
350         r_u->status = NT_STATUS_OK;
351
352         /* close the policy handle */
353         if (!close_policy_hnd(p, &q_u->pol))
354                 return NT_STATUS_OBJECT_NAME_INVALID;
355
356         DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
357
358         return r_u->status;
359 }
360
361 /*******************************************************************
362  samr_reply_open_domain
363  ********************************************************************/
364
365 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
366 {
367         struct    samr_info *info;
368         SEC_DESC *psd = NULL;
369         uint32    acc_granted;
370         uint32    des_access = q_u->flags;
371         size_t    sd_size;
372         NTSTATUS  status;
373
374         r_u->status = NT_STATUS_OK;
375
376         /* find the connection policy handle. */
377         if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
378                 return NT_STATUS_INVALID_HANDLE;
379
380         if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
381                 return status;
382         }
383
384         /*check if access can be granted as requested by client. */
385         samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
386         se_map_generic(&des_access,&dom_generic_mapping);
387
388         if (!NT_STATUS_IS_OK(status = 
389                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
390                                                       des_access, &acc_granted, "_samr_open_domain"))) {
391                 return status;
392         }
393
394         /* associate the domain SID with the (unique) handle. */
395         if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
396                 return NT_STATUS_NO_MEMORY;
397         info->acc_granted = acc_granted;
398
399         /* get a (unique) handle.  open a policy on it. */
400         if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
401                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
402
403         DEBUG(5,("samr_open_domain: %d\n", __LINE__));
404
405         return r_u->status;
406 }
407
408 /*******************************************************************
409  _samr_get_usrdom_pwinfo
410  ********************************************************************/
411
412 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
413 {
414         struct samr_info *info = NULL;
415
416         r_u->status = NT_STATUS_OK;
417
418         /* find the policy handle.  open a policy on it. */
419         if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
420                 return NT_STATUS_INVALID_HANDLE;
421
422         if (!sid_check_is_in_our_domain(&info->sid))
423                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
424
425         init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
426
427         DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
428
429         /* 
430          * NT sometimes return NT_STATUS_ACCESS_DENIED
431          * I don't know yet why.
432          */
433
434         return r_u->status;
435 }
436
437 /*******************************************************************
438  samr_make_dom_obj_sd
439  ********************************************************************/
440
441 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
442 {
443         extern DOM_SID global_sid_World;
444         DOM_SID adm_sid;
445         DOM_SID act_sid;
446
447         SEC_ACE ace[3];
448         SEC_ACCESS mask;
449
450         SEC_ACL *psa = NULL;
451
452         sid_copy(&adm_sid, &global_sid_Builtin);
453         sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
454
455         sid_copy(&act_sid, &global_sid_Builtin);
456         sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
457
458         /*basic access for every one*/
459         init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
460         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
461
462         /*full access for builtin aliases Administrators and Account Operators*/
463         init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
464         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
465         init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
466
467         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
468                 return NT_STATUS_NO_MEMORY;
469
470         if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
471                 return NT_STATUS_NO_MEMORY;
472
473         return NT_STATUS_OK;
474 }
475
476 /*******************************************************************
477  samr_make_usr_obj_sd
478  ********************************************************************/
479
480 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
481 {
482         extern DOM_SID global_sid_World;
483         DOM_SID adm_sid;
484         DOM_SID act_sid;
485
486         SEC_ACE ace[4];
487         SEC_ACCESS mask;
488
489         SEC_ACL *psa = NULL;
490
491         sid_copy(&adm_sid, &global_sid_Builtin);
492         sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
493
494         sid_copy(&act_sid, &global_sid_Builtin);
495         sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
496
497         /*basic access for every one*/
498         init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
499         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
500
501         /*full access for builtin aliases Administrators and Account Operators*/
502         init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
503         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
504         init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
505
506         /*extended access for the user*/
507         init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
508         init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
509
510         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
511                 return NT_STATUS_NO_MEMORY;
512
513         if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
514                 return NT_STATUS_NO_MEMORY;
515
516         return NT_STATUS_OK;
517 }
518
519 /*******************************************************************
520  samr_make_grp_obj_sd
521  ********************************************************************/
522
523 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
524 {
525         extern DOM_SID global_sid_World;
526         DOM_SID adm_sid;
527         DOM_SID act_sid;
528
529         SEC_ACE ace[3];
530         SEC_ACCESS mask;
531
532         SEC_ACL *psa = NULL;
533
534         sid_copy(&adm_sid, &global_sid_Builtin);
535         sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
536
537         sid_copy(&act_sid, &global_sid_Builtin);
538         sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
539
540         /*basic access for every one*/
541         init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
542         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
543
544         /*full access for builtin aliases Administrators and Account Operators*/
545         init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
546         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
547         init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
548
549         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
550                 return NT_STATUS_NO_MEMORY;
551
552         if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
553                 return NT_STATUS_NO_MEMORY;
554
555         return NT_STATUS_OK;
556 }
557
558 /*******************************************************************
559  samr_make_ali_obj_sd
560  ********************************************************************/
561
562 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
563 {
564         extern DOM_SID global_sid_World;
565         DOM_SID adm_sid;
566         DOM_SID act_sid;
567
568         SEC_ACE ace[3];
569         SEC_ACCESS mask;
570
571         SEC_ACL *psa = NULL;
572
573         sid_copy(&adm_sid, &global_sid_Builtin);
574         sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
575
576         sid_copy(&act_sid, &global_sid_Builtin);
577         sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
578
579         /*basic access for every one*/
580         init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
581         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
582
583         /*full access for builtin aliases Administrators and Account Operators*/
584         init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
585         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
586         init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
587
588         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
589                 return NT_STATUS_NO_MEMORY;
590
591         if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
592                 return NT_STATUS_NO_MEMORY;
593
594         return NT_STATUS_OK;
595 }
596
597 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
598 {
599         struct samr_info *info = NULL;
600
601         /* find the policy handle.  open a policy on it. */
602         if (!find_policy_by_hnd(p, pol, (void **)&info))
603                 return False;
604
605         if (!info)
606                 return False;
607
608         *sid = info->sid;
609         *acc_granted = info->acc_granted;
610         return True;
611 }
612
613 /*******************************************************************
614  _samr_set_sec_obj
615  ********************************************************************/
616
617 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
618 {
619         DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
620         return NT_STATUS_NOT_IMPLEMENTED;
621 }
622
623
624 /*******************************************************************
625  _samr_query_sec_obj
626  ********************************************************************/
627
628 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
629 {
630         DOM_SID pol_sid;
631         fstring str_sid;
632         SEC_DESC * psd = NULL;
633         size_t sd_size;
634         uint32 acc_granted;
635
636         r_u->status = NT_STATUS_OK;
637
638         /* Get the SID. */
639         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
640                 return NT_STATUS_INVALID_HANDLE;
641
642
643
644         DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
645
646         /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
647
648         /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
649         if (pol_sid.sid_rev_num == 0)
650         {
651                 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
652                 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
653         }
654         else if (sid_equal(&pol_sid,get_global_sam_sid()))  /* check if it is our domain SID */
655
656         {
657                 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
658                 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
659         }
660         else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin  Domain */
661         {
662                 /* TODO: Builtin probably needs a different SD with restricted write access*/
663                 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
664                 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
665         }
666         else if (sid_check_is_in_our_domain(&pol_sid) ||
667                  sid_check_is_in_builtin(&pol_sid))
668         {
669                 /* TODO: different SDs have to be generated for aliases groups and users.
670                          Currently all three get a default user SD  */
671                 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
672                 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
673         }
674         else return NT_STATUS_OBJECT_TYPE_MISMATCH;
675
676         if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
677                 return NT_STATUS_NO_MEMORY;
678
679         if (NT_STATUS_IS_OK(r_u->status))
680                 r_u->ptr = 1;
681
682         return r_u->status;
683 }
684
685 /*******************************************************************
686 makes a SAM_ENTRY / UNISTR2* structure from a user list.
687 ********************************************************************/
688
689 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
690                                          uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
691                                          DOM_SID *domain_sid)
692 {
693         uint32 i;
694         SAM_ENTRY *sam;
695         UNISTR2 *uni_name;
696         SAM_ACCOUNT *pwd = NULL;
697         UNISTR2 uni_temp_name;
698         const char *temp_name;
699         const DOM_SID *user_sid;
700         uint32 user_rid;
701         fstring user_sid_string;
702         fstring domain_sid_string;
703         
704         *sam_pp = NULL;
705         *uni_name_pp = NULL;
706
707         if (num_entries == 0)
708                 return NT_STATUS_OK;
709
710         sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
711
712         uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
713
714         if (sam == NULL || uni_name == NULL) {
715                 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
716                 return NT_STATUS_NO_MEMORY;
717         }
718
719         for (i = 0; i < num_entries; i++) {
720                 pwd = &disp_user_info[i+start_idx];
721                 temp_name = pdb_get_username(pwd);
722                 init_unistr2(&uni_temp_name, temp_name, strlen(temp_name)+1);
723                 user_sid = pdb_get_user_sid(pwd);
724
725                 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
726                         DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
727                                   "the domain sid %s.  Failing operation.\n", 
728                                   temp_name, 
729                                   sid_to_string(user_sid_string, user_sid),
730                                   sid_to_string(domain_sid_string, domain_sid)));
731                         return NT_STATUS_UNSUCCESSFUL;
732                 }
733
734                 init_sam_entry(&sam[i], uni_temp_name.uni_str_len, user_rid);
735                 copy_unistr2(&uni_name[i], &uni_temp_name);
736         }
737
738         *sam_pp = sam;
739         *uni_name_pp = uni_name;
740         return NT_STATUS_OK;
741 }
742
743 /*******************************************************************
744  samr_reply_enum_dom_users
745  ********************************************************************/
746
747 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, 
748                               SAMR_R_ENUM_DOM_USERS *r_u)
749 {
750         struct samr_info *info = NULL;
751         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
752         int num_account;
753         uint32 enum_context=q_u->start_idx;
754         uint32 max_size=q_u->max_size;
755         uint32 temp_size;
756         enum remote_arch_types ra_type = get_remote_arch();
757         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
758         uint32 max_entries = max_sam_entries;
759         DOM_SID domain_sid;
760         
761         r_u->status = NT_STATUS_OK;
762
763         /* find the policy handle.  open a policy on it. */
764         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
765                 return NT_STATUS_INVALID_HANDLE;
766
767         domain_sid = info->sid;
768
769         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, 
770                                         SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, 
771                                         "_samr_enum_dom_users"))) {
772                 return r_u->status;
773         }
774         
775         DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
776
777         become_root();
778         r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
779         unbecome_root();
780         
781         if (!NT_STATUS_IS_OK(r_u->status))
782                 return r_u->status;
783
784         num_account = info->disp_info.num_user_account;
785
786         if (enum_context > num_account) {
787                 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
788                 return NT_STATUS_OK;
789         }
790
791         /* verify we won't overflow */
792         if (max_entries > num_account-enum_context) {
793                 max_entries = num_account-enum_context;
794                 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
795         }
796
797         /* calculate the size and limit on the number of entries we will return */
798         temp_size=max_entries*struct_size;
799         
800         if (temp_size>max_size) {
801                 max_entries=MIN((max_size/struct_size),max_entries);;
802                 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
803         }
804
805         /* 
806          * Note from JRA. total_entries is not being used here. Currently if there is a
807          * large user base then it looks like NT will enumerate until get_sampwd_entries
808          * returns False due to num_entries being zero. This will cause an access denied
809          * return. I don't think this is right and needs further investigation. Note that
810          * this is also the same in the TNG code (I don't think that has been tested with
811          * a very large user list as MAX_SAM_ENTRIES is set to 600).
812          * 
813          * I also think that one of the 'num_entries' return parameters is probably
814          * the "max entries" parameter - but in the TNG code they're all currently set to the same
815          * value (again I think this is wrong).
816          */
817
818         r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, 
819                                                max_entries, enum_context, 
820                                                info->disp_info.disp_user_info,
821                                                &domain_sid);
822
823         if (!NT_STATUS_IS_OK(r_u->status))
824                 return r_u->status;
825
826         if (enum_context+max_entries < num_account)
827                 r_u->status = STATUS_MORE_ENTRIES;
828
829         DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
830
831         init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
832
833         DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
834
835         return r_u->status;
836 }
837
838 /*******************************************************************
839 makes a SAM_ENTRY / UNISTR2* structure from a group list.
840 ********************************************************************/
841
842 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
843                 uint32 num_sam_entries, DOMAIN_GRP *grp)
844 {
845         uint32 i;
846         SAM_ENTRY *sam;
847         UNISTR2 *uni_name;
848
849         *sam_pp = NULL;
850         *uni_name_pp = NULL;
851
852         if (num_sam_entries == 0)
853                 return;
854
855         sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
856
857         uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
858
859         if (sam == NULL || uni_name == NULL) {
860                 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
861                 return;
862         }
863
864         for (i = 0; i < num_sam_entries; i++) {
865                 /*
866                  * JRA. I think this should include the null. TNG does not.
867                  */
868                 int len = strlen(grp[i].name)+1;
869
870                 init_sam_entry(&sam[i], len, grp[i].rid);
871                 init_unistr2(&uni_name[i], grp[i].name, len);
872         }
873
874         *sam_pp = sam;
875         *uni_name_pp = uni_name;
876 }
877
878 /*******************************************************************
879  Get the group entries - similar to get_sampwd_entries().
880  ********************************************************************/
881
882 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
883                                     uint32 *p_num_entries, uint32 max_entries)
884 {
885         fstring sid_str;
886         uint32 num_entries = 0;
887         int i;
888         GROUP_MAP smap;
889         GROUP_MAP *map = NULL;
890
891         sid_to_string(sid_str, sid);
892         DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
893
894         *p_num_entries = 0;
895
896         /* well-known aliases */
897         if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
898                 
899                 pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED);
900                 
901                 if (num_entries != 0) {         
902                         *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
903                         if (*d_grp==NULL)
904                                 return NT_STATUS_NO_MEMORY;
905                         
906                         for(i=0; i<num_entries && i<max_entries; i++) {
907                                 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
908                                 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
909                                 
910                         }
911                 }
912                 SAFE_FREE(map);
913                 
914         } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
915                 struct sys_grent *glist;
916                 struct sys_grent *grp;
917                 struct passwd *pw;
918                 gid_t winbind_gid_low, winbind_gid_high;
919                 BOOL winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
920
921                 /* local aliases */
922                 /* we return the UNIX groups here.  This seems to be the right */
923                 /* thing to do, since NT member servers return their local     */
924                 /* groups in the same situation.                               */
925
926                 /* use getgrent_list() to retrieve the list of groups to avoid
927                  * problems with getgrent possible infinite loop by internal
928                  * libc grent structures overwrites by called functions */
929                 grp = glist = getgrent_list();
930                 if (grp == NULL)
931                         return NT_STATUS_NO_MEMORY;
932                 
933                 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
934                         uint32 trid;
935                         
936                         if(!pdb_getgrgid(&smap, grp->gr_gid))
937                                 continue;
938                         
939                         if (smap.sid_name_use!=SID_NAME_ALIAS) {
940                                 continue;
941                         }
942
943                         sid_split_rid(&smap.sid, &trid);
944                         
945                         if (!sid_equal(sid, &smap.sid))
946                                 continue;
947
948                         /* Don't return winbind groups as they are not local! */
949                         if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
950                                 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
951                                 continue;
952                         }
953
954                         /* Don't return user private groups... */
955
956                         if ((pw = Get_Pwnam(smap.nt_name)) != 0) {
957                                 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
958                                 continue;                       
959                         }
960
961                         for( i = 0; i < num_entries; i++)
962                                 if ( (*d_grp)[i].rid == trid )
963                                         break;
964
965                         if ( i < num_entries ) {
966                                 continue; /* rid was there, dup! */
967                         }
968
969                         /* JRA - added this for large group db enumeration... */
970
971                         if (start_idx > 0) {
972                                 /* skip the requested number of entries.
973                                         not very efficient, but hey...
974                                 */
975                                 start_idx--;
976                                 continue;
977                         }
978
979                         *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
980                         if (*d_grp==NULL) {
981                                 grent_free(glist);
982                                 return NT_STATUS_NO_MEMORY;
983                         }
984
985                         fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
986                         (*d_grp)[num_entries].rid = trid;
987                         num_entries++;
988                         DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
989                 }
990
991                 grent_free(glist);
992         }
993
994         *p_num_entries = num_entries;
995
996         DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
997
998         if (num_entries >= max_entries)
999                 return STATUS_MORE_ENTRIES;
1000         return NT_STATUS_OK;
1001 }
1002
1003 /*******************************************************************
1004  Get the group entries - similar to get_sampwd_entries().
1005  ********************************************************************/
1006
1007 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
1008                                      uint32 *p_num_entries, uint32 max_entries)
1009 {
1010         GROUP_MAP *map=NULL;
1011         int i;
1012         uint32 group_entries = 0;
1013         uint32 num_entries = 0;
1014
1015         *p_num_entries = 0;
1016
1017         pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
1018
1019         num_entries=group_entries-start_idx;
1020
1021         /* limit the number of entries */
1022         if (num_entries>max_entries) {
1023                 DEBUG(5,("Limiting to %d entries\n", max_entries));
1024                 num_entries=max_entries;
1025         }
1026
1027         *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
1028         if (num_entries!=0 && *d_grp==NULL){
1029                 SAFE_FREE(map);
1030                 return NT_STATUS_NO_MEMORY;
1031         }
1032         
1033         for (i=0; i<num_entries; i++) {
1034                 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
1035                 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
1036                 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
1037                 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
1038         }
1039
1040         SAFE_FREE(map);
1041
1042         *p_num_entries = num_entries;
1043
1044         return NT_STATUS_OK;
1045 }
1046
1047 /*******************************************************************
1048  samr_reply_enum_dom_groups
1049  ********************************************************************/
1050
1051 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1052 {
1053         DOMAIN_GRP *grp=NULL;
1054         uint32 num_entries;
1055         DOM_SID sid;
1056         uint32 acc_granted;
1057
1058         r_u->status = NT_STATUS_OK;
1059
1060         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1061                 return NT_STATUS_INVALID_HANDLE;
1062                 
1063         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1064                 return r_u->status;
1065         }
1066
1067         DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1068
1069         /* the domain group array is being allocated in the function below */
1070         if (!NT_STATUS_IS_OK(r_u->status = get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))) {
1071                 return r_u->status;
1072         }
1073
1074         make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1075
1076         init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1077
1078         DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1079
1080         return r_u->status;
1081 }
1082
1083
1084 /*******************************************************************
1085  samr_reply_enum_dom_aliases
1086  ********************************************************************/
1087
1088 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1089 {
1090         DOMAIN_GRP *grp=NULL;
1091         uint32 num_entries = 0;
1092         fstring sid_str;
1093         DOM_SID sid;
1094         NTSTATUS status;
1095         uint32  acc_granted;
1096         
1097         r_u->status = NT_STATUS_OK;
1098
1099         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1100                 return NT_STATUS_INVALID_HANDLE;
1101
1102         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1103                 return r_u->status;
1104         }
1105         
1106         sid_to_string(sid_str, &sid);
1107         DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1108
1109         status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, 
1110                                          &num_entries, MAX_SAM_ENTRIES);
1111         if (NT_STATUS_IS_ERR(status)) return status;
1112
1113         make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1114
1115         /*safe_free(grp);*/
1116
1117         init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1118
1119         DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1120
1121         return r_u->status;
1122 }
1123
1124 /*******************************************************************
1125  samr_reply_query_dispinfo
1126  ********************************************************************/
1127
1128 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, 
1129                               SAMR_R_QUERY_DISPINFO *r_u)
1130 {
1131         struct samr_info *info = NULL;
1132         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1133         
1134         uint32 max_entries=q_u->max_entries;
1135         uint32 enum_context=q_u->start_idx;
1136         uint32 max_size=q_u->max_size;
1137
1138         SAM_DISPINFO_CTR *ctr;
1139         uint32 temp_size=0, total_data_size=0;
1140         NTSTATUS disp_ret;
1141         uint32 num_account = 0;
1142         enum remote_arch_types ra_type = get_remote_arch();
1143         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1144         DOM_SID domain_sid;
1145
1146         DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1147         r_u->status = NT_STATUS_OK;
1148
1149         /* find the policy handle.  open a policy on it. */
1150         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1151                 return NT_STATUS_INVALID_HANDLE;
1152
1153         domain_sid = info->sid;
1154
1155         /*
1156          * calculate how many entries we will return.
1157          * based on 
1158          * - the number of entries the client asked
1159          * - our limit on that
1160          * - the starting point (enumeration context)
1161          * - the buffer size the client will accept
1162          */
1163
1164         /*
1165          * We are a lot more like W2K. Instead of reading the SAM
1166          * each time to find the records we need to send back,
1167          * we read it once and link that copy to the sam handle.
1168          * For large user list (over the MAX_SAM_ENTRIES)
1169          * it's a definitive win.
1170          * second point to notice: between enumerations
1171          * our sam is now the same as it's a snapshoot.
1172          * third point: got rid of the static SAM_USER_21 struct
1173          * no more intermediate.
1174          * con: it uses much more memory, as a full copy is stored
1175          * in memory.
1176          *
1177          * If you want to change it, think twice and think
1178          * of the second point , that's really important.
1179          *
1180          * JFM, 12/20/2001
1181          */
1182
1183         /* Get what we need from the password database */
1184         switch (q_u->switch_level) {
1185                 case 0x1:
1186                         /* When playing with usrmgr, this is necessary
1187                            if you want immediate refresh after editing
1188                            a user. I would like to do this after the
1189                            setuserinfo2, but we do not have access to
1190                            the domain handle in that call, only to the
1191                            user handle. Where else does this hurt?
1192                            -- Volker
1193                         */
1194 #if 0
1195                         /* We cannot do this here - it kills performace. JRA. */
1196                         free_samr_users(info);
1197 #endif
1198                 case 0x2:
1199                 case 0x4:
1200                         become_root();          
1201                         /* Level 2 is for all machines, otherwise only 'normal' users */
1202                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1203                         unbecome_root();
1204                         if (!NT_STATUS_IS_OK(r_u->status)) {
1205                                 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1206                                 return r_u->status;
1207                         }
1208                         num_account = info->disp_info.num_user_account;
1209                         break;
1210                 case 0x3:
1211                 case 0x5:
1212                         r_u->status = load_group_domain_entries(info, &info->sid);
1213                         if (!NT_STATUS_IS_OK(r_u->status))
1214                                 return r_u->status;
1215                         num_account = info->disp_info.num_group_account;
1216                         break;
1217                 default:
1218                         DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1219                         return NT_STATUS_INVALID_INFO_CLASS;
1220         }
1221
1222         /* first limit the number of entries we will return */
1223         if(max_entries > max_sam_entries) {
1224                 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1225                 max_entries = max_sam_entries;
1226         }
1227
1228         if (enum_context > num_account) {
1229                 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1230                 return NT_STATUS_NO_MORE_ENTRIES;
1231         }
1232
1233         /* verify we won't overflow */
1234         if (max_entries > num_account-enum_context) {
1235                 max_entries = num_account-enum_context;
1236                 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1237         }
1238
1239         /* calculate the size and limit on the number of entries we will return */
1240         temp_size=max_entries*struct_size;
1241         
1242         if (temp_size>max_size) {
1243                 max_entries=MIN((max_size/struct_size),max_entries);;
1244                 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1245         }
1246
1247         if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1248                 return NT_STATUS_NO_MEMORY;
1249
1250         ZERO_STRUCTP(ctr);
1251
1252         /* Now create reply structure */
1253         switch (q_u->switch_level) {
1254         case 0x1:
1255                 if (max_entries) {
1256                         if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1257                                 return NT_STATUS_NO_MEMORY;
1258                 }
1259                 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context, 
1260                                                info->disp_info.disp_user_info, &domain_sid);
1261                 if (!NT_STATUS_IS_OK(disp_ret))
1262                         return disp_ret;
1263                 break;
1264         case 0x2:
1265                 if (max_entries) {
1266                         if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1267                                 return NT_STATUS_NO_MEMORY;
1268                 }
1269                 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context, 
1270                                                info->disp_info.disp_user_info, &domain_sid);
1271                 if (!NT_STATUS_IS_OK(disp_ret))
1272                         return disp_ret;
1273                 break;
1274         case 0x3:
1275                 if (max_entries) {
1276                         if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1277                                 return NT_STATUS_NO_MEMORY;
1278                 }
1279                 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1280                 if (!NT_STATUS_IS_OK(disp_ret))
1281                         return disp_ret;
1282                 break;
1283         case 0x4:
1284                 if (max_entries) {
1285                         if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1286                                 return NT_STATUS_NO_MEMORY;
1287                 }
1288                 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1289                 if (!NT_STATUS_IS_OK(disp_ret))
1290                         return disp_ret;
1291                 break;
1292         case 0x5:
1293                 if (max_entries) {
1294                         if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1295                                 return NT_STATUS_NO_MEMORY;
1296                 }
1297                 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1298                 if (!NT_STATUS_IS_OK(disp_ret))
1299                         return disp_ret;
1300                 break;
1301
1302         default:
1303                 ctr->sam.info = NULL;
1304                 return NT_STATUS_INVALID_INFO_CLASS;
1305         }
1306
1307         /* calculate the total size */
1308         total_data_size=num_account*struct_size;
1309
1310         if (enum_context+max_entries < num_account)
1311                 r_u->status = STATUS_MORE_ENTRIES;
1312
1313         DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1314
1315         init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1316
1317         return r_u->status;
1318
1319 }
1320
1321 /*******************************************************************
1322  samr_reply_query_aliasinfo
1323  ********************************************************************/
1324
1325 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1326 {
1327         DOM_SID   sid;
1328         GROUP_MAP map;
1329         uint32    acc_granted;
1330
1331         r_u->status = NT_STATUS_OK;
1332
1333         DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1334
1335         /* find the policy handle.  open a policy on it. */
1336         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1337                 return NT_STATUS_INVALID_HANDLE;
1338         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1339                 return r_u->status;
1340         }
1341
1342         if (!sid_check_is_in_our_domain(&sid) &&
1343             !sid_check_is_in_builtin(&sid))
1344                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1345
1346         if (!pdb_getgrsid(&map, sid))
1347                 return NT_STATUS_NO_SUCH_ALIAS;
1348
1349         switch (q_u->switch_level) {
1350         case 1:
1351                 r_u->ptr = 1;
1352                 r_u->ctr.switch_value1 = 1;
1353                 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1354                 break;
1355         case 3:
1356                 r_u->ptr = 1;
1357                 r_u->ctr.switch_value1 = 3;
1358                 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1359                 break;
1360         default:
1361                 return NT_STATUS_INVALID_INFO_CLASS;
1362         }
1363
1364         DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1365
1366         return r_u->status;
1367 }
1368
1369 #if 0
1370 /*******************************************************************
1371  samr_reply_lookup_ids
1372  ********************************************************************/
1373
1374  uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1375 {
1376     uint32 rid[MAX_SAM_ENTRIES];
1377     int num_rids = q_u->num_sids1;
1378
1379     r_u->status = NT_STATUS_OK;
1380
1381     DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1382
1383     if (num_rids > MAX_SAM_ENTRIES) {
1384         num_rids = MAX_SAM_ENTRIES;
1385         DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1386     }
1387
1388 #if 0
1389     int i;
1390     SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1391
1392     for (i = 0; i < num_rids && status == 0; i++)
1393     {
1394         struct sam_passwd *sam_pass;
1395         fstring user_name;
1396
1397
1398         fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1399                                     q_u->uni_user_name[i].uni_str_len));
1400
1401         /* find the user account */
1402         become_root();
1403         sam_pass = get_smb21pwd_entry(user_name, 0);
1404         unbecome_root();
1405
1406         if (sam_pass == NULL)
1407         {
1408             status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1409             rid[i] = 0;
1410         }
1411         else
1412         {
1413             rid[i] = sam_pass->user_rid;
1414         }
1415     }
1416 #endif
1417
1418     num_rids = 1;
1419     rid[0] = BUILTIN_ALIAS_RID_USERS;
1420
1421     init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1422
1423     DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1424
1425     return r_u->status;
1426 }
1427 #endif
1428
1429 /*******************************************************************
1430  _samr_lookup_names
1431  ********************************************************************/
1432
1433 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1434 {
1435         uint32 rid[MAX_SAM_ENTRIES];
1436         uint32 local_rid;
1437         enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1438         enum SID_NAME_USE local_type;
1439         int i;
1440         int num_rids = q_u->num_names2;
1441         DOM_SID pol_sid;
1442         fstring sid_str;
1443         uint32  acc_granted;
1444
1445         r_u->status = NT_STATUS_OK;
1446
1447         DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1448
1449         ZERO_ARRAY(rid);
1450         ZERO_ARRAY(type);
1451
1452         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1453                 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1454                 return r_u->status;
1455         }
1456         
1457         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, 0, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */
1458                 return r_u->status;
1459         }
1460
1461         if (num_rids > MAX_SAM_ENTRIES) {
1462                 num_rids = MAX_SAM_ENTRIES;
1463                 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1464         }
1465
1466         DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1467         
1468         become_root(); /* local_lookup_name can require root privs */
1469
1470         for (i = 0; i < num_rids; i++) {
1471                 fstring name;
1472                 DOM_SID sid;
1473                 int ret;
1474
1475                 r_u->status = NT_STATUS_NONE_MAPPED;
1476
1477                 rid [i] = 0xffffffff;
1478                 type[i] = SID_NAME_UNKNOWN;
1479
1480                 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1481
1482                 /*
1483                  * we are only looking for a name
1484                  * the SID we get back can be outside
1485                  * the scope of the pol_sid
1486                  * 
1487                  * in clear: it prevents to reply to domain\group: yes
1488                  * when only builtin\group exists.
1489                  *
1490                  * a cleaner code is to add the sid of the domain we're looking in
1491                  * to the local_lookup_name function.
1492                  */
1493                  
1494                 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1495                         sid_split_rid(&sid, &local_rid);
1496                                 
1497                         if (sid_equal(&sid, &pol_sid)) {
1498                                 rid[i]=local_rid;
1499                                 type[i]=local_type;
1500                                 r_u->status = NT_STATUS_OK;
1501                         }
1502                 }
1503         }
1504
1505         unbecome_root();
1506
1507         init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1508
1509         DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1510
1511         return r_u->status;
1512 }
1513
1514 /*******************************************************************
1515  _samr_chgpasswd_user
1516  ********************************************************************/
1517
1518 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1519 {
1520     fstring user_name;
1521     fstring wks;
1522
1523     DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1524
1525     r_u->status = NT_STATUS_OK;
1526
1527     rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1528     rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1529
1530     DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1531
1532         /*
1533          * Pass the user through the NT -> unix user mapping
1534          * function.
1535          */
1536  
1537         (void)map_username(user_name);
1538  
1539         /*
1540          * UNIX username case mangling not required, pass_oem_change 
1541          * is case insensitive.
1542          */
1543
1544     r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1545                                   q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1546
1547     init_samr_r_chgpasswd_user(r_u, r_u->status);
1548
1549     DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1550
1551     return r_u->status;
1552 }
1553
1554 /*******************************************************************
1555 makes a SAMR_R_LOOKUP_RIDS structure.
1556 ********************************************************************/
1557
1558 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1559             UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1560 {
1561         uint32 i;
1562         UNIHDR *hdr_name=NULL;
1563         UNISTR2 *uni_name=NULL;
1564
1565         *pp_uni_name = NULL;
1566         *pp_hdr_name = NULL;
1567
1568         if (num_names != 0) {
1569                 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1570                 if (hdr_name == NULL)
1571                         return False;
1572
1573                 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1574                 if (uni_name == NULL)
1575                         return False;
1576         }
1577
1578         for (i = 0; i < num_names; i++) {
1579                 int len = names[i] != NULL ? strlen(names[i]) : 0;
1580                 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1581                 init_uni_hdr(&hdr_name[i], len);
1582                 init_unistr2(&uni_name[i], names[i], len);
1583         }
1584
1585         *pp_uni_name = uni_name;
1586         *pp_hdr_name = hdr_name;
1587
1588         return True;
1589 }
1590
1591 /*******************************************************************
1592  _samr_lookup_rids
1593  ********************************************************************/
1594
1595 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1596 {
1597         fstring group_names[MAX_SAM_ENTRIES];
1598         uint32 *group_attrs = NULL;
1599         UNIHDR *hdr_name = NULL;
1600         UNISTR2 *uni_name = NULL;
1601         DOM_SID pol_sid;
1602         int num_rids = q_u->num_rids1;
1603         int i;
1604         uint32 acc_granted;
1605
1606         r_u->status = NT_STATUS_OK;
1607
1608         DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1609
1610         /* find the policy handle.  open a policy on it. */
1611         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1612                 return NT_STATUS_INVALID_HANDLE;
1613
1614         if (num_rids > MAX_SAM_ENTRIES) {
1615                 num_rids = MAX_SAM_ENTRIES;
1616                 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1617         }
1618
1619         if (num_rids) {
1620                 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1621                         return NT_STATUS_NO_MEMORY;
1622         }
1623  
1624         r_u->status = NT_STATUS_NONE_MAPPED;
1625
1626         become_root();  /* lookup_sid can require root privs */
1627
1628         for (i = 0; i < num_rids; i++) {
1629                 fstring tmpname;
1630                 fstring domname;
1631                 DOM_SID sid;
1632                 enum SID_NAME_USE type;
1633
1634                 group_attrs[i] = SID_NAME_UNKNOWN;
1635                 *group_names[i] = '\0';
1636
1637                 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1638                         sid_copy(&sid, &pol_sid);
1639                         sid_append_rid(&sid, q_u->rid[i]);
1640
1641                         if (lookup_sid(&sid, domname, tmpname, &type)) {
1642                                 r_u->status = NT_STATUS_OK;
1643                                 group_attrs[i] = (uint32)type;
1644                                 fstrcpy(group_names[i],tmpname);
1645                                 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1646                         }
1647                 }
1648         }
1649
1650         unbecome_root();
1651
1652         if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1653                 return NT_STATUS_NO_MEMORY;
1654
1655         init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1656
1657         DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1658
1659         return r_u->status;
1660 }
1661
1662 /*******************************************************************
1663  _api_samr_open_user. Safe - gives out no passwd info.
1664  ********************************************************************/
1665
1666 NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1667 {
1668         SAM_ACCOUNT *sampass=NULL;
1669         DOM_SID sid;
1670         POLICY_HND domain_pol = q_u->domain_pol;
1671         POLICY_HND *user_pol = &r_u->user_pol;
1672         struct samr_info *info = NULL;
1673         SEC_DESC *psd = NULL;
1674         uint32    acc_granted;
1675         uint32    des_access = q_u->access_mask;
1676         size_t    sd_size;
1677         BOOL ret;
1678         NTSTATUS nt_status;
1679
1680         r_u->status = NT_STATUS_OK;
1681
1682         /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1683         if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1684                 return NT_STATUS_INVALID_HANDLE;
1685         
1686         if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1687                 return nt_status;
1688         }
1689
1690         nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1691         if (!NT_STATUS_IS_OK(nt_status)) {
1692                 return nt_status;
1693         }
1694
1695         /* append the user's RID to it */
1696         if (!sid_append_rid(&sid, q_u->user_rid))
1697                 return NT_STATUS_NO_SUCH_USER;
1698         
1699         /* check if access can be granted as requested by client. */
1700         samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1701         se_map_generic(&des_access, &usr_generic_mapping);
1702         if (!NT_STATUS_IS_OK(nt_status = 
1703                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
1704                                                       des_access, &acc_granted, "_samr_open_user"))) {
1705                 return nt_status;
1706         }
1707
1708         become_root();
1709         ret=pdb_getsampwsid(sampass, &sid);
1710         unbecome_root();
1711
1712         /* check that the SID exists in our domain. */
1713         if (ret == False) {
1714                 return NT_STATUS_NO_SUCH_USER;
1715         }
1716
1717         pdb_free_sam(&sampass);
1718
1719         /* associate the user's SID and access bits with the new handle. */
1720         if ((info = get_samr_info_by_sid(&sid)) == NULL)
1721                 return NT_STATUS_NO_MEMORY;
1722         info->acc_granted = acc_granted;
1723
1724         /* get a (unique) handle.  open a policy on it. */
1725         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1726                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1727
1728         return r_u->status;
1729 }
1730
1731 /*************************************************************************
1732  get_user_info_10. Safe. Only gives out acb bits.
1733  *************************************************************************/
1734
1735 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1736 {
1737         SAM_ACCOUNT *smbpass=NULL;
1738         BOOL ret;
1739         NTSTATUS nt_status;
1740
1741         nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1742         
1743         if (!NT_STATUS_IS_OK(nt_status)) {
1744                 return nt_status;
1745         }
1746
1747         become_root();
1748         ret = pdb_getsampwsid(smbpass, user_sid);
1749         unbecome_root();
1750
1751         if (ret==False) {
1752                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1753                 return NT_STATUS_NO_SUCH_USER;
1754         }
1755
1756         DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1757
1758         ZERO_STRUCTP(id10);
1759         init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1760
1761         pdb_free_sam(&smbpass);
1762
1763         return NT_STATUS_OK;
1764 }
1765
1766 /*************************************************************************
1767  get_user_info_12. OK - this is the killer as it gives out password info.
1768  Ensure that this is only allowed on an encrypted connection with a root
1769  user. JRA. 
1770  *************************************************************************/
1771
1772 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1773 {
1774         SAM_ACCOUNT *smbpass=NULL;
1775         BOOL ret;
1776         NTSTATUS nt_status;
1777
1778         if (!p->ntlmssp_auth_validated)
1779                 return NT_STATUS_ACCESS_DENIED;
1780
1781         if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1782                 return NT_STATUS_ACCESS_DENIED;
1783
1784         /*
1785          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1786          */
1787
1788         nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1789         
1790         if (!NT_STATUS_IS_OK(nt_status)) {
1791                 return nt_status;
1792         }
1793
1794         ret = pdb_getsampwsid(smbpass, user_sid);
1795
1796         if (ret == False) {
1797                 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1798                 pdb_free_sam(&smbpass);
1799                 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1800         }
1801
1802         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1803
1804         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1805                 pdb_free_sam(&smbpass);
1806                 return NT_STATUS_ACCOUNT_DISABLED;
1807         }
1808
1809         ZERO_STRUCTP(id12);
1810         init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1811         
1812         pdb_free_sam(&smbpass);
1813
1814         return NT_STATUS_OK;
1815 }
1816
1817 /*************************************************************************
1818  get_user_info_20
1819  *************************************************************************/
1820
1821 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1822 {
1823         SAM_ACCOUNT *sampass=NULL;
1824         BOOL ret;
1825
1826         pdb_init_sam_talloc(mem_ctx, &sampass);
1827
1828         become_root();
1829         ret = pdb_getsampwsid(sampass, user_sid);
1830         unbecome_root();
1831
1832         if (ret == False) {
1833                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1834                 return NT_STATUS_NO_SUCH_USER;
1835         }
1836
1837         samr_clear_sam_passwd(sampass);
1838
1839         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
1840
1841         ZERO_STRUCTP(id20);
1842         init_sam_user_info20A(id20, sampass);
1843         
1844         pdb_free_sam(&sampass);
1845
1846         return NT_STATUS_OK;
1847 }
1848
1849 /*************************************************************************
1850  get_user_info_21
1851  *************************************************************************/
1852
1853 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21, 
1854                                  DOM_SID *user_sid, DOM_SID *domain_sid)
1855 {
1856         SAM_ACCOUNT *sampass=NULL;
1857         BOOL ret;
1858         NTSTATUS nt_status;
1859
1860         nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1861         if (!NT_STATUS_IS_OK(nt_status)) {
1862                 return nt_status;
1863         }
1864
1865         become_root();
1866         ret = pdb_getsampwsid(sampass, user_sid);
1867         unbecome_root();
1868
1869         if (ret == False) {
1870                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1871                 return NT_STATUS_NO_SUCH_USER;
1872         }
1873
1874         samr_clear_sam_passwd(sampass);
1875
1876         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
1877
1878         ZERO_STRUCTP(id21);
1879         nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1880         
1881         pdb_free_sam(&sampass);
1882
1883         return NT_STATUS_OK;
1884 }
1885
1886 /*******************************************************************
1887  _samr_query_userinfo
1888  ********************************************************************/
1889
1890 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1891 {
1892         SAM_USERINFO_CTR *ctr;
1893         struct samr_info *info = NULL;
1894         DOM_SID domain_sid;
1895         uint32 rid;
1896         
1897         r_u->status=NT_STATUS_OK;
1898
1899         /* search for the handle */
1900         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1901                 return NT_STATUS_INVALID_HANDLE;
1902
1903         domain_sid = info->sid;
1904
1905         sid_split_rid(&domain_sid, &rid);
1906
1907         if (!sid_check_is_in_our_domain(&info->sid))
1908                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1909
1910         DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1911
1912         ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1913         if (!ctr)
1914                 return NT_STATUS_NO_MEMORY;
1915
1916         ZERO_STRUCTP(ctr);
1917
1918         /* ok!  user info levels (lots: see MSDEV help), off we go... */
1919         ctr->switch_value = q_u->switch_value;
1920
1921         switch (q_u->switch_value) {
1922         case 0x10:
1923                 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1924                 if (ctr->info.id10 == NULL)
1925                         return NT_STATUS_NO_MEMORY;
1926
1927                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1928                         return r_u->status;
1929                 break;
1930
1931 #if 0
1932 /* whoops - got this wrong.  i think.  or don't understand what's happening. */
1933         case 0x11:
1934         {
1935             NTTIME expire;
1936             info = (void *)&id11;
1937
1938             expire.low = 0xffffffff;
1939             expire.high = 0x7fffffff;
1940
1941             ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1942                                     sizeof
1943                                     (*ctr->
1944                                      info.
1945                                      id11));
1946             ZERO_STRUCTP(ctr->info.id11);
1947             init_sam_user_info11(ctr->info.id11, &expire,
1948                          "BROOKFIELDS$",    /* name */
1949                          0x03ef,    /* user rid */
1950                          0x201, /* group rid */
1951                          0x0080);   /* acb info */
1952
1953             break;
1954         }
1955 #endif
1956
1957         case 0x12:
1958                 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1959                 if (ctr->info.id12 == NULL)
1960                         return NT_STATUS_NO_MEMORY;
1961
1962                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1963                         return r_u->status;
1964                 break;
1965                 
1966         case 20:
1967                 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1968                 if (ctr->info.id20 == NULL)
1969                         return NT_STATUS_NO_MEMORY;
1970                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1971                         return r_u->status;
1972                 break;
1973
1974         case 21:
1975                 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1976                 if (ctr->info.id21 == NULL)
1977                         return NT_STATUS_NO_MEMORY;
1978                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21, 
1979                                                                     &info->sid, &domain_sid)))
1980                         return r_u->status;
1981                 break;
1982
1983         default:
1984                 return NT_STATUS_INVALID_INFO_CLASS;
1985         }
1986
1987         init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1988
1989         DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1990         
1991         return r_u->status;
1992 }
1993
1994 /*******************************************************************
1995  samr_reply_query_usergroups
1996  ********************************************************************/
1997
1998 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1999 {
2000         SAM_ACCOUNT *sam_pass=NULL;
2001         DOM_SID  sid;
2002         DOM_GID *gids = NULL;
2003         int num_groups = 0;
2004         uint32 acc_granted;
2005         BOOL ret;
2006
2007         /*
2008          * from the SID in the request:
2009          * we should send back the list of DOMAIN GROUPS
2010          * the user is a member of
2011          *
2012          * and only the DOMAIN GROUPS
2013          * no ALIASES !!! neither aliases of the domain
2014          * nor aliases of the builtin SID
2015          *
2016          * JFM, 12/2/2001
2017          */
2018
2019         r_u->status = NT_STATUS_OK;
2020
2021         DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2022
2023         /* find the policy handle.  open a policy on it. */
2024         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
2025                 return NT_STATUS_INVALID_HANDLE;
2026         
2027         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2028                 return r_u->status;
2029         }
2030
2031         if (!sid_check_is_in_our_domain(&sid))
2032                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2033
2034         pdb_init_sam(&sam_pass);
2035         
2036         become_root();
2037         ret = pdb_getsampwsid(sam_pass, &sid);
2038         unbecome_root();
2039
2040         if (ret == False) {
2041                 pdb_free_sam(&sam_pass);
2042                 return NT_STATUS_NO_SUCH_USER;
2043         }
2044         
2045         if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
2046                 pdb_free_sam(&sam_pass);
2047                 return NT_STATUS_NO_SUCH_GROUP;
2048         }
2049         
2050         /* construct the response.  lkclXXXX: gids are not copied! */
2051         init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2052         
2053         DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2054         
2055         pdb_free_sam(&sam_pass);
2056         
2057         return r_u->status;
2058 }
2059
2060 /*******************************************************************
2061  _samr_query_dom_info
2062  ********************************************************************/
2063
2064 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2065 {
2066         struct samr_info *info = NULL;
2067         SAM_UNK_CTR *ctr;
2068         uint32 min_pass_len,pass_hist,flag;
2069         time_t u_expire, u_min_age;
2070         NTTIME nt_expire, nt_min_age;
2071
2072         time_t u_lock_duration, u_reset_time;
2073         NTTIME nt_lock_duration, nt_reset_time;
2074         uint32 lockout;
2075         
2076         time_t u_logout;
2077         NTTIME nt_logout;
2078
2079         uint32 account_policy_temp;
2080
2081         uint32 num_users=0, num_groups=0, num_aliases=0;
2082
2083         if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2084                 return NT_STATUS_NO_MEMORY;
2085
2086         ZERO_STRUCTP(ctr);
2087
2088         r_u->status = NT_STATUS_OK;
2089         
2090         DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2091         
2092         /* find the policy handle.  open a policy on it. */
2093         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2094                 return NT_STATUS_INVALID_HANDLE;
2095         
2096         switch (q_u->switch_value) {
2097                 case 0x01:
2098                         
2099                         account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2100                         min_pass_len = account_policy_temp;
2101
2102                         account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2103                         pass_hist = account_policy_temp;
2104
2105                         account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2106                         flag = account_policy_temp;
2107
2108                         account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2109                         u_expire = account_policy_temp;
2110
2111                         account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2112                         u_min_age = account_policy_temp;
2113                         
2114                         unix_to_nt_time_abs(&nt_expire, u_expire);
2115                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
2116
2117                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
2118                                        flag, nt_expire, nt_min_age);
2119                         break;
2120                 case 0x02:
2121                         become_root();          
2122                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2123                         unbecome_root();
2124                         if (!NT_STATUS_IS_OK(r_u->status)) {
2125                                 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2126                                 return r_u->status;
2127                         }
2128                         num_users=info->disp_info.num_user_account;
2129                         free_samr_db(info);
2130                         
2131                         r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2132                         if (!NT_STATUS_IS_OK(r_u->status)) {
2133                                 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2134                                 return r_u->status;
2135                         }
2136                         num_groups=info->disp_info.num_group_account;
2137                         free_samr_db(info);
2138                         
2139                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2140                         init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL), 
2141                                        num_users, num_groups, num_aliases);
2142                         break;
2143                 case 0x03:
2144                         account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
2145                         unix_to_nt_time_abs(&nt_logout, u_logout);
2146                         
2147                         init_unk_info3(&ctr->info.inf3, nt_logout);
2148                         break;
2149                 case 0x05:
2150                         init_unk_info5(&ctr->info.inf5, global_myname());
2151                         break;
2152                 case 0x06:
2153                         init_unk_info6(&ctr->info.inf6);
2154                         break;
2155                 case 0x07:
2156                         init_unk_info7(&ctr->info.inf7);
2157                         break;
2158                 case 0x0c:
2159                         account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2160                         u_lock_duration = account_policy_temp;
2161
2162                         account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2163                         u_reset_time = account_policy_temp;
2164
2165                         account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2166                         lockout = account_policy_temp;
2167
2168                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2169                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2170         
2171                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2172                         break;
2173                 default:
2174                         return NT_STATUS_INVALID_INFO_CLASS;
2175                 }
2176         
2177         init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2178         
2179         DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2180         
2181         return r_u->status;
2182 }
2183
2184 /*******************************************************************
2185  _api_samr_create_user
2186  Create an account, can be either a normal user or a machine.
2187  This funcion will need to be updated for bdc/domain trusts.
2188  ********************************************************************/
2189
2190 NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2191 {
2192         SAM_ACCOUNT *sam_pass=NULL;
2193         fstring account;
2194         DOM_SID sid;
2195         pstring add_script;
2196         POLICY_HND dom_pol = q_u->domain_pol;
2197         UNISTR2 user_account = q_u->uni_name;
2198         uint16 acb_info = q_u->acb_info;
2199         POLICY_HND *user_pol = &r_u->user_pol;
2200         struct samr_info *info = NULL;
2201         BOOL ret;
2202         NTSTATUS nt_status;
2203         struct passwd *pw;
2204         uint32 acc_granted;
2205         SEC_DESC *psd;
2206         size_t    sd_size;
2207         /* check this, when giving away 'add computer to domain' privs */
2208         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2209
2210         /* Get the domain SID stored in the domain policy */
2211         if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2212                 return NT_STATUS_INVALID_HANDLE;
2213
2214         if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2215                 return nt_status;
2216         }
2217
2218         /* find the account: tell the caller if it exists.
2219           lkclXXXX i have *no* idea if this is a problem or not
2220           or even if you are supposed to construct a different
2221           reply if the account already exists...
2222          */
2223
2224         rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2225         strlower_m(account);
2226
2227         pdb_init_sam(&sam_pass);
2228
2229         become_root();
2230         ret = pdb_getsampwnam(sam_pass, account);
2231         unbecome_root();
2232         if (ret == True) {
2233                 /* this account exists: say so */
2234                 pdb_free_sam(&sam_pass);
2235                 return NT_STATUS_USER_EXISTS;
2236         }
2237
2238         pdb_free_sam(&sam_pass);
2239
2240         /*
2241          * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2242          * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2243          * that only people with write access to the smbpasswd file will be able
2244          * to create a user. JRA.
2245          */
2246
2247         /*
2248          * add the user in the /etc/passwd file or the unix authority system.
2249          * We don't check if the smb_create_user() function succed or not for 2 reasons:
2250          * a) local_password_change() checks for us if the /etc/passwd account really exists
2251          * b) smb_create_user() would return an error if the account already exists
2252          * and as it could return an error also if it can't create the account, it would be tricky.
2253          *
2254          * So we go the easy way, only check after if the account exists.
2255          * JFM (2/3/2001), to clear any possible bad understanding (-:
2256          *
2257          * We now have seperate script paramaters for adding users/machines so we
2258          * now have some sainity-checking to match. 
2259          */
2260
2261         DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1));
2262 #if 0
2263         if ((acb_info & ACB_WSTRUST) && (account[strlen(account)-1] == '$')) {
2264                 pstrcpy(add_script, lp_addmachine_script());            
2265         } else if ((!(acb_info & ACB_WSTRUST)) && (account[strlen(account)-1] != '$')) {
2266                 pstrcpy(add_script, lp_adduser_script());
2267         } else {
2268                 DEBUG(0, ("_api_samr_create_user: mismatch between trust flags and $ termination\n"));
2269                 pdb_free_sam(&sam_pass);
2270                 return NT_STATUS_UNSUCCESSFUL;
2271         }
2272 #endif
2273
2274         /* the passdb lookup has failed; check to see if we need to run the
2275            add user/machine script */
2276            
2277         pw = Get_Pwnam(account);
2278         
2279         if ( !pw ) {
2280                 /* 
2281                  * we can't check both the ending $ and the acb_info.
2282                  * 
2283                  * UserManager creates trust accounts (ending in $,
2284                  * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2285                  * JFM, 11/29/2001
2286                  */
2287                 if (account[strlen(account)-1] == '$')
2288                         pstrcpy(add_script, lp_addmachine_script());            
2289                 else 
2290                         pstrcpy(add_script, lp_adduser_script());
2291
2292                 if (*add_script) {
2293                         int add_ret;
2294                         all_string_sub(add_script, "%u", account, sizeof(account));
2295                         add_ret = smbrun(add_script,NULL);
2296                         DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2297                 }
2298                 
2299         }
2300         
2301         nt_status = pdb_init_sam_new(&sam_pass, account);
2302         if (!NT_STATUS_IS_OK(nt_status))
2303                 return nt_status;
2304                 
2305         pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2306         
2307         if (!pdb_add_sam_account(sam_pass)) {
2308                 pdb_free_sam(&sam_pass);
2309                 DEBUG(0, ("could not add user/computer %s to passdb.  Check permissions?\n", 
2310                           account));
2311                 return NT_STATUS_ACCESS_DENIED;         
2312         }
2313         
2314         /* Get the user's SID */
2315         sid_copy(&sid, pdb_get_user_sid(sam_pass));
2316         
2317         samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2318         se_map_generic(&des_access, &usr_generic_mapping);
2319         if (!NT_STATUS_IS_OK(nt_status = 
2320                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2321                                                       des_access, &acc_granted, "_samr_create_user"))) {
2322                 return nt_status;
2323         }
2324
2325         /* associate the user's SID with the new handle. */
2326         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2327                 pdb_free_sam(&sam_pass);
2328                 return NT_STATUS_NO_MEMORY;
2329         }
2330
2331         ZERO_STRUCTP(info);
2332         info->sid = sid;
2333         info->acc_granted = acc_granted;
2334
2335         /* get a (unique) handle.  open a policy on it. */
2336         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2337                 pdb_free_sam(&sam_pass);
2338                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2339         }
2340
2341         r_u->user_rid=pdb_get_user_rid(sam_pass);
2342
2343         r_u->access_granted = acc_granted;
2344
2345         pdb_free_sam(&sam_pass);
2346
2347         return NT_STATUS_OK;
2348 }
2349
2350 /*******************************************************************
2351  samr_reply_connect_anon
2352  ********************************************************************/
2353
2354 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2355 {
2356         struct samr_info *info = NULL;
2357
2358         /* Access check */
2359
2360         if (!pipe_access_check(p)) {
2361                 DEBUG(3, ("access denied to samr_connect_anon\n"));
2362                 r_u->status = NT_STATUS_ACCESS_DENIED;
2363                 return r_u->status;
2364         }
2365
2366         /* set up the SAMR connect_anon response */
2367
2368         r_u->status = NT_STATUS_OK;
2369
2370         /* associate the user's SID with the new handle. */
2371         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2372                 return NT_STATUS_NO_MEMORY;
2373
2374         info->status = q_u->unknown_0;
2375
2376         /* get a (unique) handle.  open a policy on it. */
2377         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2378                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2379
2380         return r_u->status;
2381 }
2382
2383 /*******************************************************************
2384  samr_reply_connect
2385  ********************************************************************/
2386
2387 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2388 {
2389         struct samr_info *info = NULL;
2390         SEC_DESC *psd = NULL;
2391         uint32    acc_granted;
2392         uint32    des_access = q_u->access_mask;
2393         size_t    sd_size;
2394         NTSTATUS  nt_status;
2395
2396
2397         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2398
2399         /* Access check */
2400
2401         if (!pipe_access_check(p)) {
2402                 DEBUG(3, ("access denied to samr_connect\n"));
2403                 r_u->status = NT_STATUS_ACCESS_DENIED;
2404                 return r_u->status;
2405         }
2406
2407         samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2408         se_map_generic(&des_access, &sam_generic_mapping);
2409         if (!NT_STATUS_IS_OK(nt_status = 
2410                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2411                                                       des_access, &acc_granted, "_samr_connect"))) {
2412                 return nt_status;
2413         }
2414
2415         r_u->status = NT_STATUS_OK;
2416
2417         /* associate the user's SID and access granted with the new handle. */
2418         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2419                 return NT_STATUS_NO_MEMORY;
2420
2421         info->acc_granted = acc_granted;
2422         info->status = q_u->access_mask;
2423
2424         /* get a (unique) handle.  open a policy on it. */
2425         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2426                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2427
2428         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2429
2430         return r_u->status;
2431 }
2432
2433 /*******************************************************************
2434  samr_connect4
2435  ********************************************************************/
2436
2437 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2438 {
2439         struct samr_info *info = NULL;
2440         SEC_DESC *psd = NULL;
2441         uint32    acc_granted;
2442         uint32    des_access = q_u->access_mask;
2443         size_t    sd_size;
2444         NTSTATUS  nt_status;
2445
2446
2447         DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2448
2449         /* Access check */
2450
2451         if (!pipe_access_check(p)) {
2452                 DEBUG(3, ("access denied to samr_connect4\n"));
2453                 r_u->status = NT_STATUS_ACCESS_DENIED;
2454                 return r_u->status;
2455         }
2456
2457         samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2458         se_map_generic(&des_access, &sam_generic_mapping);
2459         if (!NT_STATUS_IS_OK(nt_status = 
2460                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2461                                                       des_access, &acc_granted, "_samr_connect"))) {
2462                 return nt_status;
2463         }
2464
2465         r_u->status = NT_STATUS_OK;
2466
2467         /* associate the user's SID and access granted with the new handle. */
2468         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2469                 return NT_STATUS_NO_MEMORY;
2470
2471         info->acc_granted = acc_granted;
2472         info->status = q_u->access_mask;
2473
2474         /* get a (unique) handle.  open a policy on it. */
2475         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2476                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2477
2478         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2479
2480         return r_u->status;
2481 }
2482
2483 /**********************************************************************
2484  api_samr_lookup_domain
2485  **********************************************************************/
2486
2487 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2488 {
2489         struct samr_info *info;
2490         fstring domain_name;
2491         DOM_SID sid;
2492
2493         r_u->status = NT_STATUS_OK;
2494
2495         if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2496                 return NT_STATUS_INVALID_HANDLE;
2497
2498         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) {
2499                 return r_u->status;
2500         }
2501
2502         rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2503
2504         ZERO_STRUCT(sid);
2505
2506         if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2507                 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2508         }
2509
2510         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2511
2512         init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2513
2514         return r_u->status;
2515 }
2516
2517 /******************************************************************
2518 makes a SAMR_R_ENUM_DOMAINS structure.
2519 ********************************************************************/
2520
2521 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2522                         UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2523 {
2524         uint32 i;
2525         SAM_ENTRY *sam;
2526         UNISTR2 *uni_name;
2527
2528         DEBUG(5, ("make_enum_domains\n"));
2529
2530         *pp_sam = NULL;
2531         *pp_uni_name = NULL;
2532
2533         if (num_sam_entries == 0)
2534                 return True;
2535
2536         sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2537         uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2538
2539         if (sam == NULL || uni_name == NULL)
2540                 return False;
2541
2542         for (i = 0; i < num_sam_entries; i++) {
2543                 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2544
2545                 init_sam_entry(&sam[i], len, 0);
2546                 init_unistr2(&uni_name[i], doms[i], len);
2547         }
2548
2549         *pp_sam = sam;
2550         *pp_uni_name = uni_name;
2551
2552         return True;
2553 }
2554
2555 /**********************************************************************
2556  api_samr_enum_domains
2557  **********************************************************************/
2558
2559 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2560 {
2561         struct samr_info *info;
2562         uint32 num_entries = 2;
2563         fstring dom[2];
2564         const char *name;
2565
2566         r_u->status = NT_STATUS_OK;
2567         
2568         if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2569                 return NT_STATUS_INVALID_HANDLE;
2570         
2571         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2572                 return r_u->status;
2573         }
2574
2575         name = get_global_sam_name();
2576
2577         fstrcpy(dom[0],name);
2578         strupper_m(dom[0]);
2579         fstrcpy(dom[1],"Builtin");
2580
2581         if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2582                 return NT_STATUS_NO_MEMORY;
2583
2584         init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2585
2586         return r_u->status;
2587 }
2588
2589 /*******************************************************************
2590  api_samr_open_alias
2591  ********************************************************************/
2592
2593 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2594 {
2595         DOM_SID sid;
2596         POLICY_HND domain_pol = q_u->dom_pol;
2597         uint32 alias_rid = q_u->rid_alias;
2598         POLICY_HND *alias_pol = &r_u->pol;
2599         struct    samr_info *info = NULL;
2600         SEC_DESC *psd = NULL;
2601         uint32    acc_granted;
2602         uint32    des_access = q_u->access_mask;
2603         size_t    sd_size;
2604         NTSTATUS  status;
2605
2606         r_u->status = NT_STATUS_OK;
2607
2608         /* find the domain policy and get the SID / access bits stored in the domain policy */
2609         if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2610                 return NT_STATUS_INVALID_HANDLE;
2611                 
2612         if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2613                 return status;
2614         }
2615
2616         /* append the alias' RID to it */
2617         if (!sid_append_rid(&sid, alias_rid))
2618                 return NT_STATUS_NO_SUCH_USER;
2619                 
2620         /*check if access can be granted as requested by client. */
2621         samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2622         se_map_generic(&des_access,&ali_generic_mapping);
2623         if (!NT_STATUS_IS_OK(status = 
2624                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2625                                                       des_access, &acc_granted, "_samr_open_alias"))) {
2626                 return status;
2627         }
2628
2629         /*
2630          * we should check if the rid really exist !!!
2631          * JFM.
2632          */
2633
2634         /* associate the user's SID with the new handle. */
2635         if ((info = get_samr_info_by_sid(&sid)) == NULL)
2636                 return NT_STATUS_NO_MEMORY;
2637                 
2638         info->acc_granted = acc_granted;
2639
2640         /* get a (unique) handle.  open a policy on it. */
2641         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2642                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2643
2644         return r_u->status;
2645 }
2646
2647 /*******************************************************************
2648  set_user_info_10
2649  ********************************************************************/
2650
2651 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2652 {
2653         SAM_ACCOUNT *pwd =NULL;
2654         BOOL ret;
2655         
2656         pdb_init_sam(&pwd);
2657         
2658         ret = pdb_getsampwsid(pwd, sid);
2659         
2660         if(ret==False) {
2661                 pdb_free_sam(&pwd);
2662                 return False;
2663         }
2664
2665         if (id10 == NULL) {
2666                 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2667                 pdb_free_sam(&pwd);
2668                 return False;
2669         }
2670         
2671         /* FIX ME: check if the value is really changed --metze */
2672         if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2673                 pdb_free_sam(&pwd);
2674                 return False;
2675         }
2676
2677         if(!pdb_update_sam_account(pwd)) {
2678                 pdb_free_sam(&pwd);
2679                 return False;
2680         }
2681
2682         pdb_free_sam(&pwd);
2683
2684         return True;
2685 }
2686
2687 /*******************************************************************
2688  set_user_info_12
2689  ********************************************************************/
2690
2691 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2692 {
2693         SAM_ACCOUNT *pwd = NULL;
2694
2695         pdb_init_sam(&pwd);
2696
2697         if(!pdb_getsampwsid(pwd, sid)) {
2698                 pdb_free_sam(&pwd);
2699                 return False;
2700         }
2701
2702         if (id12 == NULL) {
2703                 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2704                 pdb_free_sam(&pwd);
2705                 return False;
2706         }
2707  
2708         if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2709                 pdb_free_sam(&pwd);
2710                 return False;
2711         }
2712         if (!pdb_set_nt_passwd     (pwd, id12->nt_pwd, PDB_CHANGED)) {
2713                 pdb_free_sam(&pwd);
2714                 return False;
2715         }
2716         if (!pdb_set_pass_changed_now (pwd)) {
2717                 pdb_free_sam(&pwd);
2718                 return False; 
2719         }
2720  
2721         if(!pdb_update_sam_account(pwd)) {
2722                 pdb_free_sam(&pwd);
2723                 return False;
2724         }
2725
2726         pdb_free_sam(&pwd);
2727         return True;
2728 }
2729
2730 /*******************************************************************
2731  The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2732  ********************************************************************/
2733 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2734 {
2735         struct group *grp;
2736         gid_t gid;
2737
2738         if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2739                                         &gid))) {
2740                 DEBUG(2,("Could not get gid for primary group of "
2741                          "user %s\n", pdb_get_username(sampass)));
2742                 return False;
2743         }
2744
2745         grp = getgrgid(gid);
2746
2747         if (grp == NULL) {
2748                 DEBUG(2,("Could not find primary group %d for "
2749                          "user %s\n", gid, pdb_get_username(sampass)));
2750                 return False;
2751         }
2752
2753         if (smb_set_primary_group(grp->gr_name,
2754                                   pdb_get_username(sampass)) != 0) {
2755                 DEBUG(2,("Could not set primary group for user %s to "
2756                          "%s\n",
2757                          pdb_get_username(sampass), grp->gr_name));
2758                 return False;
2759         }
2760
2761         return True;
2762 }
2763         
2764
2765 /*******************************************************************
2766  set_user_info_21
2767  ********************************************************************/
2768
2769 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2770 {
2771         SAM_ACCOUNT *pwd = NULL;
2772  
2773         if (id21 == NULL) {
2774                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2775                 return False;
2776         }
2777  
2778         pdb_init_sam(&pwd);
2779  
2780         if (!pdb_getsampwsid(pwd, sid)) {
2781                 pdb_free_sam(&pwd);
2782                 return False;
2783         }
2784  
2785         copy_id21_to_sam_passwd(pwd, id21);
2786  
2787         /*
2788          * The funny part about the previous two calls is
2789          * that pwd still has the password hashes from the
2790          * passdb entry.  These have not been updated from
2791          * id21.  I don't know if they need to be set.    --jerry
2792          */
2793  
2794         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2795                 set_unix_primary_group(pwd);
2796
2797         /* write the change out */
2798         if(!pdb_update_sam_account(pwd)) {
2799                 pdb_free_sam(&pwd);
2800                 return False;
2801         }
2802
2803         pdb_free_sam(&pwd);
2804
2805         return True;
2806 }
2807
2808 /*******************************************************************
2809  set_user_info_23
2810  ********************************************************************/
2811
2812 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2813 {
2814         SAM_ACCOUNT *pwd = NULL;
2815         pstring plaintext_buf;
2816         uint32 len;
2817         uint16 acct_ctrl;
2818  
2819         if (id23 == NULL) {
2820                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2821                 return False;
2822         }
2823  
2824         pdb_init_sam(&pwd);
2825  
2826         if (!pdb_getsampwsid(pwd, sid)) {
2827                 pdb_free_sam(&pwd);
2828                 return False;
2829         }
2830
2831         DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2832                   pdb_get_username(pwd)));
2833
2834         acct_ctrl = pdb_get_acct_ctrl(pwd);
2835
2836         if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2837                 pdb_free_sam(&pwd);
2838                 return False;
2839         }
2840   
2841         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2842                 pdb_free_sam(&pwd);
2843                 return False;
2844         }
2845  
2846         copy_id23_to_sam_passwd(pwd, id23);
2847  
2848         /* if it's a trust account, don't update /etc/passwd */
2849         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2850                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2851                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2852                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2853         } else  {
2854                 /* update the UNIX password */
2855                 if (lp_unix_password_sync() )
2856                         if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2857                                 pdb_free_sam(&pwd);
2858                                 return False;
2859                         }
2860         }
2861  
2862         ZERO_STRUCT(plaintext_buf);
2863  
2864         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2865                 set_unix_primary_group(pwd);
2866
2867         if(!pdb_update_sam_account(pwd)) {
2868                 pdb_free_sam(&pwd);
2869                 return False;
2870         }
2871  
2872         pdb_free_sam(&pwd);
2873
2874         return True;
2875 }
2876
2877 /*******************************************************************
2878  set_user_info_pw
2879  ********************************************************************/
2880
2881 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2882 {
2883         SAM_ACCOUNT *pwd = NULL;
2884         uint32 len;
2885         pstring plaintext_buf;
2886         uint16 acct_ctrl;
2887  
2888         pdb_init_sam(&pwd);
2889  
2890         if (!pdb_getsampwsid(pwd, sid)) {
2891                 pdb_free_sam(&pwd);
2892                 return False;
2893         }
2894         
2895         DEBUG(5, ("Attempting administrator password change for user %s\n",
2896                   pdb_get_username(pwd)));
2897
2898         acct_ctrl = pdb_get_acct_ctrl(pwd);
2899
2900         ZERO_STRUCT(plaintext_buf);
2901  
2902         if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2903                 pdb_free_sam(&pwd);
2904                 return False;
2905         }
2906
2907         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2908                 pdb_free_sam(&pwd);
2909                 return False;
2910         }
2911  
2912         /* if it's a trust account, don't update /etc/passwd */
2913         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2914                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2915                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2916                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2917         } else {
2918                 /* update the UNIX password */
2919                 if (lp_unix_password_sync()) {
2920                         if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2921                                 pdb_free_sam(&pwd);
2922                                 return False;
2923                         }
2924                 }
2925         }
2926  
2927         ZERO_STRUCT(plaintext_buf);
2928  
2929         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2930  
2931         /* update the SAMBA password */
2932         if(!pdb_update_sam_account(pwd)) {
2933                 pdb_free_sam(&pwd);
2934                 return False;
2935         }
2936
2937         pdb_free_sam(&pwd);
2938
2939         return True;
2940 }
2941
2942 /*******************************************************************
2943  samr_reply_set_userinfo
2944  ********************************************************************/
2945
2946 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2947 {
2948         DOM_SID sid;
2949         POLICY_HND *pol = &q_u->pol;
2950         uint16 switch_value = q_u->switch_value;
2951         SAM_USERINFO_CTR *ctr = q_u->ctr;
2952         uint32 acc_granted;
2953         uint32 acc_required;
2954
2955         DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2956
2957         r_u->status = NT_STATUS_OK;
2958
2959         /* find the policy handle.  open a policy on it. */
2960         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2961                 return NT_STATUS_INVALID_HANDLE;
2962         
2963         acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */   
2964         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2965                 return r_u->status;
2966         }
2967                 
2968         DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2969
2970         if (ctr == NULL) {
2971                 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2972                 return NT_STATUS_INVALID_INFO_CLASS;
2973         }
2974
2975         /* ok!  user info levels (lots: see MSDEV help), off we go... */
2976         switch (switch_value) {
2977                 case 0x12:
2978                         if (!set_user_info_12(ctr->info.id12, &sid))
2979                                 return NT_STATUS_ACCESS_DENIED;
2980                         break;
2981
2982                 case 24:
2983                         SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
2984
2985                         dump_data(100, (char *)ctr->info.id24->pass, 516);
2986
2987                         if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
2988                                 return NT_STATUS_ACCESS_DENIED;
2989                         break;
2990
2991                 case 25:
2992 #if 0
2993                         /*
2994                          * Currently we don't really know how to unmarshall
2995                          * the level 25 struct, and the password encryption
2996                          * is different. This is a placeholder for when we
2997                          * do understand it. In the meantime just return INVALID
2998                          * info level and W2K SP2 drops down to level 23... JRA.
2999                          */
3000
3001                         SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
3002
3003                         dump_data(100, (char *)ctr->info.id25->pass, 532);
3004
3005                         if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3006                                 return NT_STATUS_ACCESS_DENIED;
3007                         break;
3008 #endif
3009                         return NT_STATUS_INVALID_INFO_CLASS;
3010
3011                 case 23:
3012                         SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
3013
3014                         dump_data(100, (char *)ctr->info.id23->pass, 516);
3015
3016                         if (!set_user_info_23(ctr->info.id23, &sid))
3017                                 return NT_STATUS_ACCESS_DENIED;
3018                         break;
3019
3020                 default:
3021                         return NT_STATUS_INVALID_INFO_CLASS;
3022         }
3023
3024         return r_u->status;
3025 }
3026
3027 /*******************************************************************
3028  samr_reply_set_userinfo2
3029  ********************************************************************/
3030
3031 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3032 {
3033         DOM_SID sid;
3034         SAM_USERINFO_CTR *ctr = q_u->ctr;
3035         POLICY_HND *pol = &q_u->pol;
3036         uint16 switch_value = q_u->switch_value;
3037         uint32 acc_granted;
3038         uint32 acc_required;
3039
3040         DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3041
3042         r_u->status = NT_STATUS_OK;
3043
3044         /* find the policy handle.  open a policy on it. */
3045         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3046                 return NT_STATUS_INVALID_HANDLE;
3047         
3048         acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */   
3049         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3050                 return r_u->status;
3051         }
3052
3053         DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3054
3055         if (ctr == NULL) {
3056                 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3057                 return NT_STATUS_INVALID_INFO_CLASS;
3058         }
3059
3060         switch_value=ctr->switch_value;
3061
3062         /* ok!  user info levels (lots: see MSDEV help), off we go... */
3063         switch (switch_value) {
3064                 case 21:
3065                         if (!set_user_info_21(ctr->info.id21, &sid))
3066                                 return NT_STATUS_ACCESS_DENIED;
3067                         break;
3068                 case 16:
3069                         if (!set_user_info_10(ctr->info.id10, &sid))
3070                                 return NT_STATUS_ACCESS_DENIED;
3071                         break;
3072                 case 18:
3073                         /* Used by AS/U JRA. */
3074                         if (!set_user_info_12(ctr->info.id12, &sid))
3075                                 return NT_STATUS_ACCESS_DENIED;
3076                         break;
3077                 default:
3078                         return NT_STATUS_INVALID_INFO_CLASS;
3079         }
3080
3081         return r_u->status;
3082 }
3083
3084 /*********************************************************************
3085  _samr_query_aliasmem
3086 *********************************************************************/
3087
3088 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3089 {
3090         int num_groups = 0, tmp_num_groups=0;
3091         uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3092         struct samr_info *info = NULL;
3093         int i,j;
3094                 
3095         NTSTATUS ntstatus1;
3096         NTSTATUS ntstatus2;
3097
3098         /* until i see a real useraliases query, we fack one up */
3099
3100         /* I have seen one, JFM 2/12/2001 */
3101         /*
3102          * Explanation of what this call does:
3103          * for all the SID given in the request:
3104          * return a list of alias (local groups)
3105          * that have those SID as members.
3106          *
3107          * and that's the alias in the domain specified
3108          * in the policy_handle
3109          *
3110          * if the policy handle is on an incorrect sid
3111          * for example a user's sid
3112          * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3113          */
3114         
3115         r_u->status = NT_STATUS_OK;
3116
3117         DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3118
3119         /* find the policy handle.  open a policy on it. */
3120         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3121                 return NT_STATUS_INVALID_HANDLE;
3122                 
3123         ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3124         ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3125         
3126         if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3127                 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3128                     !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3129                         return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3130                 }
3131         }               
3132
3133         if (!sid_check_is_domain(&info->sid) &&
3134             !sid_check_is_builtin(&info->sid))
3135                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3136
3137
3138         for (i=0; i<q_u->num_sids1; i++) {
3139
3140                 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3141
3142                 /*
3143                  * if there is an error, we just continue as
3144                  * it can be an unfound user or group
3145                  */
3146                 if (!NT_STATUS_IS_OK(r_u->status)) {
3147                         DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3148                         continue;
3149                 }
3150
3151                 if (tmp_num_groups==0) {
3152                         DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3153                         continue;
3154                 }
3155
3156                 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3157                 if (new_rids==NULL) {
3158                         DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3159                         return NT_STATUS_NO_MEMORY;
3160                 }
3161                 rids=new_rids;
3162
3163                 for (j=0; j<tmp_num_groups; j++)
3164                         rids[j+num_groups]=tmp_rids[j];
3165                 
3166                 safe_free(tmp_rids);
3167                 
3168                 num_groups+=tmp_num_groups;
3169         }
3170         
3171         init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3172         return NT_STATUS_OK;
3173 }
3174
3175 /*********************************************************************
3176  _samr_query_aliasmem
3177 *********************************************************************/
3178
3179 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3180 {
3181         int i;
3182
3183         GROUP_MAP map;
3184         int num_uids = 0;
3185         DOM_SID2 *sid;
3186         uid_t *uid=NULL;
3187
3188         DOM_SID alias_sid;
3189         DOM_SID als_sid;
3190         uint32 alias_rid;
3191         fstring alias_sid_str;
3192         DOM_SID temp_sid;
3193
3194         SAM_ACCOUNT *sam_user = NULL;
3195         BOOL check;
3196         uint32 acc_granted;
3197
3198         /* find the policy handle.  open a policy on it. */
3199         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3200                 return NT_STATUS_INVALID_HANDLE;
3201         
3202         if (!NT_STATUS_IS_OK(r_u->status = 
3203                 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3204                 return r_u->status;
3205         }
3206                 
3207         sid_copy(&als_sid, &alias_sid);
3208         sid_to_string(alias_sid_str, &alias_sid);
3209         sid_split_rid(&alias_sid, &alias_rid);
3210
3211         DEBUG(10, ("sid is %s\n", alias_sid_str));
3212
3213         if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3214                 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3215                 if(!get_builtin_group_from_sid(als_sid, &map))
3216                         return NT_STATUS_NO_SUCH_ALIAS;
3217         } else {
3218                 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3219                         DEBUG(10, ("lookup on Server SID\n"));
3220                         if(!get_local_group_from_sid(als_sid, &map))
3221                                 return NT_STATUS_NO_SUCH_ALIAS;
3222                 }
3223         }
3224
3225         if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3226                 return NT_STATUS_NO_SUCH_ALIAS;
3227
3228         DEBUG(10, ("sid is %s\n", alias_sid_str));
3229         sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids); 
3230         if (num_uids!=0 && sid == NULL) 
3231                 return NT_STATUS_NO_MEMORY;
3232
3233         for (i = 0; i < num_uids; i++) {
3234                 struct passwd *pass;
3235                 uint32 rid;
3236
3237                 sid_copy(&temp_sid, get_global_sam_sid());
3238
3239                 pass = getpwuid_alloc(uid[i]);
3240                 if (!pass) continue;
3241
3242                 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3243                         passwd_free(&pass);
3244                         continue;
3245                 }
3246
3247                 become_root();
3248                 check = pdb_getsampwnam(sam_user, pass->pw_name);
3249                 unbecome_root();
3250         
3251                 if (check != True) {
3252                         pdb_free_sam(&sam_user);
3253                         passwd_free(&pass);
3254                         continue;
3255                 }
3256         
3257                 rid = pdb_get_user_rid(sam_user);
3258                 if (rid == 0) {
3259                         pdb_free_sam(&sam_user);
3260                         passwd_free(&pass);
3261                         continue;
3262                 }
3263
3264                 pdb_free_sam(&sam_user);
3265                 passwd_free(&pass);
3266
3267                 sid_append_rid(&temp_sid, rid);
3268                 
3269                 init_dom_sid2(&sid[i], &temp_sid);
3270         }
3271
3272         DEBUG(10, ("sid is %s\n", alias_sid_str));
3273         init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3274
3275         return NT_STATUS_OK;
3276 }
3277
3278 /*********************************************************************
3279  _samr_query_groupmem
3280 *********************************************************************/
3281
3282 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3283 {
3284         int num_uids = 0;
3285         int i;
3286         DOM_SID group_sid;
3287         uint32 group_rid;
3288         fstring group_sid_str;
3289         uid_t *uid=NULL;
3290         
3291         GROUP_MAP map;
3292
3293         uint32 *rid=NULL;
3294         uint32 *attr=NULL;
3295
3296         SAM_ACCOUNT *sam_user = NULL;
3297         BOOL check;
3298         uint32 acc_granted;
3299
3300         /* find the policy handle.  open a policy on it. */
3301         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3302                 return NT_STATUS_INVALID_HANDLE;
3303                 
3304         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3305                 return r_u->status;
3306         }
3307                 
3308         /* todo: change to use sid_compare_front */
3309
3310         sid_split_rid(&group_sid, &group_rid);
3311         sid_to_string(group_sid_str, &group_sid);
3312         DEBUG(10, ("sid is %s\n", group_sid_str));
3313
3314         /* can we get a query for an SID outside our domain ? */
3315         if (!sid_equal(&group_sid, get_global_sam_sid()))
3316                 return NT_STATUS_NO_SUCH_GROUP;
3317
3318         sid_append_rid(&group_sid, group_rid);
3319         DEBUG(10, ("lookup on Domain SID\n"));
3320
3321         if(!get_domain_group_from_sid(group_sid, &map))
3322                 return NT_STATUS_NO_SUCH_GROUP;
3323
3324         if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3325                 return NT_STATUS_NO_SUCH_GROUP;
3326
3327         rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3328         attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3329         
3330         if (num_uids!=0 && (rid==NULL || attr==NULL))
3331                 return NT_STATUS_NO_MEMORY;
3332         
3333         for (i=0; i<num_uids; i++) {
3334                 struct passwd *pass;
3335                 uint32 urid;
3336
3337                 pass = getpwuid_alloc(uid[i]);
3338                 if (!pass) continue;
3339
3340                 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3341                         passwd_free(&pass);
3342                         continue;
3343                 }
3344
3345                 become_root();
3346                 check = pdb_getsampwnam(sam_user, pass->pw_name);
3347                 unbecome_root();
3348         
3349                 if (check != True) {
3350                         pdb_free_sam(&sam_user);
3351                         passwd_free(&pass);
3352                         continue;
3353                 }
3354         
3355                 urid = pdb_get_user_rid(sam_user);
3356                 if (urid == 0) {
3357                         pdb_free_sam(&sam_user);
3358                         passwd_free(&pass);
3359                         continue;
3360                 }
3361
3362                 pdb_free_sam(&sam_user);
3363                 passwd_free(&pass);
3364
3365                 rid[i] = urid;
3366                 attr[i] = SID_NAME_USER;                
3367         }
3368
3369         init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3370
3371         return NT_STATUS_OK;
3372 }
3373
3374 /*********************************************************************
3375  _samr_add_aliasmem
3376 *********************************************************************/
3377
3378 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3379 {
3380         DOM_SID alias_sid;
3381         fstring alias_sid_str;
3382         uid_t uid;
3383         struct passwd *pwd;
3384         struct group *grp;
3385         fstring grp_name;
3386         GROUP_MAP map;
3387         NTSTATUS ret;
3388         SAM_ACCOUNT *sam_user = NULL;
3389         BOOL check;
3390         uint32 acc_granted;
3391
3392         /* Find the policy handle. Open a policy on it. */
3393         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3394                 return NT_STATUS_INVALID_HANDLE;
3395         
3396         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3397                 return r_u->status;
3398         }
3399                 
3400         sid_to_string(alias_sid_str, &alias_sid);
3401         DEBUG(10, ("sid is %s\n", alias_sid_str));
3402
3403         if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3404                 DEBUG(10, ("adding member on Server SID\n"));
3405                 if(!get_local_group_from_sid(alias_sid, &map))
3406                         return NT_STATUS_NO_SUCH_ALIAS;
3407         
3408         } else {
3409                 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3410                         DEBUG(10, ("adding member on BUILTIN SID\n"));
3411                         if( !get_local_group_from_sid(alias_sid, &map))
3412                                 return NT_STATUS_NO_SUCH_ALIAS;
3413
3414                 } else
3415                         return NT_STATUS_NO_SUCH_ALIAS;
3416         }
3417
3418         ret = pdb_init_sam(&sam_user);
3419         if (!NT_STATUS_IS_OK(ret))
3420                 return ret;
3421         
3422         check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3423         
3424         if (check != True) {
3425                 pdb_free_sam(&sam_user);
3426                 return NT_STATUS_NO_SUCH_USER;
3427         }
3428
3429         /* check a real user exist before we run the script to add a user to a group */
3430         if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3431                 pdb_free_sam(&sam_user);
3432                 return NT_STATUS_NO_SUCH_USER;
3433         }
3434
3435         pdb_free_sam(&sam_user);
3436
3437         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3438                 return NT_STATUS_NO_SUCH_USER;
3439         }
3440         
3441         if ((grp=getgrgid(map.gid)) == NULL) {
3442                 passwd_free(&pwd);
3443                 return NT_STATUS_NO_SUCH_ALIAS;
3444         }
3445
3446         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3447         fstrcpy(grp_name, grp->gr_name);
3448
3449         /* if the user is already in the group */
3450         if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3451                 passwd_free(&pwd);
3452                 return NT_STATUS_MEMBER_IN_ALIAS;
3453         }
3454
3455         /* 
3456          * ok, the group exist, the user exist, the user is not in the group,
3457          * we can (finally) add it to the group !
3458          */
3459         smb_add_user_group(grp_name, pwd->pw_name);
3460
3461         /* check if the user has been added then ... */
3462         if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3463                 passwd_free(&pwd);
3464                 return NT_STATUS_MEMBER_NOT_IN_ALIAS;   /* don't know what to reply else */
3465         }
3466
3467         passwd_free(&pwd);
3468         return NT_STATUS_OK;
3469 }
3470
3471 /*********************************************************************
3472  _samr_del_aliasmem
3473 *********************************************************************/
3474
3475 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3476 {
3477         DOM_SID alias_sid;
3478         fstring alias_sid_str;
3479         struct group *grp;
3480         fstring grp_name;
3481         GROUP_MAP map;
3482         SAM_ACCOUNT *sam_pass=NULL;
3483         uint32 acc_granted;
3484
3485         /* Find the policy handle. Open a policy on it. */
3486         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3487                 return NT_STATUS_INVALID_HANDLE;
3488         
3489         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3490                 return r_u->status;
3491         }
3492         
3493         sid_to_string(alias_sid_str, &alias_sid);
3494         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3495
3496         if (!sid_check_is_in_our_domain(&alias_sid) &&
3497             !sid_check_is_in_builtin(&alias_sid)) {
3498                 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3499                 return NT_STATUS_NO_SUCH_ALIAS;
3500         }
3501
3502         if( !get_local_group_from_sid(alias_sid, &map))
3503                 return NT_STATUS_NO_SUCH_ALIAS;
3504
3505         if ((grp=getgrgid(map.gid)) == NULL)
3506                 return NT_STATUS_NO_SUCH_ALIAS;
3507
3508         /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3509         fstrcpy(grp_name, grp->gr_name);
3510
3511         /* check if the user exists before trying to remove it from the group */
3512         pdb_init_sam(&sam_pass);
3513         if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3514                 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3515                 pdb_free_sam(&sam_pass);
3516                 return NT_STATUS_NO_SUCH_USER;
3517         }
3518
3519         /* if the user is not in the group */
3520         if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3521                 pdb_free_sam(&sam_pass);
3522                 return NT_STATUS_MEMBER_IN_ALIAS;
3523         }
3524
3525         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3526
3527         /* check if the user has been removed then ... */
3528         if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3529                 pdb_free_sam(&sam_pass);
3530                 return NT_STATUS_MEMBER_NOT_IN_ALIAS;   /* don't know what to reply else */
3531         }
3532
3533         pdb_free_sam(&sam_pass);
3534         return NT_STATUS_OK;
3535 }
3536
3537 /*********************************************************************
3538  _samr_add_groupmem
3539 *********************************************************************/
3540
3541 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3542 {
3543         DOM_SID group_sid;
3544         DOM_SID user_sid;
3545         fstring group_sid_str;
3546         uid_t uid;
3547         struct passwd *pwd;
3548         struct group *grp;
3549         fstring grp_name;
3550         GROUP_MAP map;
3551         NTSTATUS ret;
3552         SAM_ACCOUNT *sam_user=NULL;
3553         BOOL check;
3554         uint32 acc_granted;
3555
3556         /* Find the policy handle. Open a policy on it. */
3557         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3558                 return NT_STATUS_INVALID_HANDLE;
3559         
3560         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3561                 return r_u->status;
3562         }
3563
3564         sid_to_string(group_sid_str, &group_sid);
3565         DEBUG(10, ("sid is %s\n", group_sid_str));
3566
3567         if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3568                 return NT_STATUS_NO_SUCH_GROUP;
3569
3570         DEBUG(10, ("lookup on Domain SID\n"));
3571
3572         if(!get_domain_group_from_sid(group_sid, &map))
3573                 return NT_STATUS_NO_SUCH_GROUP;
3574
3575         sid_copy(&user_sid, get_global_sam_sid());
3576         sid_append_rid(&user_sid, q_u->rid);
3577
3578         ret = pdb_init_sam(&sam_user);
3579         if (!NT_STATUS_IS_OK(ret))
3580                 return ret;
3581         
3582         check = pdb_getsampwsid(sam_user, &user_sid);
3583         
3584         if (check != True) {
3585                 pdb_free_sam(&sam_user);
3586                 return NT_STATUS_NO_SUCH_USER;
3587         }
3588
3589         /* check a real user exist before we run the script to add a user to a group */
3590         if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3591                 pdb_free_sam(&sam_user);
3592                 return NT_STATUS_NO_SUCH_USER;
3593         }
3594
3595         pdb_free_sam(&sam_user);
3596
3597         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3598                 return NT_STATUS_NO_SUCH_USER;
3599         }
3600
3601         if ((grp=getgrgid(map.gid)) == NULL) {
3602                 passwd_free(&pwd);
3603                 return NT_STATUS_NO_SUCH_GROUP;
3604         }
3605
3606         /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3607         fstrcpy(grp_name, grp->gr_name);
3608
3609         /* if the user is already in the group */
3610         if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3611                 passwd_free(&pwd);
3612                 return NT_STATUS_MEMBER_IN_GROUP;
3613         }
3614
3615         /* 
3616          * ok, the group exist, the user exist, the user is not in the group,
3617          *
3618          * we can (finally) add it to the group !
3619          */
3620
3621         smb_add_user_group(grp_name, pwd->pw_name);
3622
3623         /* check if the user has been added then ... */
3624         if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3625                 passwd_free(&pwd);
3626                 return NT_STATUS_MEMBER_NOT_IN_GROUP;           /* don't know what to reply else */
3627         }
3628
3629         passwd_free(&pwd);
3630         return NT_STATUS_OK;
3631 }
3632
3633 /*********************************************************************
3634  _samr_del_groupmem
3635 *********************************************************************/
3636
3637 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3638 {
3639         DOM_SID group_sid;
3640         DOM_SID user_sid;
3641         SAM_ACCOUNT *sam_pass=NULL;
3642         GROUP_MAP map;
3643         fstring grp_name;
3644         struct group *grp;
3645         uint32 acc_granted;
3646
3647         /*
3648          * delete the group member named q_u->rid
3649          * who is a member of the sid associated with the handle
3650          * the rid is a user's rid as the group is a domain group.
3651          */
3652
3653         /* Find the policy handle. Open a policy on it. */
3654         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3655                 return NT_STATUS_INVALID_HANDLE;
3656         
3657         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3658                 return r_u->status;
3659         }
3660                 
3661         if (!sid_check_is_in_our_domain(&group_sid))
3662                 return NT_STATUS_NO_SUCH_GROUP;
3663
3664         sid_copy(&user_sid, get_global_sam_sid());
3665         sid_append_rid(&user_sid, q_u->rid);
3666
3667         if (!get_domain_group_from_sid(group_sid, &map))
3668                 return NT_STATUS_NO_SUCH_GROUP;
3669
3670         if ((grp=getgrgid(map.gid)) == NULL)
3671                 return NT_STATUS_NO_SUCH_GROUP;
3672
3673         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3674         fstrcpy(grp_name, grp->gr_name);
3675
3676         /* check if the user exists before trying to remove it from the group */
3677         pdb_init_sam(&sam_pass);
3678         if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3679                 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3680                 pdb_free_sam(&sam_pass);
3681                 return NT_STATUS_NO_SUCH_USER;
3682         }
3683
3684         /* if the user is not in the group */
3685         if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3686                 pdb_free_sam(&sam_pass);
3687                 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3688         }
3689
3690         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3691
3692         /* check if the user has been removed then ... */
3693         if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3694                 pdb_free_sam(&sam_pass);
3695                 return NT_STATUS_ACCESS_DENIED;         /* don't know what to reply else */
3696         }
3697         
3698         pdb_free_sam(&sam_pass);
3699         return NT_STATUS_OK;
3700
3701 }
3702
3703 /****************************************************************************
3704  Delete a UNIX user on demand.
3705 ****************************************************************************/
3706
3707 static int smb_delete_user(const char *unix_user)
3708 {
3709         pstring del_script;
3710         int ret;
3711
3712         pstrcpy(del_script, lp_deluser_script());
3713         if (! *del_script)
3714                 return -1;
3715         all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3716         ret = smbrun(del_script,NULL);
3717         DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3718         return ret;
3719 }
3720
3721 /*********************************************************************
3722  _samr_delete_dom_user
3723 *********************************************************************/
3724
3725 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3726 {
3727         DOM_SID user_sid;
3728         SAM_ACCOUNT *sam_pass=NULL;
3729         uint32 acc_granted;
3730
3731         DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3732
3733         /* Find the policy handle. Open a policy on it. */
3734         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted)) 
3735                 return NT_STATUS_INVALID_HANDLE;
3736                 
3737         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3738                 return r_u->status;
3739         }
3740                 
3741         if (!sid_check_is_in_our_domain(&user_sid))
3742                 return NT_STATUS_CANNOT_DELETE;
3743
3744         /* check if the user exists before trying to delete */
3745         pdb_init_sam(&sam_pass);
3746         if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3747                 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3748                 pdb_free_sam(&sam_pass);
3749                 return NT_STATUS_NO_SUCH_USER;
3750         }
3751
3752         /* delete the unix side */
3753         /*
3754          * note: we don't check if the delete really happened
3755          * as the script is not necessary present
3756          * and maybe the sysadmin doesn't want to delete the unix side
3757          */
3758         smb_delete_user(pdb_get_username(sam_pass));
3759
3760         /* and delete the samba side */
3761         if (!pdb_delete_sam_account(sam_pass)) {
3762                 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3763                 pdb_free_sam(&sam_pass);
3764                 return NT_STATUS_CANNOT_DELETE;
3765         }
3766         
3767         pdb_free_sam(&sam_pass);
3768
3769         if (!close_policy_hnd(p, &q_u->user_pol))
3770                 return NT_STATUS_OBJECT_NAME_INVALID;
3771
3772         return NT_STATUS_OK;
3773 }
3774
3775 /*********************************************************************
3776  _samr_delete_dom_group
3777 *********************************************************************/
3778
3779 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3780 {
3781         DOM_SID group_sid;
3782         DOM_SID dom_sid;
3783         uint32 group_rid;
3784         fstring group_sid_str;
3785         gid_t gid;
3786         struct group *grp;
3787         GROUP_MAP map;
3788         uint32 acc_granted;
3789
3790         DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3791
3792         /* Find the policy handle. Open a policy on it. */
3793         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3794                 return NT_STATUS_INVALID_HANDLE;
3795                 
3796         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3797                 return r_u->status;
3798         }
3799                 
3800         sid_copy(&dom_sid, &group_sid);
3801         sid_to_string(group_sid_str, &dom_sid);
3802         sid_split_rid(&dom_sid, &group_rid);
3803
3804         DEBUG(10, ("sid is %s\n", group_sid_str));
3805
3806         /* we check if it's our SID before deleting */
3807         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3808                 return NT_STATUS_NO_SUCH_GROUP;
3809
3810         DEBUG(10, ("lookup on Domain SID\n"));
3811
3812         if(!get_domain_group_from_sid(group_sid, &map))
3813                 return NT_STATUS_NO_SUCH_GROUP;
3814
3815         gid=map.gid;
3816
3817         /* check if group really exists */
3818         if ( (grp=getgrgid(gid)) == NULL)
3819                 return NT_STATUS_NO_SUCH_GROUP;
3820
3821         /* we can delete the UNIX group */
3822         smb_delete_group(grp->gr_name);
3823
3824         /* check if the group has been successfully deleted */
3825         if ( (grp=getgrgid(gid)) != NULL)
3826                 return NT_STATUS_ACCESS_DENIED;
3827
3828         if(!pdb_delete_group_mapping_entry(group_sid))
3829                 return NT_STATUS_ACCESS_DENIED;
3830
3831         if (!close_policy_hnd(p, &q_u->group_pol))
3832                 return NT_STATUS_OBJECT_NAME_INVALID;
3833
3834         return NT_STATUS_OK;
3835 }
3836
3837 /*********************************************************************
3838  _samr_delete_dom_alias
3839 *********************************************************************/
3840
3841 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3842 {
3843         DOM_SID alias_sid;
3844         DOM_SID dom_sid;
3845         uint32 alias_rid;
3846         fstring alias_sid_str;
3847         gid_t gid;
3848         struct group *grp;
3849         GROUP_MAP map;
3850         uint32 acc_granted;
3851
3852         DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3853
3854         /* Find the policy handle. Open a policy on it. */
3855         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3856                 return NT_STATUS_INVALID_HANDLE;
3857         
3858         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3859                 return r_u->status;
3860         }
3861                 
3862         sid_copy(&dom_sid, &alias_sid);
3863         sid_to_string(alias_sid_str, &dom_sid);
3864         sid_split_rid(&dom_sid, &alias_rid);
3865
3866         DEBUG(10, ("sid is %s\n", alias_sid_str));
3867
3868         /* we check if it's our SID before deleting */
3869         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3870                 return NT_STATUS_NO_SUCH_ALIAS;
3871
3872         DEBUG(10, ("lookup on Local SID\n"));
3873
3874         if(!get_local_group_from_sid(alias_sid, &map))
3875                 return NT_STATUS_NO_SUCH_ALIAS;
3876
3877         gid=map.gid;
3878
3879         /* check if group really exists */
3880         if ( (grp=getgrgid(gid)) == NULL)
3881                 return NT_STATUS_NO_SUCH_ALIAS;
3882
3883         /* we can delete the UNIX group */
3884         smb_delete_group(grp->gr_name);
3885
3886         /* check if the group has been successfully deleted */
3887         if ( (grp=getgrgid(gid)) != NULL)
3888                 return NT_STATUS_ACCESS_DENIED;
3889
3890         /* don't check if we removed it as it could be an un-mapped group */
3891         pdb_delete_group_mapping_entry(alias_sid);
3892
3893         if (!close_policy_hnd(p, &q_u->alias_pol))
3894                 return NT_STATUS_OBJECT_NAME_INVALID;
3895
3896         return NT_STATUS_OK;
3897 }
3898
3899 /*********************************************************************
3900  _samr_create_dom_group
3901 *********************************************************************/
3902
3903 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3904 {
3905         DOM_SID dom_sid;
3906         DOM_SID info_sid;
3907         fstring name;
3908         fstring sid_string;
3909         struct group *grp;
3910         struct samr_info *info;
3911         uint32 acc_granted;
3912         gid_t gid;
3913
3914         /* Find the policy handle. Open a policy on it. */
3915         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted)) 
3916                 return NT_STATUS_INVALID_HANDLE;
3917         
3918         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3919                 return r_u->status;
3920         }
3921                 
3922         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3923                 return NT_STATUS_ACCESS_DENIED;
3924
3925         /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3926
3927         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3928
3929         /* check if group already exist */
3930         if ((grp=getgrnam(name)) != NULL)
3931                 return NT_STATUS_GROUP_EXISTS;
3932
3933         /* we can create the UNIX group */
3934         if (smb_create_group(name, &gid) != 0)
3935                 return NT_STATUS_ACCESS_DENIED;
3936
3937         /* check if the group has been successfully created */
3938         if ((grp=getgrgid(gid)) == NULL)
3939                 return NT_STATUS_ACCESS_DENIED;
3940
3941         r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3942
3943         /* add the group to the mapping table */
3944         sid_copy(&info_sid, get_global_sam_sid());
3945         sid_append_rid(&info_sid, r_u->rid);
3946         sid_to_string(sid_string, &info_sid);
3947
3948         if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3949                 return NT_STATUS_ACCESS_DENIED;
3950
3951         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3952                 return NT_STATUS_NO_MEMORY;
3953
3954         /* get a (unique) handle.  open a policy on it. */
3955         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3956                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3957
3958         return NT_STATUS_OK;
3959 }
3960
3961 /*********************************************************************
3962  _samr_create_dom_alias
3963 *********************************************************************/
3964
3965 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3966 {
3967         DOM_SID dom_sid;
3968         DOM_SID info_sid;
3969         fstring name;
3970         fstring sid_string;
3971         struct group *grp;
3972         struct samr_info *info;
3973         uint32 acc_granted;
3974         gid_t gid;
3975
3976         /* Find the policy handle. Open a policy on it. */
3977         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) 
3978                 return NT_STATUS_INVALID_HANDLE;
3979                 
3980         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3981                 return r_u->status;
3982         }
3983                 
3984         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3985                 return NT_STATUS_ACCESS_DENIED;
3986
3987         /* TODO: check if allowed to create group  and add a become_root/unbecome_root pair.*/
3988
3989         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3990
3991         /* check if group already exists */
3992         if ( (grp=getgrnam(name)) != NULL)
3993                 return NT_STATUS_GROUP_EXISTS;
3994
3995         /* we can create the UNIX group */
3996         if (smb_create_group(name, &gid) != 0)
3997                 return NT_STATUS_ACCESS_DENIED;
3998
3999         /* check if the group has been successfully created */
4000         if ((grp=getgrgid(gid)) == NULL)
4001                 return NT_STATUS_ACCESS_DENIED;
4002
4003         r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
4004
4005         sid_copy(&info_sid, get_global_sam_sid());
4006         sid_append_rid(&info_sid, r_u->rid);
4007         sid_to_string(sid_string, &info_sid);
4008
4009         /* add the group to the mapping table */
4010         if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL))
4011                 return NT_STATUS_ACCESS_DENIED;
4012
4013         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4014                 return NT_STATUS_NO_MEMORY;
4015
4016         /* get a (unique) handle.  open a policy on it. */
4017         if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4018                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4019
4020         return NT_STATUS_OK;
4021 }
4022
4023 /*********************************************************************
4024  _samr_query_groupinfo
4025
4026 sends the name/comment pair of a domain group
4027 level 1 send also the number of users of that group
4028 *********************************************************************/
4029
4030 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4031 {
4032         DOM_SID group_sid;
4033         GROUP_MAP map;
4034         uid_t *uid=NULL;
4035         int num_uids=0;
4036         GROUP_INFO_CTR *ctr;
4037         uint32 acc_granted;
4038
4039         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
4040                 return NT_STATUS_INVALID_HANDLE;
4041         
4042         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4043                 return r_u->status;
4044         }
4045                 
4046         if (!get_domain_group_from_sid(group_sid, &map))
4047                 return NT_STATUS_INVALID_HANDLE;
4048
4049         ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4050         if (ctr==NULL)
4051                 return NT_STATUS_NO_MEMORY;
4052
4053         switch (q_u->switch_level) {
4054                 case 1:
4055                         ctr->switch_value1 = 1;
4056                         if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4057                                 return NT_STATUS_NO_SUCH_GROUP;
4058                         init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4059                         SAFE_FREE(uid);
4060                         break;
4061                 case 3:
4062                         ctr->switch_value1 = 3;
4063                         init_samr_group_info3(&ctr->group.info3);
4064                         break;
4065                 case 4:
4066                         ctr->switch_value1 = 4;
4067                         init_samr_group_info4(&ctr->group.info4, map.comment);
4068                         break;
4069                 default:
4070                         return NT_STATUS_INVALID_INFO_CLASS;
4071         }
4072
4073         init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4074
4075         return NT_STATUS_OK;
4076 }
4077
4078 /*********************************************************************
4079  _samr_set_groupinfo
4080  
4081  update a domain group's comment.
4082 *********************************************************************/
4083
4084 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4085 {
4086         DOM_SID group_sid;
4087         GROUP_MAP map;
4088         GROUP_INFO_CTR *ctr;
4089         uint32 acc_granted;
4090
4091         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4092                 return NT_STATUS_INVALID_HANDLE;
4093         
4094         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4095                 return r_u->status;
4096         }
4097                 
4098         if (!get_domain_group_from_sid(group_sid, &map))
4099                 return NT_STATUS_NO_SUCH_GROUP;
4100         
4101         ctr=q_u->ctr;
4102
4103         switch (ctr->switch_value1) {
4104                 case 1:
4105                         unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4106                         break;
4107                 case 4:
4108                         unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4109                         break;
4110                 default:
4111                         return NT_STATUS_INVALID_INFO_CLASS;
4112         }
4113
4114         if(!pdb_update_group_mapping_entry(&map)) {
4115                 return NT_STATUS_NO_SUCH_GROUP;
4116         }
4117
4118         return NT_STATUS_OK;
4119 }
4120
4121 /*********************************************************************
4122  _samr_set_aliasinfo
4123  
4124  update an alias's comment.
4125 *********************************************************************/
4126
4127 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4128 {
4129         DOM_SID group_sid;
4130         GROUP_MAP map;
4131         ALIAS_INFO_CTR *ctr;
4132         uint32 acc_granted;
4133
4134         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4135                 return NT_STATUS_INVALID_HANDLE;
4136         
4137         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4138                 return r_u->status;
4139         }
4140                 
4141         if (!get_local_group_from_sid(group_sid, &map))
4142                 return NT_STATUS_NO_SUCH_GROUP;
4143         
4144         ctr=&q_u->ctr;
4145
4146         switch (ctr->switch_value1) {
4147                 case 3:
4148                         unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4149                         break;
4150                 default:
4151                         return NT_STATUS_INVALID_INFO_CLASS;
4152         }
4153
4154         if(!pdb_update_group_mapping_entry(&map)) {
4155                 return NT_STATUS_NO_SUCH_GROUP;
4156         }
4157
4158         return NT_STATUS_OK;
4159 }
4160
4161 /*********************************************************************
4162  _samr_get_dom_pwinfo
4163 *********************************************************************/
4164
4165 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4166 {
4167         /* Perform access check.  Since this rpc does not require a
4168            policy handle it will not be caught by the access checks on
4169            SAMR_CONNECT or SAMR_CONNECT_ANON. */
4170
4171         if (!pipe_access_check(p)) {
4172                 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4173                 r_u->status = NT_STATUS_ACCESS_DENIED;
4174                 return r_u->status;
4175         }
4176
4177         /* Actually, returning zeros here works quite well :-). */
4178
4179         return NT_STATUS_OK;
4180 }
4181
4182 /*********************************************************************
4183  _samr_open_group
4184 *********************************************************************/
4185
4186 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4187 {
4188         DOM_SID sid;
4189         DOM_SID info_sid;
4190         GROUP_MAP map;
4191         struct samr_info *info;
4192         SEC_DESC         *psd = NULL;
4193         uint32            acc_granted;
4194         uint32            des_access;
4195         size_t            sd_size;
4196         NTSTATUS          status;
4197         fstring sid_string;
4198
4199         if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted)) 
4200                 return NT_STATUS_INVALID_HANDLE;
4201         
4202         if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4203                 return status;
4204         }
4205                 
4206         /*check if access can be granted as requested by client. */
4207         samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4208         se_map_generic(&des_access,&grp_generic_mapping);
4209         if (!NT_STATUS_IS_OK(status = 
4210                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
4211                                                       des_access, &acc_granted, "_samr_open_group"))) {
4212                 return status;
4213         }
4214
4215
4216         /* this should not be hard-coded like this */
4217         if (!sid_equal(&sid, get_global_sam_sid()))
4218                 return NT_STATUS_ACCESS_DENIED;
4219
4220         sid_copy(&info_sid, get_global_sam_sid());
4221         sid_append_rid(&info_sid, q_u->rid_group);
4222         sid_to_string(sid_string, &info_sid);
4223
4224         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4225                 return NT_STATUS_NO_MEMORY;
4226                 
4227         info->acc_granted = acc_granted;
4228
4229         DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4230
4231         /* check if that group really exists */
4232         if (!get_domain_group_from_sid(info->sid, &map))
4233                 return NT_STATUS_NO_SUCH_GROUP;
4234
4235         /* get a (unique) handle.  open a policy on it. */
4236         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4237                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4238
4239         return NT_STATUS_OK;
4240 }
4241
4242 /*********************************************************************
4243  _samr_unknown_2d
4244 *********************************************************************/
4245
4246 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
4247 {
4248         DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4249         return NT_STATUS_NOT_IMPLEMENTED;
4250 }
4251
4252 /*******************************************************************
4253  _samr_unknown_2e
4254  ********************************************************************/
4255
4256 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4257 {
4258         struct samr_info *info = NULL;
4259         SAM_UNK_CTR *ctr;
4260         uint32 min_pass_len,pass_hist,flag;
4261         time_t u_expire, u_min_age;
4262         NTTIME nt_expire, nt_min_age;
4263
4264         time_t u_lock_duration, u_reset_time;
4265         NTTIME nt_lock_duration, nt_reset_time;
4266         uint32 lockout;
4267         
4268         time_t u_logout;
4269         NTTIME nt_logout;
4270
4271         uint32 num_users=0, num_groups=0, num_aliases=0;
4272
4273         uint32 account_policy_temp;
4274
4275         if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4276                 return NT_STATUS_NO_MEMORY;
4277
4278         ZERO_STRUCTP(ctr);
4279
4280         r_u->status = NT_STATUS_OK;
4281
4282         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4283
4284         /* find the policy handle.  open a policy on it. */
4285         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4286                 return NT_STATUS_INVALID_HANDLE;
4287
4288         switch (q_u->switch_value) {
4289                 case 0x01:
4290                         account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4291                         min_pass_len = account_policy_temp;
4292
4293                         account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4294                         pass_hist = account_policy_temp;
4295
4296                         account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4297                         flag = account_policy_temp;
4298
4299                         account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4300                         u_expire = account_policy_temp;
4301
4302                         account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4303                         u_min_age = account_policy_temp;
4304
4305                         unix_to_nt_time_abs(&nt_expire, u_expire);
4306                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
4307
4308                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
4309                                        flag, nt_expire, nt_min_age);
4310                         break;
4311                 case 0x02:
4312                         become_root();          
4313                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4314                         unbecome_root();
4315                         if (!NT_STATUS_IS_OK(r_u->status)) {
4316                                 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4317                                 return r_u->status;
4318                         }
4319                         num_users=info->disp_info.num_user_account;
4320                         free_samr_db(info);
4321                         
4322                         r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4323                         if (NT_STATUS_IS_ERR(r_u->status)) {
4324                                 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4325                                 return r_u->status;
4326                         }
4327                         num_groups=info->disp_info.num_group_account;
4328                         free_samr_db(info);
4329
4330                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4331                         init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL), 
4332                                        num_users, num_groups, num_aliases);
4333                         break;
4334                 case 0x03:
4335                         account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4336                         u_logout = account_policy_temp;
4337
4338                         unix_to_nt_time_abs(&nt_logout, u_logout);
4339                         
4340                         init_unk_info3(&ctr->info.inf3, nt_logout);
4341                         break;
4342                 case 0x05:
4343                         init_unk_info5(&ctr->info.inf5, global_myname());
4344                         break;
4345                 case 0x06:
4346                         init_unk_info6(&ctr->info.inf6);
4347                         break;
4348                 case 0x07:
4349                         init_unk_info7(&ctr->info.inf7);
4350                         break;
4351                 case 0x0c:
4352                         account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4353                         u_lock_duration = account_policy_temp;
4354
4355                         account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4356                         u_reset_time = account_policy_temp;
4357
4358                         account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4359                         lockout = account_policy_temp;
4360         
4361                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4362                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4363         
4364                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4365                         break;
4366                 default:
4367                         return NT_STATUS_INVALID_INFO_CLASS;
4368         }
4369
4370         init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4371
4372         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4373
4374         return r_u->status;
4375 }
4376
4377 /*******************************************************************
4378  _samr_
4379  ********************************************************************/
4380
4381 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4382 {
4383         time_t u_expire, u_min_age;
4384         time_t u_logout;
4385         time_t u_lock_duration, u_reset_time;
4386
4387         r_u->status = NT_STATUS_OK;
4388
4389         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4390
4391         /* find the policy handle.  open a policy on it. */
4392         if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4393                 return NT_STATUS_INVALID_HANDLE;
4394
4395         DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4396
4397         switch (q_u->switch_value) {
4398                 case 0x01:
4399                         u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4400                         u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4401                         
4402                         account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4403                         account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4404                         account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4405                         account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4406                         account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4407                         break;
4408                 case 0x02:
4409                         break;
4410                 case 0x03:
4411                         u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4412                         account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4413                         break;
4414                 case 0x05:
4415                         break;
4416                 case 0x06:
4417                         break;
4418                 case 0x07:
4419                         break;
4420                 case 0x0c:
4421                         u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4422                         u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4423                         
4424                         account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4425                         account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4426                         account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4427                         break;
4428                 default:
4429                         return NT_STATUS_INVALID_INFO_CLASS;
4430         }
4431
4432         init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4433
4434         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4435
4436         return r_u->status;
4437 }
4438