/src/samba/auth/wbc_auth_util.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | Unix SMB/CIFS implementation. |
3 | | Authentication utility functions |
4 | | Copyright (C) Volker Lendecke 2010 |
5 | | |
6 | | This program is free software; you can redistribute it and/or modify |
7 | | it under the terms of the GNU General Public License as published by |
8 | | the Free Software Foundation; either version 3 of the License, or |
9 | | (at your option) any later version. |
10 | | |
11 | | This program is distributed in the hope that it will be useful, |
12 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | GNU General Public License for more details. |
15 | | |
16 | | You should have received a copy of the GNU General Public License |
17 | | along with this program. If not, see <http://www.gnu.org/licenses/>. |
18 | | */ |
19 | | |
20 | | #include "includes.h" |
21 | | #include "libcli/security/security.h" |
22 | | #include "librpc/gen_ndr/netlogon.h" |
23 | | #include "nsswitch/libwbclient/wbclient.h" |
24 | | #include "librpc/gen_ndr/auth.h" |
25 | | #include "auth/auth_sam_reply.h" |
26 | | |
27 | | #undef DBGC_CLASS |
28 | 0 | #define DBGC_CLASS DBGC_AUTH |
29 | | |
30 | | static NTSTATUS wbcsids_to_samr_RidWithAttributeArray( |
31 | | TALLOC_CTX *mem_ctx, |
32 | | struct samr_RidWithAttributeArray *groups, |
33 | | const struct dom_sid *domain_sid, |
34 | | const struct wbcSidWithAttr *sids, |
35 | | size_t num_sids) |
36 | 0 | { |
37 | 0 | unsigned int i, j = 0; |
38 | 0 | bool ok; |
39 | |
|
40 | 0 | groups->rids = talloc_array(mem_ctx, |
41 | 0 | struct samr_RidWithAttribute, num_sids); |
42 | 0 | if (!groups->rids) { |
43 | 0 | return NT_STATUS_NO_MEMORY; |
44 | 0 | } |
45 | | |
46 | | /* a wbcDomainSid is the same as a dom_sid */ |
47 | 0 | for (i = 0; i < num_sids; i++) { |
48 | 0 | ok = sid_peek_check_rid(domain_sid, |
49 | 0 | (const struct dom_sid *)&sids[i].sid, |
50 | 0 | &groups->rids[j].rid); |
51 | 0 | if (!ok) continue; |
52 | | |
53 | 0 | groups->rids[j].attributes = SE_GROUP_DEFAULT_FLAGS; |
54 | 0 | j++; |
55 | 0 | } |
56 | |
|
57 | 0 | groups->count = j; |
58 | 0 | return NT_STATUS_OK; |
59 | 0 | } |
60 | | |
61 | | static NTSTATUS wbcsids_to_netr_SidAttrArray( |
62 | | const struct dom_sid *domain_sid, |
63 | | const struct wbcSidWithAttr *sids, |
64 | | size_t num_sids, |
65 | | TALLOC_CTX *mem_ctx, |
66 | | struct netr_SidAttr **_info3_sids, |
67 | | uint32_t *info3_num_sids) |
68 | 0 | { |
69 | 0 | unsigned int i, j = 0; |
70 | 0 | struct netr_SidAttr *info3_sids; |
71 | |
|
72 | 0 | info3_sids = talloc_array(mem_ctx, struct netr_SidAttr, num_sids); |
73 | 0 | if (info3_sids == NULL) { |
74 | 0 | return NT_STATUS_NO_MEMORY; |
75 | 0 | } |
76 | | |
77 | | /* a wbcDomainSid is the same as a dom_sid */ |
78 | 0 | for (i = 0; i < num_sids; i++) { |
79 | 0 | const struct dom_sid *sid; |
80 | |
|
81 | 0 | sid = (const struct dom_sid *)&sids[i].sid; |
82 | |
|
83 | 0 | if (dom_sid_in_domain(domain_sid, sid)) { |
84 | 0 | continue; |
85 | 0 | } |
86 | | |
87 | 0 | info3_sids[j].sid = dom_sid_dup(info3_sids, sid); |
88 | 0 | if (info3_sids[j].sid == NULL) { |
89 | 0 | talloc_free(info3_sids); |
90 | 0 | return NT_STATUS_NO_MEMORY; |
91 | 0 | } |
92 | 0 | info3_sids[j].attributes = SE_GROUP_DEFAULT_FLAGS; |
93 | 0 | j++; |
94 | 0 | } |
95 | | |
96 | 0 | *info3_num_sids = j; |
97 | 0 | *_info3_sids = info3_sids; |
98 | 0 | return NT_STATUS_OK; |
99 | 0 | } |
100 | | |
101 | | #undef RET_NOMEM |
102 | | |
103 | 0 | #define RET_NOMEM(ptr) do { \ |
104 | 0 | if (!ptr) { \ |
105 | 0 | TALLOC_FREE(info6); \ |
106 | 0 | return NULL; \ |
107 | 0 | } } while(0) |
108 | | |
109 | | struct netr_SamInfo6 *wbcAuthUserInfo_to_netr_SamInfo6(TALLOC_CTX *mem_ctx, |
110 | | const struct wbcAuthUserInfo *info) |
111 | 0 | { |
112 | 0 | struct netr_SamInfo6 *info6; |
113 | 0 | struct dom_sid user_sid; |
114 | 0 | struct dom_sid group_sid; |
115 | 0 | struct dom_sid domain_sid; |
116 | 0 | NTSTATUS status; |
117 | 0 | bool ok; |
118 | |
|
119 | 0 | memcpy(&user_sid, &info->sids[PRIMARY_USER_SID_INDEX].sid, sizeof(user_sid)); |
120 | 0 | memcpy(&group_sid, &info->sids[PRIMARY_GROUP_SID_INDEX].sid, sizeof(group_sid)); |
121 | |
|
122 | 0 | info6 = talloc_zero(mem_ctx, struct netr_SamInfo6); |
123 | 0 | if (!info6) return NULL; |
124 | | |
125 | 0 | unix_to_nt_time(&info6->base.logon_time, info->logon_time); |
126 | 0 | unix_to_nt_time(&info6->base.logoff_time, info->logoff_time); |
127 | 0 | unix_to_nt_time(&info6->base.kickoff_time, info->kickoff_time); |
128 | 0 | unix_to_nt_time(&info6->base.last_password_change, info->pass_last_set_time); |
129 | 0 | unix_to_nt_time(&info6->base.allow_password_change, |
130 | 0 | info->pass_can_change_time); |
131 | 0 | unix_to_nt_time(&info6->base.force_password_change, |
132 | 0 | info->pass_must_change_time); |
133 | |
|
134 | 0 | if (info->account_name) { |
135 | 0 | info6->base.account_name.string = |
136 | 0 | talloc_strdup(info6, info->account_name); |
137 | 0 | RET_NOMEM(info6->base.account_name.string); |
138 | 0 | } |
139 | 0 | if (info->user_principal) { |
140 | 0 | info6->principal_name.string = |
141 | 0 | talloc_strdup(info6, info->user_principal); |
142 | 0 | RET_NOMEM(info6->principal_name.string); |
143 | 0 | } |
144 | 0 | if (info->full_name) { |
145 | 0 | info6->base.full_name.string = |
146 | 0 | talloc_strdup(info6, info->full_name); |
147 | 0 | RET_NOMEM(info6->base.full_name.string); |
148 | 0 | } |
149 | 0 | if (info->domain_name) { |
150 | 0 | info6->base.logon_domain.string = |
151 | 0 | talloc_strdup(info6, info->domain_name); |
152 | 0 | RET_NOMEM(info6->base.logon_domain.string); |
153 | 0 | } |
154 | 0 | if (info->dns_domain_name) { |
155 | 0 | info6->dns_domainname.string = |
156 | 0 | talloc_strdup(info6, info->dns_domain_name); |
157 | 0 | RET_NOMEM(info6->dns_domainname.string); |
158 | 0 | } |
159 | 0 | if (info->logon_script) { |
160 | 0 | info6->base.logon_script.string = |
161 | 0 | talloc_strdup(info6, info->logon_script); |
162 | 0 | RET_NOMEM(info6->base.logon_script.string); |
163 | 0 | } |
164 | 0 | if (info->profile_path) { |
165 | 0 | info6->base.profile_path.string = |
166 | 0 | talloc_strdup(info6, info->profile_path); |
167 | 0 | RET_NOMEM(info6->base.profile_path.string); |
168 | 0 | } |
169 | 0 | if (info->home_directory) { |
170 | 0 | info6->base.home_directory.string = |
171 | 0 | talloc_strdup(info6, info->home_directory); |
172 | 0 | RET_NOMEM(info6->base.home_directory.string); |
173 | 0 | } |
174 | 0 | if (info->home_drive) { |
175 | 0 | info6->base.home_drive.string = |
176 | 0 | talloc_strdup(info6, info->home_drive); |
177 | 0 | RET_NOMEM(info6->base.home_drive.string); |
178 | 0 | } |
179 | | |
180 | 0 | info6->base.logon_count = info->logon_count; |
181 | 0 | info6->base.bad_password_count = info->bad_password_count; |
182 | |
|
183 | 0 | sid_copy(&domain_sid, &user_sid); |
184 | 0 | sid_split_rid(&domain_sid, &info6->base.rid); |
185 | |
|
186 | 0 | ok = sid_peek_check_rid(&domain_sid, &group_sid, |
187 | 0 | &info6->base.primary_gid); |
188 | 0 | if (!ok) { |
189 | 0 | DEBUG(1, ("The primary group sid domain does not" |
190 | 0 | "match user sid domain for user: %s\n", |
191 | 0 | info->account_name)); |
192 | 0 | TALLOC_FREE(info6); |
193 | 0 | return NULL; |
194 | 0 | } |
195 | | |
196 | 0 | status = wbcsids_to_samr_RidWithAttributeArray(info6, |
197 | 0 | &info6->base.groups, |
198 | 0 | &domain_sid, |
199 | 0 | &info->sids[PRIMARY_GROUP_SID_INDEX], |
200 | 0 | info->num_sids - 1); |
201 | 0 | if (!NT_STATUS_IS_OK(status)) { |
202 | 0 | TALLOC_FREE(info6); |
203 | 0 | return NULL; |
204 | 0 | } |
205 | | |
206 | 0 | status = wbcsids_to_netr_SidAttrArray(&domain_sid, |
207 | 0 | &info->sids[PRIMARY_GROUP_SID_INDEX], |
208 | 0 | info->num_sids - 1, |
209 | 0 | info6, |
210 | 0 | &info6->sids, |
211 | 0 | &info6->sidcount); |
212 | 0 | if (!NT_STATUS_IS_OK(status)) { |
213 | 0 | TALLOC_FREE(info6); |
214 | 0 | return NULL; |
215 | 0 | } |
216 | | |
217 | 0 | info6->base.user_flags = info->user_flags; |
218 | 0 | memcpy(info6->base.key.key, info->user_session_key, 16); |
219 | |
|
220 | 0 | if (info->logon_server) { |
221 | 0 | info6->base.logon_server.string = |
222 | 0 | talloc_strdup(info6, info->logon_server); |
223 | 0 | RET_NOMEM(info6->base.logon_server.string); |
224 | 0 | } |
225 | 0 | if (info->domain_name) { |
226 | 0 | info6->base.logon_domain.string = |
227 | 0 | talloc_strdup(info6, info->domain_name); |
228 | 0 | RET_NOMEM(info6->base.logon_domain.string); |
229 | 0 | } |
230 | | |
231 | 0 | info6->base.domain_sid = dom_sid_dup(info6, &domain_sid); |
232 | 0 | RET_NOMEM(info6->base.domain_sid); |
233 | | |
234 | 0 | memcpy(info6->base.LMSessKey.key, info->lm_session_key, 8); |
235 | 0 | info6->base.acct_flags = info->acct_flags; |
236 | |
|
237 | 0 | return info6; |
238 | 0 | } |