autorid: Add allocation from above in alloc range for well known sids
[Samba/wip.git] / auth / wbc_auth_util.c
blobebd24a967abb6d50ff713239574842204c742d92
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"
25 #undef DBGC_CLASS
26 #define DBGC_CLASS DBGC_AUTH
28 static NTSTATUS wbcsids_to_samr_RidWithAttributeArray(
29 TALLOC_CTX *mem_ctx,
30 struct samr_RidWithAttributeArray *groups,
31 const struct dom_sid *domain_sid,
32 const struct wbcSidWithAttr *sids,
33 size_t num_sids)
35 unsigned int i, j = 0;
36 bool ok;
38 groups->rids = talloc_array(mem_ctx,
39 struct samr_RidWithAttribute, num_sids);
40 if (!groups->rids) {
41 return NT_STATUS_NO_MEMORY;
44 /* a wbcDomainSid is the same as a dom_sid */
45 for (i = 0; i < num_sids; i++) {
46 ok = sid_peek_check_rid(domain_sid,
47 (const struct dom_sid *)&sids[i].sid,
48 &groups->rids[j].rid);
49 if (!ok) continue;
51 groups->rids[j].attributes = SE_GROUP_MANDATORY |
52 SE_GROUP_ENABLED_BY_DEFAULT |
53 SE_GROUP_ENABLED;
54 j++;
57 groups->count = j;
58 return NT_STATUS_OK;
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)
69 unsigned int i, j = 0;
70 struct netr_SidAttr *info3_sids;
72 info3_sids = talloc_array(mem_ctx, struct netr_SidAttr, num_sids);
73 if (info3_sids == NULL) {
74 return NT_STATUS_NO_MEMORY;
77 /* a wbcDomainSid is the same as a dom_sid */
78 for (i = 0; i < num_sids; i++) {
79 const struct dom_sid *sid;
81 sid = (const struct dom_sid *)&sids[i].sid;
83 if (dom_sid_in_domain(domain_sid, sid)) {
84 continue;
87 info3_sids[j].sid = dom_sid_dup(info3_sids, sid);
88 if (info3_sids[j].sid == NULL) {
89 talloc_free(info3_sids);
90 return NT_STATUS_NO_MEMORY;
92 info3_sids[j].attributes = SE_GROUP_MANDATORY |
93 SE_GROUP_ENABLED_BY_DEFAULT |
94 SE_GROUP_ENABLED;
95 j++;
98 *info3_num_sids = j;
99 *_info3_sids = info3_sids;
100 return NT_STATUS_OK;
103 #undef RET_NOMEM
105 #define RET_NOMEM(ptr) do { \
106 if (!ptr) { \
107 TALLOC_FREE(info3); \
108 return NULL; \
109 } } while(0)
111 struct netr_SamInfo3 *wbcAuthUserInfo_to_netr_SamInfo3(TALLOC_CTX *mem_ctx,
112 const struct wbcAuthUserInfo *info)
114 struct netr_SamInfo3 *info3;
115 struct dom_sid user_sid;
116 struct dom_sid group_sid;
117 struct dom_sid domain_sid;
118 NTSTATUS status;
119 bool ok;
121 memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid));
122 memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid));
124 info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
125 if (!info3) return NULL;
127 unix_to_nt_time(&info3->base.logon_time, info->logon_time);
128 unix_to_nt_time(&info3->base.logoff_time, info->logoff_time);
129 unix_to_nt_time(&info3->base.kickoff_time, info->kickoff_time);
130 unix_to_nt_time(&info3->base.last_password_change, info->pass_last_set_time);
131 unix_to_nt_time(&info3->base.allow_password_change,
132 info->pass_can_change_time);
133 unix_to_nt_time(&info3->base.force_password_change,
134 info->pass_must_change_time);
136 if (info->account_name) {
137 info3->base.account_name.string =
138 talloc_strdup(info3, info->account_name);
139 RET_NOMEM(info3->base.account_name.string);
141 if (info->full_name) {
142 info3->base.full_name.string =
143 talloc_strdup(info3, info->full_name);
144 RET_NOMEM(info3->base.full_name.string);
146 if (info->logon_script) {
147 info3->base.logon_script.string =
148 talloc_strdup(info3, info->logon_script);
149 RET_NOMEM(info3->base.logon_script.string);
151 if (info->profile_path) {
152 info3->base.profile_path.string =
153 talloc_strdup(info3, info->profile_path);
154 RET_NOMEM(info3->base.profile_path.string);
156 if (info->home_directory) {
157 info3->base.home_directory.string =
158 talloc_strdup(info3, info->home_directory);
159 RET_NOMEM(info3->base.home_directory.string);
161 if (info->home_drive) {
162 info3->base.home_drive.string =
163 talloc_strdup(info3, info->home_drive);
164 RET_NOMEM(info3->base.home_drive.string);
167 info3->base.logon_count = info->logon_count;
168 info3->base.bad_password_count = info->bad_password_count;
170 sid_copy(&domain_sid, &user_sid);
171 sid_split_rid(&domain_sid, &info3->base.rid);
173 ok = sid_peek_check_rid(&domain_sid, &group_sid,
174 &info3->base.primary_gid);
175 if (!ok) {
176 DEBUG(1, ("The primary group sid domain does not"
177 "match user sid domain for user: %s\n",
178 info->account_name));
179 TALLOC_FREE(info3);
180 return NULL;
183 status = wbcsids_to_samr_RidWithAttributeArray(info3,
184 &info3->base.groups,
185 &domain_sid,
186 &info->sids[1],
187 info->num_sids - 1);
188 if (!NT_STATUS_IS_OK(status)) {
189 TALLOC_FREE(info3);
190 return NULL;
193 status = wbcsids_to_netr_SidAttrArray(&domain_sid,
194 &info->sids[1],
195 info->num_sids - 1,
196 info3,
197 &info3->sids,
198 &info3->sidcount);
199 if (!NT_STATUS_IS_OK(status)) {
200 TALLOC_FREE(info3);
201 return NULL;
204 info3->base.user_flags = info->user_flags;
205 memcpy(info3->base.key.key, info->user_session_key, 16);
207 if (info->logon_server) {
208 info3->base.logon_server.string =
209 talloc_strdup(info3, info->logon_server);
210 RET_NOMEM(info3->base.logon_server.string);
212 if (info->domain_name) {
213 info3->base.logon_domain.string =
214 talloc_strdup(info3, info->domain_name);
215 RET_NOMEM(info3->base.logon_domain.string);
218 info3->base.domain_sid = dom_sid_dup(info3, &domain_sid);
219 RET_NOMEM(info3->base.domain_sid);
221 memcpy(info3->base.LMSessKey.key, info->lm_session_key, 8);
222 info3->base.acct_flags = info->acct_flags;
224 return info3;