domain.py: Add a schemaupgrade option to apply missing 2008R2 schema
[Samba.git] / auth / wbc_auth_util.c
blob52573e2a773b7216be55dd9d245dc3f52337a622
1 /*
2 Unix SMB/CIFS implementation.
3 Authentication utility functions
4 Copyright (C) Volker Lendecke 2010
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.
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.
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/>.
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"
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_AUTH
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)
37 unsigned int i, j = 0;
38 bool ok;
40 groups->rids = talloc_array(mem_ctx,
41 struct samr_RidWithAttribute, num_sids);
42 if (!groups->rids) {
43 return NT_STATUS_NO_MEMORY;
46 /* a wbcDomainSid is the same as a dom_sid */
47 for (i = 0; i < num_sids; i++) {
48 ok = sid_peek_check_rid(domain_sid,
49 (const struct dom_sid *)&sids[i].sid,
50 &groups->rids[j].rid);
51 if (!ok) continue;
53 groups->rids[j].attributes = SE_GROUP_MANDATORY |
54 SE_GROUP_ENABLED_BY_DEFAULT |
55 SE_GROUP_ENABLED;
56 j++;
59 groups->count = j;
60 return NT_STATUS_OK;
63 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)
71 unsigned int i, j = 0;
72 struct netr_SidAttr *info3_sids;
74 info3_sids = talloc_array(mem_ctx, struct netr_SidAttr, num_sids);
75 if (info3_sids == NULL) {
76 return NT_STATUS_NO_MEMORY;
79 /* a wbcDomainSid is the same as a dom_sid */
80 for (i = 0; i < num_sids; i++) {
81 const struct dom_sid *sid;
83 sid = (const struct dom_sid *)&sids[i].sid;
85 if (dom_sid_in_domain(domain_sid, sid)) {
86 continue;
89 info3_sids[j].sid = dom_sid_dup(info3_sids, sid);
90 if (info3_sids[j].sid == NULL) {
91 talloc_free(info3_sids);
92 return NT_STATUS_NO_MEMORY;
94 info3_sids[j].attributes = SE_GROUP_MANDATORY |
95 SE_GROUP_ENABLED_BY_DEFAULT |
96 SE_GROUP_ENABLED;
97 j++;
100 *info3_num_sids = j;
101 *_info3_sids = info3_sids;
102 return NT_STATUS_OK;
105 #undef RET_NOMEM
107 #define RET_NOMEM(ptr) do { \
108 if (!ptr) { \
109 TALLOC_FREE(info6); \
110 return NULL; \
111 } } while(0)
113 struct netr_SamInfo6 *wbcAuthUserInfo_to_netr_SamInfo6(TALLOC_CTX *mem_ctx,
114 const struct wbcAuthUserInfo *info)
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;
123 memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid));
124 memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid));
126 info6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
127 if (!info6) return NULL;
129 unix_to_nt_time(&info6->base.logon_time, info->logon_time);
130 unix_to_nt_time(&info6->base.logoff_time, info->logoff_time);
131 unix_to_nt_time(&info6->base.kickoff_time, info->kickoff_time);
132 unix_to_nt_time(&info6->base.last_password_change, info->pass_last_set_time);
133 unix_to_nt_time(&info6->base.allow_password_change,
134 info->pass_can_change_time);
135 unix_to_nt_time(&info6->base.force_password_change,
136 info->pass_must_change_time);
138 if (info->account_name) {
139 info6->base.account_name.string =
140 talloc_strdup(info6, info->account_name);
141 RET_NOMEM(info6->base.account_name.string);
143 if (info->user_principal) {
144 info6->principal_name.string =
145 talloc_strdup(info6, info->user_principal);
146 RET_NOMEM(info6->principal_name.string);
148 if (info->full_name) {
149 info6->base.full_name.string =
150 talloc_strdup(info6, info->full_name);
151 RET_NOMEM(info6->base.full_name.string);
153 if (info->domain_name) {
154 info6->base.logon_domain.string =
155 talloc_strdup(info6, info->domain_name);
156 RET_NOMEM(info6->base.logon_domain.string);
158 if (info->dns_domain_name) {
159 info6->dns_domainname.string =
160 talloc_strdup(info6, info->dns_domain_name);
161 RET_NOMEM(info6->dns_domainname.string);
163 if (info->logon_script) {
164 info6->base.logon_script.string =
165 talloc_strdup(info6, info->logon_script);
166 RET_NOMEM(info6->base.logon_script.string);
168 if (info->profile_path) {
169 info6->base.profile_path.string =
170 talloc_strdup(info6, info->profile_path);
171 RET_NOMEM(info6->base.profile_path.string);
173 if (info->home_directory) {
174 info6->base.home_directory.string =
175 talloc_strdup(info6, info->home_directory);
176 RET_NOMEM(info6->base.home_directory.string);
178 if (info->home_drive) {
179 info6->base.home_drive.string =
180 talloc_strdup(info6, info->home_drive);
181 RET_NOMEM(info6->base.home_drive.string);
184 info6->base.logon_count = info->logon_count;
185 info6->base.bad_password_count = info->bad_password_count;
187 sid_copy(&domain_sid, &user_sid);
188 sid_split_rid(&domain_sid, &info6->base.rid);
190 ok = sid_peek_check_rid(&domain_sid, &group_sid,
191 &info6->base.primary_gid);
192 if (!ok) {
193 DEBUG(1, ("The primary group sid domain does not"
194 "match user sid domain for user: %s\n",
195 info->account_name));
196 TALLOC_FREE(info6);
197 return NULL;
200 status = wbcsids_to_samr_RidWithAttributeArray(info6,
201 &info6->base.groups,
202 &domain_sid,
203 &info->sids[1],
204 info->num_sids - 1);
205 if (!NT_STATUS_IS_OK(status)) {
206 TALLOC_FREE(info6);
207 return NULL;
210 status = wbcsids_to_netr_SidAttrArray(&domain_sid,
211 &info->sids[1],
212 info->num_sids - 1,
213 info6,
214 &info6->sids,
215 &info6->sidcount);
216 if (!NT_STATUS_IS_OK(status)) {
217 TALLOC_FREE(info6);
218 return NULL;
221 info6->base.user_flags = info->user_flags;
222 memcpy(info6->base.key.key, info->user_session_key, 16);
224 if (info->logon_server) {
225 info6->base.logon_server.string =
226 talloc_strdup(info6, info->logon_server);
227 RET_NOMEM(info6->base.logon_server.string);
229 if (info->domain_name) {
230 info6->base.logon_domain.string =
231 talloc_strdup(info6, info->domain_name);
232 RET_NOMEM(info6->base.logon_domain.string);
235 info6->base.domain_sid = dom_sid_dup(info6, &domain_sid);
236 RET_NOMEM(info6->base.domain_sid);
238 memcpy(info6->base.LMSessKey.key, info->lm_session_key, 8);
239 info6->base.acct_flags = info->acct_flags;
241 return info6;