This is another *BIG* change...
[kai/samba.git] / source3 / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/Netbios implementation.
3  *  Version 1.9.
4  *  RPC Pipe client / server routines
5  *  Copyright (C) Andrew Tridgell              1992-1997,
6  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
7  *  Copyright (C) Paul Ashton                       1997.
8  *  Copyright (C) Marc Jacobsen                     1999.
9  *  Copyright (C) Jeremy Allison               2001-2002.
10  *  Copyright (C) Jean Fran├žois Micouleau      1998-2001.
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  */
26
27 /*
28  * This is the implementation of the SAMR code.
29  */
30
31 #include "includes.h"
32
33 extern fstring global_myworkgroup;
34 extern pstring global_myname;
35 extern DOM_SID global_sam_sid;
36 extern DOM_SID global_sid_Builtin;
37
38 extern rid_name domain_group_rids[];
39 extern rid_name domain_alias_rids[];
40 extern rid_name builtin_alias_rids[];
41
42
43 typedef struct _disp_info {
44         BOOL user_dbloaded;
45         uint32 num_user_account;
46         DISP_USER_INFO *disp_user_info;
47         BOOL group_dbloaded;
48         uint32 num_group_account;
49         DISP_GROUP_INFO *disp_group_info;
50 } DISP_INFO;
51
52 struct samr_info {
53         /* for use by the \PIPE\samr policy */
54         DOM_SID sid;
55         uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
56         DISP_INFO disp_info;
57 };
58
59 /*******************************************************************
60  Create a samr_info struct.
61 ********************************************************************/
62
63 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
64 {
65         struct samr_info *info;
66         fstring sid_str;
67
68         if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
69                 return NULL;
70
71         ZERO_STRUCTP(info);
72         if (psid) {
73                 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_to_string(sid_str, psid) ));
74                 sid_copy( &info->sid, psid);
75         } else {
76                 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
77         }
78         return info;
79 }
80
81 /*******************************************************************
82  Function to free the per handle data.
83  ********************************************************************/
84 static void free_samr_db(struct samr_info *info)
85 {
86         int i;
87
88         if (info->disp_info.group_dbloaded) {
89                 for (i=0; i<info->disp_info.num_group_account; i++)
90                         SAFE_FREE(info->disp_info.disp_group_info[i].grp);
91
92                 SAFE_FREE(info->disp_info.disp_group_info);
93         }
94
95         if (info->disp_info.user_dbloaded){
96                 for (i=0; i<info->disp_info.num_user_account; i++)
97                         pdb_free_sam(&info->disp_info.disp_user_info[i].sam);
98
99                 SAFE_FREE(info->disp_info.disp_user_info);
100         }
101
102         info->disp_info.user_dbloaded=False;
103         info->disp_info.group_dbloaded=False;
104         info->disp_info.num_group_account=0;
105         info->disp_info.num_user_account=0;
106 }
107
108
109 static void free_samr_info(void *ptr)
110 {
111         struct samr_info *info=(struct samr_info *) ptr;
112
113         free_samr_db(info);
114         SAFE_FREE(info);
115 }
116
117 /*******************************************************************
118  Ensure password info is never given out. Paranioa... JRA.
119  ********************************************************************/
120
121 static void samr_clear_passwd_fields( SAM_USER_INFO_21 *pass, int num_entries)
122 {
123         int i;
124
125         if (!pass)
126                 return;
127
128         for (i = 0; i < num_entries; i++) {
129                 memset(&pass[i].lm_pwd, '\0', sizeof(pass[i].lm_pwd));
130                 memset(&pass[i].nt_pwd, '\0', sizeof(pass[i].nt_pwd));
131         }
132 }
133
134 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
135 {
136         
137         if (!sam_pass)
138                 return;
139
140         /* These now zero out the old password */
141
142         pdb_set_lanman_passwd(sam_pass, NULL);
143         pdb_set_nt_passwd(sam_pass, NULL);
144 }
145
146
147 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask)
148 {
149         SAM_ACCOUNT *pwd = NULL;
150         DISP_USER_INFO *pwd_array = NULL;
151
152         DEBUG(10,("load_sampwd_entries\n"));
153
154         /* if the snapshoot is already loaded, return */
155         if (info->disp_info.user_dbloaded==True) {
156                 DEBUG(10,("load_sampwd_entries: already in memory\n"));
157                 return NT_STATUS_OK;
158         }
159
160         if (!pdb_setsampwent(False)) {
161                 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
162                 return NT_STATUS_ACCESS_DENIED;
163         }
164
165         for (pdb_init_sam(&pwd); pdb_getsampwent(pwd) == True; pwd=NULL, pdb_init_sam(&pwd) ) {
166                 
167                 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
168                         pdb_free_sam(&pwd);
169                         DEBUG(5,(" acb_mask %x reject\n", acb_mask));
170                         continue;
171                 }
172
173                 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
174                 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
175                 
176                         DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
177                         pwd_array=(DISP_USER_INFO *)Realloc(info->disp_info.disp_user_info, 
178                                           (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO));
179
180                         if (pwd_array==NULL)
181                                 return NT_STATUS_NO_MEMORY;
182
183                         info->disp_info.disp_user_info=pwd_array;
184                 }
185         
186                 /* link the SAM_ACCOUNT to the array */
187                 info->disp_info.disp_user_info[info->disp_info.num_user_account].sam=pwd;
188
189                 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
190
191                 info->disp_info.num_user_account++;     
192         }
193
194         pdb_endsampwent();
195
196         /* the snapshoot is in memory, we're ready to enumerate fast */
197
198         info->disp_info.user_dbloaded=True;
199
200         DEBUG(12,("load_sampwd_entries: done\n"));
201
202         return NT_STATUS_OK;
203 }
204
205 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
206 {
207         GROUP_MAP *map=NULL;
208         DISP_GROUP_INFO *grp_array = NULL;
209         uint32 group_entries = 0;
210         uint32 i;
211
212         DEBUG(10,("load_group_domain_entries\n"));
213
214         /* if the snapshoot is already loaded, return */
215         if (info->disp_info.group_dbloaded==True) {
216                 DEBUG(10,("load_group_domain_entries: already in memory\n"));
217                 return NT_STATUS_OK;
218         }
219
220         enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
221
222         info->disp_info.num_group_account=group_entries;
223
224         grp_array=(DISP_GROUP_INFO *)malloc(info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO));
225
226         if (group_entries!=0 && grp_array==NULL) {
227                 SAFE_FREE(map);
228                 return NT_STATUS_NO_MEMORY;
229         }
230
231         info->disp_info.disp_group_info=grp_array;
232
233         for (i=0; i<group_entries; i++) {
234         
235                 grp_array[i].grp=(DOMAIN_GRP *)malloc(sizeof(DOMAIN_GRP));
236         
237                 fstrcpy(grp_array[i].grp->name, map[i].nt_name);
238                 fstrcpy(grp_array[i].grp->comment, map[i].comment);
239                 sid_split_rid(&map[i].sid, &grp_array[i].grp->rid);
240                 grp_array[i].grp->attr=SID_NAME_DOM_GRP;
241         }
242
243         SAFE_FREE(map);
244
245         /* the snapshoot is in memory, we're ready to enumerate fast */
246
247         info->disp_info.group_dbloaded=True;
248
249         DEBUG(12,("load_group_domain_entries: done\n"));
250
251         return NT_STATUS_OK;
252 }
253
254
255 /*******************************************************************
256   This next function should be replaced with something that
257   dynamically returns the correct user info..... JRA.
258  ********************************************************************/
259
260 static NTSTATUS get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
261                                 int *total_entries, int *num_entries,
262                                 int max_num_entries, uint16 acb_mask)
263 {
264         SAM_ACCOUNT *pwd = NULL;
265         BOOL not_finished = True;
266  
267         (*num_entries) = 0;
268         (*total_entries) = 0;
269
270         if (pw_buf == NULL)
271                 return NT_STATUS_NO_MEMORY;
272
273         pdb_init_sam(&pwd);
274
275         if (!pdb_setsampwent(False)) {
276                 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
277                 pdb_free_sam(&pwd);
278                 return NT_STATUS_ACCESS_DENIED;
279         }
280         
281         while (((not_finished = pdb_getsampwent(pwd)) != False) 
282                && (*num_entries) < max_num_entries) 
283         {
284                 int user_name_len;
285                 
286                 if (start_idx > 0) {
287
288                         pdb_reset_sam(pwd);
289
290                         /* skip the requested number of entries.
291                            not very efficient, but hey...  */
292                         start_idx--;
293                         continue;
294                 }
295                 
296                 user_name_len = strlen(pdb_get_username(pwd))+1;
297                 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
298                 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
299                 pw_buf[(*num_entries)].user_rid = pdb_get_user_rid(pwd);
300                 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
301                 
302                 /* Now check if the NT compatible password is available. */
303                 if (pdb_get_nt_passwd(pwd))
304                         memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
305                 
306                 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
307                 
308                 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
309                           (*num_entries), pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
310                 
311                 if (acb_mask == 0 || (pdb_get_acct_ctrl(pwd) & acb_mask)) {
312                         DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
313                         (*num_entries)++;
314                 } else {
315                         DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
316                 }
317
318                 (*total_entries)++;
319                 
320                 pdb_reset_sam(pwd);
321
322         }
323         
324         pdb_endsampwent();
325         pdb_free_sam(&pwd);
326
327         if (not_finished)
328                 return STATUS_MORE_ENTRIES;
329         else
330                 return NT_STATUS_OK;
331 }
332
333 /*******************************************************************
334  _samr_close_hnd
335  ********************************************************************/
336
337 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
338 {
339         r_u->status = NT_STATUS_OK;
340
341         /* close the policy handle */
342         if (!close_policy_hnd(p, &q_u->pol))
343                 return NT_STATUS_OBJECT_NAME_INVALID;
344
345         DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
346
347         return r_u->status;
348 }
349
350 /*******************************************************************
351  samr_reply_open_domain
352  ********************************************************************/
353
354 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
355 {
356         struct samr_info *info;
357
358         r_u->status = NT_STATUS_OK;
359
360         /* find the connection policy handle. */
361         if (!find_policy_by_hnd(p, &q_u->pol, NULL))
362                 return NT_STATUS_INVALID_HANDLE;
363
364         /* associate the domain SID with the (unique) handle. */
365         if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
366                 return NT_STATUS_NO_MEMORY;
367
368         /* get a (unique) handle.  open a policy on it. */
369         if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
370                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
371
372         DEBUG(5,("samr_open_domain: %d\n", __LINE__));
373
374         return r_u->status;
375 }
376
377 /*******************************************************************
378  _samr_get_usrdom_pwinfo
379  ********************************************************************/
380
381 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
382 {
383         struct samr_info *info = NULL;
384
385         r_u->status = NT_STATUS_OK;
386
387         /* find the policy handle.  open a policy on it. */
388         if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
389                 return NT_STATUS_INVALID_HANDLE;
390
391         if (!sid_check_is_in_our_domain(&info->sid))
392                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
393
394         init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
395
396         DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
397
398         /* 
399          * NT sometimes return NT_STATUS_ACCESS_DENIED
400          * I don't know yet why.
401          */
402
403         return r_u->status;
404 }
405
406 /*******************************************************************
407  samr_make_usr_obj_sd
408  ********************************************************************/
409
410 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC_BUF **buf, DOM_SID *usr_sid)
411 {
412         extern DOM_SID global_sid_World;
413         DOM_SID adm_sid;
414         DOM_SID act_sid;
415
416         SEC_ACE ace[4];
417         SEC_ACCESS mask;
418
419         SEC_ACL *psa = NULL;
420         SEC_DESC *psd = NULL;
421         size_t sd_size;
422
423         sid_copy(&adm_sid, &global_sid_Builtin);
424         sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
425
426         sid_copy(&act_sid, &global_sid_Builtin);
427         sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
428
429         init_sec_access(&mask, 0x2035b);
430         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
431
432         init_sec_access(&mask, 0xf07ff);
433         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
434         init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
435
436         init_sec_access(&mask,0x20044);
437         init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
438
439         if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
440                 return NT_STATUS_NO_MEMORY;
441
442         if((psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, &sd_size)) == NULL)
443                 return NT_STATUS_NO_MEMORY;
444
445         if((*buf = make_sec_desc_buf(ctx, sd_size, psd)) == NULL)
446                 return NT_STATUS_NO_MEMORY;
447
448         return NT_STATUS_OK;
449 }
450
451 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid)
452 {
453         struct samr_info *info = NULL;
454
455         /* find the policy handle.  open a policy on it. */
456         if (!find_policy_by_hnd(p, pol, (void **)&info))
457                 return False;
458
459         if (!info)
460                 return False;
461
462         *sid = info->sid;
463         return True;
464 }
465
466 /*******************************************************************
467  _samr_query_sec_obj
468  ********************************************************************/
469
470 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
471 {
472         DOM_SID pol_sid;
473         fstring str_sid;
474
475         r_u->status = NT_STATUS_OK;
476
477         /* Get the SID. */
478
479         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid))
480                 return NT_STATUS_INVALID_HANDLE;
481
482         DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
483
484         r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &r_u->buf, &pol_sid);
485
486         if (NT_STATUS_IS_OK(r_u->status))
487                 r_u->ptr = 1;
488
489         return r_u->status;
490 }
491
492 /*******************************************************************
493 makes a SAM_ENTRY / UNISTR2* structure from a user list.
494 ********************************************************************/
495
496 static void make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
497                 uint32 num_sam_entries, SAM_USER_INFO_21 *pass)
498 {
499         uint32 i;
500         SAM_ENTRY *sam;
501         UNISTR2 *uni_name;
502
503         *sam_pp = NULL;
504         *uni_name_pp = NULL;
505
506         if (num_sam_entries == 0)
507                 return;
508
509         sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
510
511         uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
512
513         if (sam == NULL || uni_name == NULL) {
514                 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
515                 return;
516         }
517
518         ZERO_STRUCTP(sam);
519         ZERO_STRUCTP(uni_name);
520
521         for (i = 0; i < num_sam_entries; i++) {
522                 int len = pass[i].uni_user_name.uni_str_len;
523
524                 init_sam_entry(&sam[i], len, pass[i].user_rid);
525                 copy_unistr2(&uni_name[i], &pass[i].uni_user_name);
526         }
527
528         *sam_pp = sam;
529         *uni_name_pp = uni_name;
530 }
531
532 /*******************************************************************
533  samr_reply_enum_dom_users
534  ********************************************************************/
535
536 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u)
537 {
538         SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
539         int num_entries = 0;
540         int total_entries = 0;
541         
542         r_u->status = NT_STATUS_OK;
543
544         /* find the policy handle.  open a policy on it. */
545         if (!find_policy_by_hnd(p, &q_u->pol, NULL))
546                 return NT_STATUS_INVALID_HANDLE;
547
548         DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
549
550         become_root();
551         r_u->status = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
552                                                                 MAX_SAM_ENTRIES, q_u->acb_mask);
553         unbecome_root();
554
555         if (NT_STATUS_IS_ERR(r_u->status))
556                 return r_u->status;
557
558         samr_clear_passwd_fields(pass, num_entries);
559
560         /* 
561          * Note from JRA. total_entries is not being used here. Currently if there is a
562          * large user base then it looks like NT will enumerate until get_sampwd_entries
563          * returns False due to num_entries being zero. This will cause an access denied
564          * return. I don't think this is right and needs further investigation. Note that
565          * this is also the same in the TNG code (I don't think that has been tested with
566          * a very large user list as MAX_SAM_ENTRIES is set to 600).
567          * 
568          * I also think that one of the 'num_entries' return parameters is probably
569          * the "max entries" parameter - but in the TNG code they're all currently set to the same
570          * value (again I think this is wrong).
571          */
572
573         make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, num_entries, pass);
574
575         init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_entries, num_entries);
576
577         DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
578
579         return r_u->status;
580 }
581
582 /*******************************************************************
583 makes a SAM_ENTRY / UNISTR2* structure from a group list.
584 ********************************************************************/
585
586 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
587                 uint32 num_sam_entries, DOMAIN_GRP *grp)
588 {
589         uint32 i;
590         SAM_ENTRY *sam;
591         UNISTR2 *uni_name;
592
593         *sam_pp = NULL;
594         *uni_name_pp = NULL;
595
596         if (num_sam_entries == 0)
597                 return;
598
599         sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
600
601         uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
602
603         if (sam == NULL || uni_name == NULL) {
604                 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
605                 return;
606         }
607
608         for (i = 0; i < num_sam_entries; i++) {
609                 /*
610                  * JRA. I think this should include the null. TNG does not.
611                  */
612                 int len = strlen(grp[i].name)+1;
613
614                 init_sam_entry(&sam[i], len, grp[i].rid);
615                 init_unistr2(&uni_name[i], grp[i].name, len);
616         }
617
618         *sam_pp = sam;
619         *uni_name_pp = uni_name;
620 }
621
622 /*******************************************************************
623  Get the group entries - similar to get_sampwd_entries().
624  ********************************************************************/
625
626 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
627                                     uint32 *p_num_entries, uint32 max_entries)
628 {
629         fstring sid_str;
630         uint32 num_entries = 0;
631         int i;
632         GROUP_MAP smap;
633         GROUP_MAP *map;
634
635         sid_to_string(sid_str, sid);
636         DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
637
638         *p_num_entries = 0;
639
640         /* well-known aliases */
641         if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
642                 
643                 enum_group_mapping(SID_NAME_ALIAS, &map, (int *)&num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
644                 
645                 if (num_entries != 0) {         
646                         *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
647                         if (*d_grp==NULL)
648                                 return NT_STATUS_NO_MEMORY;
649                         
650                         for(i=0; i<num_entries && i<max_entries; i++) {
651                                 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
652                                 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
653                                 
654                         }
655                 }
656                 SAFE_FREE(map);
657                 
658         } else if (sid_equal(sid, &global_sam_sid) && !lp_hide_local_users()) {
659                 struct sys_grent *glist;
660                 struct sys_grent *grp;
661                 struct passwd *pw;
662                 gid_t winbind_gid_low, winbind_gid_high;
663         
664                 lp_winbind_gid(&winbind_gid_low, &winbind_gid_high);
665
666                 /* local aliases */
667                 /* we return the UNIX groups here.  This seems to be the right */
668                 /* thing to do, since NT member servers return their local     */
669                 /* groups in the same situation.                               */
670
671                 /* use getgrent_list() to retrieve the list of groups to avoid
672                  * problems with getgrent possible infinite loop by internal
673                  * libc grent structures overwrites by called functions */
674                 grp = glist = getgrent_list();
675                 if (grp == NULL)
676                         return NT_STATUS_NO_MEMORY;
677                 
678                 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
679                         uint32 trid;
680                         
681                         if(!get_group_from_gid(grp->gr_gid, &smap, MAPPING_WITHOUT_PRIV))
682                                 continue;
683                         
684                         if (smap.sid_name_use!=SID_NAME_ALIAS) {
685                                 continue;
686                         }
687
688                         sid_split_rid(&smap.sid, &trid);
689                         
690                         if (!sid_equal(sid, &smap.sid))
691                                 continue;
692
693                         /* Don't return winbind groups as they are not local! */
694                         if ((grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
695                                 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
696                                 continue;
697                         }
698
699                         /* Don't return user private groups... */
700                         
701                         /* 
702                          *  We used to do a Get_Pwnam() here, but this has been
703                          * trimmed back to the common case for private groups
704                          * to save lookups and to use the _alloc interface.
705                          *
706                          * This also matches the group mapping code
707                          */
708
709                         if ((pw = getpwnam_alloc(smap.nt_name)) != 0) {
710                                 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
711                                 passwd_free(&pw);
712                                 continue;                       
713                         }
714
715                         for( i = 0; i < num_entries; i++)
716                                 if ( (*d_grp)[i].rid == trid )
717                                         break;
718
719                         if ( i < num_entries ) {
720                                 continue; /* rid was there, dup! */
721                         }
722
723                         /* JRA - added this for large group db enumeration... */
724
725                         if (start_idx > 0) {
726                                 /* skip the requested number of entries.
727                                         not very efficient, but hey...
728                                 */
729                                 start_idx--;
730                                 continue;
731                         }
732
733                         *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
734                         if (*d_grp==NULL) {
735                                 grent_free(glist);
736                                 return NT_STATUS_NO_MEMORY;
737                         }
738
739                         fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
740                         (*d_grp)[num_entries].rid = trid;
741                         num_entries++;
742                         DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
743                 }
744
745                 grent_free(glist);
746         }
747
748         *p_num_entries = num_entries;
749
750         DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
751
752         if (num_entries >= max_entries)
753                 return STATUS_MORE_ENTRIES;
754         return NT_STATUS_OK;
755 }
756
757 /*******************************************************************
758  Get the group entries - similar to get_sampwd_entries().
759  ********************************************************************/
760
761 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
762                                      uint32 *p_num_entries, uint32 max_entries)
763 {
764         GROUP_MAP *map=NULL;
765         int i;
766         uint32 group_entries = 0;
767         uint32 num_entries = 0;
768
769         *p_num_entries = 0;
770
771         enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
772
773         num_entries=group_entries-start_idx;
774
775         /* limit the number of entries */
776         if (num_entries>max_entries) {
777                 DEBUG(5,("Limiting to %d entries\n", max_entries));
778                 num_entries=max_entries;
779         }
780
781         *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
782         if (num_entries!=0 && *d_grp==NULL){
783                 SAFE_FREE(map);
784                 return NT_STATUS_NO_MEMORY;
785         }
786         
787         for (i=0; i<num_entries; i++) {
788                 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
789                 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
790                 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
791                 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
792         }
793
794         SAFE_FREE(map);
795
796         *p_num_entries = num_entries;
797
798         return NT_STATUS_OK;
799 }
800
801 /*******************************************************************
802  samr_reply_enum_dom_groups
803  Only reply with one group - domain admins. This must be fixed for
804  a real PDC. JRA.
805  ********************************************************************/
806
807 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
808 {
809         DOMAIN_GRP *grp=NULL;
810         uint32 num_entries;
811         DOM_SID sid;
812
813         r_u->status = NT_STATUS_OK;
814
815         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
816                 return NT_STATUS_INVALID_HANDLE;
817
818         DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
819
820         /* the domain group array is being allocated in the function below */
821         get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
822
823         make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
824
825         init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
826
827         DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
828
829         return r_u->status;
830 }
831
832
833 /*******************************************************************
834  samr_reply_enum_dom_aliases
835  ********************************************************************/
836
837 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
838 {
839         DOMAIN_GRP *grp=NULL;
840         uint32 num_entries = 0;
841         fstring sid_str;
842         DOM_SID sid;
843         NTSTATUS status;
844         
845         r_u->status = NT_STATUS_OK;
846
847         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
848                 return NT_STATUS_INVALID_HANDLE;
849
850         sid_to_string(sid_str, &sid);
851         DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
852
853         status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, 
854                                          &num_entries, MAX_SAM_ENTRIES);
855         if (NT_STATUS_IS_ERR(status)) return status;
856
857         make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
858
859         /*safe_free(grp);*/
860
861         init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
862
863         DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
864
865         return r_u->status;
866 }
867
868 /*******************************************************************
869  samr_reply_query_dispinfo
870  ********************************************************************/
871 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u)
872 {
873         struct samr_info *info = NULL;
874         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
875         uint16 acb_mask;
876         
877         uint32 max_entries=q_u->max_entries;
878         uint32 enum_context=q_u->start_idx;
879         uint32 max_size=q_u->max_size;
880
881         SAM_DISPINFO_CTR *ctr;
882         uint32 temp_size=0, total_data_size=0;
883         NTSTATUS disp_ret;
884         uint32 num_account = 0;
885         enum remote_arch_types ra_type = get_remote_arch();
886         int max_sam_entries;
887
888         max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
889
890         DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
891         r_u->status = NT_STATUS_OK;
892
893         /* find the policy handle.  open a policy on it. */
894         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
895                 return NT_STATUS_INVALID_HANDLE;
896
897         /*
898          * calculate how many entries we will return.
899          * based on 
900          * - the number of entries the client asked
901          * - our limit on that
902          * - the starting point (enumeration context)
903          * - the buffer size the client will accept
904          */
905
906         /*
907          * We are a lot more like W2K. Instead of reading the SAM
908          * each time to find the records we need to send back,
909          * we read it once and link that copy to the sam handle.
910          * For large user list (over the MAX_SAM_ENTRIES)
911          * it's a definitive win.
912          * second point to notice: between enumerations
913          * our sam is now the same as it's a snapshoot.
914          * third point: got rid of the static SAM_USER_21 struct
915          * no more intermediate.
916          * con: it uses much more memory, as a full copy is stored
917          * in memory.
918          *
919          * If you want to change it, think twice and think
920          * of the second point , that's really important.
921          *
922          * JFM, 12/20/2001
923          */
924
925         /* Get what we need from the password database */
926
927         if (q_u->switch_level==2)
928                 acb_mask = ACB_WSTRUST;
929         else
930                 acb_mask = ACB_NORMAL;
931
932         /* Get what we need from the password database */
933         switch (q_u->switch_level) {
934                 case 0x1:
935                 case 0x2:
936                 case 0x4:
937                         become_root();          
938                         r_u->status=load_sampwd_entries(info, acb_mask);
939                         unbecome_root();
940                         if (NT_STATUS_IS_ERR(r_u->status)) {
941                                 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
942                                 return r_u->status;
943                         }
944                         num_account = info->disp_info.num_user_account;
945                         break;
946                 case 0x3:
947                 case 0x5:
948                         r_u->status = load_group_domain_entries(info, &info->sid);
949                         if (NT_STATUS_IS_ERR(r_u->status))
950                                 return r_u->status;
951                         num_account = info->disp_info.num_group_account;
952                         break;
953                 default:
954                         DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
955                         return NT_STATUS_INVALID_INFO_CLASS;
956         }
957
958         /* first limit the number of entries we will return */
959         if(max_entries > max_sam_entries) {
960                 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
961                 max_entries = max_sam_entries;
962         }
963
964         if (enum_context > num_account) {
965                 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
966                 return NT_STATUS_OK;
967         }
968
969         /* verify we won't overflow */
970         if (max_entries > num_account-enum_context) {
971                 max_entries = num_account-enum_context;
972                 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
973         }
974
975         /* calculate the size and limit on the number of entries we will return */
976         temp_size=(enum_context+max_entries)*struct_size;
977         
978         if (temp_size>max_size) {
979                 max_entries=max_size/struct_size;
980                 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
981         }
982
983         if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
984                 return NT_STATUS_NO_MEMORY;
985
986         ZERO_STRUCTP(ctr);
987
988         /* Now create reply structure */
989         switch (q_u->switch_level) {
990         case 0x1:
991                 if (max_entries) {
992                         if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
993                                 return NT_STATUS_NO_MEMORY;
994                 }
995                 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context, info->disp_info.disp_user_info);
996                 if (NT_STATUS_IS_ERR(disp_ret))
997                         return disp_ret;
998                 break;
999         case 0x2:
1000                 if (max_entries) {
1001                         if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1002                                 return NT_STATUS_NO_MEMORY;
1003                 }
1004                 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context, info->disp_info.disp_user_info);
1005                 if (NT_STATUS_IS_ERR(disp_ret))
1006                         return disp_ret;
1007                 break;
1008         case 0x3:
1009                 if (max_entries) {
1010                         if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1011                                 return NT_STATUS_NO_MEMORY;
1012                 }
1013                 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1014                 if (NT_STATUS_IS_ERR(disp_ret))
1015                         return disp_ret;
1016                 break;
1017         case 0x4:
1018                 if (max_entries) {
1019                         if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1020                                 return NT_STATUS_NO_MEMORY;
1021                 }
1022                 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1023                 if (NT_STATUS_IS_ERR(disp_ret))
1024                         return disp_ret;
1025                 break;
1026         case 0x5:
1027                 if (max_entries) {
1028                         if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1029                                 return NT_STATUS_NO_MEMORY;
1030                 }
1031                 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1032                 if (NT_STATUS_IS_ERR(disp_ret))
1033                         return disp_ret;
1034                 break;
1035
1036         default:
1037                 ctr->sam.info = NULL;
1038                 return NT_STATUS_INVALID_INFO_CLASS;
1039         }
1040
1041         /* calculate the total size */
1042         total_data_size=num_account*struct_size;
1043
1044         if (enum_context+max_entries < num_account)
1045                 r_u->status = STATUS_MORE_ENTRIES;
1046
1047         DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1048
1049         init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1050
1051         return r_u->status;
1052
1053 }
1054
1055 /*******************************************************************
1056  samr_reply_query_aliasinfo
1057  ********************************************************************/
1058
1059 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1060 {
1061         struct samr_info *info = NULL;
1062         GROUP_MAP map;
1063
1064         r_u->status = NT_STATUS_OK;
1065
1066         DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1067
1068         /* find the policy handle.  open a policy on it. */
1069         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1070                 return NT_STATUS_INVALID_HANDLE;
1071
1072         if (!sid_check_is_in_our_domain(&info->sid) &&
1073             !sid_check_is_in_builtin(&info->sid))
1074                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1075
1076         if(!get_local_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV))
1077                 return NT_STATUS_NO_SUCH_ALIAS;
1078
1079         switch (q_u->switch_level) {
1080         case 1:
1081                 r_u->ptr = 1;
1082                 r_u->ctr.switch_value1 = 1;
1083                 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1084                 break;
1085         case 3:
1086                 r_u->ptr = 1;
1087                 r_u->ctr.switch_value1 = 3;
1088                 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1089                 break;
1090         default:
1091                 return NT_STATUS_INVALID_INFO_CLASS;
1092         }
1093
1094         DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1095
1096         return r_u->status;
1097 }
1098
1099 #if 0
1100 /*******************************************************************
1101  samr_reply_lookup_ids
1102  ********************************************************************/
1103
1104  uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1105 {
1106     uint32 rid[MAX_SAM_ENTRIES];
1107     int num_rids = q_u->num_sids1;
1108
1109     r_u->status = NT_STATUS_OK;
1110
1111     DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1112
1113     if (num_rids > MAX_SAM_ENTRIES) {
1114         num_rids = MAX_SAM_ENTRIES;
1115         DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1116     }
1117
1118 #if 0
1119     int i;
1120     SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1121
1122     for (i = 0; i < num_rids && status == 0; i++)
1123     {
1124         struct sam_passwd *sam_pass;
1125         fstring user_name;
1126
1127
1128         fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1129                                     q_u->uni_user_name[i].uni_str_len));
1130
1131         /* find the user account */
1132         become_root();
1133         sam_pass = get_smb21pwd_entry(user_name, 0);
1134         unbecome_root();
1135
1136         if (sam_pass == NULL)
1137         {
1138             status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1139             rid[i] = 0;
1140         }
1141         else
1142         {
1143             rid[i] = sam_pass->user_rid;
1144         }
1145     }
1146 #endif
1147
1148     num_rids = 1;
1149     rid[0] = BUILTIN_ALIAS_RID_USERS;
1150
1151     init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1152
1153     DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1154
1155     return r_u->status;
1156 }
1157 #endif
1158
1159 /*******************************************************************
1160  _samr_lookup_names
1161  ********************************************************************/
1162
1163 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1164 {
1165         uint32 rid[MAX_SAM_ENTRIES];
1166         uint32 local_rid;
1167         enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1168         enum SID_NAME_USE local_type;
1169         int i;
1170         int num_rids = q_u->num_names2;
1171         DOM_SID pol_sid;
1172         fstring sid_str;
1173
1174         r_u->status = NT_STATUS_OK;
1175
1176         DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1177
1178         ZERO_ARRAY(rid);
1179         ZERO_ARRAY(type);
1180
1181         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid)) {
1182                 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1183                 return r_u->status;
1184         }
1185
1186         if (num_rids > MAX_SAM_ENTRIES) {
1187                 num_rids = MAX_SAM_ENTRIES;
1188                 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1189         }
1190
1191         DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1192
1193         for (i = 0; i < num_rids; i++) {
1194                 fstring name;
1195                 DOM_SID sid;
1196
1197                 r_u->status = NT_STATUS_NONE_MAPPED;
1198
1199                 rid [i] = 0xffffffff;
1200                 type[i] = SID_NAME_UNKNOWN;
1201
1202                 rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1203
1204                 /*
1205                  * we are only looking for a name
1206                  * the SID we get back can be outside
1207                  * the scope of the pol_sid
1208                  * 
1209                  * in clear: it prevents to reply to domain\group: yes
1210                  * when only builtin\group exists.
1211                  *
1212                  * a cleaner code is to add the sid of the domain we're looking in
1213                  * to the local_lookup_name function.
1214                  */
1215                 if(local_lookup_name(global_myname, name, &sid, &local_type)) {
1216                         sid_split_rid(&sid, &local_rid);
1217                                 
1218                         if (sid_equal(&sid, &pol_sid)) {
1219                                 rid[i]=local_rid;
1220                                 type[i]=local_type;
1221                                 r_u->status = NT_STATUS_OK;
1222                         }
1223                 }
1224         }
1225
1226         init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1227
1228         DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1229
1230         return r_u->status;
1231 }
1232
1233 /*******************************************************************
1234  _samr_chgpasswd_user
1235  ********************************************************************/
1236
1237 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1238 {
1239     fstring user_name;
1240     fstring wks;
1241
1242     DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1243
1244     r_u->status = NT_STATUS_OK;
1245
1246     rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1247     rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1248
1249     DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1250
1251         /*
1252          * Pass the user through the NT -> unix user mapping
1253          * function.
1254          */
1255  
1256         (void)map_username(user_name);
1257  
1258         /*
1259          * UNIX username case mangling not required, pass_oem_change 
1260          * is case insensitive.
1261          */
1262
1263     if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1264                          q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1265         r_u->status = NT_STATUS_WRONG_PASSWORD;
1266
1267     init_samr_r_chgpasswd_user(r_u, r_u->status);
1268
1269     DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1270
1271     return r_u->status;
1272 }
1273
1274 /*******************************************************************
1275 makes a SAMR_R_LOOKUP_RIDS structure.
1276 ********************************************************************/
1277
1278 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1279             UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1280 {
1281         uint32 i;
1282         UNIHDR *hdr_name=NULL;
1283         UNISTR2 *uni_name=NULL;
1284
1285         *pp_uni_name = NULL;
1286         *pp_hdr_name = NULL;
1287
1288         if (num_names != 0) {
1289                 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1290                 if (hdr_name == NULL)
1291                         return False;
1292
1293                 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1294                 if (uni_name == NULL)
1295                         return False;
1296         }
1297
1298         for (i = 0; i < num_names; i++) {
1299                 int len = names[i] != NULL ? strlen(names[i]) : 0;
1300                 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1301                 init_uni_hdr(&hdr_name[i], len);
1302                 init_unistr2(&uni_name[i], names[i], len);
1303         }
1304
1305         *pp_uni_name = uni_name;
1306         *pp_hdr_name = hdr_name;
1307
1308         return True;
1309 }
1310
1311 /*******************************************************************
1312  _samr_lookup_rids
1313  ********************************************************************/
1314
1315 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1316 {
1317         fstring group_names[MAX_SAM_ENTRIES];
1318         uint32 *group_attrs = NULL;
1319         UNIHDR *hdr_name = NULL;
1320         UNISTR2 *uni_name = NULL;
1321         DOM_SID pol_sid;
1322         int num_rids = q_u->num_rids1;
1323         int i;
1324
1325         r_u->status = NT_STATUS_OK;
1326
1327         DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1328
1329         /* find the policy handle.  open a policy on it. */
1330         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid))
1331                 return NT_STATUS_INVALID_HANDLE;
1332
1333         if (num_rids > MAX_SAM_ENTRIES) {
1334                 num_rids = MAX_SAM_ENTRIES;
1335                 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1336         }
1337
1338         if (num_rids) {
1339                 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1340                         return NT_STATUS_NO_MEMORY;
1341         }
1342  
1343         r_u->status = NT_STATUS_NONE_MAPPED;
1344
1345         for (i = 0; i < num_rids; i++) {
1346                 fstring tmpname;
1347                 fstring domname;
1348                 DOM_SID sid;
1349                 enum SID_NAME_USE type;
1350
1351                 group_attrs[i] = SID_NAME_UNKNOWN;
1352                 *group_names[i] = '\0';
1353
1354                 if (sid_equal(&pol_sid, &global_sam_sid)) {
1355                         sid_copy(&sid, &pol_sid);
1356                         sid_append_rid(&sid, q_u->rid[i]);
1357
1358                         if (lookup_sid(&sid, domname, tmpname, &type)) {
1359                                 r_u->status = NT_STATUS_OK;
1360                                 group_attrs[i] = (uint32)type;
1361                                 fstrcpy(group_names[i],tmpname);
1362                                 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1363                         }
1364                 }
1365         }
1366
1367         if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1368                 return NT_STATUS_NO_MEMORY;
1369
1370         init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1371
1372         DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1373
1374         return r_u->status;
1375 }
1376
1377 /*******************************************************************
1378  _api_samr_open_user. Safe - gives out no passwd info.
1379  ********************************************************************/
1380
1381 NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1382 {
1383         SAM_ACCOUNT *sampass=NULL;
1384         DOM_SID sid;
1385         POLICY_HND domain_pol = q_u->domain_pol;
1386         uint32 user_rid = q_u->user_rid;
1387         POLICY_HND *user_pol = &r_u->user_pol;
1388         struct samr_info *info = NULL;
1389         BOOL ret;
1390
1391         r_u->status = NT_STATUS_OK;
1392
1393         /* find the domain policy handle. */
1394         if (!find_policy_by_hnd(p, &domain_pol, NULL))
1395                 return NT_STATUS_INVALID_HANDLE;
1396
1397         pdb_init_sam(&sampass);
1398
1399         become_root();
1400         ret=pdb_getsampwrid(sampass, user_rid);
1401         unbecome_root();
1402
1403         /* check that the RID exists in our domain. */
1404         if (ret == False) {
1405                 pdb_free_sam(&sampass);
1406                 return NT_STATUS_NO_SUCH_USER;
1407         }
1408
1409         pdb_free_sam(&sampass);
1410
1411         /* Get the domain SID stored in the domain policy */
1412         if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
1413                 return NT_STATUS_INVALID_HANDLE;
1414
1415         /* append the user's RID to it */
1416         if(!sid_append_rid(&sid, user_rid))
1417                 return NT_STATUS_NO_SUCH_USER;
1418
1419         /* associate the user's SID with the new handle. */
1420         if ((info = get_samr_info_by_sid(&sid)) == NULL)
1421                 return NT_STATUS_NO_MEMORY;
1422
1423         /* get a (unique) handle.  open a policy on it. */
1424         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1425                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1426
1427         return r_u->status;
1428 }
1429
1430 /*************************************************************************
1431  get_user_info_10. Safe. Only gives out acb bits.
1432  *************************************************************************/
1433
1434 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1435 {
1436         SAM_ACCOUNT *smbpass=NULL;
1437         BOOL ret;
1438
1439         if (!pdb_rid_is_user(user_rid)) {
1440                 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1441                 return False;
1442         }
1443
1444         pdb_init_sam(&smbpass);
1445
1446         become_root();
1447         ret = pdb_getsampwrid(smbpass, user_rid);
1448         unbecome_root();
1449
1450         if (ret==False) {
1451                 DEBUG(4,("User 0x%x not found\n", user_rid));
1452                 pdb_free_sam(&smbpass);
1453                 return False;
1454         }
1455
1456         DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1457
1458         ZERO_STRUCTP(id10);
1459         init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1460
1461         pdb_free_sam(&smbpass);
1462
1463         return True;
1464 }
1465
1466 /*************************************************************************
1467  get_user_info_12. OK - this is the killer as it gives out password info.
1468  Ensure that this is only allowed on an encrypted connection with a root
1469  user. JRA. 
1470  *************************************************************************/
1471
1472 static NTSTATUS get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid)
1473 {
1474         SAM_ACCOUNT *smbpass=NULL;
1475         BOOL ret;
1476
1477         if (!p->ntlmssp_auth_validated)
1478                 return NT_STATUS_ACCESS_DENIED;
1479
1480         if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1481                 return NT_STATUS_ACCESS_DENIED;
1482
1483         /*
1484          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1485          */
1486         pdb_init_sam(&smbpass);
1487
1488         ret = pdb_getsampwrid(smbpass, user_rid);
1489
1490         if (ret == False) {
1491                 DEBUG(4, ("User 0x%x not found\n", user_rid));
1492                 pdb_free_sam(&smbpass);
1493                 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1494         }
1495
1496         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1497
1498         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1499                 pdb_free_sam(&smbpass);
1500                 return NT_STATUS_ACCOUNT_DISABLED;
1501         }
1502
1503         ZERO_STRUCTP(id12);
1504         init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1505         
1506         pdb_free_sam(&smbpass);
1507
1508         return NT_STATUS_OK;
1509 }
1510
1511 /*************************************************************************
1512  get_user_info_20
1513  *************************************************************************/
1514
1515 static BOOL get_user_info_20(SAM_USER_INFO_20 *id20, uint32 user_rid)
1516 {
1517         SAM_ACCOUNT *sampass=NULL;
1518         BOOL ret;
1519
1520         if (!pdb_rid_is_user(user_rid)) {
1521                 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1522                 return False;
1523         }
1524
1525         pdb_init_sam(&sampass);
1526
1527         become_root();
1528         ret = pdb_getsampwrid(sampass, user_rid);
1529         unbecome_root();
1530
1531         if (ret == False) {
1532                 DEBUG(4,("User 0x%x not found\n", user_rid));
1533                 pdb_free_sam(&sampass);
1534                 return False;
1535         }
1536
1537         samr_clear_sam_passwd(sampass);
1538
1539         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
1540
1541         ZERO_STRUCTP(id20);
1542         init_sam_user_info20A(id20, sampass);
1543         
1544         pdb_free_sam(&sampass);
1545
1546         return True;
1547 }
1548
1549 /*************************************************************************
1550  get_user_info_21
1551  *************************************************************************/
1552
1553 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1554 {
1555         SAM_ACCOUNT *sampass=NULL;
1556         BOOL ret;
1557
1558         if (!pdb_rid_is_user(user_rid)) {
1559                 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1560                 return False;
1561         }
1562
1563         pdb_init_sam(&sampass);
1564
1565         become_root();
1566         ret = pdb_getsampwrid(sampass, user_rid);
1567         unbecome_root();
1568
1569         if (ret == False) {
1570                 DEBUG(4,("User 0x%x not found\n", user_rid));
1571                 pdb_free_sam(&sampass);
1572                 return False;
1573         }
1574
1575         samr_clear_sam_passwd(sampass);
1576
1577         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
1578
1579         ZERO_STRUCTP(id21);
1580         init_sam_user_info21A(id21, sampass);
1581         
1582         pdb_free_sam(&sampass);
1583
1584         return True;
1585 }
1586
1587 /*******************************************************************
1588  _samr_query_userinfo
1589  ********************************************************************/
1590
1591 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1592 {
1593         SAM_USERINFO_CTR *ctr;
1594         uint32 rid = 0;
1595         struct samr_info *info = NULL;
1596
1597         r_u->status=NT_STATUS_OK;
1598
1599         /* search for the handle */
1600         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1601                 return NT_STATUS_INVALID_HANDLE;
1602
1603         if (!sid_check_is_in_our_domain(&info->sid))
1604                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1605
1606         sid_peek_rid(&info->sid, &rid);
1607
1608         DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid));
1609
1610         ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1611         if (!ctr)
1612                 return NT_STATUS_NO_MEMORY;
1613
1614         ZERO_STRUCTP(ctr);
1615
1616         /* ok!  user info levels (lots: see MSDEV help), off we go... */
1617         ctr->switch_value = q_u->switch_value;
1618
1619         switch (q_u->switch_value) {
1620         case 0x10:
1621                 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1622                 if (ctr->info.id10 == NULL)
1623                         return NT_STATUS_NO_MEMORY;
1624
1625                 if (!get_user_info_10(ctr->info.id10, rid))
1626                         return NT_STATUS_NO_SUCH_USER;
1627                 break;
1628
1629 #if 0
1630 /* whoops - got this wrong.  i think.  or don't understand what's happening. */
1631         case 0x11:
1632         {
1633             NTTIME expire;
1634             info = (void *)&id11;
1635
1636             expire.low = 0xffffffff;
1637             expire.high = 0x7fffffff;
1638
1639             ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1640                                     sizeof
1641                                     (*ctr->
1642                                      info.
1643                                      id11));
1644             ZERO_STRUCTP(ctr->info.id11);
1645             init_sam_user_info11(ctr->info.id11, &expire,
1646                          "BROOKFIELDS$",    /* name */
1647                          0x03ef,    /* user rid */
1648                          0x201, /* group rid */
1649                          0x0080);   /* acb info */
1650
1651             break;
1652         }
1653 #endif
1654
1655         case 0x12:
1656                 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1657                 if (ctr->info.id12 == NULL)
1658                         return NT_STATUS_NO_MEMORY;
1659
1660                 if (NT_STATUS_IS_ERR(r_u->status = get_user_info_12(p, ctr->info.id12, rid)))
1661                         return r_u->status;
1662                 break;
1663
1664         case 20:
1665                 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1666                 if (ctr->info.id20 == NULL)
1667                         return NT_STATUS_NO_MEMORY;
1668                 if (!get_user_info_20(ctr->info.id20, rid))
1669                         return NT_STATUS_NO_SUCH_USER;
1670                 break;
1671
1672         case 21:
1673                 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1674                 if (ctr->info.id21 == NULL)
1675                         return NT_STATUS_NO_MEMORY;
1676                 if (!get_user_info_21(ctr->info.id21, rid))
1677                         return NT_STATUS_NO_SUCH_USER;
1678                 break;
1679
1680         default:
1681                 return NT_STATUS_INVALID_INFO_CLASS;
1682         }
1683
1684         init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1685
1686         DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1687
1688         return r_u->status;
1689 }
1690
1691 /*******************************************************************
1692  samr_reply_query_usergroups
1693  ********************************************************************/
1694
1695 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1696 {
1697         SAM_ACCOUNT *sam_pass=NULL;
1698         DOM_GID *gids = NULL;
1699         int num_groups = 0;
1700         uint32 rid;
1701         struct samr_info *info = NULL;
1702         BOOL ret;
1703
1704         /*
1705          * from the SID in the request:
1706          * we should send back the list of DOMAIN GROUPS
1707          * the user is a member of
1708          *
1709          * and only the DOMAIN GROUPS
1710          * no ALIASES !!! neither aliases of the domain
1711          * nor aliases of the builtin SID
1712          *
1713          * JFM, 12/2/2001
1714          */
1715
1716         r_u->status = NT_STATUS_OK;
1717
1718         DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1719
1720         /* find the policy handle.  open a policy on it. */
1721         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1722                 return NT_STATUS_INVALID_HANDLE;
1723
1724         if (!sid_check_is_in_our_domain(&info->sid))
1725                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1726
1727         sid_peek_rid(&info->sid, &rid);
1728
1729         pdb_init_sam(&sam_pass);
1730
1731         become_root();
1732         ret = pdb_getsampwrid(sam_pass, rid);
1733         unbecome_root();
1734
1735         if (ret == False) {
1736                 pdb_free_sam(&sam_pass);
1737                 return NT_STATUS_NO_SUCH_USER;
1738         }
1739
1740         if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
1741                 pdb_free_sam(&sam_pass);
1742                 return NT_STATUS_NO_SUCH_GROUP;
1743         }
1744
1745         /* construct the response.  lkclXXXX: gids are not copied! */
1746         init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1747
1748         DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1749         
1750         pdb_free_sam(&sam_pass);
1751
1752         return r_u->status;
1753 }
1754
1755 /*******************************************************************
1756  _samr_query_dom_info
1757  ********************************************************************/
1758
1759 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
1760 {
1761         struct samr_info *info = NULL;
1762         SAM_UNK_CTR *ctr;
1763         uint32 min_pass_len,pass_hist,flag;
1764         time_t u_expire, u_min_age;
1765         NTTIME nt_expire, nt_min_age;
1766
1767         time_t u_lock_duration, u_reset_time;
1768         NTTIME nt_lock_duration, nt_reset_time;
1769         uint32 lockout;
1770         
1771         time_t u_logout;
1772         NTTIME nt_logout;
1773
1774         uint32 num_users=0, num_groups=0, num_aliases=0;
1775
1776         if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
1777                 return NT_STATUS_NO_MEMORY;
1778
1779         ZERO_STRUCTP(ctr);
1780
1781         r_u->status = NT_STATUS_OK;
1782
1783         DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1784
1785         /* find the policy handle.  open a policy on it. */
1786         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1787                 return NT_STATUS_INVALID_HANDLE;
1788
1789         switch (q_u->switch_value) {
1790                 case 0x01:
1791                         account_policy_get(AP_MIN_PASSWORD_LEN, &min_pass_len);
1792                         account_policy_get(AP_PASSWORD_HISTORY, &pass_hist);
1793                         account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &flag);
1794                         account_policy_get(AP_MAX_PASSWORD_AGE, (int *)&u_expire);
1795                         account_policy_get(AP_MIN_PASSWORD_AGE, (int *)&u_min_age);
1796
1797                         unix_to_nt_time_abs(&nt_expire, u_expire);
1798                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
1799
1800                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
1801                                        flag, nt_expire, nt_min_age);
1802                         break;
1803                 case 0x02:
1804                         become_root();          
1805                         r_u->status=load_sampwd_entries(info, ACB_NORMAL);
1806                         unbecome_root();
1807                         if (NT_STATUS_IS_ERR(r_u->status)) {
1808                                 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1809                                 return r_u->status;
1810                         }
1811                         num_users=info->disp_info.num_user_account;
1812                         free_samr_db(info);
1813                         
1814                         r_u->status=load_group_domain_entries(info, &global_sam_sid);
1815                         if (NT_STATUS_IS_ERR(r_u->status)) {
1816                                 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
1817                                 return r_u->status;
1818                         }
1819                         num_groups=info->disp_info.num_group_account;
1820                         free_samr_db(info);
1821                         
1822                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
1823                         init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL), 
1824                                        num_users, num_groups, num_aliases);
1825                         break;
1826                 case 0x03:
1827                         account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
1828                         unix_to_nt_time_abs(&nt_logout, u_logout);
1829                         
1830                         init_unk_info3(&ctr->info.inf3, nt_logout);
1831                         break;
1832                 case 0x05:
1833                         init_unk_info5(&ctr->info.inf5, global_myname);
1834                         break;
1835                 case 0x06:
1836                         init_unk_info6(&ctr->info.inf6);
1837                         break;
1838                 case 0x07:
1839                         init_unk_info7(&ctr->info.inf7);
1840                         break;
1841                 case 0x0c:
1842                         account_policy_get(AP_LOCK_ACCOUNT_DURATION, (int *)&u_lock_duration);
1843                         account_policy_get(AP_RESET_COUNT_TIME, (int *)&u_reset_time);
1844                         account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &lockout);
1845         
1846                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
1847                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
1848         
1849                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
1850                         break;
1851                 default:
1852                         return NT_STATUS_INVALID_INFO_CLASS;
1853         }
1854
1855         init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
1856
1857         DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1858
1859         return r_u->status;
1860 }
1861
1862 /*******************************************************************
1863  _api_samr_create_user
1864  Create an account, can be either a normal user or a machine.
1865  This funcion will need to be updated for bdc/domain trusts.
1866  ********************************************************************/
1867
1868 NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
1869 {
1870         SAM_ACCOUNT *sam_pass=NULL;
1871         fstring account;
1872         DOM_SID sid;
1873         pstring add_script;
1874         POLICY_HND dom_pol = q_u->domain_pol;
1875         UNISTR2 user_account = q_u->uni_name;
1876         uint16 acb_info = q_u->acb_info;
1877         POLICY_HND *user_pol = &r_u->user_pol;
1878         struct samr_info *info = NULL;
1879         BOOL ret;
1880         NTSTATUS nt_status;
1881         struct passwd *pw;
1882
1883         /* find the policy handle.  open a policy on it. */
1884         if (!find_policy_by_hnd(p, &dom_pol, NULL))
1885                 return NT_STATUS_INVALID_HANDLE;
1886
1887         /* find the account: tell the caller if it exists.
1888           lkclXXXX i have *no* idea if this is a problem or not
1889           or even if you are supposed to construct a different
1890           reply if the account already exists...
1891          */
1892
1893         rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
1894         strlower(account);
1895
1896         pdb_init_sam(&sam_pass);
1897
1898         become_root();
1899         ret = pdb_getsampwnam(sam_pass, account);
1900         unbecome_root();
1901         if (ret == True) {
1902                 /* this account exists: say so */
1903                 pdb_free_sam(&sam_pass);
1904                 return NT_STATUS_USER_EXISTS;
1905         }
1906
1907         pdb_free_sam(&sam_pass);
1908
1909         /*
1910          * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1911          * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1912          * that only people with write access to the smbpasswd file will be able
1913          * to create a user. JRA.
1914          */
1915
1916         /*
1917          * add the user in the /etc/passwd file or the unix authority system.
1918          * We don't check if the smb_create_user() function succed or not for 2 reasons:
1919          * a) local_password_change() checks for us if the /etc/passwd account really exists
1920          * b) smb_create_user() would return an error if the account already exists
1921          * and as it could return an error also if it can't create the account, it would be tricky.
1922          *
1923          * So we go the easy way, only check after if the account exists.
1924          * JFM (2/3/2001), to clear any possible bad understanding (-:
1925          *
1926          * We now have seperate script paramaters for adding users/machines so we
1927          * now have some sainity-checking to match. 
1928          */
1929
1930         DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1));
1931 #if 0
1932         if ((acb_info & ACB_WSTRUST) && (account[strlen(account)-1] == '$')) {
1933                 pstrcpy(add_script, lp_addmachine_script());            
1934         } else if ((!(acb_info & ACB_WSTRUST)) && (account[strlen(account)-1] != '$')) {
1935                 pstrcpy(add_script, lp_adduser_script());
1936         } else {
1937                 DEBUG(0, ("_api_samr_create_user: mismatch between trust flags and $ termination\n"));
1938                 pdb_free_sam(&sam_pass);
1939                 return NT_STATUS_UNSUCCESSFUL;
1940         }
1941 #endif
1942
1943         /* 
1944          * we can't check both the ending $ and the acb_info.
1945          * 
1946          * UserManager creates trust accounts (ending in $,
1947          * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
1948          * JFM, 11/29/2001
1949          */
1950         if (account[strlen(account)-1] == '$')
1951                 pstrcpy(add_script, lp_addmachine_script());            
1952         else 
1953                 pstrcpy(add_script, lp_adduser_script());
1954
1955         if(*add_script) {
1956                 int add_ret;
1957                 all_string_sub(add_script, "%u", account, sizeof(account));
1958                 add_ret = smbrun(add_script,NULL);
1959                 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
1960         }
1961         
1962         pw = getpwnam_alloc(account);
1963
1964         if (pw) {
1965                 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sam_pass, pw))) {
1966                         passwd_free(&pw);
1967                         return nt_status;
1968                 }
1969                 passwd_free(&pw); /* done with this now */
1970         } else {
1971                 DEBUG(3,("attempting to create non-unix account %s\n", account));
1972                 
1973                 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sam_pass))) {
1974                         return nt_status;
1975                 }
1976                 
1977                 if (!pdb_set_username(sam_pass, account)) {
1978                         pdb_free_sam(&sam_pass);
1979                         return NT_STATUS_NO_MEMORY;
1980                 }
1981         }
1982
1983         pdb_set_acct_ctrl(sam_pass, acb_info);
1984  
1985         if (!pdb_add_sam_account(sam_pass)) {
1986                 pdb_free_sam(&sam_pass);
1987                 DEBUG(0, ("could not add user/computer %s to passdb.  Check permissions?\n", 
1988                           account));
1989                 return NT_STATUS_ACCESS_DENIED;         
1990         }
1991
1992         pdb_reset_sam(sam_pass);
1993         
1994         if (!pdb_getsampwnam(sam_pass, account)) {
1995                 pdb_free_sam(&sam_pass);
1996                 DEBUG(0, ("could not find user/computer %s just added to passdb?!?\n", 
1997                           account));
1998                 return NT_STATUS_ACCESS_DENIED;         
1999         }
2000         
2001         /* Get the domain SID stored in the domain policy */
2002         if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
2003                 pdb_free_sam(&sam_pass);
2004                 return NT_STATUS_INVALID_HANDLE;
2005         }
2006
2007         /* append the user's RID to it */
2008         if(!sid_append_rid(&sid, pdb_get_user_rid(sam_pass) )) {
2009                 pdb_free_sam(&sam_pass);
2010                 return NT_STATUS_NO_SUCH_USER;
2011         }
2012
2013         /* associate the user's SID with the new handle. */
2014         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2015                 pdb_free_sam(&sam_pass);
2016                 return NT_STATUS_NO_MEMORY;
2017         }
2018
2019         ZERO_STRUCTP(info);
2020         info->sid = sid;
2021
2022         /* get a (unique) handle.  open a policy on it. */
2023         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2024                 pdb_free_sam(&sam_pass);
2025                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2026         }
2027
2028         r_u->user_rid=pdb_get_user_rid(sam_pass);
2029         r_u->unknown_0 = 0x000703ff;
2030
2031         pdb_free_sam(&sam_pass);
2032
2033         return NT_STATUS_OK;
2034 }
2035
2036 /*******************************************************************
2037  samr_reply_connect_anon
2038  ********************************************************************/
2039
2040 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2041 {
2042         struct samr_info *info = NULL;
2043
2044     /* set up the SAMR connect_anon response */
2045
2046     r_u->status = NT_STATUS_OK;
2047
2048     /* associate the user's SID with the new handle. */
2049     if ((info = get_samr_info_by_sid(NULL)) == NULL)
2050         return NT_STATUS_NO_MEMORY;
2051
2052     info->status = q_u->unknown_0;
2053
2054     /* get a (unique) handle.  open a policy on it. */
2055     if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2056         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2057
2058     return r_u->status;
2059 }
2060
2061 /*******************************************************************
2062  samr_reply_connect
2063  ********************************************************************/
2064
2065 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2066 {
2067         struct samr_info *info = NULL;
2068
2069     DEBUG(5,("_samr_connect: %d\n", __LINE__));
2070
2071     r_u->status = NT_STATUS_OK;
2072
2073     /* associate the user's SID with the new handle. */
2074         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2075         return NT_STATUS_NO_MEMORY;
2076
2077     info->status = q_u->access_mask;
2078
2079     /* get a (unique) handle.  open a policy on it. */
2080     if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2081         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2082
2083     DEBUG(5,("_samr_connect: %d\n", __LINE__));
2084
2085     return r_u->status;
2086 }
2087
2088 /**********************************************************************
2089  api_samr_lookup_domain
2090  **********************************************************************/
2091
2092 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2093 {
2094     r_u->status = NT_STATUS_OK;
2095
2096     if (!find_policy_by_hnd(p, &q_u->connect_pol, NULL))
2097         return NT_STATUS_INVALID_HANDLE;
2098
2099     /* assume the domain name sent is our global_myname and
2100        send global_sam_sid */
2101     init_samr_r_lookup_domain(r_u, &global_sam_sid, r_u->status);
2102
2103     return r_u->status;
2104 }
2105
2106 /******************************************************************
2107 makes a SAMR_R_ENUM_DOMAINS structure.
2108 ********************************************************************/
2109
2110 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2111                         UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2112 {
2113         uint32 i;
2114         SAM_ENTRY *sam;
2115         UNISTR2 *uni_name;
2116
2117         DEBUG(5, ("make_enum_domains\n"));
2118
2119         *pp_sam = NULL;
2120         *pp_uni_name = NULL;
2121
2122         if (num_sam_entries == 0)
2123                 return True;
2124
2125         sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2126         uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2127
2128         if (sam == NULL || uni_name == NULL)
2129                 return False;
2130
2131         for (i = 0; i < num_sam_entries; i++) {
2132                 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2133
2134                 init_sam_entry(&sam[i], len, 0);
2135                 init_unistr2(&uni_name[i], doms[i], len);
2136         }
2137
2138         *pp_sam = sam;
2139         *pp_uni_name = uni_name;
2140
2141         return True;
2142 }
2143
2144 /**********************************************************************
2145  api_samr_enum_domains
2146  **********************************************************************/
2147
2148 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2149 {
2150         uint32 num_entries = 2;
2151         fstring dom[2];
2152
2153         r_u->status = NT_STATUS_OK;
2154
2155         fstrcpy(dom[0],global_myworkgroup);
2156         fstrcpy(dom[1],"Builtin");
2157
2158         if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2159                 return NT_STATUS_NO_MEMORY;
2160
2161         init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2162
2163         return r_u->status;
2164 }
2165
2166 /*******************************************************************
2167  api_samr_open_alias
2168  ********************************************************************/
2169
2170 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2171 {
2172         DOM_SID sid;
2173         POLICY_HND domain_pol = q_u->dom_pol;
2174         uint32 alias_rid = q_u->rid_alias;
2175         POLICY_HND *alias_pol = &r_u->pol;
2176         struct samr_info *info = NULL;
2177
2178         r_u->status = NT_STATUS_OK;
2179
2180         /* get the domain policy. */
2181         if (!find_policy_by_hnd(p, &domain_pol, NULL))
2182                 return NT_STATUS_INVALID_HANDLE;
2183
2184         /* Get the domain SID stored in the domain policy */
2185         if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
2186                 return NT_STATUS_INVALID_HANDLE;
2187
2188         /* append the alias' RID to it */
2189         if(!sid_append_rid(&sid, alias_rid))
2190                 return NT_STATUS_NO_SUCH_USER;
2191
2192         /*
2193          * we should check if the rid really exist !!!
2194          * JFM.
2195          */
2196
2197         /* associate the user's SID with the new handle. */
2198         if ((info = get_samr_info_by_sid(&sid)) == NULL)
2199                 return NT_STATUS_NO_MEMORY;
2200
2201         /* get a (unique) handle.  open a policy on it. */
2202         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2203                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2204
2205         return r_u->status;
2206 }
2207
2208 /*******************************************************************
2209  set_user_info_10
2210  ********************************************************************/
2211
2212 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
2213 {
2214         SAM_ACCOUNT *pwd =NULL;
2215         BOOL ret;
2216         
2217         pdb_init_sam(&pwd);
2218         
2219         ret = pdb_getsampwrid(pwd, rid);
2220         
2221         if(ret==False) {
2222                 pdb_free_sam(&pwd);
2223                 return False;
2224         }
2225
2226         if (id10 == NULL) {
2227                 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2228                 pdb_free_sam(&pwd);
2229                 return False;
2230         }
2231
2232         if (!pdb_set_acct_ctrl(pwd, id10->acb_info)) {
2233                 pdb_free_sam(&pwd);
2234                 return False;
2235         }
2236
2237         if(!pdb_update_sam_account(pwd)) {
2238                 pdb_free_sam(&pwd);
2239                 return False;
2240         }
2241
2242         pdb_free_sam(&pwd);
2243
2244         return True;
2245 }
2246
2247 /*******************************************************************
2248  set_user_info_12
2249  ********************************************************************/
2250
2251 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
2252 {
2253         SAM_ACCOUNT *pwd = NULL;
2254
2255         pdb_init_sam(&pwd);
2256
2257         if(!pdb_getsampwrid(pwd, rid)) {
2258                 pdb_free_sam(&pwd);
2259                 return False;
2260         }
2261
2262         if (id12 == NULL) {
2263                 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2264                 pdb_free_sam(&pwd);
2265                 return False;
2266         }
2267  
2268         if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd)) {
2269                 pdb_free_sam(&pwd);
2270                 return False;
2271         }
2272         if (!pdb_set_nt_passwd     (pwd, id12->nt_pwd)) {
2273                 pdb_free_sam(&pwd);
2274                 return False;
2275         }
2276         if (!pdb_set_pass_changed_now (pwd)) {
2277                 pdb_free_sam(&pwd);
2278                 return False; 
2279         }
2280  
2281         if(!pdb_update_sam_account(pwd)) {
2282                 pdb_free_sam(&pwd);
2283                 return False;
2284         }
2285
2286         pdb_free_sam(&pwd);
2287         return True;
2288 }
2289
2290 /*******************************************************************
2291  set_user_info_21
2292  ********************************************************************/
2293
2294 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
2295 {
2296         SAM_ACCOUNT *pwd = NULL;
2297  
2298         if (id21 == NULL) {
2299                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2300                 return False;
2301         }
2302  
2303         pdb_init_sam(&pwd);
2304  
2305         if (!pdb_getsampwrid(pwd, rid)) {
2306                 pdb_free_sam(&pwd);
2307                 return False;
2308         }
2309  
2310         copy_id21_to_sam_passwd(pwd, id21);
2311  
2312         /*
2313          * The funny part about the previous two calls is
2314          * that pwd still has the password hashes from the
2315          * passdb entry.  These have not been updated from
2316          * id21.  I don't know if they need to be set.    --jerry
2317          */
2318  
2319         /* write the change out */
2320         if(!pdb_update_sam_account(pwd)) {
2321                 pdb_free_sam(&pwd);
2322                 return False;
2323         }
2324
2325         pdb_free_sam(&pwd);
2326
2327         return True;
2328 }
2329
2330 /*******************************************************************
2331  set_user_info_23
2332  ********************************************************************/
2333
2334 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2335 {
2336         SAM_ACCOUNT *pwd = NULL;
2337         pstring plaintext_buf;
2338         uint32 len;
2339         uint16 acct_ctrl;
2340  
2341         if (id23 == NULL) {
2342                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2343                 return False;
2344         }
2345  
2346         pdb_init_sam(&pwd);
2347  
2348         if (!pdb_getsampwrid(pwd, rid)) {
2349                 pdb_free_sam(&pwd);
2350                 return False;
2351         }
2352
2353         DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2354                   pdb_get_username(pwd)));
2355
2356         acct_ctrl = pdb_get_acct_ctrl(pwd);
2357
2358         copy_id23_to_sam_passwd(pwd, id23);
2359  
2360         if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2361                 pdb_free_sam(&pwd);
2362                 return False;
2363         }
2364   
2365         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2366                 pdb_free_sam(&pwd);
2367                 return False;
2368         }
2369  
2370         /* if it's a trust account, don't update /etc/passwd */
2371         if ( (!IS_SAM_UNIX_USER(pwd)) ||
2372                 ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2373                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2374                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2375                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2376         } else  {
2377                 /* update the UNIX password */
2378                 if (lp_unix_password_sync() )
2379                         if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2380                                 pdb_free_sam(&pwd);
2381                                 return False;
2382                         }
2383         }
2384  
2385         ZERO_STRUCT(plaintext_buf);
2386  
2387         if(!pdb_update_sam_account(pwd)) {
2388                 pdb_free_sam(&pwd);
2389                 return False;
2390         }
2391  
2392         pdb_free_sam(&pwd);
2393
2394         return True;
2395 }
2396
2397 /*******************************************************************
2398  set_user_info_pw
2399  ********************************************************************/
2400
2401 static BOOL set_user_info_pw(char *pass, uint32 rid)
2402 {
2403         SAM_ACCOUNT *pwd = NULL;
2404         uint32 len;
2405         pstring plaintext_buf;
2406         uint16 acct_ctrl;
2407  
2408         pdb_init_sam(&pwd);
2409  
2410         if (!pdb_getsampwrid(pwd, rid)) {
2411                 pdb_free_sam(&pwd);
2412                 return False;
2413         }
2414         
2415         DEBUG(5, ("Attempting administrator password change for user %s\n",
2416                   pdb_get_username(pwd)));
2417
2418         acct_ctrl = pdb_get_acct_ctrl(pwd);
2419
2420         ZERO_STRUCT(plaintext_buf);
2421  
2422         if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2423                 pdb_free_sam(&pwd);
2424                 return False;
2425         }
2426
2427         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2428                 pdb_free_sam(&pwd);
2429                 return False;
2430         }
2431  
2432         /* if it's a trust account, don't update /etc/passwd */
2433         if ( (!IS_SAM_UNIX_USER(pwd)) ||
2434                 ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2435                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2436                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2437                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2438         } else {
2439                 /* update the UNIX password */
2440                 if (lp_unix_password_sync()) {
2441                         if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2442                                 pdb_free_sam(&pwd);
2443                                 return False;
2444                         }
2445                 }
2446         }
2447  
2448         ZERO_STRUCT(plaintext_buf);
2449  
2450         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2451  
2452         /* update the SAMBA password */
2453         if(!pdb_update_sam_account(pwd)) {
2454                 pdb_free_sam(&pwd);
2455                 return False;
2456         }
2457
2458         pdb_free_sam(&pwd);
2459
2460         return True;
2461 }
2462
2463 /*******************************************************************
2464  samr_reply_set_userinfo
2465  ********************************************************************/
2466
2467 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2468 {
2469         uint32 rid = 0x0;
2470         DOM_SID sid;
2471         POLICY_HND *pol = &q_u->pol;
2472         uint16 switch_value = q_u->switch_value;
2473         SAM_USERINFO_CTR *ctr = q_u->ctr;
2474
2475         DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2476
2477         r_u->status = NT_STATUS_OK;
2478
2479         /* find the policy handle.  open a policy on it. */
2480         if (!get_lsa_policy_samr_sid(p, pol, &sid))
2481                 return NT_STATUS_INVALID_HANDLE;
2482
2483         sid_split_rid(&sid, &rid);
2484
2485         DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2486
2487         if (ctr == NULL) {
2488                 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2489                 return NT_STATUS_INVALID_INFO_CLASS;
2490         }
2491
2492         /* ok!  user info levels (lots: see MSDEV help), off we go... */
2493         switch (switch_value) {
2494                 case 0x12:
2495                         if (!set_user_info_12(ctr->info.id12, rid))
2496                                 return NT_STATUS_ACCESS_DENIED;
2497                         break;
2498
2499                 case 24:
2500                         SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
2501
2502                         dump_data(100, (char *)ctr->info.id24->pass, 516);
2503
2504                         if (!set_user_info_pw((char *)ctr->info.id24->pass, rid))
2505                                 return NT_STATUS_ACCESS_DENIED;
2506                         break;
2507
2508                 case 25:
2509 #if 0
2510                         /*
2511                          * Currently we don't really know how to unmarshall
2512                          * the level 25 struct, and the password encryption
2513                          * is different. This is a placeholder for when we
2514                          * do understand it. In the meantime just return INVALID
2515                          * info level and W2K SP2 drops down to level 23... JRA.
2516                          */
2517
2518                         SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
2519
2520                         dump_data(100, (char *)ctr->info.id25->pass, 532);
2521
2522                         if (!set_user_info_pw(ctr->info.id25->pass, rid))
2523                                 return NT_STATUS_ACCESS_DENIED;
2524                         break;
2525 #endif
2526                         return NT_STATUS_INVALID_INFO_CLASS;
2527
2528                 case 23:
2529                         SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
2530
2531                         dump_data(100, (char *)ctr->info.id23->pass, 516);
2532
2533                         if (!set_user_info_23(ctr->info.id23, rid))
2534                                 return NT_STATUS_ACCESS_DENIED;
2535                         break;
2536
2537                 default:
2538                         return NT_STATUS_INVALID_INFO_CLASS;
2539         }
2540
2541         return r_u->status;
2542 }
2543
2544 /*******************************************************************
2545  samr_reply_set_userinfo2
2546  ********************************************************************/
2547
2548 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
2549 {
2550         DOM_SID sid;
2551         uint32 rid = 0x0;
2552         SAM_USERINFO_CTR *ctr = q_u->ctr;
2553         POLICY_HND *pol = &q_u->pol;
2554         uint16 switch_value = q_u->switch_value;
2555
2556         DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2557
2558         r_u->status = NT_STATUS_OK;
2559
2560         /* find the policy handle.  open a policy on it. */
2561         if (!get_lsa_policy_samr_sid(p, pol, &sid))
2562                 return NT_STATUS_INVALID_HANDLE;
2563
2564         sid_split_rid(&sid, &rid);
2565
2566         DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2567
2568         if (ctr == NULL) {
2569                 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2570                 return NT_STATUS_INVALID_INFO_CLASS;
2571         }
2572
2573         switch_value=ctr->switch_value;
2574
2575         /* ok!  user info levels (lots: see MSDEV help), off we go... */
2576         switch (switch_value) {
2577                 case 21:
2578                         if (!set_user_info_21(ctr->info.id21, rid))
2579                                 return NT_STATUS_ACCESS_DENIED;
2580                         break;
2581                 case 16:
2582                         if (!set_user_info_10(ctr->info.id10, rid))
2583                                 return NT_STATUS_ACCESS_DENIED;
2584                         break;
2585                 case 18:
2586                         /* Used by AS/U JRA. */
2587                         if (!set_user_info_12(ctr->info.id12, rid))
2588                                 return NT_STATUS_ACCESS_DENIED;
2589                         break;
2590                 default:
2591                         return NT_STATUS_INVALID_INFO_CLASS;
2592         }
2593
2594         return r_u->status;
2595 }
2596
2597 /*********************************************************************
2598  _samr_query_aliasmem
2599 *********************************************************************/
2600
2601 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
2602 {
2603         int num_groups = 0, tmp_num_groups=0;
2604         uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
2605         struct samr_info *info = NULL;
2606         int i,j;
2607         /* until i see a real useraliases query, we fack one up */
2608
2609         /* I have seen one, JFM 2/12/2001 */
2610         /*
2611          * Explanation of what this call does:
2612          * for all the SID given in the request:
2613          * return a list of alias (local groups)
2614          * that have those SID as members.
2615          *
2616          * and that's the alias in the domain specified
2617          * in the policy_handle
2618          *
2619          * if the policy handle is on an incorrect sid
2620          * for example a user's sid
2621          * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
2622          */
2623         
2624         r_u->status = NT_STATUS_OK;
2625
2626         DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
2627
2628         /* find the policy handle.  open a policy on it. */
2629         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
2630                 return NT_STATUS_INVALID_HANDLE;
2631
2632         if (!sid_check_is_domain(&info->sid) &&
2633             !sid_check_is_builtin(&info->sid))
2634                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2635
2636
2637         for (i=0; i<q_u->num_sids1; i++) {
2638
2639                 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
2640
2641                 /*
2642                  * if there is an error, we just continue as
2643                  * it can be an unfound user or group
2644                  */
2645                 if (NT_STATUS_IS_ERR(r_u->status)) {
2646                         DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
2647                         continue;
2648                 }
2649
2650                 if (tmp_num_groups==0) {
2651                         DEBUG(10,("_samr_query_useraliases: no groups found\n"));
2652                         continue;
2653                 }
2654
2655                 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
2656                 if (new_rids==NULL) {
2657                         DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
2658                         return NT_STATUS_NO_MEMORY;
2659                 }
2660                 rids=new_rids;
2661
2662                 for (j=0; j<tmp_num_groups; j++)
2663                         rids[j+num_groups]=tmp_rids[j];
2664                 
2665                 safe_free(tmp_rids);
2666                 
2667                 num_groups+=tmp_num_groups;
2668         }
2669         
2670         init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
2671         return NT_STATUS_OK;
2672 }
2673
2674 /*********************************************************************
2675  _samr_query_aliasmem
2676 *********************************************************************/
2677
2678 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
2679 {
2680         int i;
2681
2682         GROUP_MAP map;
2683         int num_uids = 0;
2684         DOM_SID2 *sid;
2685         uid_t *uid=NULL;
2686
2687         DOM_SID alias_sid;
2688         DOM_SID als_sid;
2689         uint32 alias_rid;
2690         fstring alias_sid_str;
2691         DOM_SID temp_sid;
2692
2693
2694         /* find the policy handle.  open a policy on it. */
2695         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid)) 
2696                 return NT_STATUS_INVALID_HANDLE;
2697
2698         sid_copy(&als_sid, &alias_sid);
2699         sid_to_string(alias_sid_str, &alias_sid);
2700         sid_split_rid(&alias_sid, &alias_rid);
2701
2702         DEBUG(10, ("sid is %s\n", alias_sid_str));
2703
2704         if (sid_equal(&alias_sid, &global_sid_Builtin)) {
2705                 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
2706                 if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
2707                         return NT_STATUS_NO_SUCH_ALIAS;
2708         } else {
2709                 if (sid_equal(&alias_sid, &global_sam_sid)) {
2710                         DEBUG(10, ("lookup on Server SID\n"));
2711                         if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
2712                                 return NT_STATUS_NO_SUCH_ALIAS;
2713                 }
2714         }
2715
2716         if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2717                 return NT_STATUS_NO_SUCH_ALIAS;
2718
2719         DEBUG(10, ("sid is %s\n", alias_sid_str));
2720         sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids); 
2721         if (num_uids!=0 && sid == NULL) 
2722                 return NT_STATUS_NO_MEMORY;
2723
2724         for (i = 0; i < num_uids; i++) {
2725                 sid_copy(&temp_sid, &global_sam_sid);
2726                 sid_append_rid(&temp_sid, pdb_uid_to_user_rid(uid[i]));
2727                 
2728                 init_dom_sid2(&sid[i], &temp_sid);
2729         }
2730
2731         DEBUG(10, ("sid is %s\n", alias_sid_str));
2732         init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
2733
2734         return NT_STATUS_OK;
2735 }
2736
2737 /*********************************************************************
2738  _samr_query_groupmem
2739 *********************************************************************/
2740
2741 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
2742 {
2743         int num_uids = 0;
2744         int i;
2745         DOM_SID group_sid;
2746         uint32 group_rid;
2747         fstring group_sid_str;
2748         uid_t *uid=NULL;
2749         
2750         GROUP_MAP map;
2751
2752         uint32 *rid=NULL;
2753         uint32 *attr=NULL;
2754
2755
2756         /* find the policy handle.  open a policy on it. */
2757         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid)) 
2758                 return NT_STATUS_INVALID_HANDLE;
2759
2760         /* todo: change to use sid_compare_front */
2761
2762         sid_split_rid(&group_sid, &group_rid);
2763         sid_to_string(group_sid_str, &group_sid);
2764         DEBUG(10, ("sid is %s\n", group_sid_str));
2765
2766         /* can we get a query for an SID outside our domain ? */
2767         if (!sid_equal(&group_sid, &global_sam_sid))
2768                 return NT_STATUS_NO_SUCH_GROUP;
2769
2770         sid_append_rid(&group_sid, group_rid);
2771         DEBUG(10, ("lookup on Domain SID\n"));
2772
2773         if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
2774                 return NT_STATUS_NO_SUCH_GROUP;
2775
2776         if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2777                 return NT_STATUS_NO_SUCH_GROUP;
2778
2779         rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
2780         attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
2781         
2782         if (num_uids!=0 && (rid==NULL || attr==NULL))
2783                 return NT_STATUS_NO_MEMORY;
2784         
2785         for (i=0; i<num_uids; i++) {
2786                 rid[i]=pdb_uid_to_user_rid(uid[i]);
2787                 attr[i] = SID_NAME_USER;                
2788         }
2789
2790         init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
2791
2792         return NT_STATUS_OK;
2793 }
2794
2795 /*********************************************************************
2796  _samr_add_aliasmem
2797 *********************************************************************/
2798
2799 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
2800 {
2801         DOM_SID alias_sid;
2802         fstring alias_sid_str;
2803         uid_t uid;
2804         struct passwd *pwd;
2805         struct group *grp;
2806         fstring grp_name;
2807         uint32 rid;
2808         GROUP_MAP map;
2809
2810         /* Find the policy handle. Open a policy on it. */
2811         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid)) 
2812                 return NT_STATUS_INVALID_HANDLE;
2813
2814         sid_to_string(alias_sid_str, &alias_sid);
2815         DEBUG(10, ("sid is %s\n", alias_sid_str));
2816
2817         if (sid_compare(&alias_sid, &global_sam_sid)>0) {
2818                 DEBUG(10, ("adding member on Server SID\n"));
2819                 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
2820                         return NT_STATUS_NO_SUCH_ALIAS;
2821         
2822         } else {
2823                 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
2824                         DEBUG(10, ("adding member on BUILTIN SID\n"));
2825                         if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
2826                                 return NT_STATUS_NO_SUCH_ALIAS;
2827
2828                 } else
2829                         return NT_STATUS_NO_SUCH_ALIAS;
2830         }
2831
2832         sid_split_rid(&q_u->sid.sid, &rid);
2833         uid=pdb_user_rid_to_uid(rid);
2834
2835         if ((pwd=getpwuid(uid)) == NULL)
2836                 return NT_STATUS_NO_SUCH_USER;
2837
2838         if ((grp=getgrgid(map.gid)) == NULL)
2839                 return NT_STATUS_NO_SUCH_ALIAS;
2840
2841         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2842         fstrcpy(grp_name, grp->gr_name);
2843
2844         /* if the user is already in the group */
2845         if(user_in_group_list(pwd->pw_name, grp_name))
2846                 return NT_STATUS_MEMBER_IN_ALIAS;
2847
2848         /* 
2849          * ok, the group exist, the user exist, the user is not in the group,
2850          * we can (finally) add it to the group !
2851          */
2852         smb_add_user_group(grp_name, pwd->pw_name);
2853
2854         /* check if the user has been added then ... */
2855         if(!user_in_group_list(pwd->pw_name, grp_name))
2856                 return NT_STATUS_MEMBER_NOT_IN_ALIAS;   /* don't know what to reply else */
2857
2858         return NT_STATUS_OK;
2859 }
2860
2861 /*********************************************************************
2862  _samr_del_aliasmem
2863 *********************************************************************/
2864
2865 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
2866 {
2867         DOM_SID alias_sid;
2868         fstring alias_sid_str;
2869         struct group *grp;
2870         fstring grp_name;
2871         uint32 rid;
2872         GROUP_MAP map;
2873         SAM_ACCOUNT *sam_pass=NULL;
2874
2875         /* Find the policy handle. Open a policy on it. */
2876         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid)) 
2877                 return NT_STATUS_INVALID_HANDLE;
2878
2879         sid_to_string(alias_sid_str, &alias_sid);
2880         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
2881
2882         if (!sid_check_is_in_our_domain(&alias_sid) &&
2883             !sid_check_is_in_builtin(&alias_sid)) {
2884                 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
2885                 return NT_STATUS_NO_SUCH_ALIAS;
2886         }
2887
2888         if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
2889                 return NT_STATUS_NO_SUCH_ALIAS;
2890
2891         if ((grp=getgrgid(map.gid)) == NULL)
2892                 return NT_STATUS_NO_SUCH_ALIAS;
2893
2894         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2895         fstrcpy(grp_name, grp->gr_name);
2896
2897         sid_peek_rid(&q_u->sid.sid, &rid);
2898
2899         /* check if the user exists before trying to remove it from the group */
2900         pdb_init_sam(&sam_pass);
2901         if(!pdb_getsampwrid(sam_pass, rid)) {
2902                 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
2903                 pdb_free_sam(&sam_pass);
2904                 return NT_STATUS_NO_SUCH_USER;
2905         }
2906
2907         /* if the user is not in the group */
2908         if(!user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
2909                 pdb_free_sam(&sam_pass);
2910                 return NT_STATUS_MEMBER_IN_ALIAS;
2911         }
2912
2913         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
2914
2915         /* check if the user has been removed then ... */
2916         if(user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
2917                 pdb_free_sam(&sam_pass);
2918                 return NT_STATUS_MEMBER_NOT_IN_ALIAS;   /* don't know what to reply else */
2919         }
2920
2921         pdb_free_sam(&sam_pass);
2922         return NT_STATUS_OK;
2923 }
2924
2925 /*********************************************************************
2926  _samr_add_groupmem
2927 *********************************************************************/
2928
2929 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
2930 {
2931         DOM_SID group_sid;
2932         fstring group_sid_str;
2933         struct passwd *pwd;
2934         struct group *grp;
2935         fstring grp_name;
2936         GROUP_MAP map;
2937
2938         /* Find the policy handle. Open a policy on it. */
2939         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid)) 
2940                 return NT_STATUS_INVALID_HANDLE;
2941
2942         sid_to_string(group_sid_str, &group_sid);
2943         DEBUG(10, ("sid is %s\n", group_sid_str));
2944
2945         if (sid_compare(&group_sid, &global_sam_sid)<=0)
2946                 return NT_STATUS_NO_SUCH_GROUP;
2947
2948         DEBUG(10, ("lookup on Domain SID\n"));
2949
2950         if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
2951                 return NT_STATUS_NO_SUCH_GROUP;
2952
2953         if ((pwd=getpwuid(pdb_user_rid_to_uid(q_u->rid))) ==NULL)
2954                 return NT_STATUS_NO_SUCH_USER;
2955
2956         if ((grp=getgrgid(map.gid)) == NULL)
2957                 return NT_STATUS_NO_SUCH_GROUP;
2958
2959         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2960         fstrcpy(grp_name, grp->gr_name);
2961
2962         /* if the user is already in the group */
2963         if(user_in_group_list(pwd->pw_name, grp_name))
2964                 return NT_STATUS_MEMBER_IN_GROUP;
2965
2966         /* 
2967          * ok, the group exist, the user exist, the user is not in the group,
2968          *
2969          * we can (finally) add it to the group !
2970          */
2971
2972         smb_add_user_group(grp_name, pwd->pw_name);
2973
2974         /* check if the user has been added then ... */
2975         if(!user_in_group_list(pwd->pw_name, grp_name))
2976                 return NT_STATUS_MEMBER_NOT_IN_GROUP;           /* don't know what to reply else */
2977
2978         return NT_STATUS_OK;
2979 }
2980
2981 /*********************************************************************
2982  _samr_del_groupmem
2983 *********************************************************************/
2984
2985 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
2986 {
2987         DOM_SID group_sid;
2988         SAM_ACCOUNT *sam_pass=NULL;
2989         uint32 rid;
2990         GROUP_MAP map;
2991         fstring grp_name;
2992         struct group *grp;
2993
2994         /*
2995          * delete the group member named q_u->rid
2996          * who is a member of the sid associated with the handle
2997          * the rid is a user's rid as the group is a domain group.
2998          */
2999
3000         /* Find the policy handle. Open a policy on it. */
3001         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid)) 
3002                 return NT_STATUS_INVALID_HANDLE;
3003
3004         if(!sid_check_is_in_our_domain(&group_sid))
3005                 return NT_STATUS_NO_SUCH_GROUP;
3006
3007         rid=q_u->rid;
3008
3009         if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3010                 return NT_STATUS_NO_SUCH_GROUP;
3011
3012         if ((grp=getgrgid(map.gid)) == NULL)
3013                 return NT_STATUS_NO_SUCH_GROUP;
3014
3015         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3016         fstrcpy(grp_name, grp->gr_name);
3017
3018         /* check if the user exists before trying to remove it from the group */
3019         pdb_init_sam(&sam_pass);
3020         if(!pdb_getsampwrid(sam_pass, rid)) {
3021                 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3022                 pdb_free_sam(&sam_pass);
3023                 return NT_STATUS_NO_SUCH_USER;
3024         }
3025
3026         /* if the user is not in the group */
3027         if(!user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3028                 pdb_free_sam(&sam_pass);
3029                 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3030         }
3031
3032         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3033
3034         /* check if the user has been removed then ... */
3035         if(user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3036                 pdb_free_sam(&sam_pass);
3037                 return NT_STATUS_ACCESS_DENIED;         /* don't know what to reply else */
3038         }
3039         
3040         pdb_free_sam(&sam_pass);
3041         return NT_STATUS_OK;
3042
3043 }
3044
3045 /*********************************************************************
3046  _samr_delete_dom_user
3047 *********************************************************************/
3048
3049 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3050 {
3051         DOM_SID user_sid;
3052         SAM_ACCOUNT *sam_pass=NULL;
3053         uint32 rid;
3054
3055         DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3056
3057         /* Find the policy handle. Open a policy on it. */
3058         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid)) 
3059                 return NT_STATUS_INVALID_HANDLE;
3060
3061         if (!sid_check_is_in_our_domain(&user_sid))
3062                 return NT_STATUS_CANNOT_DELETE;
3063
3064         sid_peek_rid(&user_sid, &rid);
3065
3066         /* check if the user exists before trying to delete */
3067         pdb_init_sam(&sam_pass);
3068         if(!pdb_getsampwrid(sam_pass, rid)) {
3069                 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3070                 pdb_free_sam(&sam_pass);
3071                 return NT_STATUS_NO_SUCH_USER;
3072         }
3073
3074         /* delete the unix side */
3075         /*
3076          * note: we don't check if the delete really happened
3077          * as the script is not necessary present
3078          * and maybe the sysadmin doesn't want to delete the unix side
3079          */
3080         smb_delete_user(pdb_get_username(sam_pass));
3081
3082         /* and delete the samba side */
3083         if (!pdb_delete_sam_account(sam_pass)) {
3084                 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3085                 pdb_free_sam(&sam_pass);
3086                 return NT_STATUS_CANNOT_DELETE;
3087         }
3088         
3089         pdb_free_sam(&sam_pass);
3090
3091         if (!close_policy_hnd(p, &q_u->user_pol))
3092                 return NT_STATUS_OBJECT_NAME_INVALID;
3093
3094         return NT_STATUS_OK;
3095 }
3096
3097 /*********************************************************************
3098  _samr_delete_dom_group
3099 *********************************************************************/
3100
3101 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3102 {
3103         DOM_SID group_sid;
3104         DOM_SID dom_sid;
3105         uint32 group_rid;
3106         fstring group_sid_str;
3107         gid_t gid;
3108         struct group *grp;
3109         GROUP_MAP map;
3110
3111         DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3112
3113         /* Find the policy handle. Open a policy on it. */
3114         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid)) 
3115                 return NT_STATUS_INVALID_HANDLE;
3116
3117         sid_copy(&dom_sid, &group_sid);
3118         sid_to_string(group_sid_str, &dom_sid);
3119         sid_split_rid(&dom_sid, &group_rid);
3120
3121         DEBUG(10, ("sid is %s\n", group_sid_str));
3122
3123         /* we check if it's our SID before deleting */
3124         if (!sid_equal(&dom_sid, &global_sam_sid))
3125                 return NT_STATUS_NO_SUCH_GROUP;
3126
3127         DEBUG(10, ("lookup on Domain SID\n"));
3128
3129         if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3130                 return NT_STATUS_NO_SUCH_GROUP;
3131
3132         gid=map.gid;
3133
3134         /* check if group really exists */
3135         if ( (grp=getgrgid(gid)) == NULL)
3136                 return NT_STATUS_NO_SUCH_GROUP;
3137
3138         /* we can delete the UNIX group */
3139         smb_delete_group(grp->gr_name);
3140
3141         /* check if the group has been successfully deleted */
3142         if ( (grp=getgrgid(gid)) != NULL)
3143                 return NT_STATUS_ACCESS_DENIED;
3144
3145         if(!group_map_remove(group_sid))
3146                 return NT_STATUS_ACCESS_DENIED;
3147
3148         if (!close_policy_hnd(p, &q_u->group_pol))
3149                 return NT_STATUS_OBJECT_NAME_INVALID;
3150
3151         return NT_STATUS_OK;
3152 }
3153
3154 /*********************************************************************
3155  _samr_delete_dom_alias
3156 *********************************************************************/
3157
3158 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3159 {
3160         DOM_SID alias_sid;
3161         DOM_SID dom_sid;
3162         uint32 alias_rid;
3163         fstring alias_sid_str;
3164         gid_t gid;
3165         struct group *grp;
3166         GROUP_MAP map;
3167
3168         DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3169
3170         /* Find the policy handle. Open a policy on it. */
3171         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid)) 
3172                 return NT_STATUS_INVALID_HANDLE;
3173
3174         sid_copy(&dom_sid, &alias_sid);
3175         sid_to_string(alias_sid_str, &dom_sid);
3176         sid_split_rid(&dom_sid, &alias_rid);
3177
3178         DEBUG(10, ("sid is %s\n", alias_sid_str));
3179
3180         /* we check if it's our SID before deleting */
3181         if (!sid_equal(&dom_sid, &global_sam_sid))
3182                 return NT_STATUS_NO_SUCH_ALIAS;
3183
3184         DEBUG(10, ("lookup on Local SID\n"));
3185
3186         if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3187                 return NT_STATUS_NO_SUCH_ALIAS;
3188
3189         gid=map.gid;
3190
3191         /* check if group really exists */
3192         if ( (grp=getgrgid(gid)) == NULL)
3193                 return NT_STATUS_NO_SUCH_ALIAS;
3194
3195         /* we can delete the UNIX group */
3196         smb_delete_group(grp->gr_name);
3197
3198         /* check if the group has been successfully deleted */
3199         if ( (grp=getgrgid(gid)) != NULL)
3200                 return NT_STATUS_ACCESS_DENIED;
3201
3202         /* don't check if we removed it as it could be an un-mapped group */
3203         group_map_remove(alias_sid);
3204
3205         if (!close_policy_hnd(p, &q_u->alias_pol))
3206                 return NT_STATUS_OBJECT_NAME_INVALID;
3207
3208         return NT_STATUS_OK;
3209 }
3210
3211 /*********************************************************************
3212  _samr_create_dom_group
3213 *********************************************************************/
3214
3215 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3216 {
3217         DOM_SID dom_sid;
3218         DOM_SID info_sid;
3219         fstring name;
3220         fstring sid_string;
3221         struct group *grp;
3222         struct samr_info *info;
3223         PRIVILEGE_SET priv_set;
3224
3225         init_privilege(&priv_set);
3226
3227         /* Find the policy handle. Open a policy on it. */
3228         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid)) 
3229                 return NT_STATUS_INVALID_HANDLE;
3230
3231         if (!sid_equal(&dom_sid, &global_sam_sid))
3232                 return NT_STATUS_ACCESS_DENIED;
3233
3234         /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3235
3236         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3237
3238         /* check if group already exist */
3239         if ((grp=getgrnam(name)) != NULL)
3240                 return NT_STATUS_GROUP_EXISTS;
3241
3242         /* we can create the UNIX group */
3243         smb_create_group(name);
3244
3245         /* check if the group has been successfully created */
3246         if ((grp=getgrnam(name)) == NULL)
3247                 return NT_STATUS_ACCESS_DENIED;
3248
3249         r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3250
3251         /* add the group to the mapping table */
3252         sid_copy(&info_sid, &global_sam_sid);
3253         sid_append_rid(&info_sid, r_u->rid);
3254         sid_to_string(sid_string, &info_sid);
3255
3256         if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3257                 return NT_STATUS_ACCESS_DENIED;
3258
3259         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3260                 return NT_STATUS_NO_MEMORY;
3261
3262         /* get a (unique) handle.  open a policy on it. */
3263         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3264                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3265
3266         return NT_STATUS_OK;
3267 }
3268
3269 /*********************************************************************
3270  _samr_create_dom_alias
3271 *********************************************************************/
3272
3273 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3274 {
3275         DOM_SID dom_sid;
3276         DOM_SID info_sid;
3277         fstring name;
3278         fstring sid_string;
3279         struct group *grp;
3280         struct samr_info *info;
3281         PRIVILEGE_SET priv_set;
3282
3283         init_privilege(&priv_set);
3284
3285         /* Find the policy handle. Open a policy on it. */
3286         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid)) 
3287                 return NT_STATUS_INVALID_HANDLE;
3288
3289         if (!sid_equal(&dom_sid, &global_sam_sid))
3290                 return NT_STATUS_ACCESS_DENIED;
3291
3292         /* TODO: check if allowed to create group  and add a become_root/unbecome_root pair.*/
3293
3294         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);