Line data Source code
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 : #define DBGC_CLASS DBGC_AUTH
29 :
30 1097 : 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 : {
37 1097 : unsigned int i, j = 0;
38 0 : bool ok;
39 :
40 1097 : groups->rids = talloc_array(mem_ctx,
41 : struct samr_RidWithAttribute, num_sids);
42 1097 : if (!groups->rids) {
43 0 : return NT_STATUS_NO_MEMORY;
44 : }
45 :
46 : /* a wbcDomainSid is the same as a dom_sid */
47 9267 : for (i = 0; i < num_sids; i++) {
48 8170 : ok = sid_peek_check_rid(domain_sid,
49 8170 : (const struct dom_sid *)&sids[i].sid,
50 8170 : &groups->rids[j].rid);
51 8170 : if (!ok) continue;
52 :
53 6688 : groups->rids[j].attributes = SE_GROUP_DEFAULT_FLAGS;
54 6688 : j++;
55 : }
56 :
57 1097 : groups->count = j;
58 1097 : return NT_STATUS_OK;
59 : }
60 :
61 1097 : 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 : {
69 1097 : unsigned int i, j = 0;
70 0 : struct netr_SidAttr *info3_sids;
71 :
72 1097 : info3_sids = talloc_array(mem_ctx, struct netr_SidAttr, num_sids);
73 1097 : if (info3_sids == NULL) {
74 0 : return NT_STATUS_NO_MEMORY;
75 : }
76 :
77 : /* a wbcDomainSid is the same as a dom_sid */
78 9267 : for (i = 0; i < num_sids; i++) {
79 0 : const struct dom_sid *sid;
80 :
81 8170 : sid = (const struct dom_sid *)&sids[i].sid;
82 :
83 8170 : if (dom_sid_in_domain(domain_sid, sid)) {
84 6688 : continue;
85 : }
86 :
87 1482 : info3_sids[j].sid = dom_sid_dup(info3_sids, sid);
88 1482 : if (info3_sids[j].sid == NULL) {
89 0 : talloc_free(info3_sids);
90 0 : return NT_STATUS_NO_MEMORY;
91 : }
92 1482 : info3_sids[j].attributes = SE_GROUP_DEFAULT_FLAGS;
93 1482 : j++;
94 : }
95 :
96 1097 : *info3_num_sids = j;
97 1097 : *_info3_sids = info3_sids;
98 1097 : return NT_STATUS_OK;
99 : }
100 :
101 : #undef RET_NOMEM
102 :
103 : #define RET_NOMEM(ptr) do { \
104 : if (!ptr) { \
105 : TALLOC_FREE(info6); \
106 : return NULL; \
107 : } } while(0)
108 :
109 1097 : struct netr_SamInfo6 *wbcAuthUserInfo_to_netr_SamInfo6(TALLOC_CTX *mem_ctx,
110 : const struct wbcAuthUserInfo *info)
111 : {
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 1097 : memcpy(&user_sid, &info->sids[PRIMARY_USER_SID_INDEX].sid, sizeof(user_sid));
120 1097 : memcpy(&group_sid, &info->sids[PRIMARY_GROUP_SID_INDEX].sid, sizeof(group_sid));
121 :
122 1097 : info6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
123 1097 : if (!info6) return NULL;
124 :
125 1097 : unix_to_nt_time(&info6->base.logon_time, info->logon_time);
126 1097 : unix_to_nt_time(&info6->base.logoff_time, info->logoff_time);
127 1097 : unix_to_nt_time(&info6->base.kickoff_time, info->kickoff_time);
128 1097 : unix_to_nt_time(&info6->base.last_password_change, info->pass_last_set_time);
129 1097 : unix_to_nt_time(&info6->base.allow_password_change,
130 1097 : info->pass_can_change_time);
131 1097 : unix_to_nt_time(&info6->base.force_password_change,
132 1097 : info->pass_must_change_time);
133 :
134 1097 : if (info->account_name) {
135 1097 : info6->base.account_name.string =
136 1097 : talloc_strdup(info6, info->account_name);
137 1097 : RET_NOMEM(info6->base.account_name.string);
138 : }
139 1097 : if (info->user_principal) {
140 1024 : info6->principal_name.string =
141 1024 : talloc_strdup(info6, info->user_principal);
142 1024 : RET_NOMEM(info6->principal_name.string);
143 : }
144 1097 : if (info->full_name) {
145 1097 : info6->base.full_name.string =
146 1097 : talloc_strdup(info6, info->full_name);
147 1097 : RET_NOMEM(info6->base.full_name.string);
148 : }
149 1097 : if (info->domain_name) {
150 1097 : info6->base.logon_domain.string =
151 1097 : talloc_strdup(info6, info->domain_name);
152 1097 : RET_NOMEM(info6->base.logon_domain.string);
153 : }
154 1097 : if (info->dns_domain_name) {
155 1024 : info6->dns_domainname.string =
156 1024 : talloc_strdup(info6, info->dns_domain_name);
157 1024 : RET_NOMEM(info6->dns_domainname.string);
158 : }
159 1097 : if (info->logon_script) {
160 1097 : info6->base.logon_script.string =
161 1097 : talloc_strdup(info6, info->logon_script);
162 1097 : RET_NOMEM(info6->base.logon_script.string);
163 : }
164 1097 : if (info->profile_path) {
165 1097 : info6->base.profile_path.string =
166 1097 : talloc_strdup(info6, info->profile_path);
167 1097 : RET_NOMEM(info6->base.profile_path.string);
168 : }
169 1097 : if (info->home_directory) {
170 1097 : info6->base.home_directory.string =
171 1097 : talloc_strdup(info6, info->home_directory);
172 1097 : RET_NOMEM(info6->base.home_directory.string);
173 : }
174 1097 : if (info->home_drive) {
175 1097 : info6->base.home_drive.string =
176 1097 : talloc_strdup(info6, info->home_drive);
177 1097 : RET_NOMEM(info6->base.home_drive.string);
178 : }
179 :
180 1097 : info6->base.logon_count = info->logon_count;
181 1097 : info6->base.bad_password_count = info->bad_password_count;
182 :
183 1097 : sid_copy(&domain_sid, &user_sid);
184 1097 : sid_split_rid(&domain_sid, &info6->base.rid);
185 :
186 1097 : ok = sid_peek_check_rid(&domain_sid, &group_sid,
187 : &info6->base.primary_gid);
188 1097 : if (!ok) {
189 0 : DEBUG(1, ("The primary group sid domain does not"
190 : "match user sid domain for user: %s\n",
191 : info->account_name));
192 0 : TALLOC_FREE(info6);
193 0 : return NULL;
194 : }
195 :
196 1097 : status = wbcsids_to_samr_RidWithAttributeArray(info6,
197 : &info6->base.groups,
198 : &domain_sid,
199 1097 : &info->sids[PRIMARY_GROUP_SID_INDEX],
200 1097 : info->num_sids - 1);
201 1097 : if (!NT_STATUS_IS_OK(status)) {
202 0 : TALLOC_FREE(info6);
203 0 : return NULL;
204 : }
205 :
206 1097 : status = wbcsids_to_netr_SidAttrArray(&domain_sid,
207 1097 : &info->sids[PRIMARY_GROUP_SID_INDEX],
208 1097 : info->num_sids - 1,
209 : info6,
210 : &info6->sids,
211 : &info6->sidcount);
212 1097 : if (!NT_STATUS_IS_OK(status)) {
213 0 : TALLOC_FREE(info6);
214 0 : return NULL;
215 : }
216 :
217 1097 : info6->base.user_flags = info->user_flags;
218 1097 : memcpy(info6->base.key.key, info->user_session_key, 16);
219 :
220 1097 : if (info->logon_server) {
221 1097 : info6->base.logon_server.string =
222 1097 : talloc_strdup(info6, info->logon_server);
223 1097 : RET_NOMEM(info6->base.logon_server.string);
224 : }
225 1097 : if (info->domain_name) {
226 1097 : info6->base.logon_domain.string =
227 1097 : talloc_strdup(info6, info->domain_name);
228 1097 : RET_NOMEM(info6->base.logon_domain.string);
229 : }
230 :
231 1097 : info6->base.domain_sid = dom_sid_dup(info6, &domain_sid);
232 1097 : RET_NOMEM(info6->base.domain_sid);
233 :
234 1097 : memcpy(info6->base.LMSessKey.key, info->lm_session_key, 8);
235 1097 : info6->base.acct_flags = info->acct_flags;
236 :
237 1097 : return info6;
238 : }
|