2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Jeremy Allison 2001,
8 * Copyright (C) Rafal Szczesniak 2002,
9 * Copyright (C) Jim McDonough 2002.
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.
26 /* This is the implementation of the lsa server code. */
31 #define DBGC_CLASS DBGC_RPC_SRV
40 struct generic_mapping lsa_generic_mapping
= {
47 /*******************************************************************
48 Function to free the per handle data.
49 ********************************************************************/
51 static void free_lsa_info(void *ptr
)
53 struct lsa_info
*lsa
= (struct lsa_info
*)ptr
;
58 /***************************************************************************
60 ***************************************************************************/
62 static void init_dom_query(DOM_QUERY
*d_q
, const char *dom_name
, DOM_SID
*dom_sid
)
64 int domlen
= (dom_name
!= NULL
) ? strlen(dom_name
) : 0;
67 * I'm not sure why this really odd combination of length
68 * values works, but it does appear to. I need to look at
69 * this *much* more closely - but at the moment leave alone
70 * until it's understood. This allows a W2k client to join
71 * a domain with both odd and even length names... JRA.
74 d_q
->uni_dom_str_len
= domlen
? ((domlen
+ 1) * 2) : 0;
75 d_q
->uni_dom_max_len
= domlen
* 2;
76 d_q
->buffer_dom_name
= domlen
!= 0 ? 1 : 0; /* domain buffer pointer */
77 d_q
->buffer_dom_sid
= dom_sid
!= NULL
? 1 : 0; /* domain sid pointer */
79 /* this string is supposed to be character short */
80 init_unistr2(&d_q
->uni_domain_name
, dom_name
, domlen
);
81 d_q
->uni_domain_name
.uni_max_len
++;
84 init_dom_sid2(&d_q
->dom_sid
, dom_sid
);
87 /***************************************************************************
88 init_dom_ref - adds a domain if it's not already in, returns the index.
89 ***************************************************************************/
91 static int init_dom_ref(DOM_R_REF
*ref
, char *dom_name
, DOM_SID
*dom_sid
)
96 if (dom_name
!= NULL
) {
97 for (num
= 0; num
< ref
->num_ref_doms_1
; num
++) {
99 rpcstr_pull(domname
, &ref
->ref_dom
[num
].uni_dom_name
, sizeof(domname
), -1, 0);
100 if (strequal(domname
, dom_name
))
104 num
= ref
->num_ref_doms_1
;
107 if (num
>= MAX_REF_DOMAINS
) {
108 /* index not found, already at maximum domain limit */
112 ref
->num_ref_doms_1
= num
+1;
113 ref
->ptr_ref_dom
= 1;
114 ref
->max_entries
= MAX_REF_DOMAINS
;
115 ref
->num_ref_doms_2
= num
+1;
117 len
= (dom_name
!= NULL
) ? strlen(dom_name
) : 0;
118 if(dom_name
!= NULL
&& len
== 0)
121 init_uni_hdr(&ref
->hdr_ref_dom
[num
].hdr_dom_name
, len
);
122 ref
->hdr_ref_dom
[num
].ptr_dom_sid
= dom_sid
!= NULL
? 1 : 0;
124 init_unistr2(&ref
->ref_dom
[num
].uni_dom_name
, dom_name
, len
);
125 init_dom_sid2(&ref
->ref_dom
[num
].ref_dom
, dom_sid
);
130 /***************************************************************************
132 ***************************************************************************/
134 static void init_lsa_rid2s(DOM_R_REF
*ref
, DOM_RID2
*rid2
,
135 int num_entries
, UNISTR2
*name
,
136 uint32
*mapped_count
, BOOL endian
)
142 SMB_ASSERT(num_entries
<= MAX_LOOKUP_SIDS
);
144 become_root(); /* lookup_name can require root privs */
146 for (i
= 0; i
< num_entries
; i
++) {
149 uint32 rid
= 0xffffffff;
152 fstring dom_name
, user
;
153 enum SID_NAME_USE name_type
= SID_NAME_UNKNOWN
;
155 /* Split name into domain and user component */
157 unistr2_to_ascii(full_name
, &name
[i
], sizeof(full_name
));
158 split_domain_name(full_name
, dom_name
, user
);
162 DEBUG(5, ("init_lsa_rid2s: looking up name %s\n", full_name
));
164 status
= lookup_name(dom_name
, user
, &sid
, &name_type
);
166 DEBUG(5, ("init_lsa_rid2s: %s\n", status
? "found" :
169 if (status
&& name_type
!= SID_NAME_UNKNOWN
) {
170 sid_split_rid(&sid
, &rid
);
171 dom_idx
= init_dom_ref(ref
, dom_name
, &sid
);
176 name_type
= SID_NAME_UNKNOWN
;
179 init_dom_rid2(&rid2
[total
], rid
, name_type
, dom_idx
);
186 /***************************************************************************
187 init_reply_lookup_names
188 ***************************************************************************/
190 static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES
*r_l
,
191 DOM_R_REF
*ref
, uint32 num_entries
,
192 DOM_RID2
*rid2
, uint32 mapped_count
)
194 r_l
->ptr_dom_ref
= 1;
197 r_l
->num_entries
= num_entries
;
198 r_l
->ptr_entries
= 1;
199 r_l
->num_entries2
= num_entries
;
202 r_l
->mapped_count
= mapped_count
;
204 if (mapped_count
== 0)
205 r_l
->status
= NT_STATUS_NONE_MAPPED
;
207 r_l
->status
= NT_STATUS_OK
;
210 /***************************************************************************
211 Init lsa_trans_names.
212 ***************************************************************************/
214 static void init_lsa_trans_names(TALLOC_CTX
*ctx
, DOM_R_REF
*ref
, LSA_TRANS_NAME_ENUM
*trn
,
215 int num_entries
, DOM_SID2
*sid
,
216 uint32
*mapped_count
)
222 /* Allocate memory for list of names */
224 if (num_entries
> 0) {
225 if (!(trn
->name
= (LSA_TRANS_NAME
*)talloc(ctx
, sizeof(LSA_TRANS_NAME
) *
227 DEBUG(0, ("init_lsa_trans_names(): out of memory\n"));
231 if (!(trn
->uni_name
= (UNISTR2
*)talloc(ctx
, sizeof(UNISTR2
) *
233 DEBUG(0, ("init_lsa_trans_names(): out of memory\n"));
238 become_root(); /* Need root to get to passdb to for local sids */
240 for (i
= 0; i
< num_entries
; i
++) {
242 DOM_SID find_sid
= sid
[i
].sid
;
243 uint32 rid
= 0xffffffff;
245 fstring name
, dom_name
;
246 enum SID_NAME_USE sid_name_use
= (enum SID_NAME_USE
)0;
248 sid_to_string(name
, &find_sid
);
249 DEBUG(5, ("init_lsa_trans_names: looking up sid %s\n", name
));
251 /* Lookup sid from winbindd */
253 memset(dom_name
, '\0', sizeof(dom_name
));
254 memset(name
, '\0', sizeof(name
));
256 status
= lookup_sid(&find_sid
, dom_name
, name
, &sid_name_use
);
258 DEBUG(5, ("init_lsa_trans_names: %s\n", status
? "found" :
262 sid_name_use
= SID_NAME_UNKNOWN
;
267 /* Store domain sid in ref array */
269 if (find_sid
.num_auths
== 5) {
270 sid_split_rid(&find_sid
, &rid
);
273 dom_idx
= init_dom_ref(ref
, dom_name
, &find_sid
);
275 DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to "
276 "referenced list.\n", dom_name
, name
));
278 init_lsa_trans_name(&trn
->name
[total
], &trn
->uni_name
[total
],
279 sid_name_use
, name
, dom_idx
);
285 trn
->num_entries
= total
;
286 trn
->ptr_trans_names
= 1;
287 trn
->num_entries2
= total
;
290 /***************************************************************************
291 Init_reply_lookup_sids.
292 ***************************************************************************/
294 static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS
*r_l
,
295 DOM_R_REF
*ref
, LSA_TRANS_NAME_ENUM
*names
,
298 r_l
->ptr_dom_ref
= 1;
301 r_l
->mapped_count
= mapped_count
;
303 if (mapped_count
== 0)
304 r_l
->status
= NT_STATUS_NONE_MAPPED
;
306 r_l
->status
= NT_STATUS_OK
;
309 static NTSTATUS
lsa_get_generic_sd(TALLOC_CTX
*mem_ctx
, SEC_DESC
**sd
, size_t *sd_size
)
311 extern DOM_SID global_sid_World
;
312 extern DOM_SID global_sid_Builtin
;
313 DOM_SID local_adm_sid
;
321 init_sec_access(&mask
, POLICY_EXECUTE
);
322 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
324 sid_copy(&adm_sid
, get_global_sam_sid());
325 sid_append_rid(&adm_sid
, DOMAIN_GROUP_RID_ADMINS
);
326 init_sec_access(&mask
, POLICY_ALL_ACCESS
);
327 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
329 sid_copy(&local_adm_sid
, &global_sid_Builtin
);
330 sid_append_rid(&local_adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
331 init_sec_access(&mask
, POLICY_ALL_ACCESS
);
332 init_sec_ace(&ace
[2], &local_adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
334 if((psa
= make_sec_acl(mem_ctx
, NT4_ACL_REVISION
, 3, ace
)) == NULL
)
335 return NT_STATUS_NO_MEMORY
;
337 if((*sd
= make_sec_desc(mem_ctx
, SEC_DESC_REVISION
, &adm_sid
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
338 return NT_STATUS_NO_MEMORY
;
343 /***************************************************************************
345 ***************************************************************************/
347 static void init_dns_dom_info(LSA_DNS_DOM_INFO
*r_l
, const char *nb_name
,
348 const char *dns_name
, const char *forest_name
,
349 GUID
*dom_guid
, DOM_SID
*dom_sid
)
351 if (nb_name
&& *nb_name
) {
352 init_uni_hdr(&r_l
->hdr_nb_dom_name
, strlen(nb_name
));
353 init_unistr2(&r_l
->uni_nb_dom_name
, nb_name
,
355 r_l
->hdr_nb_dom_name
.uni_max_len
+= 2;
356 r_l
->uni_nb_dom_name
.uni_max_len
+= 1;
359 if (dns_name
&& *dns_name
) {
360 init_uni_hdr(&r_l
->hdr_dns_dom_name
, strlen(dns_name
));
361 init_unistr2(&r_l
->uni_dns_dom_name
, dns_name
,
363 r_l
->hdr_dns_dom_name
.uni_max_len
+= 2;
364 r_l
->uni_dns_dom_name
.uni_max_len
+= 1;
367 if (forest_name
&& *forest_name
) {
368 init_uni_hdr(&r_l
->hdr_forest_name
, strlen(forest_name
));
369 init_unistr2(&r_l
->uni_forest_name
, forest_name
,
370 strlen(forest_name
));
371 r_l
->hdr_forest_name
.uni_max_len
+= 2;
372 r_l
->uni_forest_name
.uni_max_len
+= 1;
375 /* how do we init the guid ? probably should write an init fn */
377 memcpy(&r_l
->dom_guid
, dom_guid
, sizeof(GUID
));
381 r_l
->ptr_dom_sid
= 1;
382 init_dom_sid2(&r_l
->dom_sid
, dom_sid
);
386 /***************************************************************************
388 ***************************************************************************/
390 NTSTATUS
_lsa_open_policy2(pipes_struct
*p
, LSA_Q_OPEN_POL2
*q_u
, LSA_R_OPEN_POL2
*r_u
)
392 struct lsa_info
*info
;
393 SEC_DESC
*psd
= NULL
;
395 uint32 des_access
=q_u
->des_access
;
400 /* map the generic bits to the lsa policy ones */
401 se_map_generic(&des_access
, &lsa_generic_mapping
);
403 /* get the generic lsa policy SD until we store it */
404 lsa_get_generic_sd(p
->mem_ctx
, &psd
, &sd_size
);
406 if(!se_access_check(psd
, p
->pipe_user
.nt_user_token
, des_access
, &acc_granted
, &status
))
409 /* associate the domain SID with the (unique) handle. */
410 if ((info
= (struct lsa_info
*)malloc(sizeof(struct lsa_info
))) == NULL
)
411 return NT_STATUS_NO_MEMORY
;
414 sid_copy(&info
->sid
,get_global_sam_sid());
415 info
->access
= acc_granted
;
417 /* set up the LSA QUERY INFO response */
418 if (!create_policy_hnd(p
, &r_u
->pol
, free_lsa_info
, (void *)info
))
419 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
424 /***************************************************************************
426 ***************************************************************************/
428 NTSTATUS
_lsa_open_policy(pipes_struct
*p
, LSA_Q_OPEN_POL
*q_u
, LSA_R_OPEN_POL
*r_u
)
430 struct lsa_info
*info
;
431 SEC_DESC
*psd
= NULL
;
433 uint32 des_access
=q_u
->des_access
;
438 /* map the generic bits to the lsa policy ones */
439 se_map_generic(&des_access
, &lsa_generic_mapping
);
441 /* get the generic lsa policy SD until we store it */
442 lsa_get_generic_sd(p
->mem_ctx
, &psd
, &sd_size
);
444 if(!se_access_check(psd
, p
->pipe_user
.nt_user_token
, des_access
, &acc_granted
, &status
))
447 /* associate the domain SID with the (unique) handle. */
448 if ((info
= (struct lsa_info
*)malloc(sizeof(struct lsa_info
))) == NULL
)
449 return NT_STATUS_NO_MEMORY
;
452 sid_copy(&info
->sid
,get_global_sam_sid());
453 info
->access
= acc_granted
;
455 /* set up the LSA QUERY INFO response */
456 if (!create_policy_hnd(p
, &r_u
->pol
, free_lsa_info
, (void *)info
))
457 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
462 /***************************************************************************
463 _lsa_enum_trust_dom - this needs fixing to do more than return NULL ! JRA.
465 ***************************************************************************/
467 NTSTATUS
_lsa_enum_trust_dom(pipes_struct
*p
, LSA_Q_ENUM_TRUST_DOM
*q_u
, LSA_R_ENUM_TRUST_DOM
*r_u
)
469 struct lsa_info
*info
;
470 uint32 enum_context
= q_u
->enum_context
;
473 * preferred length is set to 5 as a "our" preferred length
474 * nt sets this parameter to 2
475 * update (20.08.2002): it's not preferred length, but preferred size!
476 * it needs further investigation how to optimally choose this value
478 uint32 max_num_domains
= q_u
->preferred_len
< 5 ? q_u
->preferred_len
: 10;
479 TRUSTDOM
**trust_doms
;
483 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
484 return NT_STATUS_INVALID_HANDLE
;
486 /* check if the user have enough rights */
487 if (!(info
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
488 return NT_STATUS_ACCESS_DENIED
;
490 nt_status
= secrets_get_trusted_domains(p
->mem_ctx
, &enum_context
, max_num_domains
, &num_domains
, &trust_doms
);
492 if (!NT_STATUS_IS_OK(nt_status
) &&
493 !NT_STATUS_EQUAL(nt_status
, STATUS_MORE_ENTRIES
) &&
494 !NT_STATUS_EQUAL(nt_status
, NT_STATUS_NO_MORE_ENTRIES
)) {
497 r_u
->status
= nt_status
;
500 /* set up the lsa_enum_trust_dom response */
501 init_r_enum_trust_dom(p
->mem_ctx
, r_u
, enum_context
, max_num_domains
, num_domains
, trust_doms
);
506 /***************************************************************************
507 _lsa_query_info. See the POLICY_INFOMATION_CLASS docs at msdn.
508 ***************************************************************************/
510 NTSTATUS
_lsa_query_info(pipes_struct
*p
, LSA_Q_QUERY_INFO
*q_u
, LSA_R_QUERY_INFO
*r_u
)
512 struct lsa_info
*handle
;
513 LSA_INFO_UNION
*info
= &r_u
->dom
;
518 r_u
->status
= NT_STATUS_OK
;
520 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
521 return NT_STATUS_INVALID_HANDLE
;
523 switch (q_u
->info_class
) {
527 /* check if the user have enough rights */
528 if (!(handle
->access
& POLICY_VIEW_AUDIT_INFORMATION
))
529 return NT_STATUS_ACCESS_DENIED
;
531 /* fake info: We audit everything. ;) */
532 info
->id2
.auditing_enabled
= 1;
533 info
->id2
.count1
= 7;
534 info
->id2
.count2
= 7;
535 if ((info
->id2
.auditsettings
= (uint32
*)talloc(p
->mem_ctx
,7*sizeof(uint32
))) == NULL
)
536 return NT_STATUS_NO_MEMORY
;
537 for (i
= 0; i
< 7; i
++)
538 info
->id2
.auditsettings
[i
] = 3;
542 /* check if the user have enough rights */
543 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
544 return NT_STATUS_ACCESS_DENIED
;
546 /* Request PolicyPrimaryDomainInformation. */
547 switch (lp_server_role()) {
548 case ROLE_DOMAIN_PDC
:
549 case ROLE_DOMAIN_BDC
:
550 name
= lp_workgroup();
551 sid
= get_global_sam_sid();
553 case ROLE_DOMAIN_MEMBER
:
554 name
= lp_workgroup();
555 /* We need to return the Domain SID here. */
556 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid
))
559 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
561 case ROLE_STANDALONE
:
562 name
= lp_workgroup();
566 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
568 init_dom_query(&r_u
->dom
.id3
, name
, sid
);
571 /* check if the user have enough rights */
572 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
573 return NT_STATUS_ACCESS_DENIED
;
575 /* Request PolicyAccountDomainInformation. */
576 switch (lp_server_role()) {
577 case ROLE_DOMAIN_PDC
:
578 case ROLE_DOMAIN_BDC
:
579 name
= lp_workgroup();
580 sid
= get_global_sam_sid();
582 case ROLE_DOMAIN_MEMBER
:
583 name
= global_myname();
584 sid
= get_global_sam_sid();
586 case ROLE_STANDALONE
:
587 name
= global_myname();
588 sid
= get_global_sam_sid();
591 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
593 init_dom_query(&r_u
->dom
.id5
, name
, sid
);
596 /* check if the user have enough rights */
597 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
598 return NT_STATUS_ACCESS_DENIED
;
600 switch (lp_server_role()) {
601 case ROLE_DOMAIN_BDC
:
603 * only a BDC is a backup controller
604 * of the domain, it controls.
606 info
->id6
.server_role
= 2;
610 * any other role is a primary
611 * of the domain, it controls.
613 info
->id6
.server_role
= 3;
618 DEBUG(0,("_lsa_query_info: unknown info level in Lsa Query: %d\n", q_u
->info_class
));
619 r_u
->status
= NT_STATUS_INVALID_INFO_CLASS
;
623 if (NT_STATUS_IS_OK(r_u
->status
)) {
624 r_u
->undoc_buffer
= 0x22000000; /* bizarre */
625 r_u
->info_class
= q_u
->info_class
;
631 /***************************************************************************
633 ***************************************************************************/
635 NTSTATUS
_lsa_lookup_sids(pipes_struct
*p
, LSA_Q_LOOKUP_SIDS
*q_u
, LSA_R_LOOKUP_SIDS
*r_u
)
637 struct lsa_info
*handle
;
638 DOM_SID2
*sid
= q_u
->sids
.sid
;
639 int num_entries
= q_u
->sids
.num_entries
;
640 DOM_R_REF
*ref
= NULL
;
641 LSA_TRANS_NAME_ENUM
*names
= NULL
;
642 uint32 mapped_count
= 0;
644 if (num_entries
> MAX_LOOKUP_SIDS
) {
645 num_entries
= MAX_LOOKUP_SIDS
;
646 DEBUG(5,("_lsa_lookup_sids: truncating SID lookup list to %d\n", num_entries
));
649 ref
= (DOM_R_REF
*)talloc_zero(p
->mem_ctx
, sizeof(DOM_R_REF
));
650 names
= (LSA_TRANS_NAME_ENUM
*)talloc_zero(p
->mem_ctx
, sizeof(LSA_TRANS_NAME_ENUM
));
652 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
)) {
653 r_u
->status
= NT_STATUS_INVALID_HANDLE
;
657 /* check if the user have enough rights */
658 if (!(handle
->access
& POLICY_LOOKUP_NAMES
)) {
659 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
663 return NT_STATUS_NO_MEMORY
;
667 /* set up the LSA Lookup SIDs response */
668 init_lsa_trans_names(p
->mem_ctx
, ref
, names
, num_entries
, sid
, &mapped_count
);
669 init_reply_lookup_sids(r_u
, ref
, names
, mapped_count
);
674 /***************************************************************************
675 lsa_reply_lookup_names
676 ***************************************************************************/
678 NTSTATUS
_lsa_lookup_names(pipes_struct
*p
,LSA_Q_LOOKUP_NAMES
*q_u
, LSA_R_LOOKUP_NAMES
*r_u
)
680 struct lsa_info
*handle
;
681 UNISTR2
*names
= q_u
->uni_name
;
682 int num_entries
= q_u
->num_entries
;
685 uint32 mapped_count
= 0;
687 if (num_entries
> MAX_LOOKUP_SIDS
) {
688 num_entries
= MAX_LOOKUP_SIDS
;
689 DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries
));
692 ref
= (DOM_R_REF
*)talloc_zero(p
->mem_ctx
, sizeof(DOM_R_REF
));
693 rids
= (DOM_RID2
*)talloc_zero(p
->mem_ctx
, sizeof(DOM_RID2
)*num_entries
);
695 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
)) {
696 r_u
->status
= NT_STATUS_INVALID_HANDLE
;
700 /* check if the user have enough rights */
701 if (!(handle
->access
& POLICY_LOOKUP_NAMES
)) {
702 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
707 return NT_STATUS_NO_MEMORY
;
711 /* set up the LSA Lookup RIDs response */
712 init_lsa_rid2s(ref
, rids
, num_entries
, names
, &mapped_count
, p
->endian
);
713 init_reply_lookup_names(r_u
, ref
, num_entries
, rids
, mapped_count
);
718 /***************************************************************************
719 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
720 ***************************************************************************/
722 NTSTATUS
_lsa_close(pipes_struct
*p
, LSA_Q_CLOSE
*q_u
, LSA_R_CLOSE
*r_u
)
724 if (!find_policy_by_hnd(p
, &q_u
->pol
, NULL
))
725 return NT_STATUS_INVALID_HANDLE
;
727 close_policy_hnd(p
, &q_u
->pol
);
731 /***************************************************************************
732 "No more secrets Marty...." :-).
733 ***************************************************************************/
735 NTSTATUS
_lsa_open_secret(pipes_struct
*p
, LSA_Q_OPEN_SECRET
*q_u
, LSA_R_OPEN_SECRET
*r_u
)
737 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
740 /***************************************************************************
742 ***************************************************************************/
744 NTSTATUS
_lsa_enum_privs(pipes_struct
*p
, LSA_Q_ENUM_PRIVS
*q_u
, LSA_R_ENUM_PRIVS
*r_u
)
746 struct lsa_info
*handle
;
749 uint32 enum_context
=q_u
->enum_context
;
750 LSA_PRIV_ENTRY
*entry
;
751 LSA_PRIV_ENTRY
*entries
=NULL
;
753 if (enum_context
>= PRIV_ALL_INDEX
)
754 return NT_STATUS_NO_MORE_ENTRIES
;
756 entries
= (LSA_PRIV_ENTRY
*)talloc_zero(p
->mem_ctx
, sizeof(LSA_PRIV_ENTRY
) * (PRIV_ALL_INDEX
));
758 return NT_STATUS_NO_MEMORY
;
760 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
761 return NT_STATUS_INVALID_HANDLE
;
763 /* check if the user have enough rights */
766 * I don't know if it's the right one. not documented.
768 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
769 return NT_STATUS_ACCESS_DENIED
;
773 DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n", enum_context
, PRIV_ALL_INDEX
));
775 for (i
= 0; i
< PRIV_ALL_INDEX
; i
++, entry
++) {
776 if( i
<enum_context
) {
777 init_uni_hdr(&entry
->hdr_name
, 0);
778 init_unistr2(&entry
->name
, NULL
, 0 );
780 entry
->luid_high
= 0;
782 init_uni_hdr(&entry
->hdr_name
, strlen(privs
[i
+1].priv
));
783 init_unistr2(&entry
->name
, privs
[i
+1].priv
, strlen(privs
[i
+1].priv
) );
784 entry
->luid_low
= privs
[i
+1].se_priv
;
785 entry
->luid_high
= 0;
789 enum_context
= PRIV_ALL_INDEX
;
790 init_lsa_r_enum_privs(r_u
, enum_context
, PRIV_ALL_INDEX
, entries
);
795 /***************************************************************************
796 _lsa_priv_get_dispname.
797 ***************************************************************************/
799 NTSTATUS
_lsa_priv_get_dispname(pipes_struct
*p
, LSA_Q_PRIV_GET_DISPNAME
*q_u
, LSA_R_PRIV_GET_DISPNAME
*r_u
)
801 struct lsa_info
*handle
;
805 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
806 return NT_STATUS_INVALID_HANDLE
;
808 /* check if the user have enough rights */
811 * I don't know if it's the right one. not documented.
813 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
814 return NT_STATUS_ACCESS_DENIED
;
816 unistr2_to_ascii(name_asc
, &q_u
->name
, sizeof(name_asc
));
818 DEBUG(10,("_lsa_priv_get_dispname: %s", name_asc
));
820 while (privs
[i
].se_priv
!=SE_PRIV_ALL
&& strcmp(name_asc
, privs
[i
].priv
))
823 if (privs
[i
].se_priv
!=SE_PRIV_ALL
) {
824 DEBUG(10,(": %s\n", privs
[i
].description
));
825 init_uni_hdr(&r_u
->hdr_desc
, strlen(privs
[i
].description
));
826 init_unistr2(&r_u
->desc
, privs
[i
].description
, strlen(privs
[i
].description
) );
828 r_u
->ptr_info
=0xdeadbeef;
829 r_u
->lang_id
=q_u
->lang_id
;
832 DEBUG(10,("_lsa_priv_get_dispname: doesn't exist\n"));
834 return NT_STATUS_NO_SUCH_PRIVILEGE
;
838 /***************************************************************************
840 ***************************************************************************/
842 NTSTATUS
_lsa_enum_accounts(pipes_struct
*p
, LSA_Q_ENUM_ACCOUNTS
*q_u
, LSA_R_ENUM_ACCOUNTS
*r_u
)
844 struct lsa_info
*handle
;
847 LSA_SID_ENUM
*sids
=&r_u
->sids
;
850 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
851 return NT_STATUS_INVALID_HANDLE
;
853 /* check if the user have enough rights */
856 * I don't know if it's the right one. not documented.
858 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
859 return NT_STATUS_ACCESS_DENIED
;
861 /* get the list of mapped groups (domain, local, builtin) */
862 if(!pdb_enum_group_mapping(SID_NAME_UNKNOWN
, &map
, &num_entries
, ENUM_ONLY_MAPPED
, MAPPING_WITHOUT_PRIV
))
865 if (q_u
->enum_context
>= num_entries
)
866 return NT_STATUS_NO_MORE_ENTRIES
;
868 sids
->ptr_sid
= (uint32
*)talloc_zero(p
->mem_ctx
, (num_entries
-q_u
->enum_context
)*sizeof(uint32
));
869 sids
->sid
= (DOM_SID2
*)talloc_zero(p
->mem_ctx
, (num_entries
-q_u
->enum_context
)*sizeof(DOM_SID2
));
871 if (sids
->ptr_sid
==NULL
|| sids
->sid
==NULL
) {
873 return NT_STATUS_NO_MEMORY
;
876 for (i
=q_u
->enum_context
, j
=0; i
<num_entries
; i
++) {
877 init_dom_sid2( &(*sids
).sid
[j
], &map
[i
].sid
);
878 (*sids
).ptr_sid
[j
]=1;
884 init_lsa_r_enum_accounts(r_u
, j
);
890 NTSTATUS
_lsa_unk_get_connuser(pipes_struct
*p
, LSA_Q_UNK_GET_CONNUSER
*q_u
, LSA_R_UNK_GET_CONNUSER
*r_u
)
892 fstring username
, domname
;
894 user_struct
*vuser
= get_valid_user_struct(p
->vuid
);
897 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
899 fstrcpy(username
, vuser
->user
.smb_name
);
900 fstrcpy(domname
, vuser
->user
.domain
);
902 ulen
= strlen(username
) + 1;
903 dlen
= strlen(domname
) + 1;
905 init_uni_hdr(&r_u
->hdr_user_name
, ulen
);
906 r_u
->ptr_user_name
= 1;
907 init_unistr2(&r_u
->uni2_user_name
, username
, ulen
);
911 init_uni_hdr(&r_u
->hdr_dom_name
, dlen
);
912 r_u
->ptr_dom_name
= 1;
913 init_unistr2(&r_u
->uni2_dom_name
, domname
, dlen
);
915 r_u
->status
= NT_STATUS_OK
;
920 /***************************************************************************
922 ***************************************************************************/
924 NTSTATUS
_lsa_open_account(pipes_struct
*p
, LSA_Q_OPENACCOUNT
*q_u
, LSA_R_OPENACCOUNT
*r_u
)
926 struct lsa_info
*handle
;
927 struct lsa_info
*info
;
929 r_u
->status
= NT_STATUS_OK
;
931 /* find the connection policy handle. */
932 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
933 return NT_STATUS_INVALID_HANDLE
;
935 /* check if the user have enough rights */
938 * I don't know if it's the right one. not documented.
939 * but guessed with rpcclient.
941 if (!(handle
->access
& POLICY_GET_PRIVATE_INFORMATION
))
942 return NT_STATUS_ACCESS_DENIED
;
944 /* associate the user/group SID with the (unique) handle. */
945 if ((info
= (struct lsa_info
*)malloc(sizeof(struct lsa_info
))) == NULL
)
946 return NT_STATUS_NO_MEMORY
;
949 info
->sid
= q_u
->sid
.sid
;
950 info
->access
= q_u
->access
;
952 /* get a (unique) handle. open a policy on it. */
953 if (!create_policy_hnd(p
, &r_u
->pol
, free_lsa_info
, (void *)info
))
954 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
959 /***************************************************************************
960 For a given SID, enumerate all the privilege this account has.
961 ***************************************************************************/
963 NTSTATUS
_lsa_enum_privsaccount(pipes_struct
*p
, LSA_Q_ENUMPRIVSACCOUNT
*q_u
, LSA_R_ENUMPRIVSACCOUNT
*r_u
)
965 struct lsa_info
*info
=NULL
;
971 r_u
->status
= NT_STATUS_OK
;
973 /* find the connection policy handle. */
974 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
975 return NT_STATUS_INVALID_HANDLE
;
977 if (!pdb_getgrsid(&map
, info
->sid
, MAPPING_WITH_PRIV
))
978 return NT_STATUS_NO_SUCH_GROUP
;
980 DEBUG(10,("_lsa_enum_privsaccount: %d privileges\n", map
.priv_set
.count
));
981 if (map
.priv_set
.count
!=0) {
983 set
=(LUID_ATTR
*)talloc(p
->mem_ctx
, map
.priv_set
.count
*sizeof(LUID_ATTR
));
985 free_privilege(&map
.priv_set
);
986 return NT_STATUS_NO_MEMORY
;
989 for (i
=0; i
<map
.priv_set
.count
; i
++) {
990 set
[i
].luid
.low
=map
.priv_set
.set
[i
].luid
.low
;
991 set
[i
].luid
.high
=map
.priv_set
.set
[i
].luid
.high
;
992 set
[i
].attr
=map
.priv_set
.set
[i
].attr
;
993 DEBUG(10,("_lsa_enum_privsaccount: priv %d: %d:%d:%d\n", i
,
994 set
[i
].luid
.high
, set
[i
].luid
.low
, set
[i
].attr
));
998 init_lsa_r_enum_privsaccount(r_u
, set
, map
.priv_set
.count
, 0);
999 free_privilege(&map
.priv_set
);
1004 /***************************************************************************
1006 ***************************************************************************/
1008 NTSTATUS
_lsa_getsystemaccount(pipes_struct
*p
, LSA_Q_GETSYSTEMACCOUNT
*q_u
, LSA_R_GETSYSTEMACCOUNT
*r_u
)
1010 struct lsa_info
*info
=NULL
;
1012 r_u
->status
= NT_STATUS_OK
;
1014 /* find the connection policy handle. */
1015 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1016 return NT_STATUS_INVALID_HANDLE
;
1018 if (!pdb_getgrsid(&map
, info
->sid
, MAPPING_WITHOUT_PRIV
))
1019 return NT_STATUS_NO_SUCH_GROUP
;
1022 0x01 -> Log on locally
1023 0x02 -> Access this computer from network
1024 0x04 -> Log on as a batch job
1025 0x10 -> Log on as a service
1027 they can be ORed together
1030 r_u
->access
=map
.systemaccount
;
1035 /***************************************************************************
1036 update the systemaccount information
1037 ***************************************************************************/
1039 NTSTATUS
_lsa_setsystemaccount(pipes_struct
*p
, LSA_Q_SETSYSTEMACCOUNT
*q_u
, LSA_R_SETSYSTEMACCOUNT
*r_u
)
1041 struct lsa_info
*info
=NULL
;
1043 r_u
->status
= NT_STATUS_OK
;
1045 /* find the connection policy handle. */
1046 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1047 return NT_STATUS_INVALID_HANDLE
;
1049 if (!pdb_getgrsid(&map
, info
->sid
, MAPPING_WITH_PRIV
))
1050 return NT_STATUS_NO_SUCH_GROUP
;
1052 map
.systemaccount
=q_u
->access
;
1054 if(!pdb_update_group_mapping_entry(&map
))
1055 return NT_STATUS_NO_SUCH_GROUP
;
1057 free_privilege(&map
.priv_set
);
1062 /***************************************************************************
1063 For a given SID, add some privileges.
1064 ***************************************************************************/
1066 NTSTATUS
_lsa_addprivs(pipes_struct
*p
, LSA_Q_ADDPRIVS
*q_u
, LSA_R_ADDPRIVS
*r_u
)
1068 struct lsa_info
*info
=NULL
;
1072 LUID_ATTR
*luid_attr
=NULL
;
1073 PRIVILEGE_SET
*set
=NULL
;
1075 r_u
->status
= NT_STATUS_OK
;
1077 /* find the connection policy handle. */
1078 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1079 return NT_STATUS_INVALID_HANDLE
;
1081 if (!pdb_getgrsid(&map
, info
->sid
, MAPPING_WITH_PRIV
))
1082 return NT_STATUS_NO_SUCH_GROUP
;
1086 for (i
=0; i
<set
->count
; i
++) {
1087 luid_attr
=&set
->set
[i
];
1089 /* check if the privilege is already there */
1090 if (check_priv_in_privilege(&map
.priv_set
, *luid_attr
)){
1091 free_privilege(&map
.priv_set
);
1092 return NT_STATUS_NO_SUCH_PRIVILEGE
;
1095 add_privilege(&map
.priv_set
, *luid_attr
);
1098 if(!pdb_update_group_mapping_entry(&map
))
1099 return NT_STATUS_NO_SUCH_GROUP
;
1101 free_privilege(&map
.priv_set
);
1106 /***************************************************************************
1107 For a given SID, remove some privileges.
1108 ***************************************************************************/
1110 NTSTATUS
_lsa_removeprivs(pipes_struct
*p
, LSA_Q_REMOVEPRIVS
*q_u
, LSA_R_REMOVEPRIVS
*r_u
)
1112 struct lsa_info
*info
=NULL
;
1116 LUID_ATTR
*luid_attr
=NULL
;
1117 PRIVILEGE_SET
*set
=NULL
;
1119 r_u
->status
= NT_STATUS_OK
;
1121 /* find the connection policy handle. */
1122 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1123 return NT_STATUS_INVALID_HANDLE
;
1125 if (!pdb_getgrsid(&map
, info
->sid
, MAPPING_WITH_PRIV
))
1126 return NT_STATUS_NO_SUCH_GROUP
;
1128 if (q_u
->allrights
!=0) {
1129 /* log it and return, until I see one myself don't do anything */
1130 DEBUG(5,("_lsa_removeprivs: trying to remove all privileges ?\n"));
1131 return NT_STATUS_OK
;
1135 /* log it and return, until I see one myself don't do anything */
1136 DEBUG(5,("_lsa_removeprivs: no privileges to remove ?\n"));
1137 return NT_STATUS_OK
;
1142 for (i
=0; i
<set
->count
; i
++) {
1143 luid_attr
=&set
->set
[i
];
1145 /* if we don't have the privilege, we're trying to remove, give up */
1146 /* what else can we do ??? JFM. */
1147 if (!check_priv_in_privilege(&map
.priv_set
, *luid_attr
)){
1148 free_privilege(&map
.priv_set
);
1149 return NT_STATUS_NO_SUCH_PRIVILEGE
;
1152 remove_privilege(&map
.priv_set
, *luid_attr
);
1155 if(!pdb_update_group_mapping_entry(&map
))
1156 return NT_STATUS_NO_SUCH_GROUP
;
1158 free_privilege(&map
.priv_set
);
1163 /***************************************************************************
1164 For a given SID, remove some privileges.
1165 ***************************************************************************/
1167 NTSTATUS
_lsa_query_secobj(pipes_struct
*p
, LSA_Q_QUERY_SEC_OBJ
*q_u
, LSA_R_QUERY_SEC_OBJ
*r_u
)
1169 struct lsa_info
*handle
=NULL
;
1170 SEC_DESC
*psd
= NULL
;
1174 r_u
->status
= NT_STATUS_OK
;
1176 /* find the connection policy handle. */
1177 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
1178 return NT_STATUS_INVALID_HANDLE
;
1180 /* check if the user have enough rights */
1181 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
1182 return NT_STATUS_ACCESS_DENIED
;
1185 switch (q_u
->sec_info
) {
1187 /* SD contains only the owner */
1189 status
=lsa_get_generic_sd(p
->mem_ctx
, &psd
, &sd_size
);
1190 if(!NT_STATUS_IS_OK(status
))
1191 return NT_STATUS_NO_MEMORY
;
1194 if((r_u
->buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
1195 return NT_STATUS_NO_MEMORY
;
1198 /* SD contains only the ACL */
1200 status
=lsa_get_generic_sd(p
->mem_ctx
, &psd
, &sd_size
);
1201 if(!NT_STATUS_IS_OK(status
))
1202 return NT_STATUS_NO_MEMORY
;
1204 if((r_u
->buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
1205 return NT_STATUS_NO_MEMORY
;
1208 return NT_STATUS_INVALID_LEVEL
;
1217 NTSTATUS
_lsa_query_info2(pipes_struct
*p
, LSA_Q_QUERY_INFO2
*q_u
, LSA_R_QUERY_INFO2
*r_u
)
1219 struct lsa_info
*handle
;
1220 const char *nb_name
;
1221 char *dns_name
= NULL
;
1222 char *forest_name
= NULL
;
1223 DOM_SID
*sid
= NULL
;
1227 r_u
->status
= NT_STATUS_OK
;
1229 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
1230 return NT_STATUS_INVALID_HANDLE
;
1232 switch (q_u
->info_class
) {
1234 /* check if the user have enough rights */
1235 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
1236 return NT_STATUS_ACCESS_DENIED
;
1238 /* Request PolicyPrimaryDomainInformation. */
1239 switch (lp_server_role()) {
1240 case ROLE_DOMAIN_PDC
:
1241 case ROLE_DOMAIN_BDC
:
1242 nb_name
= lp_workgroup();
1243 /* ugly temp hack for these next two */
1244 dns_name
= lp_realm();
1245 forest_name
= lp_realm();
1246 sid
= get_global_sam_sid();
1247 secrets_fetch_domain_guid(lp_workgroup(), &guid
);
1250 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
1252 init_dns_dom_info(&r_u
->info
.dns_dom_info
, nb_name
, dns_name
,
1253 forest_name
,&guid
,sid
);
1256 DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u
->info_class
));
1257 r_u
->status
= NT_STATUS_INVALID_INFO_CLASS
;
1261 if (NT_STATUS_IS_OK(r_u
->status
)) {
1263 r_u
->info_class
= q_u
->info_class
;
1270 /***************************************************************************
1271 For a given SID, enumerate all the privilege this account has.
1272 ***************************************************************************/
1273 NTSTATUS
_lsa_enum_acct_rights(pipes_struct
*p
, LSA_Q_ENUM_ACCT_RIGHTS
*q_u
, LSA_R_ENUM_ACCT_RIGHTS
*r_u
)
1275 struct lsa_info
*info
=NULL
;
1276 char **rights
= NULL
;
1280 r_u
->status
= NT_STATUS_OK
;
1282 /* find the connection policy handle. */
1283 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1284 return NT_STATUS_INVALID_HANDLE
;
1286 r_u
->status
= privilege_enum_account_rights(&q_u
->sid
.sid
, &num_rights
, &rights
);
1288 init_r_enum_acct_rights(r_u
, num_rights
, (const char **)rights
);
1290 for (i
=0;i
<num_rights
;i
++) {
1298 /***************************************************************************
1299 return a list of SIDs for a particular privilege
1300 ***************************************************************************/
1301 NTSTATUS
_lsa_enum_acct_with_right(pipes_struct
*p
,
1302 LSA_Q_ENUM_ACCT_WITH_RIGHT
*q_u
,
1303 LSA_R_ENUM_ACCT_WITH_RIGHT
*r_u
)
1305 struct lsa_info
*info
=NULL
;
1307 DOM_SID
*sids
= NULL
;
1310 r_u
->status
= NT_STATUS_OK
;
1312 /* find the connection policy handle. */
1313 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1314 return NT_STATUS_INVALID_HANDLE
;
1316 right
= unistr2_tdup(p
->mem_ctx
, &q_u
->right
);
1318 DEBUG(5,("lsa_enum_acct_with_right on right %s\n", right
));
1320 r_u
->status
= privilege_enum_account_with_right(right
, &count
, &sids
);
1322 init_r_enum_acct_with_right(r_u
, count
, sids
);
1329 /***************************************************************************
1330 add privileges to a acct by SID
1331 ***************************************************************************/
1332 NTSTATUS
_lsa_add_acct_rights(pipes_struct
*p
, LSA_Q_ADD_ACCT_RIGHTS
*q_u
, LSA_R_ADD_ACCT_RIGHTS
*r_u
)
1334 struct lsa_info
*info
=NULL
;
1337 r_u
->status
= NT_STATUS_OK
;
1339 /* find the connection policy handle. */
1340 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1341 return NT_STATUS_INVALID_HANDLE
;
1343 DEBUG(5,("_lsa_add_acct_rights to %s (%d rights)\n",
1344 sid_string_static(&q_u
->sid
.sid
), q_u
->rights
.count
));
1346 for (i
=0;i
<q_u
->rights
.count
;i
++) {
1347 DEBUG(5,("\t%s\n", unistr2_static(&q_u
->rights
.strings
[i
].string
)));
1351 for (i
=0;i
<q_u
->rights
.count
;i
++) {
1352 r_u
->status
= privilege_add_account_right(unistr2_static(&q_u
->rights
.strings
[i
].string
),
1354 if (!NT_STATUS_IS_OK(r_u
->status
)) {
1355 DEBUG(2,("Failed to add right '%s'\n",
1356 unistr2_static(&q_u
->rights
.strings
[i
].string
)));
1361 init_r_add_acct_rights(r_u
);
1367 /***************************************************************************
1368 remove privileges from a acct by SID
1369 ***************************************************************************/
1370 NTSTATUS
_lsa_remove_acct_rights(pipes_struct
*p
, LSA_Q_REMOVE_ACCT_RIGHTS
*q_u
, LSA_R_REMOVE_ACCT_RIGHTS
*r_u
)
1372 struct lsa_info
*info
=NULL
;
1375 r_u
->status
= NT_STATUS_OK
;
1377 /* find the connection policy handle. */
1378 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1379 return NT_STATUS_INVALID_HANDLE
;
1382 DEBUG(5,("_lsa_remove_acct_rights from %s all=%d (%d rights)\n",
1383 sid_string_static(&q_u
->sid
.sid
),
1385 q_u
->rights
.count
));
1387 for (i
=0;i
<q_u
->rights
.count
;i
++) {
1388 DEBUG(5,("\t%s\n", unistr2_static(&q_u
->rights
.strings
[i
].string
)));
1391 for (i
=0;i
<q_u
->rights
.count
;i
++) {
1392 r_u
->status
= privilege_remove_account_right(unistr2_static(&q_u
->rights
.strings
[i
].string
),
1394 if (!NT_STATUS_IS_OK(r_u
->status
)) {
1395 DEBUG(2,("Failed to remove right '%s'\n",
1396 unistr2_static(&q_u
->rights
.strings
[i
].string
)));
1401 init_r_remove_acct_rights(r_u
);