Coverage Report

Created: 2025-07-23 07:04

/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
}