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
)
82 memset(sam_pass
->lm_pw
, '\0', 16);
83 memset(sam_pass
->nt_pw
, '\0', 16);
86 /*******************************************************************
87 This next function should be replaced with something that
88 dynamically returns the correct user info..... JRA.
89 ********************************************************************/
91 static BOOL
get_sampwd_entries(SAM_USER_INFO_21
*pw_buf
, int start_idx
,
92 int *total_entries
, int *num_entries
,
93 int max_num_entries
, uint16 acb_mask
)
95 SAM_ACCOUNT
*pwd
= NULL
;
106 if (!pdb_setsampwent(False
)) {
107 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
112 while (((ret
= pdb_getsampwent(pwd
)) != False
) && (*num_entries
) < max_num_entries
) {
116 /* skip the requested number of entries.
117 not very efficient, but hey...
123 user_name_len
= strlen(pdb_get_username(pwd
))+1;
124 init_unistr2(&pw_buf
[(*num_entries
)].uni_user_name
, pdb_get_username(pwd
), user_name_len
);
125 init_uni_hdr(&pw_buf
[(*num_entries
)].hdr_user_name
, user_name_len
);
126 pw_buf
[(*num_entries
)].user_rid
= pwd
->user_rid
;
127 memset((char *)pw_buf
[(*num_entries
)].nt_pwd
, '\0', 16);
129 /* Now check if the NT compatible password is available. */
130 if (pdb_get_nt_passwd(pwd
))
131 memcpy( pw_buf
[(*num_entries
)].nt_pwd
, pdb_get_nt_passwd(pwd
), 16);
133 pw_buf
[(*num_entries
)].acb_info
= pdb_get_acct_ctrl(pwd
);
135 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
136 (*num_entries
), pdb_get_username(pwd
), pdb_get_user_rid(pwd
), pdb_get_acct_ctrl(pwd
) ));
138 if (acb_mask
== 0 || (pwd
->acct_ctrl
& acb_mask
)) {
139 DEBUG(5,(" acb_mask %x accepts\n", acb_mask
));
143 DEBUG(5,(" acb_mask %x rejects\n", acb_mask
));
151 return (*num_entries
) > 0;
154 static BOOL
jf_get_sampwd_entries(SAM_USER_INFO_21
*pw_buf
, int start_idx
,
155 int *total_entries
, uint32
*num_entries
,
156 int max_num_entries
, uint16 acb_mask
)
158 SAM_ACCOUNT
*pwd
= NULL
;
166 DEBUG(10,("jf_get_sampwd_entries: start index:%d, max entries:%d, mask:%d\n",
167 start_idx
, max_num_entries
, acb_mask
));
169 if (!pdb_setsampwent(False
)) {
170 DEBUG(0, ("jf_get_sampwd_entries: Unable to open passdb.\n"));
176 while ((pdb_getsampwent(pwd
) != False
) && (*num_entries
) < max_num_entries
) {
180 if (acb_mask
!= 0 && !(pdb_get_acct_ctrl(pwd
) & acb_mask
))
184 /* skip the requested number of entries.
185 not very efficient, but hey...
191 ZERO_STRUCTP(&pw_buf
[(*num_entries
)]);
193 user_name_len
= strlen(pdb_get_username(pwd
));
194 init_unistr2(&pw_buf
[(*num_entries
)].uni_user_name
, pdb_get_username(pwd
), user_name_len
);
195 init_uni_hdr(&pw_buf
[(*num_entries
)].hdr_user_name
, user_name_len
);
197 full_name_len
= strlen(pdb_get_fullname(pwd
));
198 init_unistr2(&pw_buf
[(*num_entries
)].uni_full_name
, pdb_get_fullname(pwd
), full_name_len
);
199 init_uni_hdr(&pw_buf
[(*num_entries
)].hdr_full_name
, full_name_len
);
201 pw_buf
[(*num_entries
)].user_rid
= pdb_get_user_rid(pwd
);
202 memset((char *)pw_buf
[(*num_entries
)].nt_pwd
, '\0', 16);
204 /* Now check if the NT compatible password is available. */
205 if (pdb_get_nt_passwd(pwd
))
206 memcpy( pw_buf
[(*num_entries
)].nt_pwd
, pdb_get_nt_passwd(pwd
), 16);
208 pw_buf
[(*num_entries
)].acb_info
= pdb_get_acct_ctrl(pwd
);
210 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x\n", (*num_entries
),
211 pdb_get_username(pwd
), pdb_get_user_rid(pwd
), pdb_get_acct_ctrl(pwd
) ));
218 *total_entries
= *num_entries
;
225 /*******************************************************************
226 This function uses the username map file and tries to map a UNIX
227 user name to an DOS name. (Sort of the reverse of the
228 map_username() function.) Since more than one DOS name can map
229 to the UNIX name, to reverse the mapping you have to specify
230 which corresponding DOS name you want; that's where the name_idx
231 parameter comes in. Returns the string requested or NULL if it
232 fails or can't complete the request for any reason. This doesn't
233 handle group names (starting with '@') or names starting with
234 '+' or '&'. If they are encountered, they are skipped.
235 ********************************************************************/
237 static char *unmap_unixname(char *unix_user_name
, int name_idx
)
239 char *mapfile
= lp_username_map();
244 if (!*unix_user_name
) return NULL
;
245 if (!*mapfile
) return NULL
;
247 lines
= file_lines_load(mapfile
, NULL
,False
);
249 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile
));
253 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile
, name_idx
));
255 for (i
=0; lines
[i
]; i
++) {
256 char *unixname
= lines
[i
];
257 char *dosname
= strchr(unixname
,'=');
264 while (isspace(*unixname
))
266 if ('!' == *unixname
) {
268 while (*unixname
&& isspace(*unixname
))
272 if (!*unixname
|| strchr("#;",*unixname
))
275 if (strncmp(unixname
, unix_user_name
, strlen(unix_user_name
)))
278 /* We have matched the UNIX user name */
280 while(next_token(&dosname
, tok
, LIST_SEP
, sizeof(tok
))) {
281 if (!strchr("@&+", *tok
)) {
290 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
291 file_lines_free(lines
);
294 file_lines_free(lines
);
299 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
300 file_lines_free(lines
);
304 /*******************************************************************
305 This function sets up a list of users taken from the list of
306 users that UNIX knows about, as well as all the user names that
307 Samba maps to a valid UNIX user name. (This should work with
309 ********************************************************************/
311 static BOOL
get_passwd_entries(SAM_USER_INFO_21
*pw_buf
,
313 int *total_entries
, int *num_entries
,
317 static struct passwd
*pwd
= NULL
;
318 static uint32 pw_rid
;
319 static BOOL orig_done
= False
;
320 static int current_idx
= 0;
321 static int mapped_idx
= 0;
324 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
327 (*total_entries
) = 0;
329 /* Skip all this stuff if we're in appliance mode */
331 if (lp_hide_local_users()) goto done
;
333 if (pw_buf
== NULL
) return False
;
335 if (current_idx
== 0) {
339 /* These two cases are inefficient, but should be called very rarely */
340 /* they are the cases where the starting index isn't picking up */
341 /* where we left off last time. It is efficient when it starts over */
342 /* at zero though. */
343 if (start_idx
> current_idx
) {
344 /* We aren't far enough; advance to start_idx */
345 while (current_idx
<= start_idx
) {
349 if ((pwd
= sys_getpwent()) == NULL
) break;
354 while (((unmap_name
= unmap_unixname(pwd
->pw_name
, mapped_idx
)) != NULL
) &&
355 (current_idx
< start_idx
)) {
360 if (unmap_name
== NULL
) {
365 } else if (start_idx
< current_idx
) {
366 /* We are already too far; start over and advance to start_idx */
372 while (current_idx
< start_idx
) {
376 if ((pwd
= sys_getpwent()) == NULL
) break;
381 while (((unmap_name
= unmap_unixname(pwd
->pw_name
, mapped_idx
)) != NULL
) &&
382 (current_idx
< start_idx
)) {
387 if (unmap_name
== NULL
) {
394 sep
= lp_winbind_separator();
396 /* now current_idx == start_idx */
397 while ((*num_entries
) < max_num_entries
) {
401 /* This does the original UNIX user itself */
403 if ((pwd
= sys_getpwent()) == NULL
) break;
405 /* Don't enumerate winbind users as they are not local */
407 if (strchr(pwd
->pw_name
, *sep
) != NULL
) {
411 user_name_len
= strlen(pwd
->pw_name
);
413 /* skip the trust account stored in the /etc/passwd file */
414 if (pwd
->pw_name
[user_name_len
-1]=='$')
417 pw_rid
= pdb_uid_to_user_rid(pwd
->pw_uid
);
418 ZERO_STRUCTP(&pw_buf
[(*num_entries
)]);
419 init_unistr2(&pw_buf
[(*num_entries
)].uni_user_name
, pwd
->pw_name
, user_name_len
);
420 init_uni_hdr(&pw_buf
[(*num_entries
)].hdr_user_name
, user_name_len
);
421 pw_buf
[(*num_entries
)].user_rid
= pw_rid
;
422 memset((char *)pw_buf
[(*num_entries
)].nt_pwd
, '\0', 16);
424 pw_buf
[(*num_entries
)].acb_info
= ACB_NORMAL
;
426 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries
), pwd
->pw_name
, pw_rid
));
434 /* This does all the user names that map to the UNIX user */
435 while (((unmap_name
= unmap_unixname(pwd
->pw_name
, mapped_idx
)) != NULL
) &&
436 (*num_entries
< max_num_entries
)) {
437 user_name_len
= strlen(unmap_name
);
438 ZERO_STRUCTP(&pw_buf
[(*num_entries
)]);
439 init_unistr2(&pw_buf
[(*num_entries
)].uni_user_name
, unmap_name
, user_name_len
);
440 init_uni_hdr(&pw_buf
[(*num_entries
)].hdr_user_name
, user_name_len
);
441 pw_buf
[(*num_entries
)].user_rid
= pw_rid
;
442 memset((char *)pw_buf
[(*num_entries
)].nt_pwd
, '\0', 16);
444 pw_buf
[(*num_entries
)].acb_info
= ACB_NORMAL
;
446 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries
), pwd
->pw_name
, pw_rid
));
454 if (unmap_name
== NULL
) {
455 /* done with 'aliases', go on to next UNIX user */
462 /* totally done, reset everything */
469 return (*num_entries
) > 0;
472 /*******************************************************************
474 ********************************************************************/
476 uint32
_samr_close_hnd(pipes_struct
*p
, SAMR_Q_CLOSE_HND
*q_u
, SAMR_R_CLOSE_HND
*r_u
)
478 r_u
->status
= NT_STATUS_NOPROBLEMO
;
480 /* close the policy handle */
481 if (!close_policy_hnd(p
, &q_u
->pol
))
482 return NT_STATUS_OBJECT_NAME_INVALID
;
484 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__
));
489 /*******************************************************************
490 samr_reply_open_domain
491 ********************************************************************/
493 uint32
_samr_open_domain(pipes_struct
*p
, SAMR_Q_OPEN_DOMAIN
*q_u
, SAMR_R_OPEN_DOMAIN
*r_u
)
495 struct samr_info
*info
;
497 r_u
->status
= NT_STATUS_NOPROBLEMO
;
499 /* find the connection policy handle. */
500 if (!find_policy_by_hnd(p
, &q_u
->pol
, NULL
))
501 return NT_STATUS_INVALID_HANDLE
;
503 /* associate the domain SID with the (unique) handle. */
504 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
505 return NT_STATUS_NO_MEMORY
;
508 info
->sid
= q_u
->dom_sid
.sid
;
510 /* get a (unique) handle. open a policy on it. */
511 if (!create_policy_hnd(p
, &r_u
->domain_pol
, free_samr_info
, (void *)info
))
512 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
514 DEBUG(5,("samr_open_domain: %d\n", __LINE__
));
519 static uint32
get_lsa_policy_samr_rid(struct samr_info
*info
)
522 DEBUG(3,("Error getting policy\n"));
526 return info
->sid
.sub_auths
[info
->sid
.num_auths
-1];
529 /*******************************************************************
530 _samr_get_usrdom_pwinfo
531 ********************************************************************/
533 uint32
_samr_get_usrdom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_USRDOM_PWINFO
*q_u
, SAMR_R_GET_USRDOM_PWINFO
*r_u
)
535 struct samr_info
*info
= NULL
;
537 r_u
->status
= NT_STATUS_NOPROBLEMO
;
539 /* find the policy handle. open a policy on it. */
540 if (!find_policy_by_hnd(p
, &q_u
->user_pol
, (void **)&info
)) {
541 return NT_STATUS_INVALID_HANDLE
;
544 /* find the user's rid */
545 if (get_lsa_policy_samr_rid(info
) == 0xffffffff) {
546 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
549 init_samr_r_get_usrdom_pwinfo(r_u
, NT_STATUS_NOPROBLEMO
);
551 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__
));
556 /*******************************************************************
558 ********************************************************************/
560 static uint32
samr_make_usr_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC_BUF
**buf
, DOM_SID
*usr_sid
)
562 extern DOM_SID global_sid_World
;
570 SEC_DESC
*psd
= NULL
;
573 sid_copy(&adm_sid
, &global_sid_Builtin
);
574 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
576 sid_copy(&act_sid
, &global_sid_Builtin
);
577 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
579 init_sec_access(&mask
, 0x2035b);
580 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
582 init_sec_access(&mask
, 0xf07ff);
583 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
584 init_sec_ace(&ace
[2], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
586 init_sec_access(&mask
,0x20044);
587 init_sec_ace(&ace
[3], usr_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
589 if((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 4, ace
)) == NULL
)
590 return NT_STATUS_NO_MEMORY
;
592 if((psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, NULL
, NULL
, NULL
, psa
, &sd_size
)) == NULL
)
593 return NT_STATUS_NO_MEMORY
;
595 if((*buf
= make_sec_desc_buf(ctx
, sd_size
, psd
)) == NULL
)
596 return NT_STATUS_NO_MEMORY
;
598 return NT_STATUS_NOPROBLEMO
;
601 static BOOL
get_lsa_policy_samr_sid(pipes_struct
*p
, POLICY_HND
*pol
, DOM_SID
*sid
)
603 struct samr_info
*info
= NULL
;
605 /* find the policy handle. open a policy on it. */
606 if (!find_policy_by_hnd(p
, pol
, (void **)&info
))
616 /*******************************************************************
618 ********************************************************************/
620 uint32
_samr_query_sec_obj(pipes_struct
*p
, SAMR_Q_QUERY_SEC_OBJ
*q_u
, SAMR_R_QUERY_SEC_OBJ
*r_u
)
624 r_u
->status
= NT_STATUS_NOPROBLEMO
;
628 if (!get_lsa_policy_samr_sid(p
, &q_u
->user_pol
, &pol_sid
))
629 return NT_STATUS_INVALID_HANDLE
;
631 r_u
->status
= samr_make_usr_obj_sd(p
->mem_ctx
, &r_u
->buf
, &pol_sid
);
633 if (r_u
->status
== NT_STATUS_NOPROBLEMO
)
639 /*******************************************************************
640 makes a SAM_ENTRY / UNISTR2* structure from a user list.
641 ********************************************************************/
643 static void make_user_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
, UNISTR2
**uni_name_pp
,
644 uint32 num_sam_entries
, SAM_USER_INFO_21
*pass
)
653 if (num_sam_entries
== 0)
656 sam
= (SAM_ENTRY
*)talloc(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
658 uni_name
= (UNISTR2
*)talloc(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
660 if (sam
== NULL
|| uni_name
== NULL
) {
661 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
665 for (i
= 0; i
< num_sam_entries
; i
++) {
666 int len
= pass
[i
].uni_user_name
.uni_str_len
;
668 init_sam_entry(&sam
[i
], len
, pass
[i
].user_rid
);
669 copy_unistr2(&uni_name
[i
], &pass
[i
].uni_user_name
);
673 *uni_name_pp
= uni_name
;
676 /*******************************************************************
677 samr_reply_enum_dom_users
678 ********************************************************************/
680 uint32
_samr_enum_dom_users(pipes_struct
*p
, SAMR_Q_ENUM_DOM_USERS
*q_u
, SAMR_R_ENUM_DOM_USERS
*r_u
)
682 SAM_USER_INFO_21 pass
[MAX_SAM_ENTRIES
];
684 int total_entries
= 0;
687 r_u
->status
= NT_STATUS_NOPROBLEMO
;
689 /* find the policy handle. open a policy on it. */
690 if (!find_policy_by_hnd(p
, &q_u
->pol
, NULL
))
691 return NT_STATUS_INVALID_HANDLE
;
693 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
696 ret
= get_sampwd_entries(pass
, q_u
->start_idx
, &total_entries
, &num_entries
,
697 MAX_SAM_ENTRIES
, q_u
->acb_mask
);
701 return NT_STATUS_ACCESS_DENIED
;
703 samr_clear_passwd_fields(pass
, num_entries
);
706 * Note from JRA. total_entries is not being used here. Currently if there is a
707 * large user base then it looks like NT will enumerate until get_sampwd_entries
708 * returns False due to num_entries being zero. This will cause an access denied
709 * return. I don't think this is right and needs further investigation. Note that
710 * this is also the same in the TNG code (I don't think that has been tested with
711 * a very large user list as MAX_SAM_ENTRIES is set to 600).
713 * I also think that one of the 'num_entries' return parameters is probably
714 * the "max entries" parameter - but in the TNG code they're all currently set to the same
715 * value (again I think this is wrong).
718 make_user_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_acct_name
, num_entries
, pass
);
720 init_samr_r_enum_dom_users(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
722 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
727 /*******************************************************************
728 makes a SAM_ENTRY / UNISTR2* structure from a group list.
729 ********************************************************************/
731 static void make_group_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
, UNISTR2
**uni_name_pp
,
732 uint32 num_sam_entries
, DOMAIN_GRP
*grp
)
741 if (num_sam_entries
== 0)
744 sam
= (SAM_ENTRY
*)talloc(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
746 uni_name
= (UNISTR2
*)talloc(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
748 if (sam
== NULL
|| uni_name
== NULL
) {
749 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
753 for (i
= 0; i
< num_sam_entries
; i
++) {
755 * JRA. I think this should include the null. TNG does not.
757 int len
= strlen(grp
[i
].name
)+1;
759 init_sam_entry(&sam
[i
], len
, grp
[i
].rid
);
760 init_unistr2(&uni_name
[i
], grp
[i
].name
, len
);
764 *uni_name_pp
= uni_name
;
767 /*******************************************************************
768 Get the group entries - similar to get_sampwd_entries().
769 ********************************************************************/
771 static BOOL
get_group_alias_entries(DOMAIN_GRP
**d_grp
, DOM_SID
*sid
, uint32 start_idx
,
772 uint32
*p_num_entries
, uint32 max_entries
)
775 uint32 num_entries
= 0;
780 sid_to_string(sid_str
, sid
);
781 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str
));
785 /* well-known aliases */
786 if (sid_equal(sid
, &global_sid_Builtin
) && !lp_hide_local_users()) {
788 enum_group_mapping(SID_NAME_WKN_GRP
, &map
, &num_entries
, ENUM_ONLY_MAPPED
);
790 *d_grp
=(DOMAIN_GRP
*)malloc(num_entries
*sizeof(DOMAIN_GRP
));
792 return NT_STATUS_NO_MEMORY
;
794 for(i
=0; i
<num_entries
&& i
<max_entries
; i
++) {
795 fstrcpy((*d_grp
)[i
].name
, map
[i
+start_idx
].nt_name
);
796 sid_split_rid(&map
[i
].sid
, &(*d_grp
)[i
].rid
);
802 } else if (sid_equal(sid
, &global_sam_sid
) && !lp_hide_local_users()) {
807 sep
= lp_winbind_separator();
810 /* we return the UNIX groups here. This seems to be the right */
811 /* thing to do, since NT member servers return their local */
812 /* groups in the same situation. */
815 while (num_entries
< max_entries
&& ((grp
= getgrent()) != NULL
)) {
819 if(!get_group_from_gid(grp
->gr_gid
, &smap
))
822 if (smap
.sid_name_use
!=SID_NAME_ALIAS
)
825 sid_split_rid(&smap
.sid
, &trid
);
827 /* Don't return winbind groups as they are not local! */
828 if (strchr(smap
.nt_name
, *sep
) != NULL
) {
829 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap
.nt_name
));
833 /* Don't return user private groups... */
834 if (Get_Pwnam(smap
.nt_name
, False
) != 0) {
835 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap
.nt_name
));
839 for( i
= 0; i
< num_entries
; i
++)
840 if ( (*d_grp
)[i
].rid
== trid
) break;
842 if ( i
< num_entries
)
843 continue; /* rid was there, dup! */
845 /* JRA - added this for large group db enumeration... */
848 /* skip the requested number of entries.
849 not very efficient, but hey...
855 *d_grp
=Realloc(*d_grp
, (num_entries
+1)*sizeof(DOMAIN_GRP
));
857 return NT_STATUS_NO_MEMORY
;
859 fstrcpy((*d_grp
)[num_entries
].name
, smap
.nt_name
);
860 (*d_grp
)[num_entries
].rid
= trid
;
867 *p_num_entries
= num_entries
;
872 /*******************************************************************
873 Get the group entries - similar to get_sampwd_entries().
874 ********************************************************************/
876 static BOOL
get_group_domain_entries(DOMAIN_GRP
**d_grp
, DOM_SID
*sid
, uint32 start_idx
,
877 uint32
*p_num_entries
, uint32 max_entries
)
881 uint32 num_entries
= 0;
885 enum_group_mapping(SID_NAME_DOM_GRP
, &map
, &num_entries
, ENUM_ONLY_MAPPED
);
887 *d_grp
=(DOMAIN_GRP
*)malloc(num_entries
*sizeof(DOMAIN_GRP
));
891 for (i
=0; i
<num_entries
; i
++) {
892 fstrcpy((*d_grp
)[i
].name
, map
[i
].nt_name
);
893 fstrcpy((*d_grp
)[i
].comment
, map
[i
].comment
);
894 sid_split_rid(&map
[i
].sid
, &(*d_grp
)[i
].rid
);
895 (*d_grp
)[i
].attr
=SID_NAME_DOM_GRP
;
900 *p_num_entries
= num_entries
;
905 /*******************************************************************
906 samr_reply_enum_dom_groups
907 Only reply with one group - domain admins. This must be fixed for
909 ********************************************************************/
911 uint32
_samr_enum_dom_groups(pipes_struct
*p
, SAMR_Q_ENUM_DOM_GROUPS
*q_u
, SAMR_R_ENUM_DOM_GROUPS
*r_u
)
913 DOMAIN_GRP
*grp
=NULL
;
917 r_u
->status
= NT_STATUS_NOPROBLEMO
;
919 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
))
920 return NT_STATUS_INVALID_HANDLE
;
922 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__
));
924 /* the domain group array is being allocated in the function below */
925 get_group_domain_entries(&grp
, &sid
, q_u
->start_idx
, &num_entries
, MAX_SAM_ENTRIES
);
927 make_group_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_grp_name
, num_entries
, grp
);
931 init_samr_r_enum_dom_groups(r_u
, q_u
->start_idx
, num_entries
);
933 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__
));
939 /*******************************************************************
940 samr_reply_enum_dom_aliases
941 ********************************************************************/
943 uint32
_samr_enum_dom_aliases(pipes_struct
*p
, SAMR_Q_ENUM_DOM_ALIASES
*q_u
, SAMR_R_ENUM_DOM_ALIASES
*r_u
)
945 DOMAIN_GRP
*grp
=NULL
;
946 uint32 num_entries
= 0;
950 r_u
->status
= NT_STATUS_NOPROBLEMO
;
952 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
))
953 return NT_STATUS_INVALID_HANDLE
;
955 sid_to_string(sid_str
, &sid
);
956 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str
));
958 if (!get_group_alias_entries(&grp
, &sid
, q_u
->start_idx
, &num_entries
, MAX_SAM_ENTRIES
))
959 return NT_STATUS_ACCESS_DENIED
;
961 make_group_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_grp_name
, num_entries
, grp
);
965 init_samr_r_enum_dom_aliases(r_u
, q_u
->start_idx
, num_entries
);
967 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__
));
972 /*******************************************************************
973 samr_reply_query_dispinfo
974 ********************************************************************/
976 uint32
_samr_query_dispinfo(pipes_struct
*p
, SAMR_Q_QUERY_DISPINFO
*q_u
, SAMR_R_QUERY_DISPINFO
*r_u
)
978 SAM_USER_INFO_21 pass
[MAX_SAM_ENTRIES
];
979 DOMAIN_GRP
*grps
=NULL
;
980 uint16 acb_mask
= ACB_NORMAL
;
981 uint32 num_entries
= 0;
982 int orig_num_entries
= 0;
983 int total_entries
= 0;
984 uint32 data_size
= 0;
987 SAM_DISPINFO_CTR
*ctr
;
989 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__
));
991 r_u
->status
= NT_STATUS_NOPROBLEMO
;
993 if (!get_lsa_policy_samr_sid(p
, &q_u
->domain_pol
, &sid
))
994 return NT_STATUS_INVALID_HANDLE
;
996 /* decide how many entries to get depending on the max_entries
997 and max_size passed by client */
999 if(q_u
->max_entries
> MAX_SAM_ENTRIES
)
1000 q_u
->max_entries
= MAX_SAM_ENTRIES
;
1002 /* Get what we need from the password database */
1003 switch (q_u
->switch_level
) {
1005 acb_mask
= ACB_WSTRUST
;
1011 ret
= get_passwd_entries(pass
, q_u
->start_idx
, &total_entries
, &num_entries
,
1012 MAX_SAM_ENTRIES
, acb_mask
);
1016 * Which should we use here ? JRA.
1018 ret
= get_sampwd_entries(pass
, q_u
->start_idx
, &total_entries
, &num_entries
,
1019 MAX_SAM_ENTRIES
, acb_mask
);
1022 ret
= jf_get_sampwd_entries(pass
, q_u
->start_idx
, &total_entries
, &num_entries
,
1023 MAX_SAM_ENTRIES
, acb_mask
);
1027 DEBUG(5, ("get_sampwd_entries: failed\n"));
1028 return NT_STATUS_ACCESS_DENIED
;
1033 ret
= get_group_domain_entries(&grps
, &sid
, q_u
->start_idx
, &num_entries
, MAX_SAM_ENTRIES
);
1035 return NT_STATUS_ACCESS_DENIED
;
1038 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u
->switch_level
));
1039 return NT_STATUS_INVALID_INFO_CLASS
;
1043 if (num_entries
> q_u
->max_entries
)
1044 num_entries
= q_u
->max_entries
;
1046 if (num_entries
> MAX_SAM_ENTRIES
) {
1047 num_entries
= MAX_SAM_ENTRIES
;
1048 DEBUG(5, ("limiting number of entries to %d\n", num_entries
));
1051 /* Ensure password info is never given out here. PARANOIA... JRA */
1052 samr_clear_passwd_fields(pass
, num_entries
);
1054 data_size
= q_u
->max_size
;
1055 orig_num_entries
= num_entries
;
1057 ctr
= (SAM_DISPINFO_CTR
*)talloc(p
->mem_ctx
,sizeof(SAM_DISPINFO_CTR
));
1059 /* Now create reply structure */
1060 switch (q_u
->switch_level
) {
1062 ctr
->sam
.info1
= (SAM_DISPINFO_1
*)talloc(p
->mem_ctx
,num_entries
*sizeof(SAM_DISPINFO_1
));
1063 init_sam_dispinfo_1(ctr
->sam
.info1
, &num_entries
, &data_size
, q_u
->start_idx
, pass
);
1066 ctr
->sam
.info2
= (SAM_DISPINFO_2
*)talloc(p
->mem_ctx
,num_entries
*sizeof(SAM_DISPINFO_2
));
1067 init_sam_dispinfo_2(ctr
->sam
.info2
, &num_entries
, &data_size
, q_u
->start_idx
, pass
);
1070 ctr
->sam
.info3
= (SAM_DISPINFO_3
*)talloc(p
->mem_ctx
,num_entries
*sizeof(SAM_DISPINFO_3
));
1071 init_sam_dispinfo_3(ctr
->sam
.info3
, &num_entries
, &data_size
, q_u
->start_idx
, grps
);
1075 ctr
->sam
.info4
= (SAM_DISPINFO_4
*)talloc(p
->mem_ctx
,num_entries
*sizeof(SAM_DISPINFO_4
));
1076 init_sam_dispinfo_4(ctr
->sam
.info4
, &num_entries
, &data_size
, q_u
->start_idx
, pass
);
1079 ctr
->sam
.info5
= (SAM_DISPINFO_5
*)talloc(p
->mem_ctx
,num_entries
*sizeof(SAM_DISPINFO_5
));
1080 init_sam_dispinfo_5(ctr
->sam
.info5
, &num_entries
, &data_size
, q_u
->start_idx
, grps
);
1084 ctr
->sam
.info
= NULL
;
1085 return NT_STATUS_INVALID_INFO_CLASS
;
1088 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__
));
1090 init_samr_r_query_dispinfo(r_u
, num_entries
, data_size
, q_u
->switch_level
, ctr
, r_u
->status
);
1092 if (num_entries
< orig_num_entries
) {
1093 return STATUS_MORE_ENTRIES
;
1099 /*******************************************************************
1100 samr_reply_query_aliasinfo
1101 ********************************************************************/
1103 uint32
_samr_query_aliasinfo(pipes_struct
*p
, SAMR_Q_QUERY_ALIASINFO
*q_u
, SAMR_R_QUERY_ALIASINFO
*r_u
)
1105 fstring alias_desc
= "Local Unix group";
1107 enum SID_NAME_USE type
;
1109 struct samr_info
*info
= NULL
;
1111 r_u
->status
= NT_STATUS_NOPROBLEMO
;
1113 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1115 /* find the policy handle. open a policy on it. */
1116 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1117 return NT_STATUS_INVALID_HANDLE
;
1119 alias_rid
= get_lsa_policy_samr_rid(info
);
1120 if(alias_rid
== 0xffffffff)
1121 return NT_STATUS_NO_SUCH_ALIAS
;
1123 if(!local_lookup_rid(alias_rid
, alias
, &type
))
1124 return NT_STATUS_NO_SUCH_ALIAS
;
1126 switch (q_u
->switch_level
) {
1129 r_u
->ctr
.switch_value1
= 3;
1130 init_samr_alias_info3(&r_u
->ctr
.alias
.info3
, alias_desc
);
1133 return NT_STATUS_INVALID_INFO_CLASS
;
1136 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1142 /*******************************************************************
1143 samr_reply_lookup_ids
1144 ********************************************************************/
1146 uint32
_samr_lookup_ids(pipes_struct
*p
, SAMR_Q_LOOKUP_IDS
*q_u
, SAMR_R_LOOKUP_IDS
*r_u
)
1148 uint32 rid
[MAX_SAM_ENTRIES
];
1149 int num_rids
= q_u
->num_sids1
;
1151 r_u
->status
= NT_STATUS_NOPROBLEMO
;
1153 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1155 if (num_rids
> MAX_SAM_ENTRIES
) {
1156 num_rids
= MAX_SAM_ENTRIES
;
1157 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids
));
1162 SMB_ASSERT_ARRAY(q_u
->uni_user_name
, num_rids
);
1164 for (i
= 0; i
< num_rids
&& status
== 0; i
++)
1166 struct sam_passwd
*sam_pass
;
1170 fstrcpy(user_name
, unistrn2(q_u
->uni_user_name
[i
].buffer
,
1171 q_u
->uni_user_name
[i
].uni_str_len
));
1173 /* find the user account */
1175 sam_pass
= get_smb21pwd_entry(user_name
, 0);
1178 if (sam_pass
== NULL
)
1180 status
= 0xC0000000 | NT_STATUS_NO_SUCH_USER
;
1185 rid
[i
] = sam_pass
->user_rid
;
1191 rid
[0] = BUILTIN_ALIAS_RID_USERS
;
1193 init_samr_r_lookup_ids(&r_u
, num_rids
, rid
, NT_STATUS_NOPROBLEMO
);
1195 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1201 /*******************************************************************
1203 ********************************************************************/
1205 uint32
_samr_lookup_names(pipes_struct
*p
, SAMR_Q_LOOKUP_NAMES
*q_u
, SAMR_R_LOOKUP_NAMES
*r_u
)
1207 uint32 rid
[MAX_SAM_ENTRIES
];
1208 enum SID_NAME_USE type
[MAX_SAM_ENTRIES
];
1210 int num_rids
= q_u
->num_names1
;
1213 r_u
->status
= NT_STATUS_NOPROBLEMO
;
1215 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1220 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
)) {
1221 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, 0, NULL
, NULL
, NT_STATUS_OBJECT_TYPE_MISMATCH
);
1225 if (num_rids
> MAX_SAM_ENTRIES
) {
1226 num_rids
= MAX_SAM_ENTRIES
;
1227 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids
));
1230 SMB_ASSERT_ARRAY(q_u
->uni_name
, num_rids
);
1232 for (i
= 0; i
< num_rids
; i
++) {
1235 r_u
->status
= NT_STATUS_NONE_MAPPED
;
1237 rid
[i
] = 0xffffffff;
1238 type
[i
] = SID_NAME_UNKNOWN
;
1240 fstrcpy(name
, dos_unistrn2(q_u
->uni_name
[i
].buffer
, q_u
->uni_name
[i
].uni_str_len
));
1242 if(sid_equal(&pol_sid
, &global_sam_sid
)) {
1244 if(local_lookup_name(global_myname
, name
, &sid
, &type
[i
])) {
1245 sid_split_rid( &sid
, &rid
[i
]);
1246 r_u
->status
= NT_STATUS_NOPROBLEMO
;
1251 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, num_rids
, rid
, (uint32
*)type
, r_u
->status
);
1253 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1258 /*******************************************************************
1259 _samr_chgpasswd_user
1260 ********************************************************************/
1262 uint32
_samr_chgpasswd_user(pipes_struct
*p
, SAMR_Q_CHGPASSWD_USER
*q_u
, SAMR_R_CHGPASSWD_USER
*r_u
)
1267 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1269 r_u
->status
= NT_STATUS_NOPROBLEMO
;
1271 fstrcpy(user_name
, dos_unistrn2(q_u
->uni_user_name
.buffer
, q_u
->uni_user_name
.uni_str_len
));
1272 fstrcpy(wks
, dos_unistrn2(q_u
->uni_dest_host
.buffer
, q_u
->uni_dest_host
.uni_str_len
));
1274 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name
, wks
));
1277 * Pass the user through the NT -> unix user mapping
1281 (void)map_username(user_name
);
1284 * Do any UNIX username case mangling.
1286 (void)Get_Pwnam( user_name
, True
);
1288 if (!pass_oem_change(user_name
, q_u
->lm_newpass
.pass
, q_u
->lm_oldhash
.hash
,
1289 q_u
->nt_newpass
.pass
, q_u
->nt_oldhash
.hash
))
1290 r_u
->status
= NT_STATUS_WRONG_PASSWORD
;
1292 init_samr_r_chgpasswd_user(r_u
, r_u
->status
);
1294 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1299 /*******************************************************************
1300 makes a SAMR_R_LOOKUP_RIDS structure.
1301 ********************************************************************/
1303 static BOOL
make_samr_lookup_rids(TALLOC_CTX
*ctx
, uint32 num_names
, fstring names
[],
1304 UNIHDR
**pp_hdr_name
, UNISTR2
**pp_uni_name
)
1307 UNIHDR
*hdr_name
=NULL
;
1308 UNISTR2
*uni_name
=NULL
;
1310 *pp_uni_name
= NULL
;
1311 *pp_hdr_name
= NULL
;
1313 if (num_names
!= 0) {
1314 hdr_name
= (UNIHDR
*)talloc(ctx
, sizeof(UNIHDR
)*num_names
);
1315 if (hdr_name
== NULL
)
1318 uni_name
= (UNISTR2
*)talloc(ctx
,sizeof(UNISTR2
)*num_names
);
1319 if (uni_name
== NULL
)
1323 for (i
= 0; i
< num_names
; i
++) {
1324 int len
= names
[i
] != NULL
? strlen(names
[i
]) : 0;
1325 DEBUG(10, ("names[%d]:%s\n", i
, names
[i
]));
1326 init_uni_hdr(&hdr_name
[i
], len
);
1327 init_unistr2(&uni_name
[i
], names
[i
], len
);
1330 *pp_uni_name
= uni_name
;
1331 *pp_hdr_name
= hdr_name
;
1336 /*******************************************************************
1338 ********************************************************************/
1340 uint32
_samr_lookup_rids(pipes_struct
*p
, SAMR_Q_LOOKUP_RIDS
*q_u
, SAMR_R_LOOKUP_RIDS
*r_u
)
1342 fstring group_names
[MAX_SAM_ENTRIES
];
1343 uint32 group_attrs
[MAX_SAM_ENTRIES
];
1344 UNIHDR
*hdr_name
= NULL
;
1345 UNISTR2
*uni_name
= NULL
;
1347 int num_rids
= q_u
->num_rids1
;
1350 r_u
->status
= NT_STATUS_NOPROBLEMO
;
1352 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__
));
1354 /* find the policy handle. open a policy on it. */
1355 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
))
1356 return NT_STATUS_INVALID_HANDLE
;
1358 if (num_rids
> MAX_SAM_ENTRIES
) {
1359 num_rids
= MAX_SAM_ENTRIES
;
1360 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids
));
1363 r_u
->status
= NT_STATUS_NONE_MAPPED
;
1365 for (i
= 0; i
< num_rids
; i
++) {
1369 enum SID_NAME_USE type
;
1371 group_attrs
[i
] = SID_NAME_UNKNOWN
;
1372 *group_names
[i
] = '\0';
1374 if (sid_equal(&pol_sid
, &global_sam_sid
)) {
1375 sid_copy(&sid
, &pol_sid
);
1376 sid_append_rid(&sid
, q_u
->rid
[i
]);
1378 if (lookup_sid(&sid
, domname
, tmpname
, &type
)) {
1379 r_u
->status
= NT_STATUS_NOPROBLEMO
;
1380 group_attrs
[i
] = (uint32
)type
;
1381 fstrcpy(group_names
[i
],tmpname
);
1386 if(!make_samr_lookup_rids(p
->mem_ctx
, num_rids
, group_names
, &hdr_name
, &uni_name
))
1387 return NT_STATUS_NO_MEMORY
;
1389 init_samr_r_lookup_rids(r_u
, num_rids
, hdr_name
, uni_name
, group_attrs
);
1391 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__
));
1396 /*******************************************************************
1397 _api_samr_open_user. Safe - gives out no passwd info.
1398 ********************************************************************/
1400 uint32
_api_samr_open_user(pipes_struct
*p
, SAMR_Q_OPEN_USER
*q_u
, SAMR_R_OPEN_USER
*r_u
)
1402 SAM_ACCOUNT
*sampass
=NULL
;
1404 POLICY_HND domain_pol
= q_u
->domain_pol
;
1405 uint32 user_rid
= q_u
->user_rid
;
1406 POLICY_HND
*user_pol
= &r_u
->user_pol
;
1407 struct samr_info
*info
= NULL
;
1410 r_u
->status
= NT_STATUS_NO_PROBLEMO
;
1412 /* find the domain policy handle. */
1413 if (!find_policy_by_hnd(p
, &domain_pol
, NULL
))
1414 return NT_STATUS_INVALID_HANDLE
;
1417 ret
=pdb_getsampwrid(sampass
, user_rid
);
1420 /* check that the RID exists in our domain. */
1422 pdb_free_sam(sampass
);
1423 return NT_STATUS_NO_SUCH_USER
;
1426 samr_clear_sam_passwd(sampass
);
1427 pdb_free_sam(sampass
);
1429 /* Get the domain SID stored in the domain policy */
1430 if(!get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
))
1431 return NT_STATUS_INVALID_HANDLE
;
1433 /* append the user's RID to it */
1434 if(!sid_append_rid(&sid
, user_rid
))
1435 return NT_STATUS_NO_SUCH_USER
;
1437 /* associate the user's SID with the new handle. */
1438 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
1439 return NT_STATUS_NO_MEMORY
;
1444 /* get a (unique) handle. open a policy on it. */
1445 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
))
1446 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1451 /*************************************************************************
1452 get_user_info_10. Safe. Only gives out acb bits.
1453 *************************************************************************/
1455 static BOOL
get_user_info_10(SAM_USER_INFO_10
*id10
, uint32 user_rid
)
1457 SAM_ACCOUNT
*smbpass
=NULL
;
1460 if (!pdb_rid_is_user(user_rid
)) {
1461 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid
));
1465 pdb_init_sam(&smbpass
);
1468 ret
= pdb_getsampwrid(smbpass
, user_rid
);
1472 DEBUG(4,("User 0x%x not found\n", user_rid
));
1473 pdb_free_sam(smbpass
);
1477 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass
) ));
1479 init_sam_user_info10(id10
, pdb_get_acct_ctrl(smbpass
) );
1481 samr_clear_sam_passwd(smbpass
);
1482 pdb_free_sam(smbpass
);
1487 /*************************************************************************
1488 get_user_info_12. OK - this is the killer as it gives out password info.
1489 Ensure that this is only allowed on an encrypted connection with a root
1491 *************************************************************************/
1493 static uint32
get_user_info_12(pipes_struct
*p
, SAM_USER_INFO_12
* id12
, uint32 user_rid
)
1495 SAM_ACCOUNT
*smbpass
=NULL
;
1498 if (!p
->ntlmssp_auth_validated
)
1499 return NT_STATUS_ACCESS_DENIED
;
1501 if (!(p
->ntlmssp_chal_flags
& NTLMSSP_NEGOTIATE_SIGN
) || !(p
->ntlmssp_chal_flags
& NTLMSSP_NEGOTIATE_SEAL
))
1502 return NT_STATUS_ACCESS_DENIED
;
1505 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1507 pdb_init_sam(&smbpass
);
1509 ret
= pdb_getsampwrid(smbpass
, user_rid
);
1512 DEBUG(4, ("User 0x%x not found\n", user_rid
));
1513 pdb_free_sam(smbpass
);
1514 return (geteuid() == (uid_t
)0) ? NT_STATUS_NO_SUCH_USER
: NT_STATUS_ACCESS_DENIED
;
1517 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass
), pdb_get_acct_ctrl(smbpass
) ));
1519 if ( pdb_get_acct_ctrl(smbpass
) & ACB_DISABLED
) {
1520 pdb_free_sam(smbpass
);
1521 return NT_STATUS_ACCOUNT_DISABLED
;
1524 init_sam_user_info12(id12
, pdb_get_lanman_passwd(smbpass
), pdb_get_nt_passwd(smbpass
));
1526 pdb_free_sam(smbpass
);
1528 return NT_STATUS_NOPROBLEMO
;
1531 /*************************************************************************
1533 *************************************************************************/
1535 static BOOL
get_user_info_21(SAM_USER_INFO_21
*id21
, uint32 user_rid
)
1537 SAM_ACCOUNT
*sampass
=NULL
;
1540 if (!pdb_rid_is_user(user_rid
)) {
1541 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid
));
1546 ret
= pdb_getsampwrid(sampass
, user_rid
);
1550 DEBUG(4,("User 0x%x not found\n", user_rid
));
1551 pdb_free_sam(sampass
);
1555 samr_clear_sam_passwd(sampass
);
1557 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
1559 init_sam_user_info21A(id21
, sampass
);
1561 pdb_free_sam(sampass
);
1566 /*******************************************************************
1567 _samr_query_userinfo
1568 ********************************************************************/
1570 uint32
_samr_query_userinfo(pipes_struct
*p
, SAMR_Q_QUERY_USERINFO
*q_u
, SAMR_R_QUERY_USERINFO
*r_u
)
1572 SAM_USERINFO_CTR
*ctr
;
1574 struct samr_info
*info
= NULL
;
1576 r_u
->status
=NT_STATUS_NO_PROBLEMO
;
1578 /* search for the handle */
1579 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1580 return NT_STATUS_INVALID_HANDLE
;
1582 /* find the user's rid */
1583 if ((rid
= get_lsa_policy_samr_rid(info
)) == 0xffffffff)
1584 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1586 DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid
));
1588 ctr
= (SAM_USERINFO_CTR
*)talloc(p
->mem_ctx
, sizeof(SAM_USERINFO_CTR
));
1590 return NT_STATUS_NO_MEMORY
;
1594 /* ok! user info levels (lots: see MSDEV help), off we go... */
1595 ctr
->switch_value
= q_u
->switch_value
;
1597 switch (q_u
->switch_value
) {
1599 ctr
->info
.id10
= (SAM_USER_INFO_10
*)talloc(p
->mem_ctx
, sizeof(SAM_USER_INFO_10
));
1600 if (ctr
->info
.id10
== NULL
)
1601 return NT_STATUS_NO_MEMORY
;
1603 if (!get_user_info_10(ctr
->info
.id10
, rid
))
1604 return NT_STATUS_NO_SUCH_USER
;
1608 /* whoops - got this wrong. i think. or don't understand what's happening. */
1612 info
= (void *)&id11
;
1614 expire
.low
= 0xffffffff;
1615 expire
.high
= 0x7fffffff;
1617 ctr
->info
.id
= (SAM_USER_INFO_11
*)talloc(p
->mem_ctx
,
1622 init_sam_user_info11(ctr
->info
.id11
, &expire
,
1623 "BROOKFIELDS$", /* name */
1624 0x03ef, /* user rid */
1625 0x201, /* group rid */
1626 0x0080); /* acb info */
1633 ctr
->info
.id12
= (SAM_USER_INFO_12
*)talloc(p
->mem_ctx
, sizeof(SAM_USER_INFO_12
));
1634 if (ctr
->info
.id12
== NULL
)
1635 return NT_STATUS_NO_MEMORY
;
1637 if ((r_u
->status
= get_user_info_12(p
, ctr
->info
.id12
, rid
)) != NT_STATUS_NOPROBLEMO
)
1642 ctr
->info
.id21
= (SAM_USER_INFO_21
*)talloc(p
->mem_ctx
,sizeof(SAM_USER_INFO_21
));
1643 if (ctr
->info
.id21
== NULL
)
1644 return NT_STATUS_NO_MEMORY
;
1645 if (!get_user_info_21(ctr
->info
.id21
, rid
))
1646 return NT_STATUS_NO_SUCH_USER
;
1650 return NT_STATUS_INVALID_INFO_CLASS
;
1653 init_samr_r_query_userinfo(r_u
, ctr
, r_u
->status
);
1655 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__
));
1660 /*******************************************************************
1661 samr_reply_query_usergroups
1662 ********************************************************************/
1664 uint32
_samr_query_usergroups(pipes_struct
*p
, SAMR_Q_QUERY_USERGROUPS
*q_u
, SAMR_R_QUERY_USERGROUPS
*r_u
)
1666 struct sam_passwd
*sam_pass
=NULL
;
1667 DOM_GID
*gids
= NULL
;
1671 struct samr_info
*info
= NULL
;
1674 r_u
->status
= NT_STATUS_NO_PROBLEMO
;
1676 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__
));
1678 /* find the policy handle. open a policy on it. */
1679 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1680 return NT_STATUS_INVALID_HANDLE
;
1682 /* find the user's rid */
1683 if ((rid
= get_lsa_policy_samr_rid(info
)) == 0xffffffff)
1684 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1686 pdb_init_sam(&sam_pass
);
1689 ret
= pdb_getsampwrid(sam_pass
, rid
);
1693 samr_clear_sam_passwd(sam_pass
);
1694 return NT_STATUS_NO_SUCH_USER
;
1697 get_domain_user_groups(groups
, pdb_get_username(sam_pass
));
1699 num_groups
= make_dom_gids(p
->mem_ctx
, groups
, &gids
);
1701 /* construct the response. lkclXXXX: gids are not copied! */
1702 init_samr_r_query_usergroups(r_u
, num_groups
, gids
, r_u
->status
);
1704 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__
));
1706 samr_clear_sam_passwd(sam_pass
);
1711 /*******************************************************************
1712 _samr_query_dom_info
1713 ********************************************************************/
1715 uint32
_samr_query_dom_info(pipes_struct
*p
, SAMR_Q_QUERY_DOMAIN_INFO
*q_u
, SAMR_R_QUERY_DOMAIN_INFO
*r_u
)
1719 if ((ctr
= (SAM_UNK_CTR
*)talloc(p
->mem_ctx
, sizeof(SAM_UNK_CTR
))) == NULL
)
1720 return NT_STATUS_NO_MEMORY
;
1724 r_u
->status
= NT_STATUS_NO_PROBLEMO
;
1726 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__
));
1728 /* find the policy handle. open a policy on it. */
1729 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, NULL
))
1730 return NT_STATUS_INVALID_HANDLE
;
1732 switch (q_u
->switch_value
) {
1734 init_unk_info1(&ctr
->info
.inf1
);
1737 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
1738 init_unk_info2(&ctr
->info
.inf2
, global_myworkgroup
, global_myname
, (uint32
) time(NULL
));
1741 init_unk_info3(&ctr
->info
.inf3
);
1744 init_unk_info6(&ctr
->info
.inf6
);
1747 init_unk_info7(&ctr
->info
.inf7
);
1750 init_unk_info12(&ctr
->info
.inf12
);
1753 return NT_STATUS_INVALID_INFO_CLASS
;
1756 init_samr_r_query_dom_info(r_u
, q_u
->switch_value
, ctr
, NT_STATUS_NOPROBLEMO
);
1758 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__
));
1763 /*******************************************************************
1764 _api_samr_create_user
1765 ********************************************************************/
1767 uint32
_api_samr_create_user(pipes_struct
*p
, SAMR_Q_CREATE_USER
*q_u
, SAMR_R_CREATE_USER
*r_u
)
1769 SAM_ACCOUNT
*sam_pass
=NULL
;
1776 POLICY_HND dom_pol
= q_u
->domain_pol
;
1777 UNISTR2 user_account
= q_u
->uni_name
;
1778 uint16 acb_info
= q_u
->acb_info
;
1779 POLICY_HND
*user_pol
= &r_u
->user_pol
;
1780 struct samr_info
*info
= NULL
;
1783 /* find the policy handle. open a policy on it. */
1784 if (!find_policy_by_hnd(p
, &dom_pol
, NULL
))
1785 return NT_STATUS_INVALID_HANDLE
;
1787 /* find the machine account: tell the caller if it exists.
1788 lkclXXXX i have *no* idea if this is a problem or not
1789 or even if you are supposed to construct a different
1790 reply if the account already exists...
1793 fstrcpy(mach_acct
, dos_unistrn2(user_account
.buffer
, user_account
.uni_str_len
));
1794 strlower(mach_acct
);
1796 pdb_init_sam(&sam_pass
);
1799 ret
= pdb_getsampwnam(sam_pass
, mach_acct
);
1802 /* machine account exists: say so */
1803 pdb_free_sam(sam_pass
);
1804 return NT_STATUS_USER_EXISTS
;
1807 local_flags
=LOCAL_ADD_USER
|LOCAL_DISABLE_USER
|LOCAL_SET_NO_PASSWORD
;
1808 local_flags
|= (acb_info
& ACB_WSTRUST
) ? LOCAL_TRUST_ACCOUNT
:0;
1811 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1812 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1813 * that only people with write access to the smbpasswd file will be able
1814 * to create a user. JRA.
1818 * add the user in the /etc/passwd file or the unix authority system.
1819 * We don't check if the smb_create_user() function succed or not for 2 reasons:
1820 * a) local_password_change() checks for us if the /etc/passwd account really exists
1821 * b) smb_create_user() would return an error if the account already exists
1822 * and as it could return an error also if it can't create the account, it would be tricky.
1824 * So we go the easy way, only check after if the account exists.
1825 * JFM (2/3/2001), to clear any possible bad understanding (-:
1828 pstrcpy(add_script
, lp_adduser_script());
1831 smb_create_user(mach_acct
, NULL
);
1833 /* add the user in the smbpasswd file or the Samba authority database */
1834 if (!local_password_change(mach_acct
, local_flags
, NULL
, err_str
,
1835 sizeof(err_str
), msg_str
, sizeof(msg_str
))) {
1836 DEBUG(0, ("%s\n", err_str
));
1837 close_policy_hnd(p
, user_pol
);
1838 pdb_free_sam(sam_pass
);
1839 return NT_STATUS_ACCESS_DENIED
;
1843 ret
= pdb_getsampwnam(sam_pass
, mach_acct
);
1846 /* account doesn't exist: say so */
1847 close_policy_hnd(p
, user_pol
);
1848 pdb_free_sam(sam_pass
);
1849 return NT_STATUS_ACCESS_DENIED
;
1852 /* Get the domain SID stored in the domain policy */
1853 if(!get_lsa_policy_samr_sid(p
, &dom_pol
, &sid
)) {
1854 close_policy_hnd(p
, user_pol
);
1855 pdb_free_sam(sam_pass
);
1856 return NT_STATUS_INVALID_HANDLE
;
1859 /* append the user's RID to it */
1860 if(!sid_append_rid(&sid
, pdb_get_user_rid(sam_pass
) )) {
1861 close_policy_hnd(p
, user_pol
);
1862 pdb_free_sam(sam_pass
);
1863 return NT_STATUS_NO_SUCH_USER
;
1866 /* associate the user's SID with the new handle. */
1867 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
) {
1868 pdb_free_sam(sam_pass
);
1869 return NT_STATUS_NO_MEMORY
;
1875 /* get a (unique) handle. open a policy on it. */
1876 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
)) {
1877 pdb_free_sam(sam_pass
);
1878 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1881 r_u
->user_rid
=sam_pass
->user_rid
;
1882 r_u
->unknown_0
= 0x000703ff;
1884 pdb_free_sam(sam_pass
);
1886 return NT_STATUS_NO_PROBLEMO
;
1889 /*******************************************************************
1890 samr_reply_connect_anon
1891 ********************************************************************/
1893 uint32
_samr_connect_anon(pipes_struct
*p
, SAMR_Q_CONNECT_ANON
*q_u
, SAMR_R_CONNECT_ANON
*r_u
)
1895 struct samr_info
*info
= NULL
;
1897 /* set up the SAMR connect_anon response */
1899 r_u
->status
= NT_STATUS_NO_PROBLEMO
;
1901 /* associate the user's SID with the new handle. */
1902 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
1903 return NT_STATUS_NO_MEMORY
;
1906 info
->status
= q_u
->unknown_0
;
1908 /* get a (unique) handle. open a policy on it. */
1909 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
1910 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1915 /*******************************************************************
1917 ********************************************************************/
1919 uint32
_samr_connect(pipes_struct
*p
, SAMR_Q_CONNECT
*q_u
, SAMR_R_CONNECT
*r_u
)
1921 struct samr_info
*info
= NULL
;
1923 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
1925 r_u
->status
= NT_STATUS_NO_PROBLEMO
;
1927 /* associate the user's SID with the new handle. */
1928 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
1929 return NT_STATUS_NO_MEMORY
;
1932 info
->status
= q_u
->access_mask
;
1934 /* get a (unique) handle. open a policy on it. */
1935 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
1936 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1938 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
1943 /**********************************************************************
1944 api_samr_lookup_domain
1945 **********************************************************************/
1947 uint32
_samr_lookup_domain(pipes_struct
*p
, SAMR_Q_LOOKUP_DOMAIN
*q_u
, SAMR_R_LOOKUP_DOMAIN
*r_u
)
1949 r_u
->status
= NT_STATUS_NO_PROBLEMO
;
1951 if (!find_policy_by_hnd(p
, &q_u
->connect_pol
, NULL
))
1952 return NT_STATUS_INVALID_HANDLE
;
1954 /* assume the domain name sent is our global_myname and
1955 send global_sam_sid */
1956 init_samr_r_lookup_domain(r_u
, &global_sam_sid
, r_u
->status
);
1961 /******************************************************************
1962 makes a SAMR_R_ENUM_DOMAINS structure.
1963 ********************************************************************/
1965 static BOOL
make_enum_domains(TALLOC_CTX
*ctx
, SAM_ENTRY
**pp_sam
,
1966 UNISTR2
**pp_uni_name
, uint32 num_sam_entries
, fstring doms
[])
1972 DEBUG(5, ("make_enum_domains\n"));
1975 *pp_uni_name
= NULL
;
1977 if (num_sam_entries
== 0)
1980 sam
= (SAM_ENTRY
*)talloc(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
1981 uni_name
= (UNISTR2
*)talloc(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
1983 if (sam
== NULL
|| uni_name
== NULL
)
1986 for (i
= 0; i
< num_sam_entries
; i
++) {
1987 int len
= doms
[i
] != NULL
? strlen(doms
[i
]) : 0;
1989 init_sam_entry(&sam
[i
], len
, 0);
1990 init_unistr2(&uni_name
[i
], doms
[i
], len
);
1994 *pp_uni_name
= uni_name
;
1999 /**********************************************************************
2000 api_samr_enum_domains
2001 **********************************************************************/
2003 uint32
_samr_enum_domains(pipes_struct
*p
, SAMR_Q_ENUM_DOMAINS
*q_u
, SAMR_R_ENUM_DOMAINS
*r_u
)
2005 uint32 num_entries
= 2;
2008 r_u
->status
= NT_STATUS_NO_PROBLEMO
;
2010 fstrcpy(dom
[0],global_myworkgroup
);
2011 fstrcpy(dom
[1],"Builtin");
2013 if (!make_enum_domains(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_dom_name
, num_entries
, dom
))
2014 return NT_STATUS_NO_MEMORY
;
2016 init_samr_r_enum_domains(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
2021 /*******************************************************************
2023 ********************************************************************/
2025 uint32
_api_samr_open_alias(pipes_struct
*p
, SAMR_Q_OPEN_ALIAS
*q_u
, SAMR_R_OPEN_ALIAS
*r_u
)
2028 POLICY_HND domain_pol
= q_u
->dom_pol
;
2029 uint32 alias_rid
= q_u
->rid_alias
;
2030 POLICY_HND
*alias_pol
= &r_u
->pol
;
2031 struct samr_info
*info
= NULL
;
2033 r_u
->status
= NT_STATUS_NO_PROBLEMO
;
2035 /* get the domain policy. */
2036 if (!find_policy_by_hnd(p
, &domain_pol
, NULL
))
2037 return NT_STATUS_INVALID_HANDLE
;
2039 /* Get the domain SID stored in the domain policy */
2040 if(!get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
))
2041 return NT_STATUS_INVALID_HANDLE
;
2043 /* append the alias' RID to it */
2044 if(!sid_append_rid(&sid
, alias_rid
))
2045 return NT_STATUS_NO_SUCH_USER
;
2048 * we should check if the rid really exist !!!
2052 /* associate the user's SID with the new handle. */
2053 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
2054 return NT_STATUS_NO_MEMORY
;
2059 /* get a (unique) handle. open a policy on it. */
2060 if (!create_policy_hnd(p
, alias_pol
, free_samr_info
, (void *)info
))
2061 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2066 /*******************************************************************
2068 ********************************************************************/
2070 static BOOL
set_user_info_10(const SAM_USER_INFO_10
*id10
, uint32 rid
)
2072 SAM_ACCOUNT
*pwd
=NULL
;
2077 ret
= pdb_getsampwrid(pwd
, rid
);
2085 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2090 pdb_set_acct_ctrl(pwd
, id10
->acb_info
);
2092 if(!pdb_update_sam_account(pwd
, True
)) {
2102 /*******************************************************************
2104 ********************************************************************/
2106 static BOOL
set_user_info_12(SAM_USER_INFO_12
*id12
, uint32 rid
)
2108 SAM_ACCOUNT
*pwd
= NULL
;
2113 if(!pdb_getsampwrid(pwd
, rid
)) {
2119 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2124 pdb_set_lanman_passwd (pwd
, id12
->lm_pwd
);
2125 pdb_set_nt_passwd (pwd
, id12
->nt_pwd
);
2127 if(!pdb_update_sam_account(pwd
, True
)) {
2136 /*******************************************************************
2138 ********************************************************************/
2140 static BOOL
set_user_info_21(SAM_USER_INFO_21
*id21
, uint32 rid
)
2142 SAM_ACCOUNT
*pwd
= NULL
;
2143 SAM_ACCOUNT
*new_pwd
= NULL
;
2146 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2151 pdb_init_sam(&new_pwd
);
2153 if (!pdb_getsampwrid(pwd
, rid
)) {
2155 pdb_free_sam(new_pwd
);
2159 /* we make a copy so that we can modify stuff */
2160 copy_sam_passwd(new_pwd
, pwd
);
2161 copy_id21_to_sam_passwd(new_pwd
, id21
);
2164 * The funny part about the previous two calls is
2165 * that pwd still has the password hashes from the
2166 * passdb entry. These have not been updated from
2167 * id21. I don't know if they need to be set. --jerry
2170 /* write the change out */
2171 if(!pdb_update_sam_account(new_pwd
, True
)) {
2173 pdb_free_sam(new_pwd
);
2178 pdb_free_sam(new_pwd
);
2183 /*******************************************************************
2185 ********************************************************************/
2187 static BOOL
set_user_info_23(SAM_USER_INFO_23
*id23
, uint32 rid
)
2189 SAM_ACCOUNT
*pwd
= NULL
;
2190 SAM_ACCOUNT
*new_pwd
= NULL
;
2198 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2203 pdb_init_sam(&new_pwd
);
2205 if (pdb_getsampwrid(pwd
, rid
)) {
2207 pdb_free_sam(new_pwd
);
2211 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
2213 copy_sam_passwd(new_pwd
, pwd
);
2216 copy_id23_to_sam_passwd(new_pwd
, id23
);
2218 if (!decode_pw_buffer((char*)id23
->pass
, buf
, 256, &len
, nt_hash
, lm_hash
)) {
2219 pdb_free_sam(new_pwd
);
2223 pdb_set_lanman_passwd (new_pwd
, lm_hash
);
2224 pdb_set_nt_passwd (new_pwd
, nt_hash
);
2226 /* if it's a trust account, don't update /etc/passwd */
2227 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
2228 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
2229 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
2230 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2232 /* update the UNIX password */
2233 if (lp_unix_password_sync() )
2234 if(!chgpasswd(pdb_get_username(new_pwd
), "", buf
, True
)) {
2235 pdb_free_sam(new_pwd
);
2240 memset(buf
, 0, sizeof(buf
));
2242 if(!pdb_update_sam_account(new_pwd
, True
)) {
2243 pdb_free_sam(new_pwd
);
2247 pdb_free_sam(new_pwd
);
2252 /*******************************************************************
2254 ********************************************************************/
2256 static BOOL
set_user_info_24(SAM_USER_INFO_24
*id24
, uint32 rid
)
2258 SAM_ACCOUNT
*pwd
= NULL
;
2267 if (!pdb_getsampwrid(pwd
, rid
)) {
2272 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
2274 memset(buf
, 0, sizeof(buf
));
2276 if (!decode_pw_buffer((char*)id24
->pass
, buf
, 256, &len
, nt_hash
, lm_hash
)) {
2281 pdb_set_lanman_passwd (pwd
, lm_hash
);
2282 pdb_set_nt_passwd (pwd
, nt_hash
);
2284 /* if it's a trust account, don't update /etc/passwd */
2285 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
2286 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
2287 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
2288 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2290 /* update the UNIX password */
2291 if (lp_unix_password_sync())
2292 if(!chgpasswd(pdb_get_username(pwd
), "", buf
, True
)) {
2298 memset(buf
, 0, sizeof(buf
));
2300 DEBUG(0,("set_user_info_24: pdb_update_sam_account()\n"));
2302 /* update the SAMBA password */
2303 if(!pdb_update_sam_account(pwd
, True
)) {
2313 /*******************************************************************
2314 samr_reply_set_userinfo
2315 ********************************************************************/
2317 uint32
_samr_set_userinfo(pipes_struct
*p
, SAMR_Q_SET_USERINFO
*q_u
, SAMR_R_SET_USERINFO
*r_u
)
2321 struct current_user user
;
2322 SAM_ACCOUNT
*sam_pass
=NULL
;
2323 unsigned char sess_key
[16];
2324 POLICY_HND
*pol
= &q_u
->pol
;
2325 uint16 switch_value
= q_u
->switch_value
;
2326 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
2329 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__
));
2331 r_u
->status
= NT_STATUS_NOPROBLEMO
;
2333 if (p
->ntlmssp_auth_validated
) {
2334 memcpy(&user
, &p
->pipe_user
, sizeof(user
));
2336 extern struct current_user current_user
;
2337 memcpy(&user
, ¤t_user
, sizeof(user
));
2340 /* find the policy handle. open a policy on it. */
2341 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
))
2342 return NT_STATUS_INVALID_HANDLE
;
2344 sid_split_rid(&sid
, &rid
);
2346 DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid
, switch_value
));
2349 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2350 return NT_STATUS_INVALID_INFO_CLASS
;
2354 pdb_init_sam(&sam_pass
);
2357 * We need the NT hash of the user who is changing the user's password.
2358 * This NT hash is used to generate a "user session key"
2359 * This "user session key" is in turn used to encrypt/decrypt the user's password.
2363 ret
= pdb_getsampwuid(sam_pass
, user
.uid
);
2366 DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd entry for uid %u\n", (unsigned int)user
.uid
));
2367 pdb_free_sam(sam_pass
);
2368 return NT_STATUS_ACCESS_DENIED
;
2371 memset(sess_key
, '\0', 16);
2372 mdfour(sess_key
, pdb_get_nt_passwd(sam_pass
), 16);
2374 pdb_free_sam(sam_pass
);
2376 /* ok! user info levels (lots: see MSDEV help), off we go... */
2377 switch (switch_value
) {
2379 if (!set_user_info_12(ctr
->info
.id12
, rid
))
2380 return NT_STATUS_ACCESS_DENIED
;
2384 SamOEMhash(ctr
->info
.id24
->pass
, sess_key
, 1);
2385 if (!set_user_info_24(ctr
->info
.id24
, rid
))
2386 return NT_STATUS_ACCESS_DENIED
;
2390 SamOEMhash(ctr
->info
.id23
->pass
, sess_key
, 1);
2391 if (!set_user_info_23(ctr
->info
.id23
, rid
))
2392 return NT_STATUS_ACCESS_DENIED
;
2396 return NT_STATUS_INVALID_INFO_CLASS
;
2402 /*******************************************************************
2403 samr_reply_set_userinfo2
2404 ********************************************************************/
2406 uint32
_samr_set_userinfo2(pipes_struct
*p
, SAMR_Q_SET_USERINFO2
*q_u
, SAMR_R_SET_USERINFO2
*r_u
)
2410 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
2411 POLICY_HND
*pol
= &q_u
->pol
;
2412 uint16 switch_value
= q_u
->switch_value
;
2414 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__
));
2416 r_u
->status
= NT_STATUS_NOPROBLEMO
;
2418 /* find the policy handle. open a policy on it. */
2419 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
))
2420 return NT_STATUS_INVALID_HANDLE
;
2422 sid_split_rid(&sid
, &rid
);
2424 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid
));
2427 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2428 return NT_STATUS_INVALID_INFO_CLASS
;
2431 switch_value
=ctr
->switch_value
;
2433 /* ok! user info levels (lots: see MSDEV help), off we go... */
2434 switch (switch_value
) {
2436 if (!set_user_info_21(ctr
->info
.id21
, rid
))
2437 return NT_STATUS_ACCESS_DENIED
;
2440 if (!set_user_info_10(ctr
->info
.id10
, rid
))
2441 return NT_STATUS_ACCESS_DENIED
;
2444 /* Used by AS/U JRA. */
2445 if (!set_user_info_12(ctr
->info
.id12
, rid
))
2446 return NT_STATUS_ACCESS_DENIED
;
2449 return NT_STATUS_INVALID_INFO_CLASS
;
2455 /*********************************************************************
2456 _samr_query_aliasmem
2457 *********************************************************************/
2459 uint32
_samr_query_useraliases(pipes_struct
*p
, SAMR_Q_QUERY_USERALIASES
*q_u
, SAMR_R_QUERY_USERALIASES
*r_u
)
2465 rid
=(uint32
*)talloc(p
->mem_ctx
, num_rids
*sizeof(uint32
));
2467 return NT_STATUS_NO_MEMORY
;
2469 /* until i see a real useraliases query, we fack one up */
2471 rid
[0] = BUILTIN_ALIAS_RID_USERS
;
2473 init_samr_r_query_useraliases(r_u
, num_rids
, rid
, NT_STATUS_NO_PROBLEMO
);
2475 return NT_STATUS_NO_PROBLEMO
;
2479 /*********************************************************************
2480 _samr_query_aliasmem
2481 *********************************************************************/
2483 uint32
_samr_query_aliasmem(pipes_struct
*p
, SAMR_Q_QUERY_ALIASMEM
*q_u
, SAMR_R_QUERY_ALIASMEM
*r_u
)
2495 fstring alias_sid_str
;
2499 /* find the policy handle. open a policy on it. */
2500 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
))
2501 return NT_STATUS_INVALID_HANDLE
;
2503 sid_copy(&als_sid
, &alias_sid
);
2504 sid_to_string(alias_sid_str
, &alias_sid
);
2505 sid_split_rid(&alias_sid
, &alias_rid
);
2507 DEBUG(10, ("sid is %s\n", alias_sid_str
));
2509 if (sid_equal(&alias_sid
, &global_sid_Builtin
)) {
2510 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
2511 if(!get_builtin_group_from_sid(als_sid
, &map
))
2512 return NT_STATUS_NO_SUCH_ALIAS
;
2514 if (sid_equal(&alias_sid
, &global_sam_sid
)) {
2515 DEBUG(10, ("lookup on Server SID\n"));
2516 if(!get_local_group_from_sid(als_sid
, &map
))
2517 return NT_STATUS_NO_SUCH_ALIAS
;
2521 if(!get_uid_list_of_group(map
.gid
, &uid
, &num_uids
))
2522 return NT_STATUS_NO_SUCH_ALIAS
;
2524 DEBUG(10, ("sid is %s\n", alias_sid_str
));
2525 sid
= (DOM_SID2
*)talloc(p
->mem_ctx
, sizeof(DOM_SID2
) * num_uids
);
2527 return NT_STATUS_NO_SUCH_ALIAS
;
2529 for (i
= 0; i
< num_uids
; i
++) {
2530 sid_copy(&temp_sid
, &global_sam_sid
);
2531 sid_append_rid(&temp_sid
, pdb_uid_to_user_rid(uid
[i
]));
2533 init_dom_sid2(&sid
[i
], &temp_sid
);
2536 DEBUG(10, ("sid is %s\n", alias_sid_str
));
2537 init_samr_r_query_aliasmem(r_u
, num_uids
, sid
, NT_STATUS_NO_PROBLEMO
);
2539 return NT_STATUS_NOPROBLEMO
;
2542 /*********************************************************************
2543 _samr_query_groupmem
2544 *********************************************************************/
2546 uint32
_samr_query_groupmem(pipes_struct
*p
, SAMR_Q_QUERY_GROUPMEM
*q_u
, SAMR_R_QUERY_GROUPMEM
*r_u
)
2552 fstring group_sid_str
;
2561 /* find the policy handle. open a policy on it. */
2562 if (!get_lsa_policy_samr_sid(p
, &q_u
->group_pol
, &group_sid
))
2563 return NT_STATUS_INVALID_HANDLE
;
2565 /* todo: change to use sid_compare_front */
2567 sid_split_rid(&group_sid
, &group_rid
);
2568 sid_to_string(group_sid_str
, &group_sid
);
2569 DEBUG(10, ("sid is %s\n", group_sid_str
));
2571 /* can we get a query for an SID outside our domain ? */
2572 if (!sid_equal(&group_sid
, &global_sam_sid
))
2573 return NT_STATUS_NO_SUCH_GROUP
;
2575 sid_append_rid(&group_sid
, group_rid
);
2576 DEBUG(10, ("lookup on Domain SID\n"));
2578 if(!get_domain_group_from_sid(group_sid
, &map
))
2579 return NT_STATUS_NO_SUCH_GROUP
;
2581 if(!get_uid_list_of_group(map
.gid
, &uid
, &num_uids
))
2582 return NT_STATUS_NO_SUCH_GROUP
;
2584 rid
=talloc(p
->mem_ctx
, sizeof(uint32
)*num_uids
);
2585 attr
=talloc(p
->mem_ctx
, sizeof(uint32
)*num_uids
);
2587 if (rid
==NULL
|| attr
==NULL
)
2588 return NT_STATUS_NO_MEMORY
;
2590 for (i
=0; i
<num_uids
; i
++) {
2591 rid
[i
]=pdb_uid_to_user_rid(uid
[i
]);
2592 attr
[i
] = SID_NAME_USER
;
2595 init_samr_r_query_groupmem(r_u
, num_uids
, rid
, attr
, NT_STATUS_NOPROBLEMO
);
2597 return NT_STATUS_NOPROBLEMO
;
2600 /*********************************************************************
2602 *********************************************************************/
2604 uint32
_samr_add_aliasmem(pipes_struct
*p
, SAMR_Q_ADD_ALIASMEM
*q_u
, SAMR_R_ADD_ALIASMEM
*r_u
)
2607 fstring alias_sid_str
;
2615 /* Find the policy handle. Open a policy on it. */
2616 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
))
2617 return NT_STATUS_INVALID_HANDLE
;
2619 sid_to_string(alias_sid_str
, &alias_sid
);
2620 DEBUG(10, ("sid is %s\n", alias_sid_str
));
2622 if (sid_compare(&alias_sid
, &global_sam_sid
)>0) {
2623 DEBUG(10, ("adding member on Server SID\n"));
2624 if(!get_local_group_from_sid(alias_sid
, &map
))
2625 return NT_STATUS_NO_SUCH_ALIAS
;
2628 if (sid_compare(&alias_sid
, &global_sid_Builtin
)>0) {
2629 DEBUG(10, ("adding member on BUILTIN SID\n"));
2630 if( !get_builtin_group_from_sid(alias_sid
, &map
))
2631 return NT_STATUS_NO_SUCH_ALIAS
;
2634 return NT_STATUS_NO_SUCH_ALIAS
;
2637 sid_split_rid(&q_u
->sid
.sid
, &rid
);
2638 uid
=pdb_user_rid_to_uid(rid
);
2640 if ((pwd
=getpwuid(uid
)) == NULL
)
2641 return NT_STATUS_NO_SUCH_USER
;
2643 if ((grp
=getgrgid(map
.gid
)) == NULL
)
2644 return NT_STATUS_NO_SUCH_ALIAS
;
2646 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2647 fstrcpy(grp_name
, grp
->gr_name
);
2649 /* if the user is already in the group */
2650 if(user_in_group_list(pwd
->pw_name
, grp_name
))
2651 return NT_STATUS_MEMBER_IN_ALIAS
;
2654 * ok, the group exist, the user exist, the user is not in the group,
2655 * we can (finally) add it to the group !
2657 smb_add_user_group(grp_name
, pwd
->pw_name
);
2659 /* check if the user has been added then ... */
2660 if(!user_in_group_list(pwd
->pw_name
, grp_name
))
2661 return NT_STATUS_MEMBER_NOT_IN_ALIAS
; /* don't know what to reply else */
2663 return NT_STATUS_NOPROBLEMO
;
2666 /*********************************************************************
2668 *********************************************************************/
2670 uint32
_samr_del_aliasmem(pipes_struct
*p
, SAMR_Q_DEL_ALIASMEM
*q_u
, SAMR_R_DEL_ALIASMEM
*r_u
)
2672 DEBUG(0,("_samr_del_aliasmem: Not yet implemented.\n"));
2676 /*********************************************************************
2678 *********************************************************************/
2680 uint32
_samr_add_groupmem(pipes_struct
*p
, SAMR_Q_ADD_GROUPMEM
*q_u
, SAMR_R_ADD_GROUPMEM
*r_u
)
2683 fstring group_sid_str
;
2689 /* Find the policy handle. Open a policy on it. */
2690 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
))
2691 return NT_STATUS_INVALID_HANDLE
;
2693 sid_to_string(group_sid_str
, &group_sid
);
2694 DEBUG(10, ("sid is %s\n", group_sid_str
));
2696 if (sid_compare(&group_sid
, &global_sam_sid
)<=0)
2697 return NT_STATUS_NO_SUCH_GROUP
;
2699 DEBUG(10, ("lookup on Domain SID\n"));
2701 if(!get_domain_group_from_sid(group_sid
, &map
))
2702 return NT_STATUS_NO_SUCH_GROUP
;
2704 if ((pwd
=getpwuid(pdb_user_rid_to_uid(q_u
->rid
))) ==NULL
)
2705 return NT_STATUS_NO_SUCH_USER
;
2707 if ((grp
=getgrgid(map
.gid
)) == NULL
)
2708 return NT_STATUS_NO_SUCH_GROUP
;
2710 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2711 fstrcpy(grp_name
, grp
->gr_name
);
2713 /* if the user is already in the group */
2714 if(user_in_group_list(pwd
->pw_name
, grp_name
))
2715 return NT_STATUS_MEMBER_IN_GROUP
;
2718 * ok, the group exist, the user exist, the user is not in the group,
2720 * we can (finally) add it to the group !
2723 smb_add_user_group(grp_name
, pwd
->pw_name
);
2725 /* check if the user has been added then ... */
2726 if(!user_in_group_list(pwd
->pw_name
, grp_name
))
2727 return NT_STATUS_MEMBER_NOT_IN_GROUP
; /* don't know what to reply else */
2729 return NT_STATUS_NOPROBLEMO
;
2732 /*********************************************************************
2734 *********************************************************************/
2736 uint32
_samr_del_groupmem(pipes_struct
*p
, SAMR_Q_DEL_GROUPMEM
*q_u
, SAMR_R_DEL_GROUPMEM
*r_u
)
2738 DEBUG(0,("_samr_del_groupmem: Not yet implemented.\n"));
2742 /*********************************************************************
2743 _samr_delete_dom_user
2744 *********************************************************************/
2746 uint32
_samr_delete_dom_user(pipes_struct
*p
, SAMR_Q_DELETE_DOM_USER
*q_u
, SAMR_R_DELETE_DOM_USER
*r_u
)
2748 DEBUG(0,("_samr_delete_dom_user: Not yet implemented.\n"));
2752 /*********************************************************************
2753 _samr_delete_dom_group
2754 *********************************************************************/
2756 uint32
_samr_delete_dom_group(pipes_struct
*p
, SAMR_Q_DELETE_DOM_GROUP
*q_u
, SAMR_R_DELETE_DOM_GROUP
*r_u
)
2758 DEBUG(0,("_samr_delete_dom_group: Not yet implemented.\n"));
2762 /*********************************************************************
2763 _samr_delete_dom_alias
2764 *********************************************************************/
2766 uint32
_samr_delete_dom_alias(pipes_struct
*p
, SAMR_Q_DELETE_DOM_ALIAS
*q_u
, SAMR_R_DELETE_DOM_ALIAS
*r_u
)
2768 DEBUG(0,("_samr_delete_dom_alias: Not yet implemented.\n"));
2772 /*********************************************************************
2773 _samr_create_dom_group
2774 *********************************************************************/
2776 uint32
_samr_create_dom_group(pipes_struct
*p
, SAMR_Q_CREATE_DOM_GROUP
*q_u
, SAMR_R_CREATE_DOM_GROUP
*r_u
)
2783 struct samr_info
*info
;
2785 /* Find the policy handle. Open a policy on it. */
2786 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &dom_sid
))
2787 return NT_STATUS_INVALID_HANDLE
;
2789 if (!sid_equal(&dom_sid
, &global_sam_sid
))
2790 return NT_STATUS_ACCESS_DENIED
;
2792 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
2794 unistr2_to_ascii(name
, &q_u
->uni_acct_desc
, sizeof(name
)-1);
2796 /* check if group already exist */
2797 if ((grp
=getgrnam(name
)) != NULL
)
2798 return NT_STATUS_GROUP_EXISTS
;
2800 /* we can create the UNIX group */
2801 smb_create_group(name
);
2803 /* check if the group has been successfully created */
2804 if ((grp
=getgrnam(name
)) == NULL
)
2805 return NT_STATUS_ACCESS_DENIED
;
2807 r_u
->rid
=pdb_gid_to_group_rid(grp
->gr_gid
);
2809 /* add the group to the mapping table */
2810 if(!add_initial_entry(grp
->gr_gid
, sid_string
, SID_NAME_DOM_GRP
, name
, NULL
, SE_PRIV_NONE
))
2811 return NT_STATUS_ACCESS_DENIED
;
2813 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
2814 return NT_STATUS_NO_MEMORY
;
2818 sid_copy(&info_sid
, &global_sam_sid
);
2819 sid_append_rid(&info
->sid
, r_u
->rid
);
2820 sid_to_string(sid_string
, &info
->sid
);
2822 /* get a (unique) handle. open a policy on it. */
2823 if (!create_policy_hnd(p
, &r_u
->pol
, free_samr_info
, (void *)info
))
2824 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2826 return NT_STATUS_NOPROBLEMO
;
2829 /*********************************************************************
2830 _samr_create_dom_alias
2831 *********************************************************************/
2833 uint32
_samr_create_dom_alias(pipes_struct
*p
, SAMR_Q_CREATE_DOM_ALIAS
*q_u
, SAMR_R_CREATE_DOM_ALIAS
*r_u
)
2839 struct samr_info
*info
;
2841 /* Find the policy handle. Open a policy on it. */
2842 if (!get_lsa_policy_samr_sid(p
, &q_u
->dom_pol
, &dom_sid
))
2843 return NT_STATUS_INVALID_HANDLE
;
2845 if (!sid_equal(&dom_sid
, &global_sam_sid
))
2846 return NT_STATUS_ACCESS_DENIED
;
2848 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
2850 unistr2_to_ascii(name
, &q_u
->uni_acct_desc
, sizeof(name
)-1);
2852 /* check if group already exists */
2853 if ( (grp
=getgrnam(name
)) != NULL
)
2854 return NT_STATUS_GROUP_EXISTS
;
2856 /* we can create the UNIX group */
2857 smb_create_group(name
);
2859 /* check if the group has been successfully created */
2860 if ((grp
=getgrnam(name
)) == NULL
)
2861 return NT_STATUS_ACCESS_DENIED
;
2863 r_u
->rid
=pdb_gid_to_group_rid(grp
->gr_gid
);
2865 /* add the group to the mapping table */
2866 if(!add_initial_entry(grp
->gr_gid
, sid_string
, SID_NAME_ALIAS
, NULL
, NULL
, SE_PRIV_NONE
))
2867 return NT_STATUS_ACCESS_DENIED
;
2869 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
2870 return NT_STATUS_NO_MEMORY
;
2874 sid_copy(&info
->sid
, &global_sam_sid
);
2875 sid_append_rid(&info
->sid
, r_u
->rid
);
2876 sid_to_string(sid_string
, &info
->sid
);
2878 /* get a (unique) handle. open a policy on it. */
2879 if (!create_policy_hnd(p
, &r_u
->alias_pol
, free_samr_info
, (void *)info
))
2880 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2882 return NT_STATUS_NOPROBLEMO
;
2885 /*********************************************************************
2886 _samr_query_groupinfo
2888 sends the name/comment pair of a domain group
2889 level 1 send also the number of users of that group
2890 *********************************************************************/
2892 uint32
_samr_query_groupinfo(pipes_struct
*p
, SAMR_Q_QUERY_GROUPINFO
*q_u
, SAMR_R_QUERY_GROUPINFO
*r_u
)
2898 GROUP_INFO_CTR
*ctr
;
2900 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
))
2901 return NT_STATUS_INVALID_HANDLE
;
2903 if (!get_domain_group_from_sid(group_sid
, &map
))
2904 return NT_STATUS_INVALID_HANDLE
;
2906 ctr
=(GROUP_INFO_CTR
*)talloc(p
->mem_ctx
, sizeof(GROUP_INFO_CTR
));
2908 return NT_STATUS_NO_MEMORY
;
2910 switch (q_u
->switch_level
) {
2912 ctr
->switch_value1
= 1;
2913 if(!get_uid_list_of_group(map
.gid
, &uid
, &num_uids
))
2914 return NT_STATUS_NO_SUCH_GROUP
;
2915 init_samr_group_info1(&ctr
->group
.info1
, map
.nt_name
, map
.comment
, num_uids
);
2919 ctr
->switch_value1
= 4;
2920 init_samr_group_info4(&ctr
->group
.info4
, map
.comment
);
2923 return NT_STATUS_INVALID_INFO_CLASS
;
2926 init_samr_r_query_groupinfo(r_u
, ctr
, NT_STATUS_NO_PROBLEMO
);
2928 return NT_STATUS_NO_PROBLEMO
;
2931 /*********************************************************************
2934 update a domain group's comment.
2935 *********************************************************************/
2937 uint32
_samr_set_groupinfo(pipes_struct
*p
, SAMR_Q_SET_GROUPINFO
*q_u
, SAMR_R_SET_GROUPINFO
*r_u
)
2941 GROUP_INFO_CTR
*ctr
;
2943 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
))
2944 return NT_STATUS_INVALID_HANDLE
;
2946 if (!get_domain_group_from_sid(group_sid
, &map
))
2947 return NT_STATUS_NO_SUCH_GROUP
;
2951 switch (ctr
->switch_value1
) {
2953 unistr2_to_ascii(map
.comment
, &(ctr
->group
.info1
.uni_acct_desc
), sizeof(map
.comment
)-1);
2956 unistr2_to_ascii(map
.comment
, &(ctr
->group
.info4
.uni_acct_desc
), sizeof(map
.comment
)-1);
2959 return NT_STATUS_INVALID_INFO_CLASS
;
2962 if(!add_mapping_entry(&map
, TDB_REPLACE
))
2963 return NT_STATUS_NO_SUCH_GROUP
;
2965 return NT_STATUS_NO_PROBLEMO
;
2968 /*********************************************************************
2969 _samr_get_dom_pwinfo
2970 *********************************************************************/
2972 uint32
_samr_get_dom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_DOM_PWINFO
*q_u
, SAMR_R_GET_DOM_PWINFO
*r_u
)
2974 /* Actually, returning zeros here works quite well :-). */
2975 return NT_STATUS_NOPROBLEMO
;
2978 /*********************************************************************
2980 *********************************************************************/
2982 uint32
_samr_open_group(pipes_struct
*p
, SAMR_Q_OPEN_GROUP
*q_u
, SAMR_R_OPEN_GROUP
*r_u
)
2986 struct samr_info
*info
;
2989 if (!get_lsa_policy_samr_sid(p
, &q_u
->domain_pol
, &sid
))
2990 return NT_STATUS_INVALID_HANDLE
;
2992 /* this should not be hard-coded like this */
2993 if (!sid_equal(&sid
, &global_sam_sid
))
2994 return NT_STATUS_ACCESS_DENIED
;
2996 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
2997 return NT_STATUS_NO_MEMORY
;
3001 sid_copy(&info
->sid
, &global_sam_sid
);
3002 sid_append_rid(&info
->sid
, q_u
->rid_group
);
3003 sid_to_string(sid_string
, &info
->sid
);
3005 DEBUG(10, ("Opening SID: %s\n", sid_string
));
3007 /* check if that group really exists */
3008 if (!get_domain_group_from_sid(info
->sid
, &map
))
3009 return NT_STATUS_NO_SUCH_USER
;
3011 /* get a (unique) handle. open a policy on it. */
3012 if (!create_policy_hnd(p
, &r_u
->pol
, free_samr_info
, (void *)info
))
3013 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3015 return NT_STATUS_NO_PROBLEMO
;
3018 /*********************************************************************
3020 *********************************************************************/
3022 uint32
_samr_unknown_2d(pipes_struct
*p
, SAMR_Q_UNKNOWN_2D
*q_u
, SAMR_R_UNKNOWN_2D
*r_u
)
3024 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));