2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Guenther Deschner 2008.
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/>.
22 /*******************************************************************
24 ********************************************************************/
26 void init_netr_SamBaseInfo(struct netr_SamBaseInfo
*r
,
30 NTTIME last_password_change
,
31 NTTIME allow_password_change
,
32 NTTIME force_password_change
,
33 const char *account_name
,
34 const char *full_name
,
35 const char *logon_script
,
36 const char *profile_path
,
37 const char *home_directory
,
38 const char *home_drive
,
40 uint16_t bad_password_count
,
43 struct samr_RidWithAttributeArray groups
,
45 struct netr_UserSessionKey key
,
46 const char *logon_server
,
48 struct dom_sid2
*domain_sid
,
49 struct netr_LMSessionKey LMSessKey
,
52 r
->last_logon
= last_logon
;
53 r
->last_logoff
= last_logoff
;
54 r
->acct_expiry
= acct_expiry
;
55 r
->last_password_change
= last_password_change
;
56 r
->allow_password_change
= allow_password_change
;
57 r
->force_password_change
= force_password_change
;
58 init_lsa_String(&r
->account_name
, account_name
);
59 init_lsa_String(&r
->full_name
, full_name
);
60 init_lsa_String(&r
->logon_script
, logon_script
);
61 init_lsa_String(&r
->profile_path
, profile_path
);
62 init_lsa_String(&r
->home_directory
, home_directory
);
63 init_lsa_String(&r
->home_drive
, home_drive
);
64 r
->logon_count
= logon_count
;
65 r
->bad_password_count
= bad_password_count
;
67 r
->primary_gid
= primary_gid
;
69 r
->user_flags
= user_flags
;
71 init_lsa_StringLarge(&r
->logon_server
, logon_server
);
72 init_lsa_StringLarge(&r
->domain
, domain
);
73 r
->domain_sid
= domain_sid
;
74 r
->LMSessKey
= LMSessKey
;
75 r
->acct_flags
= acct_flags
;
78 /*******************************************************************
80 ********************************************************************/
82 void init_netr_SamInfo3(struct netr_SamInfo3
*r
,
86 NTTIME last_password_change
,
87 NTTIME allow_password_change
,
88 NTTIME force_password_change
,
89 const char *account_name
,
90 const char *full_name
,
91 const char *logon_script
,
92 const char *profile_path
,
93 const char *home_directory
,
94 const char *home_drive
,
96 uint16_t bad_password_count
,
99 struct samr_RidWithAttributeArray groups
,
101 struct netr_UserSessionKey key
,
102 const char *logon_server
,
104 struct dom_sid2
*domain_sid
,
105 struct netr_LMSessionKey LMSessKey
,
108 struct netr_SidAttr
*sids
)
110 init_netr_SamBaseInfo(&r
->base
,
114 last_password_change
,
115 allow_password_change
,
116 force_password_change
,
135 r
->sidcount
= sidcount
;
139 /*******************************************************************
140 gets a domain user's groups from their already-calculated NT_USER_TOKEN
141 ********************************************************************/
143 static NTSTATUS
nt_token_to_group_list(TALLOC_CTX
*mem_ctx
,
144 const DOM_SID
*domain_sid
,
147 int *numgroups
, DOM_GID
**pgids
)
154 for (i
=0; i
<num_sids
; i
++) {
156 if (!sid_peek_check_rid(domain_sid
, &sids
[i
], &gid
.g_rid
)) {
159 gid
.attr
= (SE_GROUP_MANDATORY
|SE_GROUP_ENABLED_BY_DEFAULT
|
161 ADD_TO_ARRAY(mem_ctx
, DOM_GID
, gid
, pgids
, numgroups
);
162 if (*pgids
== NULL
) {
163 return NT_STATUS_NO_MEMORY
;
169 /****************************************************************************
170 inits a netr_SamInfo3 structure from an auth_serversupplied_info. sam3 must
171 already be initialized and is used as the talloc parent for its members.
172 *****************************************************************************/
174 NTSTATUS
serverinfo_to_SamInfo3(struct auth_serversupplied_info
*server_info
,
175 uint8_t *pipe_session_key
,
176 size_t pipe_session_key_len
,
177 struct netr_SamInfo3
*sam3
)
180 DOM_GID
*gids
= NULL
;
181 const DOM_SID
*user_sid
= NULL
;
182 const DOM_SID
*group_sid
= NULL
;
184 uint32 user_rid
, group_rid
;
190 struct netr_UserSessionKey user_session_key
;
191 struct netr_LMSessionKey lm_session_key
;
193 NTTIME last_logon
, last_logoff
, acct_expiry
, last_password_change
;
194 NTTIME allow_password_change
, force_password_change
;
195 struct samr_RidWithAttributeArray groups
;
197 struct dom_sid2
*sid
= NULL
;
199 ZERO_STRUCT(user_session_key
);
200 ZERO_STRUCT(lm_session_key
);
202 sampw
= server_info
->sam_account
;
204 user_sid
= pdb_get_user_sid(sampw
);
205 group_sid
= pdb_get_group_sid(sampw
);
207 if (pipe_session_key
&& pipe_session_key_len
!= 16) {
208 DEBUG(0,("serverinfo_to_SamInfo3: invalid "
209 "pipe_session_key_len[%d] != 16\n",
210 pipe_session_key_len
));
211 return NT_STATUS_INTERNAL_ERROR
;
214 if ((user_sid
== NULL
) || (group_sid
== NULL
)) {
215 DEBUG(1, ("_netr_LogonSamLogon: User without group or user SID\n"));
216 return NT_STATUS_UNSUCCESSFUL
;
219 sid_copy(&domain_sid
, user_sid
);
220 sid_split_rid(&domain_sid
, &user_rid
);
222 sid
= sid_dup_talloc(sam3
, &domain_sid
);
224 return NT_STATUS_NO_MEMORY
;
227 if (!sid_peek_check_rid(&domain_sid
, group_sid
, &group_rid
)) {
228 DEBUG(1, ("_netr_LogonSamLogon: user %s\\%s has user sid "
229 "%s\n but group sid %s.\n"
230 "The conflicting domain portions are not "
231 "supported for NETLOGON calls\n",
232 pdb_get_domain(sampw
),
233 pdb_get_username(sampw
),
234 sid_string_dbg(user_sid
),
235 sid_string_dbg(group_sid
)));
236 return NT_STATUS_UNSUCCESSFUL
;
239 if(server_info
->login_server
) {
240 my_name
= server_info
->login_server
;
242 my_name
= global_myname();
245 status
= nt_token_to_group_list(sam3
, &domain_sid
,
246 server_info
->num_sids
,
250 if (!NT_STATUS_IS_OK(status
)) {
254 if (server_info
->user_session_key
.length
) {
255 memcpy(user_session_key
.key
,
256 server_info
->user_session_key
.data
,
257 MIN(sizeof(user_session_key
.key
),
258 server_info
->user_session_key
.length
));
259 if (pipe_session_key
) {
260 SamOEMhash(user_session_key
.key
, pipe_session_key
, 16);
263 if (server_info
->lm_session_key
.length
) {
264 memcpy(lm_session_key
.key
,
265 server_info
->lm_session_key
.data
,
266 MIN(sizeof(lm_session_key
.key
),
267 server_info
->lm_session_key
.length
));
268 if (pipe_session_key
) {
269 SamOEMhash(lm_session_key
.key
, pipe_session_key
, 8);
273 groups
.count
= num_gids
;
274 groups
.rids
= TALLOC_ARRAY(sam3
, struct samr_RidWithAttribute
, groups
.count
);
276 return NT_STATUS_NO_MEMORY
;
279 for (i
=0; i
< groups
.count
; i
++) {
280 groups
.rids
[i
].rid
= gids
[i
].g_rid
;
281 groups
.rids
[i
].attributes
= gids
[i
].attr
;
284 unix_to_nt_time(&last_logon
, pdb_get_logon_time(sampw
));
285 unix_to_nt_time(&last_logoff
, get_time_t_max());
286 unix_to_nt_time(&acct_expiry
, get_time_t_max());
287 unix_to_nt_time(&last_password_change
, pdb_get_pass_last_set_time(sampw
));
288 unix_to_nt_time(&allow_password_change
, pdb_get_pass_can_change_time(sampw
));
289 unix_to_nt_time(&force_password_change
, pdb_get_pass_must_change_time(sampw
));
291 init_netr_SamInfo3(sam3
,
295 last_password_change
,
296 allow_password_change
,
297 force_password_change
,
298 talloc_strdup(sam3
, pdb_get_username(sampw
)),
299 talloc_strdup(sam3
, pdb_get_fullname(sampw
)),
300 talloc_strdup(sam3
, pdb_get_logon_script(sampw
)),
301 talloc_strdup(sam3
, pdb_get_profile_path(sampw
)),
302 talloc_strdup(sam3
, pdb_get_homedir(sampw
)),
303 talloc_strdup(sam3
, pdb_get_dir_drive(sampw
)),
305 0, /* bad_password_count */
312 talloc_strdup(sam3
, pdb_get_domain(sampw
)),
315 pdb_get_acct_ctrl(sampw
),
317 NULL
); /* struct netr_SidAttr *sids */
318 ZERO_STRUCT(user_session_key
);
319 ZERO_STRUCT(lm_session_key
);
324 /*******************************************************************
326 ********************************************************************/
328 void init_netr_IdentityInfo(struct netr_IdentityInfo
*r
,
329 const char *domain_name
,
330 uint32_t parameter_control
,
331 uint32_t logon_id_low
,
332 uint32_t logon_id_high
,
333 const char *account_name
,
334 const char *workstation
)
336 init_lsa_String(&r
->domain_name
, domain_name
);
337 r
->parameter_control
= parameter_control
;
338 r
->logon_id_low
= logon_id_low
;
339 r
->logon_id_high
= logon_id_high
;
340 init_lsa_String(&r
->account_name
, account_name
);
341 init_lsa_String(&r
->workstation
, workstation
);
344 /*******************************************************************
346 This is a network logon packet. The log_id parameters
347 are what an NT server would generate for LUID once the
348 user is logged on. I don't think we care about them.
350 Note that this has no access to the NT and LM hashed passwords,
351 so it forwards the challenge, and the NT and LM responses (24
352 bytes each) over the secure channel to the Domain controller
353 for it to say yea or nay. This is the preferred method of
354 checking for a logon as it doesn't export the password
355 hashes to anyone who has compromised the secure channel. JRA.
357 ********************************************************************/
359 void init_netr_NetworkInfo(struct netr_NetworkInfo
*r
,
360 const char *domain_name
,
361 uint32_t parameter_control
,
362 uint32_t logon_id_low
,
363 uint32_t logon_id_high
,
364 const char *account_name
,
365 const char *workstation
,
366 uint8_t challenge
[8],
367 struct netr_ChallengeResponse nt
,
368 struct netr_ChallengeResponse lm
)
370 init_netr_IdentityInfo(&r
->identity_info
,
377 memcpy(r
->challenge
, challenge
, 8);
382 /*******************************************************************
384 ********************************************************************/
386 void init_netr_PasswordInfo(struct netr_PasswordInfo
*r
,
387 const char *domain_name
,
388 uint32_t parameter_control
,
389 uint32_t logon_id_low
,
390 uint32_t logon_id_high
,
391 const char *account_name
,
392 const char *workstation
,
393 struct samr_Password lmpassword
,
394 struct samr_Password ntpassword
)
396 init_netr_IdentityInfo(&r
->identity_info
,
403 r
->lmpassword
= lmpassword
;
404 r
->ntpassword
= ntpassword
;
407 /*************************************************************************
408 inits a netr_CryptPassword structure
409 *************************************************************************/
411 void init_netr_CryptPassword(const char *pwd
,
412 unsigned char session_key
[16],
413 struct netr_CryptPassword
*pwd_buf
)
415 struct samr_CryptPassword password_buf
;
417 encode_pw_buffer(password_buf
.data
, pwd
, STR_UNICODE
);
419 SamOEMhash(password_buf
.data
, session_key
, 516);
420 memcpy(pwd_buf
->data
, password_buf
.data
, 512);
421 pwd_buf
->length
= IVAL(password_buf
.data
, 512);