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