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 14913 : char *sid_to_fstring(fstring sidstr_out, const struct dom_sid *sid)
38 : {
39 52 : struct dom_sid_buf buf;
40 14913 : fstrcpy(sidstr_out, dom_sid_str_buf(sid, &buf));
41 14913 : return sidstr_out;
42 : }
43 :
44 : /*****************************************************************
45 : Write a sid out into on-the-wire format.
46 : *****************************************************************/
47 :
48 344 : bool sid_linearize(uint8_t *outbuf, size_t len, const struct dom_sid *sid)
49 : {
50 344 : struct ndr_push ndr = {
51 : .data = outbuf, .alloc_size = len, .fixed_buf_size = true,
52 : };
53 0 : enum ndr_err_code ndr_err;
54 :
55 344 : ndr_err = ndr_push_dom_sid(&ndr, NDR_SCALARS|NDR_BUFFERS, sid);
56 344 : return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
57 : }
58 :
59 : /*****************************************************************
60 : Returns true if SID is internal (and non-mappable).
61 : *****************************************************************/
62 :
63 248 : bool non_mappable_sid(struct dom_sid *sid)
64 : {
65 0 : struct dom_sid dom;
66 :
67 248 : sid_copy(&dom, sid);
68 248 : sid_split_rid(&dom, NULL);
69 :
70 248 : if (dom_sid_equal(&dom, &global_sid_Builtin))
71 4 : return True;
72 :
73 244 : if (dom_sid_equal(&dom, &global_sid_NT_Authority))
74 4 : return True;
75 :
76 240 : 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 66 : 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 0 : NTSTATUS status;
99 0 : struct dom_sid sid;
100 66 : struct dom_sid *sid_array = NULL;
101 66 : uint32_t num_sids = 0;
102 0 : uint32_t i;
103 :
104 66 : 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 66 : 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 66 : status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids);
124 66 : 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 202 : for (i = 0; i < info3->base.groups.count; i++) {
131 : /* Don't add the primary group sid twice. */
132 136 : if (!sid_compose(&sid, info3->base.domain_sid,
133 136 : info3->base.groups.rids[i].rid)) {
134 0 : DEBUG(3, ("could not compose SID from additional group "
135 : "rid 0x%x\n", info3->base.groups.rids[i].rid));
136 0 : return NT_STATUS_INVALID_PARAMETER;
137 : }
138 136 : status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids);
139 136 : if (!NT_STATUS_IS_OK(status)) {
140 0 : DEBUG(3, ("could not append SID from additional group "
141 : "rid 0x%x\n", info3->base.groups.rids[i].rid));
142 0 : return status;
143 : }
144 : }
145 :
146 : /* Copy 'other' sids. We need to do sid filtering here to
147 : prevent possible elevation of privileges. See:
148 :
149 : http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
150 : */
151 :
152 98 : for (i = 0; i < info3->sidcount; i++) {
153 :
154 32 : if (sid_check_is_in_asserted_identity(info3->sids[i].sid)) {
155 10 : continue;
156 : }
157 :
158 22 : status = add_sid_to_array(mem_ctx, info3->sids[i].sid,
159 : &sid_array, &num_sids);
160 22 : if (!NT_STATUS_IS_OK(status)) {
161 0 : struct dom_sid_buf buf;
162 0 : DEBUG(3, ("could not add SID to array: %s\n",
163 : dom_sid_str_buf(info3->sids[i].sid, &buf)));
164 0 : return status;
165 : }
166 : }
167 :
168 66 : *user_sids = sid_array;
169 66 : *num_user_sids = num_sids;
170 :
171 66 : return NT_STATUS_OK;
172 : }
173 :
174 71348 : bool security_token_find_npa_flags(const struct security_token *token,
175 : uint32_t *_flags)
176 : {
177 71348 : const struct dom_sid *npa_flags_sid = NULL;
178 0 : size_t num_npa_sids;
179 :
180 0 : num_npa_sids =
181 71348 : security_token_count_flag_sids(token,
182 : &global_sid_Samba_NPA_Flags,
183 : 1,
184 : &npa_flags_sid);
185 71348 : if (num_npa_sids != 1) {
186 1705 : return false;
187 : }
188 :
189 69643 : sid_peek_rid(npa_flags_sid, _flags);
190 69643 : return true;
191 : }
192 :
193 33889 : void security_token_del_npa_flags(struct security_token *token)
194 : {
195 33889 : const struct dom_sid *npa_flags_sid = NULL;
196 0 : size_t num_npa_sids;
197 :
198 0 : num_npa_sids =
199 33889 : security_token_count_flag_sids(token,
200 : &global_sid_Samba_NPA_Flags,
201 : 1,
202 : &npa_flags_sid);
203 33889 : SMB_ASSERT(num_npa_sids == 1);
204 :
205 33889 : del_sid_from_array(npa_flags_sid, &token->sids, &token->num_sids);
206 33889 : }
|