2 * Unix SMB/Netbios implementation.
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.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 * This is the implementation of the SAMR code.
32 extern int DEBUGLEVEL
;
34 extern fstring global_myworkgroup
;
35 extern pstring global_myname
;
36 extern DOM_SID global_sam_sid
;
37 extern DOM_SID global_sid_Builtin
;
39 extern rid_name domain_group_rids
[];
40 extern rid_name domain_alias_rids
[];
41 extern rid_name builtin_alias_rids
[];
44 /* for use by the \PIPE\samr policy */
46 uint32 status
; /* some sort of flag. best to record it. comes from opnum 0x39 */
49 /*******************************************************************
50 Function to free the per handle data.
51 ********************************************************************/
53 static void free_samr_info(void *ptr
)
55 struct samr_info
*samr
= (struct samr_info
*)ptr
;
60 /*******************************************************************
61 Ensure password info is never given out. Paranioa... JRA.
62 ********************************************************************/
64 static void samr_clear_passwd_fields( SAM_USER_INFO_21
*pass
, int num_entries
)
71 for (i
= 0; i
< num_entries
; i
++) {
72 memset(&pass
[i
].lm_pwd
, '\0', sizeof(pass
[i
].lm_pwd
));
73 memset(&pass
[i
].nt_pwd
, '\0', sizeof(pass
[i
].nt_pwd
));
77 static void samr_clear_sam_passwd( SAM_ACCOUNT
*sam_pass
)
83 memset(sam_pass
->lm_pw
, '\0', 16);
85 memset(sam_pass
->nt_pw
, '\0', 16);
88 /*******************************************************************
89 This next function should be replaced with something that
90 dynamically returns the correct user info..... JRA.
91 ********************************************************************/
93 static BOOL
get_sampwd_entries(SAM_USER_INFO_21
*pw_buf
, int start_idx
,
94 int *total_entries
, int *num_entries
,
95 int max_num_entries
, uint16 acb_mask
)
97 SAM_ACCOUNT
*pwd
= NULL
;
100 (*total_entries
) = 0;
105 if (!pdb_setsampwent(False
)) {
106 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
110 while (((pwd
= pdb_getsampwent()) != NULL
) && (*num_entries
) < max_num_entries
) {
114 /* skip the requested number of entries.
115 not very efficient, but hey...
121 user_name_len
= strlen(pdb_get_username(pwd
))+1;
122 init_unistr2(&pw_buf
[(*num_entries
)].uni_user_name
, pdb_get_username(pwd
), user_name_len
);
123 init_uni_hdr(&pw_buf
[(*num_entries
)].hdr_user_name
, user_name_len
);
124 pw_buf
[(*num_entries
)].user_rid
= pwd
->user_rid
;
125 memset((char *)pw_buf
[(*num_entries
)].nt_pwd
, '\0', 16);
127 /* Now check if the NT compatible password is available. */
128 if (pdb_get_nt_passwd(pwd
))
129 memcpy( pw_buf
[(*num_entries
)].nt_pwd
, pdb_get_nt_passwd(pwd
), 16);
131 pw_buf
[(*num_entries
)].acb_info
= pdb_get_acct_ctrl(pwd
);
133 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
134 (*num_entries
), pdb_get_username(pwd
), pdb_get_user_rid(pwd
), pdb_get_acct_ctrl(pwd
) ));
136 if (acb_mask
== 0 || (pwd
->acct_ctrl
& acb_mask
)) {
137 DEBUG(5,(" acb_mask %x accepts\n", acb_mask
));
141 DEBUG(5,(" acb_mask %x rejects\n", acb_mask
));
148 return (*num_entries
) > 0;
151 static BOOL
jf_get_sampwd_entries(SAM_USER_INFO_21
*pw_buf
, int start_idx
,
152 int *total_entries
, uint32
*num_entries
,
153 int max_num_entries
, uint16 acb_mask
)
155 SAM_ACCOUNT
*pwd
= NULL
;
163 if (!pdb_setsampwent(False
)) {
164 DEBUG(0, ("jf_get_sampwd_entries: Unable to open passdb.\n"));
168 while (((pwd
= pdb_getsampwent()) != NULL
) && (*num_entries
) < max_num_entries
) {
172 if (acb_mask
!= 0 && !(pdb_get_acct_ctrl(pwd
) & acb_mask
))
176 /* skip the requested number of entries.
177 not very efficient, but hey...
183 ZERO_STRUCTP(&pw_buf
[(*num_entries
)]);
185 user_name_len
= strlen(pdb_get_username(pwd
));
186 init_unistr2(&pw_buf
[(*num_entries
)].uni_user_name
, pdb_get_username(pwd
), user_name_len
);
187 init_uni_hdr(&pw_buf
[(*num_entries
)].hdr_user_name
, user_name_len
);
189 full_name_len
= strlen(pdb_get_fullname(pwd
));
190 init_unistr2(&pw_buf
[(*num_entries
)].uni_full_name
, pdb_get_fullname(pwd
), full_name_len
);
191 init_uni_hdr(&pw_buf
[(*num_entries
)].hdr_full_name
, full_name_len
);
193 pw_buf
[(*num_entries
)].user_rid
= pdb_get_user_rid(pwd
);
194 memset((char *)pw_buf
[(*num_entries
)].nt_pwd
, '\0', 16);
196 /* Now check if the NT compatible password is available. */
197 if (pdb_get_nt_passwd(pwd
))
198 memcpy( pw_buf
[(*num_entries
)].nt_pwd
, pdb_get_nt_passwd(pwd
), 16);
200 pw_buf
[(*num_entries
)].acb_info
= pdb_get_acct_ctrl(pwd
);
202 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x\n", (*num_entries
),
203 pdb_get_username(pwd
), pdb_get_user_rid(pwd
), pdb_get_acct_ctrl(pwd
) ));
209 *total_entries
= *num_entries
;
213 /*******************************************************************
214 This function uses the username map file and tries to map a UNIX
215 user name to an DOS name. (Sort of the reverse of the
216 map_username() function.) Since more than one DOS name can map
217 to the UNIX name, to reverse the mapping you have to specify
218 which corresponding DOS name you want; that's where the name_idx
219 parameter comes in. Returns the string requested or NULL if it
220 fails or can't complete the request for any reason. This doesn't
221 handle group names (starting with '@') or names starting with
222 '+' or '&'. If they are encountered, they are skipped.
223 ********************************************************************/
225 static char *unmap_unixname(char *unix_user_name
, int name_idx
)
227 char *mapfile
= lp_username_map();
232 if (!*unix_user_name
) return NULL
;
233 if (!*mapfile
) return NULL
;
235 lines
= file_lines_load(mapfile
, NULL
,False
);
237 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile
));
241 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile
, name_idx
));
243 for (i
=0; lines
[i
]; i
++) {
244 char *unixname
= lines
[i
];
245 char *dosname
= strchr(unixname
,'=');
252 while (isspace(*unixname
))
254 if ('!' == *unixname
) {
256 while (*unixname
&& isspace(*unixname
))
260 if (!*unixname
|| strchr("#;",*unixname
))
263 if (strncmp(unixname
, unix_user_name
, strlen(unix_user_name
)))
266 /* We have matched the UNIX user name */
268 while(next_token(&dosname
, tok
, LIST_SEP
, sizeof(tok
))) {
269 if (!strchr("@&+", *tok
)) {
278 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
279 file_lines_free(lines
);
282 file_lines_free(lines
);
287 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
288 file_lines_free(lines
);
292 /*******************************************************************
293 This function sets up a list of users taken from the list of
294 users that UNIX knows about, as well as all the user names that
295 Samba maps to a valid UNIX user name. (This should work with
297 ********************************************************************/
299 static BOOL
get_passwd_entries(SAM_USER_INFO_21
*pw_buf
,
301 int *total_entries
, int *num_entries
,
305 static struct passwd
*pwd
= NULL
;
306 static uint32 pw_rid
;
307 static BOOL orig_done
= False
;
308 static int current_idx
= 0;
309 static int mapped_idx
= 0;
312 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
315 (*total_entries
) = 0;
317 /* Skip all this stuff if we're in appliance mode */
319 if (lp_hide_local_users()) goto done
;
321 if (pw_buf
== NULL
) return False
;
323 if (current_idx
== 0) {
327 /* These two cases are inefficient, but should be called very rarely */
328 /* they are the cases where the starting index isn't picking up */
329 /* where we left off last time. It is efficient when it starts over */
330 /* at zero though. */
331 if (start_idx
> current_idx
) {
332 /* We aren't far enough; advance to start_idx */
333 while (current_idx
<= start_idx
) {
337 if ((pwd
= sys_getpwent()) == NULL
) break;
342 while (((unmap_name
= unmap_unixname(pwd
->pw_name
, mapped_idx
)) != NULL
) &&
343 (current_idx
< start_idx
)) {
348 if (unmap_name
== NULL
) {
353 } else if (start_idx
< current_idx
) {
354 /* We are already too far; start over and advance to start_idx */
360 while (current_idx
< start_idx
) {
364 if ((pwd
= sys_getpwent()) == NULL
) break;
369 while (((unmap_name
= unmap_unixname(pwd
->pw_name
, mapped_idx
)) != NULL
) &&
370 (current_idx
< start_idx
)) {
375 if (unmap_name
== NULL
) {
382 sep
= lp_winbind_separator();
384 /* now current_idx == start_idx */
385 while ((*num_entries
) < max_num_entries
) {
389 /* This does the original UNIX user itself */
391 if ((pwd
= sys_getpwent()) == NULL
) break;
393 /* Don't enumerate winbind users as they are not local */
395 if (strchr(pwd
->pw_name
, *sep
) != NULL
) {
399 user_name_len
= strlen(pwd
->pw_name
);
401 /* skip the trust account stored in the /etc/passwd file */
402 if (pwd
->pw_name
[user_name_len
-1]=='$')
405 pw_rid
= pdb_uid_to_user_rid(pwd
->pw_uid
);
406 ZERO_STRUCTP(&pw_buf
[(*num_entries
)]);
407 init_unistr2(&pw_buf
[(*num_entries
)].uni_user_name
, pwd
->pw_name
, user_name_len
);
408 init_uni_hdr(&pw_buf
[(*num_entries
)].hdr_user_name
, user_name_len
);
409 pw_buf
[(*num_entries
)].user_rid
= pw_rid
;
410 memset((char *)pw_buf
[(*num_entries
)].nt_pwd
, '\0', 16);
412 pw_buf
[(*num_entries
)].acb_info
= ACB_NORMAL
;
414 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries
), pwd
->pw_name
, pw_rid
));
422 /* This does all the user names that map to the UNIX user */
423 while (((unmap_name
= unmap_unixname(pwd
->pw_name
, mapped_idx
)) != NULL
) &&
424 (*num_entries
< max_num_entries
)) {
425 user_name_len
= strlen(unmap_name
);
426 ZERO_STRUCTP(&pw_buf
[(*num_entries
)]);
427 init_unistr2(&pw_buf
[(*num_entries
)].uni_user_name
, unmap_name
, user_name_len
);
428 init_uni_hdr(&pw_buf
[(*num_entries
)].hdr_user_name
, user_name_len
);
429 pw_buf
[(*num_entries
)].user_rid
= pw_rid
;
430 memset((char *)pw_buf
[(*num_entries
)].nt_pwd
, '\0', 16);
432 pw_buf
[(*num_entries
)].acb_info
= ACB_NORMAL
;
434 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries
), pwd
->pw_name
, pw_rid
));
442 if (unmap_name
== NULL
) {
443 /* done with 'aliases', go on to next UNIX user */
450 /* totally done, reset everything */
457 return (*num_entries
) > 0;
460 /*******************************************************************
462 ********************************************************************/
464 uint32
_samr_close_hnd(pipes_struct
*p
, SAMR_Q_CLOSE_HND
*q_u
, SAMR_R_CLOSE_HND
*r_u
)
466 r_u
->status
= NT_STATUS_NOPROBLEMO
;
468 /* close the policy handle */
469 if (!close_policy_hnd(p
, &q_u
->pol
))
470 return NT_STATUS_OBJECT_NAME_INVALID
;
472 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__
));
477 /*******************************************************************
478 samr_reply_open_domain
479 ********************************************************************/
481 uint32
_samr_open_domain(pipes_struct
*p
, SAMR_Q_OPEN_DOMAIN
*q_u
, SAMR_R_OPEN_DOMAIN
*r_u
)
483 struct samr_info
*info
;
485 r_u
->status
= NT_STATUS_NOPROBLEMO
;
487 /* find the connection policy handle. */
488 if (!find_policy_by_hnd(p
, &q_u
->pol
, NULL
))
489 return NT_STATUS_INVALID_HANDLE
;
491 /* associate the domain SID with the (unique) handle. */
492 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
493 return NT_STATUS_NO_MEMORY
;
496 info
->sid
= q_u
->dom_sid
.sid
;
498 /* get a (unique) handle. open a policy on it. */
499 if (!create_policy_hnd(p
, &r_u
->domain_pol
, free_samr_info
, (void *)info
))
500 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
502 DEBUG(5,("samr_open_domain: %d\n", __LINE__
));
507 static uint32
get_lsa_policy_samr_rid(struct samr_info
*info
)
510 DEBUG(3,("Error getting policy\n"));
514 return info
->sid
.sub_auths
[info
->sid
.num_auths
-1];
517 /*******************************************************************
518 _samr_get_usrdom_pwinfo
519 ********************************************************************/
521 uint32
_samr_get_usrdom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_USRDOM_PWINFO
*q_u
, SAMR_R_GET_USRDOM_PWINFO
*r_u
)
523 struct samr_info
*info
= NULL
;
525 r_u
->status
= NT_STATUS_NOPROBLEMO
;
527 /* find the policy handle. open a policy on it. */
528 if (!find_policy_by_hnd(p
, &q_u
->user_pol
, (void **)&info
)) {
529 return NT_STATUS_INVALID_HANDLE
;
532 /* find the user's rid */
533 if (get_lsa_policy_samr_rid(info
) == 0xffffffff) {
534 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
537 init_samr_r_get_usrdom_pwinfo(r_u
, NT_STATUS_NOPROBLEMO
);
539 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__
));
544 /*******************************************************************
546 ********************************************************************/
548 static uint32
samr_make_usr_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC_BUF
**buf
, DOM_SID
*usr_sid
)
550 extern DOM_SID global_sid_World
;
558 SEC_DESC
*psd
= NULL
;
561 sid_copy(&adm_sid
, &global_sid_Builtin
);
562 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
564 sid_copy(&act_sid
, &global_sid_Builtin
);
565 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
567 init_sec_access(&mask
, 0x2035b);
568 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
570 init_sec_access(&mask
, 0xf07ff);
571 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
572 init_sec_ace(&ace
[2], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
574 init_sec_access(&mask
,0x20044);
575 init_sec_ace(&ace
[3], usr_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
577 if((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 4, ace
)) == NULL
)
578 return NT_STATUS_NO_MEMORY
;
580 if((psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, NULL
, NULL
, NULL
, psa
, &sd_size
)) == NULL
)
581 return NT_STATUS_NO_MEMORY
;
583 if((*buf
= make_sec_desc_buf(ctx
, sd_size
, psd
)) == NULL
)
584 return NT_STATUS_NO_MEMORY
;
586 return NT_STATUS_NOPROBLEMO
;
589 static BOOL
get_lsa_policy_samr_sid(pipes_struct
*p
, POLICY_HND
*pol
, DOM_SID
*sid
)
591 struct samr_info
*info
= NULL
;
593 /* find the policy handle. open a policy on it. */
594 if (!find_policy_by_hnd(p
, pol
, (void **)&info
))
604 /*******************************************************************
606 ********************************************************************/
608 uint32
_samr_query_sec_obj(pipes_struct
*p
, SAMR_Q_QUERY_SEC_OBJ
*q_u
, SAMR_R_QUERY_SEC_OBJ
*r_u
)
612 r_u
->status
= NT_STATUS_NOPROBLEMO
;
616 if (!get_lsa_policy_samr_sid(p
, &q_u
->user_pol
, &pol_sid
))
617 return NT_STATUS_INVALID_HANDLE
;
619 r_u
->status
= samr_make_usr_obj_sd(p
->mem_ctx
, &r_u
->buf
, &pol_sid
);
621 if (r_u
->status
== NT_STATUS_NOPROBLEMO
)
627 /*******************************************************************
628 makes a SAM_ENTRY / UNISTR2* structure from a user list.
629 ********************************************************************/
631 static void make_user_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
, UNISTR2
**uni_name_pp
,
632 uint32 num_sam_entries
, SAM_USER_INFO_21
*pass
)
641 if (num_sam_entries
== 0)
644 sam
= (SAM_ENTRY
*)talloc(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
646 uni_name
= (UNISTR2
*)talloc(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
648 if (sam
== NULL
|| uni_name
== NULL
) {
649 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
653 for (i
= 0; i
< num_sam_entries
; i
++) {
654 int len
= pass
[i
].uni_user_name
.uni_str_len
;
656 init_sam_entry(&sam
[i
], len
, pass
[i
].user_rid
);
657 copy_unistr2(&uni_name
[i
], &pass
[i
].uni_user_name
);
661 *uni_name_pp
= uni_name
;
664 /*******************************************************************
665 samr_reply_enum_dom_users
666 ********************************************************************/
668 uint32
_samr_enum_dom_users(pipes_struct
*p
, SAMR_Q_ENUM_DOM_USERS
*q_u
, SAMR_R_ENUM_DOM_USERS
*r_u
)
670 SAM_USER_INFO_21 pass
[MAX_SAM_ENTRIES
];
672 int total_entries
= 0;
675 r_u
->status
= NT_STATUS_NOPROBLEMO
;
677 /* find the policy handle. open a policy on it. */
678 if (!find_policy_by_hnd(p
, &q_u
->pol
, NULL
))
679 return NT_STATUS_INVALID_HANDLE
;
681 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
684 ret
= get_sampwd_entries(pass
, q_u
->start_idx
, &total_entries
, &num_entries
,
685 MAX_SAM_ENTRIES
, q_u
->acb_mask
);
689 return NT_STATUS_ACCESS_DENIED
;
691 samr_clear_passwd_fields(pass
, num_entries
);
694 * Note from JRA. total_entries is not being used here. Currently if there is a
695 * large user base then it looks like NT will enumerate until get_sampwd_entries
696 * returns False due to num_entries being zero. This will cause an access denied
697 * return. I don't think this is right and needs further investigation. Note that
698 * this is also the same in the TNG code (I don't think that has been tested with
699 * a very large user list as MAX_SAM_ENTRIES is set to 600).
701 * I also think that one of the 'num_entries' return parameters is probably
702 * the "max entries" parameter - but in the TNG code they're all currently set to the same
703 * value (again I think this is wrong).
706 make_user_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_acct_name
, num_entries
, pass
);
708 init_samr_r_enum_dom_users(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
710 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
715 /*******************************************************************
716 makes a SAM_ENTRY / UNISTR2* structure from a group list.
717 ********************************************************************/
719 static void make_group_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
, UNISTR2
**uni_name_pp
,
720 uint32 num_sam_entries
, DOMAIN_GRP
*grp
)
729 if (num_sam_entries
== 0)
732 sam
= (SAM_ENTRY
*)talloc(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
734 uni_name
= (UNISTR2
*)talloc(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
736 if (sam
== NULL
|| uni_name
== NULL
) {
737 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
741 for (i
= 0; i
< num_sam_entries
; i
++) {
743 * JRA. I think this should include the null. TNG does not.
745 int len
= strlen(grp
[i
].name
)+1;
747 init_sam_entry(&sam
[i
], len
, grp
[i
].rid
);
748 init_unistr2(&uni_name
[i
], grp
[i
].name
, len
);
752 *uni_name_pp
= uni_name
;
755 /*******************************************************************
756 Get the group entries - similar to get_sampwd_entries().
757 ********************************************************************/
759 static BOOL
get_group_alias_entries(DOMAIN_GRP
*d_grp
, DOM_SID
*sid
, uint32 start_idx
,
760 uint32
*p_num_entries
, uint32 max_entries
)
764 uint32 num_entries
= 0;
766 sid_to_string(sid_str
, sid
);
767 sid_to_string(sam_sid_str
, &global_sam_sid
);
771 /* well-known aliases */
772 if (strequal(sid_str
, "S-1-5-32")) {
774 while (!lp_hide_local_users() &&
775 num_entries
< max_entries
&&
776 ((name
= builtin_alias_rids
[num_entries
].name
) != NULL
)) {
778 fstrcpy(d_grp
[num_entries
].name
, name
);
779 d_grp
[num_entries
].rid
= builtin_alias_rids
[num_entries
].rid
;
783 } else if (strequal(sid_str
, sam_sid_str
) && !lp_hide_local_users()) {
788 sep
= lp_winbind_separator();
791 /* we return the UNIX groups here. This seems to be the right */
792 /* thing to do, since NT member servers return their local */
793 /* groups in the same situation. */
796 while (num_entries
< max_entries
&& ((grp
= getgrent()) != NULL
)) {
801 DEBUG(10,("get_group_alias_entries: got group %s\n", name
));
803 /* Don't return winbind groups as they are not local! */
805 if (strchr(name
, *sep
) != NULL
) {
806 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", name
));
810 /* Don't return user private groups... */
811 if (Get_Pwnam(name
, False
) != 0) {
812 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", name
));
816 trid
= pdb_gid_to_group_rid(grp
->gr_gid
);
817 for( i
= 0; i
< num_entries
; i
++)
818 if ( d_grp
[i
].rid
== trid
) break;
820 if ( i
< num_entries
)
821 continue; /* rid was there, dup! */
823 /* JRA - added this for large group db enumeration... */
826 /* skip the requested number of entries.
827 not very efficient, but hey...
833 fstrcpy(d_grp
[num_entries
].name
, name
);
834 d_grp
[num_entries
].rid
= trid
;
841 *p_num_entries
= num_entries
;
846 /*******************************************************************
847 Get the group entries - similar to get_sampwd_entries().
848 ********************************************************************/
850 static BOOL
get_group_domain_entries(DOMAIN_GRP
*d_grp
, DOM_SID
*sid
, uint32 start_idx
,
851 uint32
*p_num_entries
, uint32 max_entries
)
855 uint32 num_entries
= 0;
856 fstring name
="Domain Admins";
857 fstring comment
="Just to make it work !";
859 sid_to_string(sid_str
, sid
);
860 sid_to_string(sam_sid_str
, &global_sam_sid
);
864 fstrcpy(d_grp
[0].name
, name
);
865 fstrcpy(d_grp
[0].comment
, comment
);
866 d_grp
[0].rid
= DOMAIN_GROUP_RID_ADMINS
;
867 d_grp
[0].attr
=SID_NAME_DOM_GRP
;
869 fstrcpy(d_grp
[1].name
, "Domain Users");
870 fstrcpy(d_grp
[1].comment
, "Just to make it work !");
871 d_grp
[1].rid
= DOMAIN_GROUP_RID_USERS
;
872 d_grp
[1].attr
=SID_NAME_DOM_GRP
;
876 *p_num_entries
= num_entries
;
881 /*******************************************************************
882 samr_reply_enum_dom_groups
883 Only reply with one group - domain admins. This must be fixed for
885 ********************************************************************/
887 uint32
_samr_enum_dom_groups(pipes_struct
*p
, SAMR_Q_ENUM_DOM_GROUPS
*q_u
, SAMR_R_ENUM_DOM_GROUPS
*r_u
)
893 r_u
->status
= NT_STATUS_NOPROBLEMO
;
895 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
))
896 return NT_STATUS_INVALID_HANDLE
;
898 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__
));
900 get_group_domain_entries(grp
, &sid
, q_u
->start_idx
, &num_entries
, MAX_SAM_ENTRIES
);
902 make_group_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_grp_name
, num_entries
, grp
);
904 init_samr_r_enum_dom_groups(r_u
, q_u
->start_idx
, num_entries
);
906 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__
));
912 /*******************************************************************
913 samr_reply_enum_dom_aliases
914 ********************************************************************/
916 uint32
_samr_enum_dom_aliases(pipes_struct
*p
, SAMR_Q_ENUM_DOM_ALIASES
*q_u
, SAMR_R_ENUM_DOM_ALIASES
*r_u
)
918 DOMAIN_GRP grp
[MAX_SAM_ENTRIES
];
919 uint32 num_entries
= 0;
923 r_u
->status
= NT_STATUS_NOPROBLEMO
;
925 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
))
926 return NT_STATUS_INVALID_HANDLE
;
928 sid_to_string(sid_str
, &sid
);
929 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str
));
931 if (!get_group_alias_entries(grp
, &sid
, q_u
->start_idx
, &num_entries
, MAX_SAM_ENTRIES
))
932 return NT_STATUS_ACCESS_DENIED
;
934 make_group_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_grp_name
, num_entries
, grp
);
936 init_samr_r_enum_dom_aliases(r_u
, q_u
->start_idx
, num_entries
);
938 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__
));
943 /*******************************************************************
944 samr_reply_query_dispinfo
945 ********************************************************************/
947 uint32
_samr_query_dispinfo(pipes_struct
*p
, SAMR_Q_QUERY_DISPINFO
*q_u
, SAMR_R_QUERY_DISPINFO
*r_u
)
949 SAM_USER_INFO_21 pass
[MAX_SAM_ENTRIES
];
950 DOMAIN_GRP grps
[MAX_SAM_ENTRIES
];
951 uint16 acb_mask
= ACB_NORMAL
;
952 uint32 num_entries
= 0;
953 int orig_num_entries
= 0;
954 int total_entries
= 0;
955 uint32 data_size
= 0;
958 SAM_DISPINFO_CTR
*ctr
;
960 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__
));
962 r_u
->status
= NT_STATUS_NOPROBLEMO
;
964 if (!get_lsa_policy_samr_sid(p
, &q_u
->domain_pol
, &sid
))
965 return NT_STATUS_INVALID_HANDLE
;
967 /* decide how many entries to get depending on the max_entries
968 and max_size passed by client */
970 if(q_u
->max_entries
> MAX_SAM_ENTRIES
)
971 q_u
->max_entries
= MAX_SAM_ENTRIES
;
973 /* Get what we need from the password database */
974 switch (q_u
->switch_level
) {
976 acb_mask
= ACB_WSTRUST
;
982 ret
= get_passwd_entries(pass
, q_u
->start_idx
, &total_entries
, &num_entries
,
983 MAX_SAM_ENTRIES
, acb_mask
);
987 * Which should we use here ? JRA.
989 ret
= get_sampwd_entries(pass
, q_u
->start_idx
, &total_entries
, &num_entries
,
990 MAX_SAM_ENTRIES
, acb_mask
);
993 ret
= jf_get_sampwd_entries(pass
, q_u
->start_idx
, &total_entries
, &num_entries
,
994 MAX_SAM_ENTRIES
, acb_mask
);
998 DEBUG(5, ("get_sampwd_entries: failed\n"));
999 return NT_STATUS_ACCESS_DENIED
;
1004 ret
= get_group_domain_entries(grps
, &sid
, q_u
->start_idx
, &num_entries
, MAX_SAM_ENTRIES
);
1006 return NT_STATUS_ACCESS_DENIED
;
1009 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u
->switch_level
));
1010 return NT_STATUS_INVALID_INFO_CLASS
;
1014 if (num_entries
> q_u
->max_entries
)
1015 num_entries
= q_u
->max_entries
;
1017 if (num_entries
> MAX_SAM_ENTRIES
) {
1018 num_entries
= MAX_SAM_ENTRIES
;
1019 DEBUG(5, ("limiting number of entries to %d\n", num_entries
));
1022 /* Ensure password info is never given out here. PARANOIA... JRA */
1023 samr_clear_passwd_fields(pass
, num_entries
);
1025 data_size
= q_u
->max_size
;
1026 orig_num_entries
= num_entries
;
1028 ctr
= (SAM_DISPINFO_CTR
*)talloc(p
->mem_ctx
,sizeof(SAM_DISPINFO_CTR
));
1030 /* Now create reply structure */
1031 switch (q_u
->switch_level
) {
1033 ctr
->sam
.info1
= (SAM_DISPINFO_1
*)talloc(p
->mem_ctx
,num_entries
*sizeof(SAM_DISPINFO_1
));
1034 init_sam_dispinfo_1(ctr
->sam
.info1
, &num_entries
, &data_size
, q_u
->start_idx
, pass
);
1037 ctr
->sam
.info2
= (SAM_DISPINFO_2
*)talloc(p
->mem_ctx
,num_entries
*sizeof(SAM_DISPINFO_2
));
1038 init_sam_dispinfo_2(ctr
->sam
.info2
, &num_entries
, &data_size
, q_u
->start_idx
, pass
);
1041 ctr
->sam
.info3
= (SAM_DISPINFO_3
*)talloc(p
->mem_ctx
,num_entries
*sizeof(SAM_DISPINFO_3
));
1042 init_sam_dispinfo_3(ctr
->sam
.info3
, &num_entries
, &data_size
, q_u
->start_idx
, grps
);
1045 ctr
->sam
.info4
= (SAM_DISPINFO_4
*)talloc(p
->mem_ctx
,num_entries
*sizeof(SAM_DISPINFO_4
));
1046 init_sam_dispinfo_4(ctr
->sam
.info4
, &num_entries
, &data_size
, q_u
->start_idx
, pass
);
1049 ctr
->sam
.info5
= (SAM_DISPINFO_5
*)talloc(p
->mem_ctx
,num_entries
*sizeof(SAM_DISPINFO_5
));
1050 init_sam_dispinfo_5(ctr
->sam
.info5
, &num_entries
, &data_size
, q_u
->start_idx
, grps
);
1053 ctr
->sam
.info
= NULL
;
1054 return NT_STATUS_INVALID_INFO_CLASS
;
1057 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__
));
1059 init_samr_r_query_dispinfo(r_u
, num_entries
, data_size
, q_u
->switch_level
, ctr
, r_u
->status
);
1061 if (num_entries
< orig_num_entries
) {
1062 return STATUS_MORE_ENTRIES
;
1068 /*******************************************************************
1069 samr_reply_query_aliasinfo
1070 ********************************************************************/
1072 uint32
_samr_query_aliasinfo(pipes_struct
*p
, SAMR_Q_QUERY_ALIASINFO
*q_u
, SAMR_R_QUERY_ALIASINFO
*r_u
)
1074 fstring alias_desc
= "Local Unix group";
1076 enum SID_NAME_USE type
;
1078 struct samr_info
*info
= NULL
;
1080 r_u
->status
= NT_STATUS_NOPROBLEMO
;
1082 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1084 /* find the policy handle. open a policy on it. */
1085 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1086 return NT_STATUS_INVALID_HANDLE
;
1088 alias_rid
= get_lsa_policy_samr_rid(info
);
1089 if(alias_rid
== 0xffffffff)
1090 return NT_STATUS_NO_SUCH_ALIAS
;
1092 if(!local_lookup_rid(alias_rid
, alias
, &type
))
1093 return NT_STATUS_NO_SUCH_ALIAS
;
1095 switch (q_u
->switch_level
) {
1098 r_u
->ctr
.switch_value1
= 3;
1099 init_samr_alias_info3(&r_u
->ctr
.alias
.info3
, alias_desc
);
1102 return NT_STATUS_INVALID_INFO_CLASS
;
1105 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1111 /*******************************************************************
1112 samr_reply_lookup_ids
1113 ********************************************************************/
1115 uint32
_samr_lookup_ids(pipes_struct
*p
, SAMR_Q_LOOKUP_IDS
*q_u
, SAMR_R_LOOKUP_IDS
*r_u
)
1117 uint32 rid
[MAX_SAM_ENTRIES
];
1118 int num_rids
= q_u
->num_sids1
;
1120 r_u
->status
= NT_STATUS_NOPROBLEMO
;
1122 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1124 if (num_rids
> MAX_SAM_ENTRIES
) {
1125 num_rids
= MAX_SAM_ENTRIES
;
1126 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids
));
1131 SMB_ASSERT_ARRAY(q_u
->uni_user_name
, num_rids
);
1133 for (i
= 0; i
< num_rids
&& status
== 0; i
++)
1135 struct sam_passwd
*sam_pass
;
1139 fstrcpy(user_name
, unistrn2(q_u
->uni_user_name
[i
].buffer
,
1140 q_u
->uni_user_name
[i
].uni_str_len
));
1142 /* find the user account */
1144 sam_pass
= get_smb21pwd_entry(user_name
, 0);
1147 if (sam_pass
== NULL
)
1149 status
= 0xC0000000 | NT_STATUS_NO_SUCH_USER
;
1154 rid
[i
] = sam_pass
->user_rid
;
1160 rid
[0] = BUILTIN_ALIAS_RID_USERS
;
1162 init_samr_r_lookup_ids(&r_u
, num_rids
, rid
, NT_STATUS_NOPROBLEMO
);
1164 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1170 /*******************************************************************
1172 ********************************************************************/
1174 uint32
_samr_lookup_names(pipes_struct
*p
, SAMR_Q_LOOKUP_NAMES
*q_u
, SAMR_R_LOOKUP_NAMES
*r_u
)
1176 uint32 rid
[MAX_SAM_ENTRIES
];
1177 enum SID_NAME_USE type
[MAX_SAM_ENTRIES
];
1179 int num_rids
= q_u
->num_names1
;
1182 r_u
->status
= NT_STATUS_NOPROBLEMO
;
1184 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1189 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
)) {
1190 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, 0, NULL
, NULL
, NT_STATUS_OBJECT_TYPE_MISMATCH
);
1194 if (num_rids
> MAX_SAM_ENTRIES
) {
1195 num_rids
= MAX_SAM_ENTRIES
;
1196 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids
));
1199 SMB_ASSERT_ARRAY(q_u
->uni_name
, num_rids
);
1201 for (i
= 0; i
< num_rids
; i
++) {
1204 r_u
->status
= NT_STATUS_NONE_MAPPED
;
1206 rid
[i
] = 0xffffffff;
1207 type
[i
] = SID_NAME_UNKNOWN
;
1209 fstrcpy(name
, dos_unistrn2(q_u
->uni_name
[i
].buffer
, q_u
->uni_name
[i
].uni_str_len
));
1211 if(sid_equal(&pol_sid
, &global_sam_sid
)) {
1213 if(local_lookup_name(global_myname
, name
, &sid
, &type
[i
])) {
1214 sid_split_rid( &sid
, &rid
[i
]);
1215 r_u
->status
= NT_STATUS_NOPROBLEMO
;
1220 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, num_rids
, rid
, (uint32
*)type
, r_u
->status
);
1222 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1227 /*******************************************************************
1228 _samr_chgpasswd_user
1229 ********************************************************************/
1231 uint32
_samr_chgpasswd_user(pipes_struct
*p
, SAMR_Q_CHGPASSWD_USER
*q_u
, SAMR_R_CHGPASSWD_USER
*r_u
)
1236 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1238 r_u
->status
= NT_STATUS_NOPROBLEMO
;
1240 fstrcpy(user_name
, dos_unistrn2(q_u
->uni_user_name
.buffer
, q_u
->uni_user_name
.uni_str_len
));
1241 fstrcpy(wks
, dos_unistrn2(q_u
->uni_dest_host
.buffer
, q_u
->uni_dest_host
.uni_str_len
));
1243 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name
, wks
));
1246 * Pass the user through the NT -> unix user mapping
1250 (void)map_username(user_name
);
1253 * Do any UNIX username case mangling.
1255 (void)Get_Pwnam( user_name
, True
);
1257 if (!pass_oem_change(user_name
, q_u
->lm_newpass
.pass
, q_u
->lm_oldhash
.hash
,
1258 q_u
->nt_newpass
.pass
, q_u
->nt_oldhash
.hash
))
1259 r_u
->status
= NT_STATUS_WRONG_PASSWORD
;
1261 init_samr_r_chgpasswd_user(r_u
, r_u
->status
);
1263 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1268 /*******************************************************************
1269 makes a SAMR_R_LOOKUP_RIDS structure.
1270 ********************************************************************/
1272 static BOOL
make_samr_lookup_rids(TALLOC_CTX
*ctx
, uint32 num_names
, fstring names
[],
1273 UNIHDR
**pp_hdr_name
, UNISTR2
**pp_uni_name
)
1276 UNIHDR
*hdr_name
=NULL
;
1277 UNISTR2
*uni_name
=NULL
;
1279 *pp_uni_name
= NULL
;
1280 *pp_hdr_name
= NULL
;
1282 if (num_names
!= 0) {
1283 hdr_name
= (UNIHDR
*)talloc(ctx
, sizeof(UNIHDR
)*num_names
);
1284 if (hdr_name
== NULL
)
1287 uni_name
= (UNISTR2
*)talloc(ctx
,sizeof(UNISTR2
)*num_names
);
1288 if (uni_name
== NULL
)
1292 for (i
= 0; i
< num_names
; i
++) {
1293 int len
= names
[i
] != NULL
? strlen(names
[i
]) : 0;
1294 DEBUG(10, ("names[%d]:%s\n", i
, names
[i
]));
1295 init_uni_hdr(&hdr_name
[i
], len
);
1296 init_unistr2(&uni_name
[i
], names
[i
], len
);
1299 *pp_uni_name
= uni_name
;
1300 *pp_hdr_name
= hdr_name
;
1305 /*******************************************************************
1307 ********************************************************************/
1309 uint32
_samr_lookup_rids(pipes_struct
*p
, SAMR_Q_LOOKUP_RIDS
*q_u
, SAMR_R_LOOKUP_RIDS
*r_u
)
1311 fstring group_names
[MAX_SAM_ENTRIES
];
1312 uint32 group_attrs
[MAX_SAM_ENTRIES
];
1313 UNIHDR
*hdr_name
= NULL
;
1314 UNISTR2
*uni_name
= NULL
;
1316 int num_rids
= q_u
->num_rids1
;
1319 r_u
->status
= NT_STATUS_NOPROBLEMO
;
1321 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__
));
1323 /* find the policy handle. open a policy on it. */
1324 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
))
1325 return NT_STATUS_INVALID_HANDLE
;
1327 if (num_rids
> MAX_SAM_ENTRIES
) {
1328 num_rids
= MAX_SAM_ENTRIES
;
1329 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids
));
1332 r_u
->status
= NT_STATUS_NONE_MAPPED
;
1334 for (i
= 0; i
< num_rids
; i
++) {
1338 enum SID_NAME_USE type
;
1340 group_attrs
[i
] = SID_NAME_UNKNOWN
;
1341 *group_names
[i
] = '\0';
1343 if (sid_equal(&pol_sid
, &global_sam_sid
)) {
1344 sid_copy(&sid
, &pol_sid
);
1345 sid_append_rid(&sid
, q_u
->rid
[i
]);
1347 if (lookup_sid(&sid
, domname
, tmpname
, &type
)) {
1348 r_u
->status
= NT_STATUS_NOPROBLEMO
;
1349 group_attrs
[i
] = (uint32
)type
;
1350 fstrcpy(group_names
[i
],tmpname
);
1355 if(!make_samr_lookup_rids(p
->mem_ctx
, num_rids
, group_names
, &hdr_name
, &uni_name
))
1356 return NT_STATUS_NO_MEMORY
;
1358 init_samr_r_lookup_rids(r_u
, num_rids
, hdr_name
, uni_name
, group_attrs
);
1360 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__
));
1365 /*******************************************************************
1366 _api_samr_open_user. Safe - gives out no passwd info.
1367 ********************************************************************/
1369 uint32
_api_samr_open_user(pipes_struct
*p
, SAMR_Q_OPEN_USER
*q_u
, SAMR_R_OPEN_USER
*r_u
)
1371 SAM_ACCOUNT
*sampass
;
1373 POLICY_HND domain_pol
= q_u
->domain_pol
;
1374 uint32 user_rid
= q_u
->user_rid
;
1375 POLICY_HND
*user_pol
= &r_u
->user_pol
;
1376 struct samr_info
*info
= NULL
;
1378 r_u
->status
= NT_STATUS_NO_PROBLEMO
;
1380 /* find the domain policy handle. */
1381 if (!find_policy_by_hnd(p
, &domain_pol
, NULL
))
1382 return NT_STATUS_INVALID_HANDLE
;
1385 sampass
= pdb_getsampwrid(user_rid
);
1388 /* check that the RID exists in our domain. */
1389 if (sampass
== NULL
)
1390 return NT_STATUS_NO_SUCH_USER
;
1392 samr_clear_sam_passwd(sampass
);
1394 /* Get the domain SID stored in the domain policy */
1395 if(!get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
))
1396 return NT_STATUS_INVALID_HANDLE
;
1398 /* append the user's RID to it */
1399 if(!sid_append_rid(&sid
, user_rid
))
1400 return NT_STATUS_NO_SUCH_USER
;
1402 /* associate the user's SID with the new handle. */
1403 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
1404 return NT_STATUS_NO_MEMORY
;
1409 /* get a (unique) handle. open a policy on it. */
1410 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
))
1411 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1416 /*************************************************************************
1417 get_user_info_10. Safe. Only gives out acb bits.
1418 *************************************************************************/
1420 static BOOL
get_user_info_10(SAM_USER_INFO_10
*id10
, uint32 user_rid
)
1422 SAM_ACCOUNT
*smbpass
;
1424 if (!pdb_rid_is_user(user_rid
)) {
1425 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid
));
1430 smbpass
= pdb_getsampwrid(user_rid
);
1433 if (smbpass
== NULL
) {
1434 DEBUG(4,("User 0x%x not found\n", user_rid
));
1438 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass
) ));
1440 init_sam_user_info10(id10
, pdb_get_acct_ctrl(smbpass
) );
1445 /*************************************************************************
1446 get_user_info_12. OK - this is the killer as it gives out password info.
1447 Ensure that this is only allowed on an encrypted connection with a root
1449 *************************************************************************/
1451 static uint32
get_user_info_12(pipes_struct
*p
, SAM_USER_INFO_12
* id12
, uint32 user_rid
)
1453 SAM_ACCOUNT
*smbpass
;
1455 if (!p
->ntlmssp_auth_validated
)
1456 return NT_STATUS_ACCESS_DENIED
;
1458 if (!(p
->ntlmssp_chal_flags
& NTLMSSP_NEGOTIATE_SIGN
) || !(p
->ntlmssp_chal_flags
& NTLMSSP_NEGOTIATE_SEAL
))
1459 return NT_STATUS_ACCESS_DENIED
;
1462 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1465 smbpass
= pdb_getsampwrid(user_rid
);
1467 if (smbpass
== NULL
) {
1468 DEBUG(4, ("User 0x%x not found\n", user_rid
));
1469 return (geteuid() == (uid_t
)0) ? NT_STATUS_NO_SUCH_USER
: NT_STATUS_ACCESS_DENIED
;
1472 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass
), pdb_get_acct_ctrl(smbpass
) ));
1474 if ( pdb_get_acct_ctrl(smbpass
) & ACB_DISABLED
)
1475 return NT_STATUS_ACCOUNT_DISABLED
;
1477 init_sam_user_info12(id12
, pdb_get_lanman_passwd(smbpass
), pdb_get_nt_passwd(smbpass
));
1479 return NT_STATUS_NOPROBLEMO
;
1482 /*************************************************************************
1484 *************************************************************************/
1486 static BOOL
get_user_info_21(SAM_USER_INFO_21
*id21
, uint32 user_rid
)
1488 SAM_ACCOUNT
*sampass
;
1490 if (!pdb_rid_is_user(user_rid
)) {
1491 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid
));
1496 sampass
= pdb_getsampwrid(user_rid
);
1499 if (sampass
== NULL
) {
1500 DEBUG(4,("User 0x%x not found\n", user_rid
));
1504 samr_clear_sam_passwd(sampass
);
1506 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
1508 init_sam_user_info21A(id21
, sampass
);
1513 /*******************************************************************
1514 _samr_query_userinfo
1515 ********************************************************************/
1517 uint32
_samr_query_userinfo(pipes_struct
*p
, SAMR_Q_QUERY_USERINFO
*q_u
, SAMR_R_QUERY_USERINFO
*r_u
)
1519 SAM_USERINFO_CTR
*ctr
;
1521 struct samr_info
*info
= NULL
;
1523 r_u
->status
=NT_STATUS_NO_PROBLEMO
;
1525 /* search for the handle */
1526 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1527 return NT_STATUS_INVALID_HANDLE
;
1529 /* find the user's rid */
1530 if ((rid
= get_lsa_policy_samr_rid(info
)) == 0xffffffff)
1531 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1533 DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid
));
1535 ctr
= (SAM_USERINFO_CTR
*)talloc(p
->mem_ctx
, sizeof(SAM_USERINFO_CTR
));
1537 return NT_STATUS_NO_MEMORY
;
1541 /* ok! user info levels (lots: see MSDEV help), off we go... */
1542 ctr
->switch_value
= q_u
->switch_value
;
1544 switch (q_u
->switch_value
) {
1546 ctr
->info
.id10
= (SAM_USER_INFO_10
*)talloc(p
->mem_ctx
, sizeof(SAM_USER_INFO_10
));
1547 if (ctr
->info
.id10
== NULL
)
1548 return NT_STATUS_NO_MEMORY
;
1550 if (!get_user_info_10(ctr
->info
.id10
, rid
))
1551 return NT_STATUS_NO_SUCH_USER
;
1555 /* whoops - got this wrong. i think. or don't understand what's happening. */
1559 info
= (void *)&id11
;
1561 expire
.low
= 0xffffffff;
1562 expire
.high
= 0x7fffffff;
1564 ctr
->info
.id
= (SAM_USER_INFO_11
*)talloc(p
->mem_ctx
,
1569 init_sam_user_info11(ctr
->info
.id11
, &expire
,
1570 "BROOKFIELDS$", /* name */
1571 0x03ef, /* user rid */
1572 0x201, /* group rid */
1573 0x0080); /* acb info */
1580 ctr
->info
.id12
= (SAM_USER_INFO_12
*)talloc(p
->mem_ctx
, sizeof(SAM_USER_INFO_12
));
1581 if (ctr
->info
.id12
== NULL
)
1582 return NT_STATUS_NO_MEMORY
;
1584 if ((r_u
->status
= get_user_info_12(p
, ctr
->info
.id12
, rid
)) != NT_STATUS_NOPROBLEMO
)
1589 ctr
->info
.id21
= (SAM_USER_INFO_21
*)talloc(p
->mem_ctx
,sizeof(SAM_USER_INFO_21
));
1590 if (ctr
->info
.id21
== NULL
)
1591 return NT_STATUS_NO_MEMORY
;
1592 if (!get_user_info_21(ctr
->info
.id21
, rid
))
1593 return NT_STATUS_NO_SUCH_USER
;
1597 return NT_STATUS_INVALID_INFO_CLASS
;
1600 init_samr_r_query_userinfo(r_u
, ctr
, r_u
->status
);
1602 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__
));
1607 /*******************************************************************
1608 samr_reply_query_usergroups
1609 ********************************************************************/
1611 uint32
_samr_query_usergroups(pipes_struct
*p
, SAMR_Q_QUERY_USERGROUPS
*q_u
, SAMR_R_QUERY_USERGROUPS
*r_u
)
1613 struct sam_passwd
*sam_pass
;
1614 DOM_GID
*gids
= NULL
;
1618 struct samr_info
*info
= NULL
;
1620 r_u
->status
= NT_STATUS_NO_PROBLEMO
;
1622 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__
));
1624 /* find the policy handle. open a policy on it. */
1625 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1626 return NT_STATUS_INVALID_HANDLE
;
1628 /* find the user's rid */
1629 if ((rid
= get_lsa_policy_samr_rid(info
)) == 0xffffffff)
1630 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1633 sam_pass
= pdb_getsampwrid(rid
);
1636 if (sam_pass
== NULL
)
1637 return NT_STATUS_NO_SUCH_USER
;
1639 samr_clear_sam_passwd(sam_pass
);
1641 get_domain_user_groups(groups
, pdb_get_username(sam_pass
));
1643 num_groups
= make_dom_gids(p
->mem_ctx
, groups
, &gids
);
1645 /* construct the response. lkclXXXX: gids are not copied! */
1646 init_samr_r_query_usergroups(r_u
, num_groups
, gids
, r_u
->status
);
1648 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__
));
1653 /*******************************************************************
1654 _samr_query_dom_info
1655 ********************************************************************/
1657 uint32
_samr_query_dom_info(pipes_struct
*p
, SAMR_Q_QUERY_DOMAIN_INFO
*q_u
, SAMR_R_QUERY_DOMAIN_INFO
*r_u
)
1661 if ((ctr
= (SAM_UNK_CTR
*)talloc(p
->mem_ctx
, sizeof(SAM_UNK_CTR
))) == NULL
)
1662 return NT_STATUS_NO_MEMORY
;
1666 r_u
->status
= NT_STATUS_NO_PROBLEMO
;
1668 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__
));
1670 /* find the policy handle. open a policy on it. */
1671 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, NULL
))
1672 return NT_STATUS_INVALID_HANDLE
;
1674 switch (q_u
->switch_value
) {
1676 init_unk_info1(&ctr
->info
.inf1
);
1679 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
1680 init_unk_info2(&ctr
->info
.inf2
, global_myworkgroup
, global_myname
, (uint32
) time(NULL
));
1683 init_unk_info3(&ctr
->info
.inf3
);
1686 init_unk_info6(&ctr
->info
.inf6
);
1689 init_unk_info7(&ctr
->info
.inf7
);
1692 init_unk_info12(&ctr
->info
.inf12
);
1695 return NT_STATUS_INVALID_INFO_CLASS
;
1698 init_samr_r_query_dom_info(r_u
, q_u
->switch_value
, ctr
, NT_STATUS_NOPROBLEMO
);
1700 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__
));
1705 /*******************************************************************
1706 _api_samr_create_user
1707 ********************************************************************/
1709 uint32
_api_samr_create_user(pipes_struct
*p
, SAMR_Q_CREATE_USER
*q_u
, SAMR_R_CREATE_USER
*r_u
)
1711 SAM_ACCOUNT
*sam_pass
;
1718 POLICY_HND dom_pol
= q_u
->domain_pol
;
1719 UNISTR2 user_account
= q_u
->uni_name
;
1720 uint16 acb_info
= q_u
->acb_info
;
1721 POLICY_HND
*user_pol
= &r_u
->user_pol
;
1722 struct samr_info
*info
= NULL
;
1724 /* find the policy handle. open a policy on it. */
1725 if (!find_policy_by_hnd(p
, &dom_pol
, NULL
))
1726 return NT_STATUS_INVALID_HANDLE
;
1728 /* find the machine account: tell the caller if it exists.
1729 lkclXXXX i have *no* idea if this is a problem or not
1730 or even if you are supposed to construct a different
1731 reply if the account already exists...
1734 fstrcpy(mach_acct
, dos_unistrn2(user_account
.buffer
, user_account
.uni_str_len
));
1735 strlower(mach_acct
);
1738 sam_pass
= pdb_getsampwnam(mach_acct
);
1740 if (sam_pass
!= NULL
) {
1741 /* machine account exists: say so */
1742 return NT_STATUS_USER_EXISTS
;
1745 local_flags
=LOCAL_ADD_USER
|LOCAL_DISABLE_USER
|LOCAL_SET_NO_PASSWORD
;
1746 local_flags
|= (acb_info
& ACB_WSTRUST
) ? LOCAL_TRUST_ACCOUNT
:0;
1749 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1750 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1751 * that only people with write access to the smbpasswd file will be able
1752 * to create a user. JRA.
1756 * add the user in the /etc/passwd file or the unix authority system.
1757 * We don't check if the smb_create_user() function succed or not for 2 reasons:
1758 * a) local_password_change() checks for us if the /etc/passwd account really exists
1759 * b) smb_create_user() would return an error if the account already exists
1760 * and as it could return an error also if it can't create the account, it would be tricky.
1762 * So we go the easy way, only check after if the account exists.
1763 * JFM (2/3/2001), to clear any possible bad understanding (-:
1766 pstrcpy(add_script
, lp_adduser_script());
1769 smb_create_user(mach_acct
, NULL
);
1771 /* add the user in the smbpasswd file or the Samba authority database */
1772 if (!local_password_change(mach_acct
, local_flags
, NULL
, err_str
,
1773 sizeof(err_str
), msg_str
, sizeof(msg_str
)))
1775 DEBUG(0, ("%s\n", err_str
));
1776 close_policy_hnd(p
, user_pol
);
1777 return NT_STATUS_ACCESS_DENIED
;
1781 sam_pass
= pdb_getsampwnam(mach_acct
);
1783 if (sam_pass
== NULL
) {
1784 /* account doesn't exist: say so */
1785 close_policy_hnd(p
, user_pol
);
1786 return NT_STATUS_ACCESS_DENIED
;
1789 /* Get the domain SID stored in the domain policy */
1790 if(!get_lsa_policy_samr_sid(p
, &dom_pol
, &sid
)) {
1791 close_policy_hnd(p
, user_pol
);
1792 return NT_STATUS_INVALID_HANDLE
;
1795 /* append the user's RID to it */
1796 if(!sid_append_rid(&sid
, pdb_get_user_rid(sam_pass
) )) {
1797 close_policy_hnd(p
, user_pol
);
1798 return NT_STATUS_NO_SUCH_USER
;
1801 /* associate the user's SID with the new handle. */
1802 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
1803 return NT_STATUS_NO_MEMORY
;
1808 /* get a (unique) handle. open a policy on it. */
1809 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
))
1810 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1812 r_u
->user_rid
=sam_pass
->user_rid
;
1813 r_u
->unknown_0
= 0x000703ff;
1815 return NT_STATUS_NO_PROBLEMO
;
1818 /*******************************************************************
1819 samr_reply_connect_anon
1820 ********************************************************************/
1822 uint32
_samr_connect_anon(pipes_struct
*p
, SAMR_Q_CONNECT_ANON
*q_u
, SAMR_R_CONNECT_ANON
*r_u
)
1824 struct samr_info
*info
= NULL
;
1826 /* set up the SAMR connect_anon response */
1828 r_u
->status
= NT_STATUS_NO_PROBLEMO
;
1830 /* associate the user's SID with the new handle. */
1831 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
1832 return NT_STATUS_NO_MEMORY
;
1835 info
->status
= q_u
->unknown_0
;
1837 /* get a (unique) handle. open a policy on it. */
1838 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
1839 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1844 /*******************************************************************
1846 ********************************************************************/
1848 uint32
_samr_connect(pipes_struct
*p
, SAMR_Q_CONNECT
*q_u
, SAMR_R_CONNECT
*r_u
)
1850 struct samr_info
*info
= NULL
;
1852 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
1854 r_u
->status
= NT_STATUS_NO_PROBLEMO
;
1856 /* associate the user's SID with the new handle. */
1857 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
1858 return NT_STATUS_NO_MEMORY
;
1861 info
->status
= q_u
->access_mask
;
1863 /* get a (unique) handle. open a policy on it. */
1864 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
1865 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1867 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
1872 /**********************************************************************
1873 api_samr_lookup_domain
1874 **********************************************************************/
1876 uint32
_samr_lookup_domain(pipes_struct
*p
, SAMR_Q_LOOKUP_DOMAIN
*q_u
, SAMR_R_LOOKUP_DOMAIN
*r_u
)
1878 r_u
->status
= NT_STATUS_NO_PROBLEMO
;
1880 if (!find_policy_by_hnd(p
, &q_u
->connect_pol
, NULL
))
1881 return NT_STATUS_INVALID_HANDLE
;
1883 /* assume the domain name sent is our global_myname and
1884 send global_sam_sid */
1885 init_samr_r_lookup_domain(r_u
, &global_sam_sid
, r_u
->status
);
1890 /******************************************************************
1891 makes a SAMR_R_ENUM_DOMAINS structure.
1892 ********************************************************************/
1894 static BOOL
make_enum_domains(TALLOC_CTX
*ctx
, SAM_ENTRY
**pp_sam
,
1895 UNISTR2
**pp_uni_name
, uint32 num_sam_entries
, fstring doms
[])
1901 DEBUG(5, ("make_enum_domains\n"));
1904 *pp_uni_name
= NULL
;
1906 if (num_sam_entries
== 0)
1909 sam
= (SAM_ENTRY
*)talloc(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
1910 uni_name
= (UNISTR2
*)talloc(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
1912 if (sam
== NULL
|| uni_name
== NULL
)
1915 for (i
= 0; i
< num_sam_entries
; i
++) {
1916 int len
= doms
[i
] != NULL
? strlen(doms
[i
]) : 0;
1918 init_sam_entry(&sam
[i
], len
, 0);
1919 init_unistr2(&uni_name
[i
], doms
[i
], len
);
1923 *pp_uni_name
= uni_name
;
1928 /**********************************************************************
1929 api_samr_enum_domains
1930 **********************************************************************/
1932 uint32
_samr_enum_domains(pipes_struct
*p
, SAMR_Q_ENUM_DOMAINS
*q_u
, SAMR_R_ENUM_DOMAINS
*r_u
)
1934 uint32 num_entries
= 2;
1937 r_u
->status
= NT_STATUS_NO_PROBLEMO
;
1939 fstrcpy(dom
[0],global_myworkgroup
);
1940 fstrcpy(dom
[1],"Builtin");
1942 if (!make_enum_domains(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_dom_name
, num_entries
, dom
))
1943 return NT_STATUS_NO_MEMORY
;
1945 init_samr_r_enum_domains(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
1950 /*******************************************************************
1952 ********************************************************************/
1954 uint32
_api_samr_open_alias(pipes_struct
*p
, SAMR_Q_OPEN_ALIAS
*q_u
, SAMR_R_OPEN_ALIAS
*r_u
)
1957 POLICY_HND domain_pol
= q_u
->dom_pol
;
1958 uint32 alias_rid
= q_u
->rid_alias
;
1959 POLICY_HND
*alias_pol
= &r_u
->pol
;
1960 struct samr_info
*info
= NULL
;
1962 r_u
->status
= NT_STATUS_NO_PROBLEMO
;
1964 /* get the domain policy. */
1965 if (!find_policy_by_hnd(p
, &domain_pol
, NULL
))
1966 return NT_STATUS_INVALID_HANDLE
;
1968 /* Get the domain SID stored in the domain policy */
1969 if(!get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
))
1970 return NT_STATUS_INVALID_HANDLE
;
1972 /* append the alias' RID to it */
1973 if(!sid_append_rid(&sid
, alias_rid
))
1974 return NT_STATUS_NO_SUCH_USER
;
1977 * we should check if the rid really exist !!!
1981 /* associate the user's SID with the new handle. */
1982 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
1983 return NT_STATUS_NO_MEMORY
;
1988 /* get a (unique) handle. open a policy on it. */
1989 if (!create_policy_hnd(p
, alias_pol
, free_samr_info
, (void *)info
))
1990 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1995 /*******************************************************************
1997 ********************************************************************/
1999 static BOOL
set_user_info_10(const SAM_USER_INFO_10
*id10
, uint32 rid
)
2001 SAM_ACCOUNT
*pwd
= pdb_getsampwrid(rid
);
2004 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2008 pwd
= pdb_getsampwrid(rid
);
2012 pdb_set_acct_ctrl(pwd
, id10
->acb_info
);
2014 if(!pdb_update_sam_account(pwd
, True
))
2020 /*******************************************************************
2022 ********************************************************************/
2024 static BOOL
set_user_info_12(SAM_USER_INFO_12
*id12
, uint32 rid
)
2026 SAM_ACCOUNT
*pwd
= pdb_getsampwrid(rid
);
2032 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2036 pdb_set_lanman_passwd (pwd
, id12
->lm_pwd
);
2037 pdb_set_nt_passwd (pwd
, id12
->nt_pwd
);
2039 if(!pdb_update_sam_account(pwd
, True
))
2045 /*******************************************************************
2047 ********************************************************************/
2049 static BOOL
set_user_info_21(SAM_USER_INFO_21
*id21
, uint32 rid
)
2051 SAM_ACCOUNT
*pwd
= pdb_getsampwrid(rid
);
2052 SAM_ACCOUNT new_pwd
;
2055 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2062 /* we make a copy so that we can modify stuff */
2063 ZERO_STRUCT(new_pwd
);
2064 copy_sam_passwd(&new_pwd
, pwd
);
2065 copy_id21_to_sam_passwd(&new_pwd
, id21
);
2068 * The funny part about the previous two calls is
2069 * that pwd still has the password hashes from the
2070 * passdb entry. These have not been updated from
2071 * id21. I don't know if they need to be set. --jerry
2074 /* write the change out */
2075 if(!pdb_update_sam_account(&new_pwd
, True
))
2081 /*******************************************************************
2083 ********************************************************************/
2085 static BOOL
set_user_info_23(SAM_USER_INFO_23
*id23
, uint32 rid
)
2087 SAM_ACCOUNT
*pwd
= pdb_getsampwrid(rid
);
2088 SAM_ACCOUNT new_pwd
;
2096 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2103 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
2105 ZERO_STRUCT (new_pwd
);
2106 copy_sam_passwd(&new_pwd
, pwd
);
2107 copy_id23_to_sam_passwd(&new_pwd
, id23
);
2109 if (!decode_pw_buffer((char*)id23
->pass
, buf
, 256, &len
, nt_hash
, lm_hash
))
2112 pdb_set_lanman_passwd (&new_pwd
, lm_hash
);
2113 pdb_set_nt_passwd (&new_pwd
, nt_hash
);
2115 /* if it's a trust account, don't update /etc/passwd */
2116 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
2117 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
2118 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
2119 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2121 /* update the UNIX password */
2122 /* update the UNIX password */
2123 if (lp_unix_password_sync() )
2124 if(!chgpasswd(pdb_get_username(&new_pwd
), "", buf
, True
))
2128 memset(buf
, 0, sizeof(buf
));
2130 if(!pdb_update_sam_account(&new_pwd
, True
))
2136 /*******************************************************************
2138 ********************************************************************/
2140 static BOOL
set_user_info_24(SAM_USER_INFO_24
*id24
, uint32 rid
)
2142 SAM_ACCOUNT
*pwd
= pdb_getsampwrid(rid
);
2152 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
2154 memset(buf
, 0, sizeof(buf
));
2156 if (!decode_pw_buffer((char*)id24
->pass
, buf
, 256, &len
, nt_hash
, lm_hash
))
2159 pdb_set_lanman_passwd (pwd
, lm_hash
);
2160 pdb_set_nt_passwd (pwd
, nt_hash
);
2162 /* if it's a trust account, don't update /etc/passwd */
2163 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
2164 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
2165 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
2166 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2168 /* update the UNIX password */
2169 if (lp_unix_password_sync())
2170 if(!chgpasswd(pdb_get_username(pwd
), "", buf
, True
))
2174 memset(buf
, 0, sizeof(buf
));
2176 DEBUG(0,("set_user_info_24: pdb_update_sam_account()\n"));
2178 /* update the SAMBA password */
2179 if(!pdb_update_sam_account(pwd
, True
))
2185 /*******************************************************************
2186 samr_reply_set_userinfo
2187 ********************************************************************/
2189 uint32
_samr_set_userinfo(pipes_struct
*p
, SAMR_Q_SET_USERINFO
*q_u
, SAMR_R_SET_USERINFO
*r_u
)
2193 struct current_user user
;
2194 SAM_ACCOUNT
*sam_pass
;
2195 unsigned char sess_key
[16];
2196 POLICY_HND
*pol
= &q_u
->pol
;
2197 uint16 switch_value
= q_u
->switch_value
;
2198 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
2200 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__
));
2202 r_u
->status
= NT_STATUS_NOPROBLEMO
;
2204 if (p
->ntlmssp_auth_validated
) {
2205 memcpy(&user
, &p
->pipe_user
, sizeof(user
));
2207 extern struct current_user current_user
;
2208 memcpy(&user
, ¤t_user
, sizeof(user
));
2211 /* find the policy handle. open a policy on it. */
2212 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
))
2213 return NT_STATUS_INVALID_HANDLE
;
2215 sid_split_rid(&sid
, &rid
);
2217 DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid
, switch_value
));
2220 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2221 return NT_STATUS_INVALID_INFO_CLASS
;
2226 * We need the NT hash of the user who is changing the user's password.
2227 * This NT hash is used to generate a "user session key"
2228 * This "user session key" is in turn used to encrypt/decrypt the user's password.
2232 sam_pass
= pdb_getsampwuid(user
.uid
);
2234 if(sam_pass
== NULL
) {
2235 DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd entry for uid %u\n", (unsigned int)user
.uid
));
2236 return NT_STATUS_ACCESS_DENIED
;
2239 memset(sess_key
, '\0', 16);
2240 mdfour(sess_key
, pdb_get_nt_passwd(sam_pass
), 16);
2242 /* ok! user info levels (lots: see MSDEV help), off we go... */
2243 switch (switch_value
) {
2245 if (!set_user_info_12(ctr
->info
.id12
, rid
))
2246 return NT_STATUS_ACCESS_DENIED
;
2250 SamOEMhash(ctr
->info
.id24
->pass
, sess_key
, 1);
2251 if (!set_user_info_24(ctr
->info
.id24
, rid
))
2252 return NT_STATUS_ACCESS_DENIED
;
2256 SamOEMhash(ctr
->info
.id23
->pass
, sess_key
, 1);
2257 if (!set_user_info_23(ctr
->info
.id23
, rid
))
2258 return NT_STATUS_ACCESS_DENIED
;
2262 return NT_STATUS_INVALID_INFO_CLASS
;
2268 /*******************************************************************
2269 samr_reply_set_userinfo2
2270 ********************************************************************/
2272 uint32
_samr_set_userinfo2(pipes_struct
*p
, SAMR_Q_SET_USERINFO2
*q_u
, SAMR_R_SET_USERINFO2
*r_u
)
2276 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
2277 POLICY_HND
*pol
= &q_u
->pol
;
2278 uint16 switch_value
= q_u
->switch_value
;
2280 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__
));
2282 r_u
->status
= NT_STATUS_NOPROBLEMO
;
2284 /* find the policy handle. open a policy on it. */
2285 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
))
2286 return NT_STATUS_INVALID_HANDLE
;
2288 sid_split_rid(&sid
, &rid
);
2290 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid
));
2293 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2294 return NT_STATUS_INVALID_INFO_CLASS
;
2297 switch_value
=ctr
->switch_value
;
2299 /* ok! user info levels (lots: see MSDEV help), off we go... */
2300 switch (switch_value
) {
2302 if (!set_user_info_21(ctr
->info
.id21
, rid
))
2303 return NT_STATUS_ACCESS_DENIED
;
2306 if (!set_user_info_10(ctr
->info
.id10
, rid
))
2307 return NT_STATUS_ACCESS_DENIED
;
2310 /* Used by AS/U JRA. */
2311 if (!set_user_info_12(ctr
->info
.id12
, rid
))
2312 return NT_STATUS_ACCESS_DENIED
;
2315 return NT_STATUS_INVALID_INFO_CLASS
;
2321 /*********************************************************************
2322 _samr_query_aliasmem
2323 *********************************************************************/
2325 uint32
_samr_query_useraliases(pipes_struct
*p
, SAMR_Q_QUERY_USERALIASES
*q_u
, SAMR_R_QUERY_USERALIASES
*r_u
)
2331 rid
=(uint32
*)talloc(p
->mem_ctx
, num_rids
*sizeof(uint32
));
2333 return NT_STATUS_NO_MEMORY
;
2335 /* until i see a real useraliases query, we fack one up */
2337 rid
[0] = BUILTIN_ALIAS_RID_USERS
;
2339 init_samr_r_query_useraliases(r_u
, num_rids
, rid
, NT_STATUS_NO_PROBLEMO
);
2341 return NT_STATUS_NO_PROBLEMO
;
2345 /*********************************************************************
2346 _samr_query_aliasmem
2347 *********************************************************************/
2349 uint32
_samr_query_aliasmem(pipes_struct
*p
, SAMR_Q_QUERY_ALIASMEM
*q_u
, SAMR_R_QUERY_ALIASMEM
*r_u
)
2361 fstring alias_sid_str
;
2365 /* find the policy handle. open a policy on it. */
2366 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
))
2367 return NT_STATUS_INVALID_HANDLE
;
2369 sid_copy(&als_sid
, &alias_sid
);
2370 sid_to_string(alias_sid_str
, &alias_sid
);
2371 sid_split_rid(&alias_sid
, &alias_rid
);
2373 DEBUG(10, ("sid is %s\n", alias_sid_str
));
2375 if (sid_equal(&alias_sid
, &global_sid_Builtin
)) {
2376 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
2377 if(!get_builtin_group_from_sid(als_sid
, &map
))
2378 return NT_STATUS_NO_SUCH_ALIAS
;
2380 if (sid_equal(&alias_sid
, &global_sam_sid
)) {
2381 DEBUG(10, ("lookup on Server SID\n"));
2382 if(!get_local_group_from_sid(als_sid
, &map
))
2383 return NT_STATUS_NO_SUCH_ALIAS
;
2387 if(!get_uid_list_of_group(map
.gid
, &uid
, &num_uids
))
2388 return NT_STATUS_NO_SUCH_ALIAS
;
2390 DEBUG(10, ("sid is %s\n", alias_sid_str
));
2391 sid
= (DOM_SID2
*)talloc(p
->mem_ctx
, sizeof(DOM_SID2
) * num_uids
);
2393 return NT_STATUS_NO_SUCH_ALIAS
;
2395 for (i
= 0; i
< num_uids
; i
++) {
2396 sid_copy(&temp_sid
, &global_sam_sid
);
2397 sid_append_rid(&temp_sid
, pdb_uid_to_user_rid(uid
[i
]));
2399 init_dom_sid2(&sid
[i
], &temp_sid
);
2402 DEBUG(10, ("sid is %s\n", alias_sid_str
));
2403 init_samr_r_query_aliasmem(r_u
, num_uids
, sid
, NT_STATUS_NO_PROBLEMO
);
2405 return NT_STATUS_NOPROBLEMO
;
2408 /*********************************************************************
2409 _samr_query_groupmem
2410 *********************************************************************/
2412 uint32
_samr_query_groupmem(pipes_struct
*p
, SAMR_Q_QUERY_GROUPMEM
*q_u
, SAMR_R_QUERY_GROUPMEM
*r_u
)
2418 fstring group_sid_str
;
2427 /* find the policy handle. open a policy on it. */
2428 if (!get_lsa_policy_samr_sid(p
, &q_u
->group_pol
, &group_sid
))
2429 return NT_STATUS_INVALID_HANDLE
;
2431 /* todo: change to use sid_compare_front */
2433 sid_split_rid(&group_sid
, &group_rid
);
2434 sid_to_string(group_sid_str
, &group_sid
);
2435 DEBUG(10, ("sid is %s\n", group_sid_str
));
2437 /* can we get a query for an SID outside our domain ? */
2438 if (!sid_equal(&group_sid
, &global_sam_sid
))
2439 return NT_STATUS_NO_SUCH_GROUP
;
2441 sid_append_rid(&group_sid
, group_rid
);
2442 DEBUG(10, ("lookup on Domain SID\n"));
2444 if(!get_domain_group_from_sid(group_sid
, &map
))
2445 return NT_STATUS_NO_SUCH_GROUP
;
2447 if(!get_uid_list_of_group(map
.gid
, &uid
, &num_uids
))
2448 return NT_STATUS_NO_SUCH_GROUP
;
2450 rid
=talloc(p
->mem_ctx
, sizeof(uint32
)*num_uids
);
2451 attr
=talloc(p
->mem_ctx
, sizeof(uint32
)*num_uids
);
2453 if (rid
==NULL
|| attr
==NULL
)
2454 return NT_STATUS_NO_MEMORY
;
2456 for (i
=0; i
<num_uids
; i
++) {
2457 rid
[i
]=pdb_uid_to_user_rid(uid
[i
]);
2458 attr
[i
] = SID_NAME_USER
;
2461 init_samr_r_query_groupmem(r_u
, num_uids
, rid
, attr
, NT_STATUS_NOPROBLEMO
);
2463 return NT_STATUS_NOPROBLEMO
;
2466 /*********************************************************************
2468 *********************************************************************/
2470 uint32
_samr_add_aliasmem(pipes_struct
*p
, SAMR_Q_ADD_ALIASMEM
*q_u
, SAMR_R_ADD_ALIASMEM
*r_u
)
2473 fstring alias_sid_str
;
2481 /* Find the policy handle. Open a policy on it. */
2482 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
))
2483 return NT_STATUS_INVALID_HANDLE
;
2485 sid_to_string(alias_sid_str
, &alias_sid
);
2486 DEBUG(10, ("sid is %s\n", alias_sid_str
));
2488 if (sid_compare(&alias_sid
, &global_sam_sid
)>0) {
2489 DEBUG(10, ("adding member on Server SID\n"));
2490 if(!get_local_group_from_sid(alias_sid
, &map
))
2491 return NT_STATUS_NO_SUCH_ALIAS
;
2494 if (sid_compare(&alias_sid
, &global_sid_Builtin
)>0) {
2495 DEBUG(10, ("adding member on BUILTIN SID\n"));
2496 if( !get_builtin_group_from_sid(alias_sid
, &map
))
2497 return NT_STATUS_NO_SUCH_ALIAS
;
2500 return NT_STATUS_NO_SUCH_ALIAS
;
2503 sid_split_rid(&q_u
->sid
.sid
, &rid
);
2504 uid
=pdb_user_rid_to_uid(rid
);
2506 if ((pwd
=getpwuid(uid
)) == NULL
)
2507 return NT_STATUS_NO_SUCH_USER
;
2509 if ((grp
=getgrgid(map
.gid
)) == NULL
)
2510 return NT_STATUS_NO_SUCH_ALIAS
;
2512 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2513 fstrcpy(grp_name
, grp
->gr_name
);
2515 /* if the user is already in the group */
2516 if(user_in_group_list(pwd
->pw_name
, grp_name
))
2517 return NT_STATUS_MEMBER_IN_ALIAS
;
2520 * ok, the group exist, the user exist, the user is not in the group,
2521 * we can (finally) add it to the group !
2523 smb_add_user_group(grp_name
, pwd
->pw_name
);
2525 /* check if the user has been added then ... */
2526 if(!user_in_group_list(pwd
->pw_name
, grp_name
))
2527 return NT_STATUS_MEMBER_NOT_IN_ALIAS
; /* don't know what to reply else */
2529 return NT_STATUS_NOPROBLEMO
;
2532 /*********************************************************************
2534 *********************************************************************/
2536 uint32
_samr_del_aliasmem(pipes_struct
*p
, SAMR_Q_DEL_ALIASMEM
*q_u
, SAMR_R_DEL_ALIASMEM
*r_u
)
2538 DEBUG(0,("_samr_del_aliasmem: Not yet implemented.\n"));
2542 /*********************************************************************
2544 *********************************************************************/
2546 uint32
_samr_add_groupmem(pipes_struct
*p
, SAMR_Q_ADD_GROUPMEM
*q_u
, SAMR_R_ADD_GROUPMEM
*r_u
)
2549 fstring group_sid_str
;
2555 /* Find the policy handle. Open a policy on it. */
2556 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
))
2557 return NT_STATUS_INVALID_HANDLE
;
2559 sid_to_string(group_sid_str
, &group_sid
);
2560 DEBUG(10, ("sid is %s\n", group_sid_str
));
2562 if (sid_compare(&group_sid
, &global_sam_sid
)<=0)
2563 return NT_STATUS_NO_SUCH_GROUP
;
2565 DEBUG(10, ("lookup on Domain SID\n"));
2567 if(!get_domain_group_from_sid(group_sid
, &map
))
2568 return NT_STATUS_NO_SUCH_GROUP
;
2570 if ((pwd
=getpwuid(pdb_user_rid_to_uid(q_u
->rid
))) ==NULL
)
2571 return NT_STATUS_NO_SUCH_USER
;
2573 if ((grp
=getgrgid(map
.gid
)) == NULL
)
2574 return NT_STATUS_NO_SUCH_GROUP
;
2576 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2577 fstrcpy(grp_name
, grp
->gr_name
);
2579 /* if the user is already in the group */
2580 if(user_in_group_list(pwd
->pw_name
, grp_name
))
2581 return NT_STATUS_MEMBER_IN_GROUP
;
2584 * ok, the group exist, the user exist, the user is not in the group,
2586 * we can (finally) add it to the group !
2589 smb_add_user_group(grp_name
, pwd
->pw_name
);
2591 /* check if the user has been added then ... */
2592 if(!user_in_group_list(pwd
->pw_name
, grp_name
))
2593 return NT_STATUS_MEMBER_NOT_IN_GROUP
; /* don't know what to reply else */
2595 return NT_STATUS_NOPROBLEMO
;
2598 /*********************************************************************
2600 *********************************************************************/
2602 uint32
_samr_del_groupmem(pipes_struct
*p
, SAMR_Q_DEL_GROUPMEM
*q_u
, SAMR_R_DEL_GROUPMEM
*r_u
)
2604 DEBUG(0,("_samr_del_groupmem: Not yet implemented.\n"));
2608 /*********************************************************************
2609 _samr_delete_dom_user
2610 *********************************************************************/
2612 uint32
_samr_delete_dom_user(pipes_struct
*p
, SAMR_Q_DELETE_DOM_USER
*q_u
, SAMR_R_DELETE_DOM_USER
*r_u
)
2614 DEBUG(0,("_samr_delete_dom_user: Not yet implemented.\n"));
2618 /*********************************************************************
2619 _samr_delete_dom_group
2620 *********************************************************************/
2622 uint32
_samr_delete_dom_group(pipes_struct
*p
, SAMR_Q_DELETE_DOM_GROUP
*q_u
, SAMR_R_DELETE_DOM_GROUP
*r_u
)
2624 DEBUG(0,("_samr_delete_dom_group: Not yet implemented.\n"));
2628 /*********************************************************************
2629 _samr_delete_dom_alias
2630 *********************************************************************/
2632 uint32
_samr_delete_dom_alias(pipes_struct
*p
, SAMR_Q_DELETE_DOM_ALIAS
*q_u
, SAMR_R_DELETE_DOM_ALIAS
*r_u
)
2634 DEBUG(0,("_samr_delete_dom_alias: Not yet implemented.\n"));
2638 /*********************************************************************
2639 _samr_create_dom_group
2640 *********************************************************************/
2642 uint32
_samr_create_dom_group(pipes_struct
*p
, SAMR_Q_CREATE_DOM_GROUP
*q_u
, SAMR_R_CREATE_DOM_GROUP
*r_u
)
2649 struct samr_info
*info
;
2651 /* Find the policy handle. Open a policy on it. */
2652 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &dom_sid
))
2653 return NT_STATUS_INVALID_HANDLE
;
2655 if (!sid_equal(&dom_sid
, &global_sam_sid
))
2656 return NT_STATUS_ACCESS_DENIED
;
2658 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
2660 unistr2_to_ascii(name
, &q_u
->uni_acct_desc
, sizeof(name
)-1);
2662 /* check if group already exist */
2663 if ((grp
=getgrnam(name
)) != NULL
)
2664 return NT_STATUS_GROUP_EXISTS
;
2666 /* we can create the UNIX group */
2667 smb_create_group(name
);
2669 /* check if the group has been successfully created */
2670 if ((grp
=getgrnam(name
)) == NULL
)
2671 return NT_STATUS_ACCESS_DENIED
;
2673 r_u
->rid
=pdb_gid_to_group_rid(grp
->gr_gid
);
2675 /* add the group to the mapping table */
2676 if(!add_initial_entry(grp
->gr_gid
, sid_string
, SID_NAME_DOM_GRP
, name
, NULL
, SE_PRIV_NONE
))
2677 return NT_STATUS_ACCESS_DENIED
;
2679 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
2680 return NT_STATUS_NO_MEMORY
;
2684 sid_copy(&info_sid
, &global_sam_sid
);
2685 sid_append_rid(&info
->sid
, r_u
->rid
);
2686 sid_to_string(sid_string
, &info
->sid
);
2688 /* get a (unique) handle. open a policy on it. */
2689 if (!create_policy_hnd(p
, &r_u
->pol
, free_samr_info
, (void *)info
))
2690 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2692 return NT_STATUS_NOPROBLEMO
;
2695 /*********************************************************************
2696 _samr_create_dom_alias
2697 *********************************************************************/
2699 uint32
_samr_create_dom_alias(pipes_struct
*p
, SAMR_Q_CREATE_DOM_ALIAS
*q_u
, SAMR_R_CREATE_DOM_ALIAS
*r_u
)
2705 struct samr_info
*info
;
2707 /* Find the policy handle. Open a policy on it. */
2708 if (!get_lsa_policy_samr_sid(p
, &q_u
->dom_pol
, &dom_sid
))
2709 return NT_STATUS_INVALID_HANDLE
;
2711 if (!sid_equal(&dom_sid
, &global_sam_sid
))
2712 return NT_STATUS_ACCESS_DENIED
;
2714 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
2716 unistr2_to_ascii(name
, &q_u
->uni_acct_desc
, sizeof(name
)-1);
2718 /* check if group already exists */
2719 if ( (grp
=getgrnam(name
)) != NULL
)
2720 return NT_STATUS_GROUP_EXISTS
;
2722 /* we can create the UNIX group */
2723 smb_create_group(name
);
2725 /* check if the group has been successfully created */
2726 if ((grp
=getgrnam(name
)) == NULL
)
2727 return NT_STATUS_ACCESS_DENIED
;
2729 r_u
->rid
=pdb_gid_to_group_rid(grp
->gr_gid
);
2731 /* add the group to the mapping table */
2732 if(!add_initial_entry(grp
->gr_gid
, sid_string
, SID_NAME_ALIAS
, NULL
, NULL
, SE_PRIV_NONE
))
2733 return NT_STATUS_ACCESS_DENIED
;
2735 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
2736 return NT_STATUS_NO_MEMORY
;
2740 sid_copy(&info
->sid
, &global_sam_sid
);
2741 sid_append_rid(&info
->sid
, r_u
->rid
);
2742 sid_to_string(sid_string
, &info
->sid
);
2744 /* get a (unique) handle. open a policy on it. */
2745 if (!create_policy_hnd(p
, &r_u
->alias_pol
, free_samr_info
, (void *)info
))
2746 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2748 return NT_STATUS_NOPROBLEMO
;
2751 /*********************************************************************
2752 _samr_query_groupinfo
2754 sends the name/comment pair of a domain group
2755 level 1 send also the number of users of that group
2756 *********************************************************************/
2758 uint32
_samr_query_groupinfo(pipes_struct
*p
, SAMR_Q_QUERY_GROUPINFO
*q_u
, SAMR_R_QUERY_GROUPINFO
*r_u
)
2764 GROUP_INFO_CTR
*ctr
;
2766 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
))
2767 return NT_STATUS_INVALID_HANDLE
;
2769 if (!get_domain_group_from_sid(group_sid
, &map
))
2770 return NT_STATUS_INVALID_HANDLE
;
2772 ctr
=(GROUP_INFO_CTR
*)talloc(p
->mem_ctx
, sizeof(GROUP_INFO_CTR
));
2774 return NT_STATUS_NO_MEMORY
;
2776 switch (q_u
->switch_level
) {
2778 ctr
->switch_value1
= 1;
2779 if(!get_uid_list_of_group(map
.gid
, &uid
, &num_uids
))
2780 return NT_STATUS_NO_SUCH_GROUP
;
2781 init_samr_group_info1(&ctr
->group
.info1
, map
.nt_name
, map
.comment
, num_uids
);
2785 ctr
->switch_value1
= 4;
2786 init_samr_group_info4(&ctr
->group
.info4
, map
.comment
);
2789 return NT_STATUS_INVALID_INFO_CLASS
;
2792 init_samr_r_query_groupinfo(r_u
, ctr
, NT_STATUS_NO_PROBLEMO
);
2794 return NT_STATUS_NO_PROBLEMO
;
2797 /*********************************************************************
2800 update a domain group's comment.
2801 *********************************************************************/
2803 uint32
_samr_set_groupinfo(pipes_struct
*p
, SAMR_Q_SET_GROUPINFO
*q_u
, SAMR_R_SET_GROUPINFO
*r_u
)
2807 GROUP_INFO_CTR
*ctr
;
2809 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
))
2810 return NT_STATUS_INVALID_HANDLE
;
2812 if (!get_domain_group_from_sid(group_sid
, &map
))
2813 return NT_STATUS_NO_SUCH_GROUP
;
2817 switch (ctr
->switch_value1
) {
2819 unistr2_to_ascii(map
.comment
, &(ctr
->group
.info1
.uni_acct_desc
), sizeof(map
.comment
)-1);
2822 unistr2_to_ascii(map
.comment
, &(ctr
->group
.info4
.uni_acct_desc
), sizeof(map
.comment
)-1);
2825 return NT_STATUS_INVALID_INFO_CLASS
;
2828 if(!add_mapping_entry(&map
, TDB_REPLACE
))
2829 return NT_STATUS_NO_SUCH_GROUP
;
2831 return NT_STATUS_NO_PROBLEMO
;
2834 /*********************************************************************
2835 _samr_get_dom_pwinfo
2836 *********************************************************************/
2838 uint32
_samr_get_dom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_DOM_PWINFO
*q_u
, SAMR_R_GET_DOM_PWINFO
*r_u
)
2840 /* Actually, returning zeros here works quite well :-). */
2841 return NT_STATUS_NOPROBLEMO
;
2844 /*********************************************************************
2846 *********************************************************************/
2848 uint32
_samr_open_group(pipes_struct
*p
, SAMR_Q_OPEN_GROUP
*q_u
, SAMR_R_OPEN_GROUP
*r_u
)
2852 struct samr_info
*info
;
2855 if (!get_lsa_policy_samr_sid(p
, &q_u
->domain_pol
, &sid
))
2856 return NT_STATUS_INVALID_HANDLE
;
2858 /* this should not be hard-coded like this */
2859 if (!sid_equal(&sid
, &global_sam_sid
))
2860 return NT_STATUS_ACCESS_DENIED
;
2862 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
2863 return NT_STATUS_NO_MEMORY
;
2867 sid_copy(&info
->sid
, &global_sam_sid
);
2868 sid_append_rid(&info
->sid
, q_u
->rid_group
);
2869 sid_to_string(sid_string
, &info
->sid
);
2871 DEBUG(10, ("Opening SID: %s\n", sid_string
));
2873 /* check if that group really exists */
2874 if (!get_domain_group_from_sid(info
->sid
, &map
))
2875 return NT_STATUS_NO_SUCH_USER
;
2877 /* get a (unique) handle. open a policy on it. */
2878 if (!create_policy_hnd(p
, &r_u
->pol
, free_samr_info
, (void *)info
))
2879 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2881 return NT_STATUS_NO_PROBLEMO
;
2884 /*********************************************************************
2886 *********************************************************************/
2888 uint32
_samr_unknown_2d(pipes_struct
*p
, SAMR_Q_UNKNOWN_2D
*q_u
, SAMR_R_UNKNOWN_2D
*r_u
)
2890 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));