Line data Source code
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
10 :
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.
15 :
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.
20 :
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/>.
23 : */
24 :
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"
31 :
32 :
33 : /*****************************************************************
34 : Convert a SID to an ascii string.
35 : *****************************************************************/
36 :
37 4194 : char *sid_to_fstring(fstring sidstr_out, const struct dom_sid *sid)
38 : {
39 : struct dom_sid_buf buf;
40 4194 : fstrcpy(sidstr_out, dom_sid_str_buf(sid, &buf));
41 4194 : return sidstr_out;
42 : }
43 :
44 : /*****************************************************************
45 : Write a sid out into on-the-wire format.
46 : *****************************************************************/
47 :
48 98 : bool sid_linearize(uint8_t *outbuf, size_t len, const struct dom_sid *sid)
49 : {
50 98 : struct ndr_push ndr = {
51 : .data = outbuf, .alloc_size = len, .fixed_buf_size = true,
52 : };
53 : enum ndr_err_code ndr_err;
54 :
55 98 : ndr_err = ndr_push_dom_sid(&ndr, NDR_SCALARS|NDR_BUFFERS, sid);
56 98 : return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
57 : }
58 :
59 : /*****************************************************************
60 : Returns true if SID is internal (and non-mappable).
61 : *****************************************************************/
62 :
63 6 : bool non_mappable_sid(struct dom_sid *sid)
64 : {
65 : struct dom_sid dom;
66 :
67 6 : sid_copy(&dom, sid);
68 6 : sid_split_rid(&dom, NULL);
69 :
70 6 : if (dom_sid_equal(&dom, &global_sid_Builtin))
71 0 : return True;
72 :
73 6 : if (dom_sid_equal(&dom, &global_sid_NT_Authority))
74 0 : return True;
75 :
76 6 : return False;
77 : }
78 :
79 : /*****************************************************************
80 : Return the binary string representation of a struct dom_sid.
81 : Caller must free.
82 : *****************************************************************/
83 :
84 0 : char *sid_binstring_hex_talloc(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
85 0 : {
86 0 : int len = ndr_size_dom_sid(sid, 0);
87 0 : uint8_t buf[len];
88 0 : sid_linearize(buf, len, sid);
89 0 : return hex_encode_talloc(mem_ctx, buf, len);
90 : }
91 :
92 62 : 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)
97 : {
98 : NTSTATUS status;
99 : struct dom_sid sid;
100 62 : struct dom_sid *sid_array = NULL;
101 62 : uint32_t num_sids = 0;
102 : uint32_t i;
103 :
104 62 : if (include_user_group_rid) {
105 4 : if (!sid_compose(&sid, info3->base.domain_sid, info3->base.rid)) {
106 0 : DEBUG(3, ("could not compose user SID from rid 0x%x\n",
107 : info3->base.rid));
108 0 : return NT_STATUS_INVALID_PARAMETER;
109 : }
110 4 : status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids);
111 4 : if (!NT_STATUS_IS_OK(status)) {
112 0 : DEBUG(3, ("could not append user SID from rid 0x%x\n",
113 : info3->base.rid));
114 0 : return status;
115 : }
116 : }
117 :
118 62 : if (!sid_compose(&sid, info3->base.domain_sid, info3->base.primary_gid)) {
119 0 : DEBUG(3, ("could not compose group SID from rid 0x%x\n",
120 : info3->base.primary_gid));
121 0 : return NT_STATUS_INVALID_PARAMETER;
122 : }
123 62 : status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids);
124 62 : if (!NT_STATUS_IS_OK(status)) {
125 0 : DEBUG(3, ("could not append group SID from rid 0x%x\n",
126 : info3->base.rid));
127 0 : return status;
128 : }
129 :
130 244 : for (i = 0; i < info3->base.groups.count; i++) {
131 : /* Don't add the primary group sid twice. */
132 182 : if (info3->base.primary_gid == info3->base.groups.rids[i].rid) {
133 22 : continue;
134 : }
135 160 : if (!sid_compose(&sid, info3->base.domain_sid,
136 160 : info3->base.groups.rids[i].rid)) {
137 0 : DEBUG(3, ("could not compose SID from additional group "
138 : "rid 0x%x\n", info3->base.groups.rids[i].rid));
139 0 : return NT_STATUS_INVALID_PARAMETER;
140 : }
141 160 : status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids);
142 160 : if (!NT_STATUS_IS_OK(status)) {
143 0 : DEBUG(3, ("could not append SID from additional group "
144 : "rid 0x%x\n", info3->base.groups.rids[i].rid));
145 0 : return status;
146 : }
147 : }
148 :
149 : /* Copy 'other' sids. We need to do sid filtering here to
150 : prevent possible elevation of privileges. See:
151 :
152 : http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
153 : */
154 :
155 67 : for (i = 0; i < info3->sidcount; i++) {
156 :
157 5 : if (sid_check_is_in_asserted_identity(info3->sids[i].sid)) {
158 5 : continue;
159 : }
160 :
161 0 : status = add_sid_to_array(mem_ctx, info3->sids[i].sid,
162 : &sid_array, &num_sids);
163 0 : if (!NT_STATUS_IS_OK(status)) {
164 : struct dom_sid_buf buf;
165 0 : DEBUG(3, ("could not add SID to array: %s\n",
166 : dom_sid_str_buf(info3->sids[i].sid, &buf)));
167 0 : return status;
168 : }
169 : }
170 :
171 62 : *user_sids = sid_array;
172 62 : *num_user_sids = num_sids;
173 :
174 62 : return NT_STATUS_OK;
175 : }
176 :
177 1583 : bool security_token_find_npa_flags(const struct security_token *token,
178 : uint32_t *_flags)
179 : {
180 1583 : const struct dom_sid *npa_flags_sid = NULL;
181 : size_t num_npa_sids;
182 :
183 874 : num_npa_sids =
184 709 : security_token_count_flag_sids(token,
185 : &global_sid_Samba_NPA_Flags,
186 : 1,
187 : &npa_flags_sid);
188 1583 : if (num_npa_sids != 1) {
189 765 : return false;
190 : }
191 :
192 818 : sid_peek_rid(npa_flags_sid, _flags);
193 818 : return true;
194 : }
195 :
196 281 : void security_token_del_npa_flags(struct security_token *token)
197 : {
198 281 : const struct dom_sid *npa_flags_sid = NULL;
199 : size_t num_npa_sids;
200 :
201 169 : num_npa_sids =
202 112 : security_token_count_flag_sids(token,
203 : &global_sid_Samba_NPA_Flags,
204 : 1,
205 : &npa_flags_sid);
206 281 : SMB_ASSERT(num_npa_sids == 1);
207 :
208 281 : del_sid_from_array(npa_flags_sid, &token->sids, &token->num_sids);
209 281 : }
|