Fix starvation of pending writes in CTDB queues
[Samba.git] / source3 / lib / util_sid.c
blobfd767f9c8b36ba8ebc5a1794c09975e2c6f9f408
1 /*
2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Luke Kenneth Caseson Leighton 1998-1999
6 Copyright (C) Jeremy Allison 1999
7 Copyright (C) Stefan (metze) Metzmacher 2002
8 Copyright (C) Simo Sorce 2002
9 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005
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 3 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, see <http://www.gnu.org/licenses/>.
25 #include "includes.h"
26 #include "../librpc/gen_ndr/ndr_security.h"
27 #include "../librpc/gen_ndr/netlogon.h"
28 #include "../libcli/security/security.h"
29 #include "lib/util/string_wrappers.h"
30 #include "source3/lib/util_specialsids.h"
33 /*****************************************************************
34 Convert a SID to an ascii string.
35 *****************************************************************/
37 char *sid_to_fstring(fstring sidstr_out, const struct dom_sid *sid)
39 struct dom_sid_buf buf;
40 fstrcpy(sidstr_out, dom_sid_str_buf(sid, &buf));
41 return sidstr_out;
44 /*****************************************************************
45 Write a sid out into on-the-wire format.
46 *****************************************************************/
48 bool sid_linearize(uint8_t *outbuf, size_t len, const struct dom_sid *sid)
50 struct ndr_push ndr = {
51 .data = outbuf, .alloc_size = len, .fixed_buf_size = true,
53 enum ndr_err_code ndr_err;
55 ndr_err = ndr_push_dom_sid(&ndr, NDR_SCALARS|NDR_BUFFERS, sid);
56 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
59 /*****************************************************************
60 Returns true if SID is internal (and non-mappable).
61 *****************************************************************/
63 bool non_mappable_sid(struct dom_sid *sid)
65 struct dom_sid dom;
67 sid_copy(&dom, sid);
68 sid_split_rid(&dom, NULL);
70 if (dom_sid_equal(&dom, &global_sid_Builtin))
71 return True;
73 if (dom_sid_equal(&dom, &global_sid_NT_Authority))
74 return True;
76 return False;
79 /*****************************************************************
80 Return the binary string representation of a struct dom_sid.
81 Caller must free.
82 *****************************************************************/
84 char *sid_binstring_hex_talloc(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
86 int len = ndr_size_dom_sid(sid, 0);
87 uint8_t buf[len];
88 sid_linearize(buf, len, sid);
89 return hex_encode_talloc(mem_ctx, buf, len);
92 NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx,
93 const struct netr_SamInfo3 *info3,
94 struct dom_sid **user_sids,
95 uint32_t *num_user_sids,
96 bool include_user_group_rid)
98 NTSTATUS status;
99 struct dom_sid sid;
100 struct dom_sid *sid_array = NULL;
101 uint32_t num_sids = 0;
102 uint32_t i;
104 if (include_user_group_rid) {
105 if (!sid_compose(&sid, info3->base.domain_sid, info3->base.rid)) {
106 DEBUG(3, ("could not compose user SID from rid 0x%x\n",
107 info3->base.rid));
108 return NT_STATUS_INVALID_PARAMETER;
110 status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids);
111 if (!NT_STATUS_IS_OK(status)) {
112 DEBUG(3, ("could not append user SID from rid 0x%x\n",
113 info3->base.rid));
114 return status;
118 if (!sid_compose(&sid, info3->base.domain_sid, info3->base.primary_gid)) {
119 DEBUG(3, ("could not compose group SID from rid 0x%x\n",
120 info3->base.primary_gid));
121 return NT_STATUS_INVALID_PARAMETER;
123 status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids);
124 if (!NT_STATUS_IS_OK(status)) {
125 DEBUG(3, ("could not append group SID from rid 0x%x\n",
126 info3->base.rid));
127 return status;
130 for (i = 0; i < info3->base.groups.count; i++) {
131 /* Don't add the primary group sid twice. */
132 if (!sid_compose(&sid, info3->base.domain_sid,
133 info3->base.groups.rids[i].rid)) {
134 DEBUG(3, ("could not compose SID from additional group "
135 "rid 0x%x\n", info3->base.groups.rids[i].rid));
136 return NT_STATUS_INVALID_PARAMETER;
138 status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids);
139 if (!NT_STATUS_IS_OK(status)) {
140 DEBUG(3, ("could not append SID from additional group "
141 "rid 0x%x\n", info3->base.groups.rids[i].rid));
142 return status;
146 /* Copy 'other' sids. We need to do sid filtering here to
147 prevent possible elevation of privileges. See:
149 http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
152 for (i = 0; i < info3->sidcount; i++) {
154 if (sid_check_is_in_asserted_identity(info3->sids[i].sid)) {
155 continue;
158 status = add_sid_to_array(mem_ctx, info3->sids[i].sid,
159 &sid_array, &num_sids);
160 if (!NT_STATUS_IS_OK(status)) {
161 struct dom_sid_buf buf;
162 DEBUG(3, ("could not add SID to array: %s\n",
163 dom_sid_str_buf(info3->sids[i].sid, &buf)));
164 return status;
168 *user_sids = sid_array;
169 *num_user_sids = num_sids;
171 return NT_STATUS_OK;
174 bool security_token_find_npa_flags(const struct security_token *token,
175 uint32_t *_flags)
177 const struct dom_sid *npa_flags_sid = NULL;
178 size_t num_npa_sids;
180 num_npa_sids =
181 security_token_count_flag_sids(token,
182 &global_sid_Samba_NPA_Flags,
184 &npa_flags_sid);
185 if (num_npa_sids != 1) {
186 return false;
189 sid_peek_rid(npa_flags_sid, _flags);
190 return true;
193 void security_token_del_npa_flags(struct security_token *token)
195 const struct dom_sid *npa_flags_sid = NULL;
196 size_t num_npa_sids;
198 num_npa_sids =
199 security_token_count_flag_sids(token,
200 &global_sid_Samba_NPA_Flags,
202 &npa_flags_sid);
203 SMB_ASSERT(num_npa_sids == 1);
205 del_sid_from_array(npa_flags_sid, &token->sids, &token->num_sids);