s4-drs: Add DRSUAPI_DRS_NONGC_RO_REP bit to DRS_OPTIONS
[Samba/fernandojvsilva.git] / source3 / auth / auth_util.c
blob46b7af4d87c9f7a82471659e09992222e4131feb
1 /*
2 Unix SMB/CIFS implementation.
3 Authentication utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Andrew Bartlett 2001
6 Copyright (C) Jeremy Allison 2000-2001
7 Copyright (C) Rafal Szczesniak 2002
8 Copyright (C) Volker Lendecke 2006
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
25 #include "smbd/globals.h"
26 #include "../libcli/auth/libcli_auth.h"
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_AUTH
31 /****************************************************************************
32 Ensure primary group SID is always at position 0 in a
33 auth_serversupplied_info struct.
34 ****************************************************************************/
36 static void sort_sid_array_for_smbd(struct auth_serversupplied_info *result,
37 const DOM_SID *pgroup_sid)
39 unsigned int i;
41 if (!result->sids) {
42 return;
45 if (sid_compare(&result->sids[0], pgroup_sid)==0) {
46 return;
49 for (i = 1; i < result->num_sids; i++) {
50 if (sid_compare(pgroup_sid,
51 &result->sids[i]) == 0) {
52 sid_copy(&result->sids[i], &result->sids[0]);
53 sid_copy(&result->sids[0], pgroup_sid);
54 return;
59 /****************************************************************************
60 Create a UNIX user on demand.
61 ****************************************************************************/
63 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
65 TALLOC_CTX *ctx = talloc_tos();
66 char *add_script;
67 int ret;
69 add_script = talloc_strdup(ctx, lp_adduser_script());
70 if (!add_script || !*add_script) {
71 return -1;
73 add_script = talloc_all_string_sub(ctx,
74 add_script,
75 "%u",
76 unix_username);
77 if (!add_script) {
78 return -1;
80 if (domain) {
81 add_script = talloc_all_string_sub(ctx,
82 add_script,
83 "%D",
84 domain);
85 if (!add_script) {
86 return -1;
89 if (homedir) {
90 add_script = talloc_all_string_sub(ctx,
91 add_script,
92 "%H",
93 homedir);
94 if (!add_script) {
95 return -1;
98 ret = smbrun(add_script,NULL);
99 flush_pwnam_cache();
100 DEBUG(ret ? 0 : 3,
101 ("smb_create_user: Running the command `%s' gave %d\n",
102 add_script,ret));
103 return ret;
106 /****************************************************************************
107 Create an auth_usersupplied_data structure
108 ****************************************************************************/
110 static NTSTATUS make_user_info(struct auth_usersupplied_info **user_info,
111 const char *smb_name,
112 const char *internal_username,
113 const char *client_domain,
114 const char *domain,
115 const char *wksta_name,
116 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
117 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
118 DATA_BLOB *plaintext,
119 bool encrypted)
122 DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
124 *user_info = SMB_MALLOC_P(struct auth_usersupplied_info);
125 if (*user_info == NULL) {
126 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
127 return NT_STATUS_NO_MEMORY;
130 ZERO_STRUCTP(*user_info);
132 DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
134 (*user_info)->smb_name = SMB_STRDUP(smb_name);
135 if ((*user_info)->smb_name == NULL) {
136 free_user_info(user_info);
137 return NT_STATUS_NO_MEMORY;
140 (*user_info)->internal_username = SMB_STRDUP(internal_username);
141 if ((*user_info)->internal_username == NULL) {
142 free_user_info(user_info);
143 return NT_STATUS_NO_MEMORY;
146 (*user_info)->domain = SMB_STRDUP(domain);
147 if ((*user_info)->domain == NULL) {
148 free_user_info(user_info);
149 return NT_STATUS_NO_MEMORY;
152 (*user_info)->client_domain = SMB_STRDUP(client_domain);
153 if ((*user_info)->client_domain == NULL) {
154 free_user_info(user_info);
155 return NT_STATUS_NO_MEMORY;
158 (*user_info)->wksta_name = SMB_STRDUP(wksta_name);
159 if ((*user_info)->wksta_name == NULL) {
160 free_user_info(user_info);
161 return NT_STATUS_NO_MEMORY;
164 DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
166 if (lm_pwd)
167 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
168 if (nt_pwd)
169 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
170 if (lm_interactive_pwd)
171 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
172 if (nt_interactive_pwd)
173 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
175 if (plaintext)
176 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
178 (*user_info)->encrypted = encrypted;
180 (*user_info)->logon_parameters = 0;
182 DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
184 return NT_STATUS_OK;
187 /****************************************************************************
188 Create an auth_usersupplied_data structure after appropriate mapping.
189 ****************************************************************************/
191 NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info,
192 const char *smb_name,
193 const char *client_domain,
194 const char *wksta_name,
195 DATA_BLOB *lm_pwd,
196 DATA_BLOB *nt_pwd,
197 DATA_BLOB *lm_interactive_pwd,
198 DATA_BLOB *nt_interactive_pwd,
199 DATA_BLOB *plaintext,
200 bool encrypted)
202 struct smbd_server_connection *sconn = smbd_server_conn;
203 const char *domain;
204 NTSTATUS result;
205 bool was_mapped;
206 fstring internal_username;
207 fstrcpy(internal_username, smb_name);
208 was_mapped = map_username(sconn, internal_username);
210 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
211 client_domain, smb_name, wksta_name));
213 domain = client_domain;
215 /* If you connect to a Windows domain member using a bogus domain name,
216 * the Windows box will map the BOGUS\user to SAMNAME\user. Thus, if
217 * the Windows box is a DC the name will become DOMAIN\user and be
218 * authenticated against AD, if the Windows box is a member server but
219 * not a DC the name will become WORKSTATION\user. A standalone
220 * non-domain member box will also map to WORKSTATION\user.
221 * This also deals with the client passing in a "" domain */
223 if (!is_trusted_domain(domain) &&
224 !strequal(domain, my_sam_name()))
226 if (lp_map_untrusted_to_domain())
227 domain = my_sam_name();
228 else
229 domain = get_global_sam_name();
230 DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
231 "workstation [%s]\n",
232 client_domain, domain, smb_name, wksta_name));
235 /* We know that the given domain is trusted (and we are allowing them),
236 * it is our global SAM name, or for legacy behavior it is our
237 * primary domain name */
239 result = make_user_info(user_info, smb_name, internal_username,
240 client_domain, domain, wksta_name,
241 lm_pwd, nt_pwd,
242 lm_interactive_pwd, nt_interactive_pwd,
243 plaintext, encrypted);
244 if (NT_STATUS_IS_OK(result)) {
245 (*user_info)->was_mapped = was_mapped;
247 return result;
250 /****************************************************************************
251 Create an auth_usersupplied_data, making the DATA_BLOBs here.
252 Decrypt and encrypt the passwords.
253 ****************************************************************************/
255 bool make_user_info_netlogon_network(struct auth_usersupplied_info **user_info,
256 const char *smb_name,
257 const char *client_domain,
258 const char *wksta_name,
259 uint32 logon_parameters,
260 const uchar *lm_network_pwd,
261 int lm_pwd_len,
262 const uchar *nt_network_pwd,
263 int nt_pwd_len)
265 bool ret;
266 NTSTATUS status;
267 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
268 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
270 status = make_user_info_map(user_info,
271 smb_name, client_domain,
272 wksta_name,
273 lm_pwd_len ? &lm_blob : NULL,
274 nt_pwd_len ? &nt_blob : NULL,
275 NULL, NULL, NULL,
276 True);
278 if (NT_STATUS_IS_OK(status)) {
279 (*user_info)->logon_parameters = logon_parameters;
281 ret = NT_STATUS_IS_OK(status) ? True : False;
283 data_blob_free(&lm_blob);
284 data_blob_free(&nt_blob);
285 return ret;
288 /****************************************************************************
289 Create an auth_usersupplied_data, making the DATA_BLOBs here.
290 Decrypt and encrypt the passwords.
291 ****************************************************************************/
293 bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_info,
294 const char *smb_name,
295 const char *client_domain,
296 const char *wksta_name,
297 uint32 logon_parameters,
298 const uchar chal[8],
299 const uchar lm_interactive_pwd[16],
300 const uchar nt_interactive_pwd[16],
301 const uchar *dc_sess_key)
303 unsigned char lm_pwd[16];
304 unsigned char nt_pwd[16];
305 unsigned char local_lm_response[24];
306 unsigned char local_nt_response[24];
307 unsigned char key[16];
309 memcpy(key, dc_sess_key, 16);
311 if (lm_interactive_pwd)
312 memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
314 if (nt_interactive_pwd)
315 memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
317 #ifdef DEBUG_PASSWORD
318 DEBUG(100,("key:"));
319 dump_data(100, key, sizeof(key));
321 DEBUG(100,("lm owf password:"));
322 dump_data(100, lm_pwd, sizeof(lm_pwd));
324 DEBUG(100,("nt owf password:"));
325 dump_data(100, nt_pwd, sizeof(nt_pwd));
326 #endif
328 if (lm_interactive_pwd)
329 arcfour_crypt(lm_pwd, key, sizeof(lm_pwd));
331 if (nt_interactive_pwd)
332 arcfour_crypt(nt_pwd, key, sizeof(nt_pwd));
334 #ifdef DEBUG_PASSWORD
335 DEBUG(100,("decrypt of lm owf password:"));
336 dump_data(100, lm_pwd, sizeof(lm_pwd));
338 DEBUG(100,("decrypt of nt owf password:"));
339 dump_data(100, nt_pwd, sizeof(nt_pwd));
340 #endif
342 if (lm_interactive_pwd)
343 SMBOWFencrypt(lm_pwd, chal,
344 local_lm_response);
346 if (nt_interactive_pwd)
347 SMBOWFencrypt(nt_pwd, chal,
348 local_nt_response);
350 /* Password info paranoia */
351 ZERO_STRUCT(key);
354 bool ret;
355 NTSTATUS nt_status;
356 DATA_BLOB local_lm_blob;
357 DATA_BLOB local_nt_blob;
359 DATA_BLOB lm_interactive_blob;
360 DATA_BLOB nt_interactive_blob;
362 if (lm_interactive_pwd) {
363 local_lm_blob = data_blob(local_lm_response,
364 sizeof(local_lm_response));
365 lm_interactive_blob = data_blob(lm_pwd,
366 sizeof(lm_pwd));
367 ZERO_STRUCT(lm_pwd);
370 if (nt_interactive_pwd) {
371 local_nt_blob = data_blob(local_nt_response,
372 sizeof(local_nt_response));
373 nt_interactive_blob = data_blob(nt_pwd,
374 sizeof(nt_pwd));
375 ZERO_STRUCT(nt_pwd);
378 nt_status = make_user_info_map(
379 user_info,
380 smb_name, client_domain, wksta_name,
381 lm_interactive_pwd ? &local_lm_blob : NULL,
382 nt_interactive_pwd ? &local_nt_blob : NULL,
383 lm_interactive_pwd ? &lm_interactive_blob : NULL,
384 nt_interactive_pwd ? &nt_interactive_blob : NULL,
385 NULL, True);
387 if (NT_STATUS_IS_OK(nt_status)) {
388 (*user_info)->logon_parameters = logon_parameters;
391 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
392 data_blob_free(&local_lm_blob);
393 data_blob_free(&local_nt_blob);
394 data_blob_free(&lm_interactive_blob);
395 data_blob_free(&nt_interactive_blob);
396 return ret;
401 /****************************************************************************
402 Create an auth_usersupplied_data structure
403 ****************************************************************************/
405 bool make_user_info_for_reply(struct auth_usersupplied_info **user_info,
406 const char *smb_name,
407 const char *client_domain,
408 const uint8 chal[8],
409 DATA_BLOB plaintext_password)
412 DATA_BLOB local_lm_blob;
413 DATA_BLOB local_nt_blob;
414 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
417 * Not encrypted - do so.
420 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
421 "format.\n"));
423 if (plaintext_password.data) {
424 unsigned char local_lm_response[24];
426 #ifdef DEBUG_PASSWORD
427 DEBUG(10,("Unencrypted password (len %d):\n",
428 (int)plaintext_password.length));
429 dump_data(100, plaintext_password.data,
430 plaintext_password.length);
431 #endif
433 SMBencrypt( (const char *)plaintext_password.data,
434 (const uchar*)chal, local_lm_response);
435 local_lm_blob = data_blob(local_lm_response, 24);
437 /* We can't do an NT hash here, as the password needs to be
438 case insensitive */
439 local_nt_blob = data_blob_null;
441 } else {
442 local_lm_blob = data_blob_null;
443 local_nt_blob = data_blob_null;
446 ret = make_user_info_map(
447 user_info, smb_name, client_domain,
448 get_remote_machine_name(),
449 local_lm_blob.data ? &local_lm_blob : NULL,
450 local_nt_blob.data ? &local_nt_blob : NULL,
451 NULL, NULL,
452 plaintext_password.data ? &plaintext_password : NULL,
453 False);
455 data_blob_free(&local_lm_blob);
456 return NT_STATUS_IS_OK(ret) ? True : False;
459 /****************************************************************************
460 Create an auth_usersupplied_data structure
461 ****************************************************************************/
463 NTSTATUS make_user_info_for_reply_enc(struct auth_usersupplied_info **user_info,
464 const char *smb_name,
465 const char *client_domain,
466 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
468 return make_user_info_map(user_info, smb_name,
469 client_domain,
470 get_remote_machine_name(),
471 lm_resp.data ? &lm_resp : NULL,
472 nt_resp.data ? &nt_resp : NULL,
473 NULL, NULL, NULL,
474 True);
477 /****************************************************************************
478 Create a guest user_info blob, for anonymous authenticaion.
479 ****************************************************************************/
481 bool make_user_info_guest(struct auth_usersupplied_info **user_info)
483 NTSTATUS nt_status;
485 nt_status = make_user_info(user_info,
486 "","",
487 "","",
488 "",
489 NULL, NULL,
490 NULL, NULL,
491 NULL,
492 True);
494 return NT_STATUS_IS_OK(nt_status) ? True : False;
497 static int server_info_dtor(struct auth_serversupplied_info *server_info)
499 TALLOC_FREE(server_info->sam_account);
500 ZERO_STRUCTP(server_info);
501 return 0;
504 /***************************************************************************
505 Make a server_info struct. Free with TALLOC_FREE().
506 ***************************************************************************/
508 static struct auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
510 struct auth_serversupplied_info *result;
512 result = TALLOC_ZERO_P(mem_ctx, struct auth_serversupplied_info);
513 if (result == NULL) {
514 DEBUG(0, ("talloc failed\n"));
515 return NULL;
518 talloc_set_destructor(result, server_info_dtor);
520 /* Initialise the uid and gid values to something non-zero
521 which may save us from giving away root access if there
522 is a bug in allocating these fields. */
524 result->utok.uid = -1;
525 result->utok.gid = -1;
526 return result;
529 static char *sanitize_username(TALLOC_CTX *mem_ctx, const char *username)
531 fstring tmp;
533 alpha_strcpy(tmp, username, ". _-$", sizeof(tmp));
534 return talloc_strdup(mem_ctx, tmp);
537 /***************************************************************************
538 Is the incoming username our own machine account ?
539 If so, the connection is almost certainly from winbindd.
540 ***************************************************************************/
542 static bool is_our_machine_account(const char *username)
544 bool ret;
545 char *truncname = NULL;
546 size_t ulen = strlen(username);
548 if (ulen == 0 || username[ulen-1] != '$') {
549 return false;
551 truncname = SMB_STRDUP(username);
552 if (!truncname) {
553 return false;
555 truncname[ulen-1] = '\0';
556 ret = strequal(truncname, global_myname());
557 SAFE_FREE(truncname);
558 return ret;
561 /***************************************************************************
562 Make (and fill) a user_info struct from a struct samu
563 ***************************************************************************/
565 NTSTATUS make_server_info_sam(struct auth_serversupplied_info **server_info,
566 struct samu *sampass)
568 struct passwd *pwd;
569 gid_t *gids;
570 struct auth_serversupplied_info *result;
571 const char *username = pdb_get_username(sampass);
572 NTSTATUS status;
574 if ( !(result = make_server_info(NULL)) ) {
575 return NT_STATUS_NO_MEMORY;
578 if ( !(pwd = getpwnam_alloc(result, username)) ) {
579 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
580 pdb_get_username(sampass)));
581 TALLOC_FREE(result);
582 return NT_STATUS_NO_SUCH_USER;
585 result->sam_account = sampass;
586 result->unix_name = pwd->pw_name;
587 /* Ensure that we keep pwd->pw_name, because we will free pwd below */
588 talloc_steal(result, pwd->pw_name);
589 result->utok.gid = pwd->pw_gid;
590 result->utok.uid = pwd->pw_uid;
592 TALLOC_FREE(pwd);
594 result->sanitized_username = sanitize_username(result,
595 result->unix_name);
596 if (result->sanitized_username == NULL) {
597 TALLOC_FREE(result);
598 return NT_STATUS_NO_MEMORY;
601 if (IS_DC && is_our_machine_account(username)) {
603 * Ensure for a connection from our own
604 * machine account (from winbindd on a DC)
605 * there are no supplementary groups.
606 * Prevents loops in calling gid_to_sid().
608 result->sids = NULL;
609 gids = NULL;
610 result->num_sids = 0;
613 * This is a hack of monstrous proportions.
614 * If we know it's winbindd talking to us,
615 * we know we must never recurse into it,
616 * so turn off contacting winbindd for this
617 * entire process. This will get fixed when
618 * winbindd doesn't need to talk to smbd on
619 * a PDC. JRA.
622 (void)winbind_off();
624 DEBUG(10, ("make_server_info_sam: our machine account %s "
625 "setting supplementary group list empty and "
626 "turning off winbindd requests.\n",
627 username));
628 } else {
629 status = pdb_enum_group_memberships(result, sampass,
630 &result->sids, &gids,
631 &result->num_sids);
633 if (!NT_STATUS_IS_OK(status)) {
634 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
635 nt_errstr(status)));
636 result->sam_account = NULL; /* Don't free on error exit. */
637 TALLOC_FREE(result);
638 return status;
642 /* For now we throw away the gids and convert via sid_to_gid
643 * later. This needs fixing, but I'd like to get the code straight and
644 * simple first. */
646 TALLOC_FREE(gids);
648 DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
649 pdb_get_username(sampass), result->unix_name));
651 *server_info = result;
652 /* Ensure that the sampass will be freed with the result */
653 talloc_steal(result, sampass);
655 return NT_STATUS_OK;
658 static NTSTATUS log_nt_token(NT_USER_TOKEN *token)
660 TALLOC_CTX *frame = talloc_stackframe();
661 char *command;
662 char *group_sidstr;
663 size_t i;
665 if ((lp_log_nt_token_command() == NULL) ||
666 (strlen(lp_log_nt_token_command()) == 0)) {
667 TALLOC_FREE(frame);
668 return NT_STATUS_OK;
671 group_sidstr = talloc_strdup(frame, "");
672 for (i=1; i<token->num_sids; i++) {
673 group_sidstr = talloc_asprintf(
674 frame, "%s %s", group_sidstr,
675 sid_string_talloc(frame, &token->user_sids[i]));
678 command = talloc_string_sub(
679 frame, lp_log_nt_token_command(),
680 "%s", sid_string_talloc(frame, &token->user_sids[0]));
681 command = talloc_string_sub(frame, command, "%t", group_sidstr);
683 if (command == NULL) {
684 TALLOC_FREE(frame);
685 return NT_STATUS_NO_MEMORY;
688 DEBUG(8, ("running command: [%s]\n", command));
689 if (smbrun(command, NULL) != 0) {
690 DEBUG(0, ("Could not log NT token\n"));
691 TALLOC_FREE(frame);
692 return NT_STATUS_ACCESS_DENIED;
695 TALLOC_FREE(frame);
696 return NT_STATUS_OK;
700 * Create the token to use from server_info->sam_account and
701 * server_info->sids (the info3/sam groups). Find the unix gids.
704 NTSTATUS create_local_token(struct auth_serversupplied_info *server_info)
706 NTSTATUS status;
707 size_t i;
708 struct dom_sid tmp_sid;
711 * If winbind is not around, we can not make much use of the SIDs the
712 * domain controller provided us with. Likewise if the user name was
713 * mapped to some local unix user.
716 if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
717 (server_info->nss_token)) {
718 status = create_token_from_username(server_info,
719 server_info->unix_name,
720 server_info->guest,
721 &server_info->utok.uid,
722 &server_info->utok.gid,
723 &server_info->unix_name,
724 &server_info->ptok);
726 } else {
727 server_info->ptok = create_local_nt_token(
728 server_info,
729 pdb_get_user_sid(server_info->sam_account),
730 server_info->guest,
731 server_info->num_sids, server_info->sids);
732 status = server_info->ptok ?
733 NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
736 if (!NT_STATUS_IS_OK(status)) {
737 return status;
740 /* Convert the SIDs to gids. */
742 server_info->utok.ngroups = 0;
743 server_info->utok.groups = NULL;
745 /* Start at index 1, where the groups start. */
747 for (i=1; i<server_info->ptok->num_sids; i++) {
748 gid_t gid;
749 DOM_SID *sid = &server_info->ptok->user_sids[i];
751 if (!sid_to_gid(sid, &gid)) {
752 DEBUG(10, ("Could not convert SID %s to gid, "
753 "ignoring it\n", sid_string_dbg(sid)));
754 continue;
756 add_gid_to_array_unique(server_info, gid,
757 &server_info->utok.groups,
758 &server_info->utok.ngroups);
762 * Add the "Unix Group" SID for each gid to catch mapped groups
763 * and their Unix equivalent. This is to solve the backwards
764 * compatibility problem of 'valid users = +ntadmin' where
765 * ntadmin has been paired with "Domain Admins" in the group
766 * mapping table. Otherwise smb.conf would need to be changed
767 * to 'valid user = "Domain Admins"'. --jerry
769 * For consistency we also add the "Unix User" SID,
770 * so that the complete unix token is represented within
771 * the nt token.
774 if (!uid_to_unix_users_sid(server_info->utok.uid, &tmp_sid)) {
775 DEBUG(1,("create_local_token: Failed to create SID "
776 "for uid %u!\n", (unsigned int)server_info->utok.uid));
778 add_sid_to_array_unique(server_info->ptok, &tmp_sid,
779 &server_info->ptok->user_sids,
780 &server_info->ptok->num_sids);
782 for ( i=0; i<server_info->utok.ngroups; i++ ) {
783 if (!gid_to_unix_groups_sid( server_info->utok.groups[i], &tmp_sid ) ) {
784 DEBUG(1,("create_local_token: Failed to create SID "
785 "for gid %u!\n", (unsigned int)server_info->utok.groups[i]));
786 continue;
788 add_sid_to_array_unique(server_info->ptok, &tmp_sid,
789 &server_info->ptok->user_sids,
790 &server_info->ptok->num_sids);
793 debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
794 debug_unix_user_token(DBGC_AUTH, 10,
795 server_info->utok.uid,
796 server_info->utok.gid,
797 server_info->utok.ngroups,
798 server_info->utok.groups);
800 status = log_nt_token(server_info->ptok);
801 return status;
805 * Create an artificial NT token given just a username. (Initially intended
806 * for force user)
808 * We go through lookup_name() to avoid problems we had with 'winbind use
809 * default domain'.
811 * We have 3 cases:
813 * unmapped unix users: Go directly to nss to find the user's group.
815 * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
817 * If the user is provided by winbind, the primary gid is set to "domain
818 * users" of the user's domain. For an explanation why this is necessary, see
819 * the thread starting at
820 * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
823 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
824 bool is_guest,
825 uid_t *uid, gid_t *gid,
826 char **found_username,
827 struct nt_user_token **token)
829 NTSTATUS result = NT_STATUS_NO_SUCH_USER;
830 TALLOC_CTX *tmp_ctx;
831 DOM_SID user_sid;
832 enum lsa_SidType type;
833 gid_t *gids;
834 DOM_SID *group_sids;
835 DOM_SID unix_group_sid;
836 size_t num_group_sids;
837 size_t num_gids;
838 size_t i;
840 tmp_ctx = talloc_new(NULL);
841 if (tmp_ctx == NULL) {
842 DEBUG(0, ("talloc_new failed\n"));
843 return NT_STATUS_NO_MEMORY;
846 if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,
847 NULL, NULL, &user_sid, &type)) {
848 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));
849 goto done;
852 if (type != SID_NAME_USER) {
853 DEBUG(1, ("%s is a %s, not a user\n", username,
854 sid_type_lookup(type)));
855 goto done;
858 if (sid_check_is_in_our_domain(&user_sid)) {
859 bool ret;
861 /* This is a passdb user, so ask passdb */
863 struct samu *sam_acct = NULL;
865 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
866 result = NT_STATUS_NO_MEMORY;
867 goto done;
870 become_root();
871 ret = pdb_getsampwsid(sam_acct, &user_sid);
872 unbecome_root();
874 if (!ret) {
875 DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
876 sid_string_dbg(&user_sid), username));
877 DEBUGADD(1, ("Fall back to unix user %s\n", username));
878 goto unix_user;
881 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
882 &group_sids, &gids,
883 &num_group_sids);
884 if (!NT_STATUS_IS_OK(result)) {
885 DEBUG(1, ("enum_group_memberships failed for %s (%s): "
886 "%s\n", username, sid_string_dbg(&user_sid),
887 nt_errstr(result)));
888 DEBUGADD(1, ("Fall back to unix user %s\n", username));
889 goto unix_user;
892 /* see the smb_panic() in pdb_default_enum_group_memberships */
893 SMB_ASSERT(num_group_sids > 0);
895 *gid = gids[0];
897 /* Ensure we're returning the found_username on the right context. */
898 *found_username = talloc_strdup(mem_ctx,
899 pdb_get_username(sam_acct));
902 * If the SID from lookup_name() was the guest sid, passdb knows
903 * about the mapping of guest sid to lp_guestaccount()
904 * username and will return the unix_pw info for a guest
905 * user. Use it if it's there, else lookup the *uid details
906 * using getpwnam_alloc(). See bug #6291 for details. JRA.
909 /* We must always assign the *uid. */
910 if (sam_acct->unix_pw == NULL) {
911 struct passwd *pwd = getpwnam_alloc(sam_acct, *found_username );
912 if (!pwd) {
913 DEBUG(10, ("getpwnam_alloc failed for %s\n",
914 *found_username));
915 result = NT_STATUS_NO_SUCH_USER;
916 goto done;
918 result = samu_set_unix(sam_acct, pwd );
919 if (!NT_STATUS_IS_OK(result)) {
920 DEBUG(10, ("samu_set_unix failed for %s\n",
921 *found_username));
922 result = NT_STATUS_NO_SUCH_USER;
923 goto done;
926 *uid = sam_acct->unix_pw->pw_uid;
928 } else if (sid_check_is_in_unix_users(&user_sid)) {
930 /* This is a unix user not in passdb. We need to ask nss
931 * directly, without consulting passdb */
933 struct passwd *pass;
936 * This goto target is used as a fallback for the passdb
937 * case. The concrete bug report is when passdb gave us an
938 * unmapped gid.
941 unix_user:
943 if (!sid_to_uid(&user_sid, uid)) {
944 DEBUG(1, ("unix_user case, sid_to_uid for %s (%s) failed\n",
945 username, sid_string_dbg(&user_sid)));
946 result = NT_STATUS_NO_SUCH_USER;
947 goto done;
950 uid_to_unix_users_sid(*uid, &user_sid);
952 pass = getpwuid_alloc(tmp_ctx, *uid);
953 if (pass == NULL) {
954 DEBUG(1, ("getpwuid(%u) for user %s failed\n",
955 (unsigned int)*uid, username));
956 goto done;
959 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
960 &gids, &num_group_sids)) {
961 DEBUG(1, ("getgroups_unix_user for user %s failed\n",
962 username));
963 goto done;
966 if (num_group_sids) {
967 group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
968 if (group_sids == NULL) {
969 DEBUG(1, ("TALLOC_ARRAY failed\n"));
970 result = NT_STATUS_NO_MEMORY;
971 goto done;
973 } else {
974 group_sids = NULL;
977 for (i=0; i<num_group_sids; i++) {
978 gid_to_sid(&group_sids[i], gids[i]);
981 /* In getgroups_unix_user we always set the primary gid */
982 SMB_ASSERT(num_group_sids > 0);
984 *gid = gids[0];
986 /* Ensure we're returning the found_username on the right context. */
987 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
988 } else {
990 /* This user is from winbind, force the primary gid to the
991 * user's "domain users" group. Under certain circumstances
992 * (user comes from NT4), this might be a loss of
993 * information. But we can not rely on winbind getting the
994 * correct info. AD might prohibit winbind looking up that
995 * information. */
997 uint32 dummy;
999 /* We must always assign the *uid. */
1000 if (!sid_to_uid(&user_sid, uid)) {
1001 DEBUG(1, ("winbindd case, sid_to_uid for %s (%s) failed\n",
1002 username, sid_string_dbg(&user_sid)));
1003 result = NT_STATUS_NO_SUCH_USER;
1004 goto done;
1007 num_group_sids = 1;
1008 group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
1009 if (group_sids == NULL) {
1010 DEBUG(1, ("TALLOC_ARRAY failed\n"));
1011 result = NT_STATUS_NO_MEMORY;
1012 goto done;
1015 sid_copy(&group_sids[0], &user_sid);
1016 sid_split_rid(&group_sids[0], &dummy);
1017 sid_append_rid(&group_sids[0], DOMAIN_GROUP_RID_USERS);
1019 if (!sid_to_gid(&group_sids[0], gid)) {
1020 DEBUG(1, ("sid_to_gid(%s) failed\n",
1021 sid_string_dbg(&group_sids[0])));
1022 goto done;
1025 gids = gid;
1027 /* Ensure we're returning the found_username on the right context. */
1028 *found_username = talloc_strdup(mem_ctx, username);
1031 /* Add the "Unix Group" SID for each gid to catch mapped groups
1032 and their Unix equivalent. This is to solve the backwards
1033 compatibility problem of 'valid users = +ntadmin' where
1034 ntadmin has been paired with "Domain Admins" in the group
1035 mapping table. Otherwise smb.conf would need to be changed
1036 to 'valid user = "Domain Admins"'. --jerry */
1038 num_gids = num_group_sids;
1039 for ( i=0; i<num_gids; i++ ) {
1040 gid_t high, low;
1042 /* don't pickup anything managed by Winbind */
1044 if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) )
1045 continue;
1047 if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {
1048 DEBUG(1,("create_token_from_username: Failed to create SID "
1049 "for gid %u!\n", (unsigned int)gids[i]));
1050 continue;
1052 result = add_sid_to_array_unique(tmp_ctx, &unix_group_sid,
1053 &group_sids, &num_group_sids);
1054 if (!NT_STATUS_IS_OK(result)) {
1055 goto done;
1059 /* Ensure we're creating the nt_token on the right context. */
1060 *token = create_local_nt_token(mem_ctx, &user_sid,
1061 is_guest, num_group_sids, group_sids);
1063 if ((*token == NULL) || (*found_username == NULL)) {
1064 result = NT_STATUS_NO_MEMORY;
1065 goto done;
1068 result = NT_STATUS_OK;
1069 done:
1070 TALLOC_FREE(tmp_ctx);
1071 return result;
1074 /***************************************************************************
1075 Build upon create_token_from_username:
1077 Expensive helper function to figure out whether a user given its name is
1078 member of a particular group.
1079 ***************************************************************************/
1081 bool user_in_group_sid(const char *username, const DOM_SID *group_sid)
1083 NTSTATUS status;
1084 uid_t uid;
1085 gid_t gid;
1086 char *found_username;
1087 struct nt_user_token *token;
1088 bool result;
1090 TALLOC_CTX *mem_ctx;
1092 mem_ctx = talloc_new(NULL);
1093 if (mem_ctx == NULL) {
1094 DEBUG(0, ("talloc_new failed\n"));
1095 return False;
1098 status = create_token_from_username(mem_ctx, username, False,
1099 &uid, &gid, &found_username,
1100 &token);
1102 if (!NT_STATUS_IS_OK(status)) {
1103 DEBUG(10, ("could not create token for %s\n", username));
1104 return False;
1107 result = nt_token_check_sid(group_sid, token);
1109 TALLOC_FREE(mem_ctx);
1110 return result;
1114 bool user_in_group(const char *username, const char *groupname)
1116 TALLOC_CTX *mem_ctx;
1117 DOM_SID group_sid;
1118 bool ret;
1120 mem_ctx = talloc_new(NULL);
1121 if (mem_ctx == NULL) {
1122 DEBUG(0, ("talloc_new failed\n"));
1123 return False;
1126 ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1127 NULL, NULL, &group_sid, NULL);
1128 TALLOC_FREE(mem_ctx);
1130 if (!ret) {
1131 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
1132 return False;
1135 return user_in_group_sid(username, &group_sid);
1138 /***************************************************************************
1139 Make (and fill) a server_info struct from a 'struct passwd' by conversion
1140 to a struct samu
1141 ***************************************************************************/
1143 NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
1144 char *unix_username,
1145 struct passwd *pwd)
1147 NTSTATUS status;
1148 struct samu *sampass = NULL;
1149 gid_t *gids;
1150 char *qualified_name = NULL;
1151 TALLOC_CTX *mem_ctx = NULL;
1152 DOM_SID u_sid;
1153 enum lsa_SidType type;
1154 struct auth_serversupplied_info *result;
1156 if ( !(sampass = samu_new( NULL )) ) {
1157 return NT_STATUS_NO_MEMORY;
1160 status = samu_set_unix( sampass, pwd );
1161 if (!NT_STATUS_IS_OK(status)) {
1162 return status;
1165 result = make_server_info(NULL);
1166 if (result == NULL) {
1167 TALLOC_FREE(sampass);
1168 return NT_STATUS_NO_MEMORY;
1171 result->sam_account = sampass;
1173 result->unix_name = talloc_strdup(result, unix_username);
1174 result->sanitized_username = sanitize_username(result, unix_username);
1176 if ((result->unix_name == NULL)
1177 || (result->sanitized_username == NULL)) {
1178 TALLOC_FREE(sampass);
1179 TALLOC_FREE(result);
1180 return NT_STATUS_NO_MEMORY;
1183 result->utok.uid = pwd->pw_uid;
1184 result->utok.gid = pwd->pw_gid;
1186 status = pdb_enum_group_memberships(result, sampass,
1187 &result->sids, &gids,
1188 &result->num_sids);
1190 if (!NT_STATUS_IS_OK(status)) {
1191 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
1192 nt_errstr(status)));
1193 TALLOC_FREE(result);
1194 return status;
1198 * The SID returned in server_info->sam_account is based
1199 * on our SAM sid even though for a pure UNIX account this should
1200 * not be the case as it doesn't really exist in the SAM db.
1201 * This causes lookups on "[in]valid users" to fail as they
1202 * will lookup this name as a "Unix User" SID to check against
1203 * the user token. Fix this by adding the "Unix User"\unix_username
1204 * SID to the sid array. The correct fix should probably be
1205 * changing the server_info->sam_account user SID to be a
1206 * S-1-22 Unix SID, but this might break old configs where
1207 * plaintext passwords were used with no SAM backend.
1210 mem_ctx = talloc_init("make_server_info_pw_tmp");
1211 if (!mem_ctx) {
1212 TALLOC_FREE(result);
1213 return NT_STATUS_NO_MEMORY;
1216 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
1217 unix_users_domain_name(),
1218 unix_username );
1219 if (!qualified_name) {
1220 TALLOC_FREE(result);
1221 TALLOC_FREE(mem_ctx);
1222 return NT_STATUS_NO_MEMORY;
1225 if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
1226 NULL, NULL,
1227 &u_sid, &type)) {
1228 TALLOC_FREE(result);
1229 TALLOC_FREE(mem_ctx);
1230 return NT_STATUS_NO_SUCH_USER;
1233 TALLOC_FREE(mem_ctx);
1235 if (type != SID_NAME_USER) {
1236 TALLOC_FREE(result);
1237 return NT_STATUS_NO_SUCH_USER;
1240 status = add_sid_to_array_unique(result, &u_sid,
1241 &result->sids,
1242 &result->num_sids);
1243 if (!NT_STATUS_IS_OK(status)) {
1244 TALLOC_FREE(result);
1245 return status;
1248 /* For now we throw away the gids and convert via sid_to_gid
1249 * later. This needs fixing, but I'd like to get the code straight and
1250 * simple first. */
1251 TALLOC_FREE(gids);
1253 *server_info = result;
1255 return NT_STATUS_OK;
1258 /***************************************************************************
1259 Make (and fill) a user_info struct for a guest login.
1260 This *must* succeed for smbd to start. If there is no mapping entry for
1261 the guest gid, then create one.
1262 ***************************************************************************/
1264 static NTSTATUS make_new_server_info_guest(struct auth_serversupplied_info **server_info)
1266 NTSTATUS status;
1267 struct samu *sampass = NULL;
1268 DOM_SID guest_sid;
1269 bool ret;
1270 static const char zeros[16] = {0, };
1271 fstring tmp;
1273 if ( !(sampass = samu_new( NULL )) ) {
1274 return NT_STATUS_NO_MEMORY;
1277 sid_compose(&guest_sid, get_global_sam_sid(), DOMAIN_USER_RID_GUEST);
1279 become_root();
1280 ret = pdb_getsampwsid(sampass, &guest_sid);
1281 unbecome_root();
1283 if (!ret) {
1284 TALLOC_FREE(sampass);
1285 return NT_STATUS_NO_SUCH_USER;
1288 status = make_server_info_sam(server_info, sampass);
1289 if (!NT_STATUS_IS_OK(status)) {
1290 TALLOC_FREE(sampass);
1291 return status;
1294 (*server_info)->guest = True;
1296 status = create_local_token(*server_info);
1297 if (!NT_STATUS_IS_OK(status)) {
1298 DEBUG(10, ("create_local_token failed: %s\n",
1299 nt_errstr(status)));
1300 return status;
1303 /* annoying, but the Guest really does have a session key, and it is
1304 all zeros! */
1305 (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1306 (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1308 alpha_strcpy(tmp, pdb_get_username(sampass), ". _-$", sizeof(tmp));
1309 (*server_info)->sanitized_username = talloc_strdup(*server_info, tmp);
1311 return NT_STATUS_OK;
1314 /****************************************************************************
1315 Fake a auth_serversupplied_info just from a username
1316 ****************************************************************************/
1318 NTSTATUS make_serverinfo_from_username(TALLOC_CTX *mem_ctx,
1319 const char *username,
1320 bool is_guest,
1321 struct auth_serversupplied_info **presult)
1323 struct auth_serversupplied_info *result;
1324 struct passwd *pwd;
1325 NTSTATUS status;
1327 pwd = getpwnam_alloc(talloc_tos(), username);
1328 if (pwd == NULL) {
1329 return NT_STATUS_NO_SUCH_USER;
1332 status = make_server_info_pw(&result, pwd->pw_name, pwd);
1334 TALLOC_FREE(pwd);
1336 if (!NT_STATUS_IS_OK(status)) {
1337 return status;
1340 result->nss_token = true;
1341 result->guest = is_guest;
1343 status = create_local_token(result);
1345 if (!NT_STATUS_IS_OK(status)) {
1346 TALLOC_FREE(result);
1347 return status;
1350 *presult = result;
1351 return NT_STATUS_OK;
1355 struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
1356 const struct auth_serversupplied_info *src)
1358 struct auth_serversupplied_info *dst;
1360 dst = make_server_info(mem_ctx);
1361 if (dst == NULL) {
1362 return NULL;
1365 dst->guest = src->guest;
1366 dst->utok.uid = src->utok.uid;
1367 dst->utok.gid = src->utok.gid;
1368 dst->utok.ngroups = src->utok.ngroups;
1369 if (src->utok.ngroups != 0) {
1370 dst->utok.groups = (gid_t *)TALLOC_MEMDUP(
1371 dst, src->utok.groups,
1372 sizeof(gid_t)*dst->utok.ngroups);
1373 } else {
1374 dst->utok.groups = NULL;
1377 if (src->ptok) {
1378 dst->ptok = dup_nt_token(dst, src->ptok);
1379 if (!dst->ptok) {
1380 TALLOC_FREE(dst);
1381 return NULL;
1385 dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
1386 src->user_session_key.length);
1388 dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
1389 src->lm_session_key.length);
1391 dst->sam_account = samu_new(NULL);
1392 if (!dst->sam_account) {
1393 TALLOC_FREE(dst);
1394 return NULL;
1397 if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) {
1398 TALLOC_FREE(dst);
1399 return NULL;
1402 dst->pam_handle = NULL;
1403 dst->unix_name = talloc_strdup(dst, src->unix_name);
1404 if (!dst->unix_name) {
1405 TALLOC_FREE(dst);
1406 return NULL;
1409 dst->sanitized_username = talloc_strdup(dst, src->sanitized_username);
1410 if (!dst->sanitized_username) {
1411 TALLOC_FREE(dst);
1412 return NULL;
1415 return dst;
1419 * Set a new session key. Used in the rpc server where we have to override the
1420 * SMB level session key with SystemLibraryDTC
1423 bool server_info_set_session_key(struct auth_serversupplied_info *info,
1424 DATA_BLOB session_key)
1426 TALLOC_FREE(info->user_session_key.data);
1428 info->user_session_key = data_blob_talloc(
1429 info, session_key.data, session_key.length);
1431 return (info->user_session_key.data != NULL);
1434 static struct auth_serversupplied_info *guest_info = NULL;
1436 bool init_guest_info(void)
1438 if (guest_info != NULL)
1439 return True;
1441 return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1444 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1445 struct auth_serversupplied_info **server_info)
1447 *server_info = copy_serverinfo(mem_ctx, guest_info);
1448 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1451 bool copy_current_user(struct current_user *dst, struct current_user *src)
1453 gid_t *groups;
1454 NT_USER_TOKEN *nt_token;
1456 groups = (gid_t *)memdup(src->ut.groups,
1457 sizeof(gid_t) * src->ut.ngroups);
1458 if ((src->ut.ngroups != 0) && (groups == NULL)) {
1459 return False;
1462 nt_token = dup_nt_token(NULL, src->nt_user_token);
1463 if (nt_token == NULL) {
1464 SAFE_FREE(groups);
1465 return False;
1468 dst->conn = src->conn;
1469 dst->vuid = src->vuid;
1470 dst->ut.uid = src->ut.uid;
1471 dst->ut.gid = src->ut.gid;
1472 dst->ut.ngroups = src->ut.ngroups;
1473 dst->ut.groups = groups;
1474 dst->nt_user_token = nt_token;
1475 return True;
1478 /***************************************************************************
1479 Purely internal function for make_server_info_info3
1480 Fill the sam account from getpwnam
1481 ***************************************************************************/
1482 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx,
1483 const char *domain,
1484 const char *username,
1485 char **found_username,
1486 uid_t *uid, gid_t *gid,
1487 struct samu *account,
1488 bool *username_was_mapped)
1490 struct smbd_server_connection *sconn = smbd_server_conn;
1491 NTSTATUS nt_status;
1492 fstring dom_user, lower_username;
1493 fstring real_username;
1494 struct passwd *passwd;
1496 fstrcpy( lower_username, username );
1497 strlower_m( lower_username );
1499 fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(),
1500 lower_username);
1502 /* Get the passwd struct. Try to create the account is necessary. */
1504 *username_was_mapped = map_username(sconn, dom_user);
1506 if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1507 return NT_STATUS_NO_SUCH_USER;
1509 *uid = passwd->pw_uid;
1510 *gid = passwd->pw_gid;
1512 /* This is pointless -- there is no suport for differing
1513 unix and windows names. Make sure to always store the
1514 one we actually looked up and succeeded. Have I mentioned
1515 why I hate the 'winbind use default domain' parameter?
1516 --jerry */
1518 *found_username = talloc_strdup( mem_ctx, real_username );
1520 DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1522 nt_status = samu_set_unix( account, passwd );
1524 TALLOC_FREE(passwd);
1526 return nt_status;
1529 /****************************************************************************
1530 Wrapper to allow the getpwnam() call to strip the domain name and
1531 try again in case a local UNIX user is already there. Also run through
1532 the username if we fallback to the username only.
1533 ****************************************************************************/
1535 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
1536 fstring save_username, bool create )
1538 struct passwd *pw = NULL;
1539 char *p;
1540 fstring username;
1542 /* we only save a copy of the username it has been mangled
1543 by winbindd use default domain */
1545 save_username[0] = '\0';
1547 /* don't call map_username() here since it has to be done higher
1548 up the stack so we don't call it mutliple times */
1550 fstrcpy( username, domuser );
1552 p = strchr_m( username, *lp_winbind_separator() );
1554 /* code for a DOMAIN\user string */
1556 if ( p ) {
1557 fstring strip_username;
1559 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1560 if ( pw ) {
1561 /* make sure we get the case of the username correct */
1562 /* work around 'winbind use default domain = yes' */
1564 if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1565 char *domain;
1567 /* split the domain and username into 2 strings */
1568 *p = '\0';
1569 domain = username;
1571 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1573 else
1574 fstrcpy( save_username, pw->pw_name );
1576 /* whew -- done! */
1577 return pw;
1580 /* setup for lookup of just the username */
1581 /* remember that p and username are overlapping memory */
1583 p++;
1584 fstrcpy( strip_username, p );
1585 fstrcpy( username, strip_username );
1588 /* just lookup a plain username */
1590 pw = Get_Pwnam_alloc(mem_ctx, username);
1592 /* Create local user if requested but only if winbindd
1593 is not running. We need to protect against cases
1594 where winbindd is failing and then prematurely
1595 creating users in /etc/passwd */
1597 if ( !pw && create && !winbind_ping() ) {
1598 /* Don't add a machine account. */
1599 if (username[strlen(username)-1] == '$')
1600 return NULL;
1602 _smb_create_user(NULL, username, NULL);
1603 pw = Get_Pwnam_alloc(mem_ctx, username);
1606 /* one last check for a valid passwd struct */
1608 if ( pw )
1609 fstrcpy( save_username, pw->pw_name );
1611 return pw;
1614 /***************************************************************************
1615 Make a server_info struct from the info3 returned by a domain logon
1616 ***************************************************************************/
1618 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1619 const char *sent_nt_username,
1620 const char *domain,
1621 struct auth_serversupplied_info **server_info,
1622 struct netr_SamInfo3 *info3)
1624 static const char zeros[16] = {0, };
1626 NTSTATUS nt_status = NT_STATUS_OK;
1627 char *found_username = NULL;
1628 const char *nt_domain;
1629 const char *nt_username;
1630 struct samu *sam_account = NULL;
1631 DOM_SID user_sid;
1632 DOM_SID group_sid;
1633 bool username_was_mapped;
1635 uid_t uid = (uid_t)-1;
1636 gid_t gid = (gid_t)-1;
1638 struct auth_serversupplied_info *result;
1641 Here is where we should check the list of
1642 trusted domains, and verify that the SID
1643 matches.
1646 if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
1647 return NT_STATUS_INVALID_PARAMETER;
1650 if (!sid_compose(&group_sid, info3->base.domain_sid,
1651 info3->base.primary_gid)) {
1652 return NT_STATUS_INVALID_PARAMETER;
1655 nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1656 if (!nt_username) {
1657 /* If the server didn't give us one, just use the one we sent
1658 * them */
1659 nt_username = sent_nt_username;
1662 nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1663 if (!nt_domain) {
1664 /* If the server didn't give us one, just use the one we sent
1665 * them */
1666 nt_domain = domain;
1669 /* try to fill the SAM account.. If getpwnam() fails, then try the
1670 add user script (2.2.x behavior).
1672 We use the _unmapped_ username here in an attempt to provide
1673 consistent username mapping behavior between kerberos and NTLM[SSP]
1674 authentication in domain mode security. I.E. Username mapping
1675 should be applied to the fully qualified username
1676 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1677 called map_username() unnecessarily in make_user_info_map() but
1678 that is how the current code is designed. Making the change here
1679 is the least disruptive place. -- jerry */
1681 if ( !(sam_account = samu_new( NULL )) ) {
1682 return NT_STATUS_NO_MEMORY;
1685 /* this call will try to create the user if necessary */
1687 nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1688 &found_username, &uid, &gid, sam_account,
1689 &username_was_mapped);
1692 /* if we still don't have a valid unix account check for
1693 'map to guest = bad uid' */
1695 if (!NT_STATUS_IS_OK(nt_status)) {
1696 TALLOC_FREE( sam_account );
1697 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1698 make_server_info_guest(NULL, server_info);
1699 return NT_STATUS_OK;
1701 return nt_status;
1704 if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1705 TALLOC_FREE(sam_account);
1706 return NT_STATUS_NO_MEMORY;
1709 if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1710 TALLOC_FREE(sam_account);
1711 return NT_STATUS_NO_MEMORY;
1714 if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1715 TALLOC_FREE(sam_account);
1716 return NT_STATUS_NO_MEMORY;
1719 if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1720 TALLOC_FREE(sam_account);
1721 return NT_STATUS_UNSUCCESSFUL;
1724 if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1725 TALLOC_FREE(sam_account);
1726 return NT_STATUS_UNSUCCESSFUL;
1729 if (!pdb_set_fullname(sam_account,
1730 info3->base.full_name.string,
1731 PDB_CHANGED)) {
1732 TALLOC_FREE(sam_account);
1733 return NT_STATUS_NO_MEMORY;
1736 if (!pdb_set_logon_script(sam_account,
1737 info3->base.logon_script.string,
1738 PDB_CHANGED)) {
1739 TALLOC_FREE(sam_account);
1740 return NT_STATUS_NO_MEMORY;
1743 if (!pdb_set_profile_path(sam_account,
1744 info3->base.profile_path.string,
1745 PDB_CHANGED)) {
1746 TALLOC_FREE(sam_account);
1747 return NT_STATUS_NO_MEMORY;
1750 if (!pdb_set_homedir(sam_account,
1751 info3->base.home_directory.string,
1752 PDB_CHANGED)) {
1753 TALLOC_FREE(sam_account);
1754 return NT_STATUS_NO_MEMORY;
1757 if (!pdb_set_dir_drive(sam_account,
1758 info3->base.home_drive.string,
1759 PDB_CHANGED)) {
1760 TALLOC_FREE(sam_account);
1761 return NT_STATUS_NO_MEMORY;
1764 if (!pdb_set_acct_ctrl(sam_account, info3->base.acct_flags, PDB_CHANGED)) {
1765 TALLOC_FREE(sam_account);
1766 return NT_STATUS_NO_MEMORY;
1769 if (!pdb_set_pass_last_set_time(
1770 sam_account,
1771 nt_time_to_unix(info3->base.last_password_change),
1772 PDB_CHANGED)) {
1773 TALLOC_FREE(sam_account);
1774 return NT_STATUS_NO_MEMORY;
1777 if (!pdb_set_pass_can_change_time(
1778 sam_account,
1779 nt_time_to_unix(info3->base.allow_password_change),
1780 PDB_CHANGED)) {
1781 TALLOC_FREE(sam_account);
1782 return NT_STATUS_NO_MEMORY;
1785 if (!pdb_set_pass_must_change_time(
1786 sam_account,
1787 nt_time_to_unix(info3->base.force_password_change),
1788 PDB_CHANGED)) {
1789 TALLOC_FREE(sam_account);
1790 return NT_STATUS_NO_MEMORY;
1793 result = make_server_info(NULL);
1794 if (result == NULL) {
1795 DEBUG(4, ("make_server_info failed!\n"));
1796 TALLOC_FREE(sam_account);
1797 return NT_STATUS_NO_MEMORY;
1800 /* save this here to _net_sam_logon() doesn't fail (it assumes a
1801 valid struct samu) */
1803 result->sam_account = sam_account;
1804 result->unix_name = talloc_strdup(result, found_username);
1806 result->sanitized_username = sanitize_username(result,
1807 result->unix_name);
1808 if (result->sanitized_username == NULL) {
1809 TALLOC_FREE(result);
1810 return NT_STATUS_NO_MEMORY;
1813 /* Fill in the unix info we found on the way */
1815 result->utok.uid = uid;
1816 result->utok.gid = gid;
1818 /* Create a 'combined' list of all SIDs we might want in the SD */
1820 result->num_sids = 0;
1821 result->sids = NULL;
1823 nt_status = sid_array_from_info3(result, info3,
1824 &result->sids,
1825 &result->num_sids,
1826 false, false);
1827 if (!NT_STATUS_IS_OK(nt_status)) {
1828 TALLOC_FREE(result);
1829 return nt_status;
1832 /* Ensure the primary group sid is at position 0. */
1833 sort_sid_array_for_smbd(result, &group_sid);
1835 result->login_server = talloc_strdup(result,
1836 info3->base.logon_server.string);
1838 /* ensure we are never given NULL session keys */
1840 if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1841 result->user_session_key = data_blob_null;
1842 } else {
1843 result->user_session_key = data_blob_talloc(
1844 result, info3->base.key.key,
1845 sizeof(info3->base.key.key));
1848 if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1849 result->lm_session_key = data_blob_null;
1850 } else {
1851 result->lm_session_key = data_blob_talloc(
1852 result, info3->base.LMSessKey.key,
1853 sizeof(info3->base.LMSessKey.key));
1856 result->nss_token |= username_was_mapped;
1858 *server_info = result;
1860 return NT_STATUS_OK;
1863 /*****************************************************************************
1864 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1865 ******************************************************************************/
1867 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1868 const char *sent_nt_username,
1869 const char *domain,
1870 const struct wbcAuthUserInfo *info,
1871 struct auth_serversupplied_info **server_info)
1873 static const char zeros[16] = {0, };
1875 NTSTATUS nt_status = NT_STATUS_OK;
1876 char *found_username = NULL;
1877 const char *nt_domain;
1878 const char *nt_username;
1879 struct samu *sam_account = NULL;
1880 DOM_SID user_sid;
1881 DOM_SID group_sid;
1882 bool username_was_mapped;
1883 uint32_t i;
1885 uid_t uid = (uid_t)-1;
1886 gid_t gid = (gid_t)-1;
1888 struct auth_serversupplied_info *result;
1890 result = make_server_info(NULL);
1891 if (result == NULL) {
1892 DEBUG(4, ("make_server_info failed!\n"));
1893 return NT_STATUS_NO_MEMORY;
1897 Here is where we should check the list of
1898 trusted domains, and verify that the SID
1899 matches.
1902 memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid));
1903 memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid));
1905 if (info->account_name) {
1906 nt_username = talloc_strdup(result, info->account_name);
1907 } else {
1908 /* If the server didn't give us one, just use the one we sent
1909 * them */
1910 nt_username = talloc_strdup(result, sent_nt_username);
1912 if (!nt_username) {
1913 TALLOC_FREE(result);
1914 return NT_STATUS_NO_MEMORY;
1917 if (info->domain_name) {
1918 nt_domain = talloc_strdup(result, info->domain_name);
1919 } else {
1920 /* If the server didn't give us one, just use the one we sent
1921 * them */
1922 nt_domain = talloc_strdup(result, domain);
1924 if (!nt_domain) {
1925 TALLOC_FREE(result);
1926 return NT_STATUS_NO_MEMORY;
1929 /* try to fill the SAM account.. If getpwnam() fails, then try the
1930 add user script (2.2.x behavior).
1932 We use the _unmapped_ username here in an attempt to provide
1933 consistent username mapping behavior between kerberos and NTLM[SSP]
1934 authentication in domain mode security. I.E. Username mapping
1935 should be applied to the fully qualified username
1936 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1937 called map_username() unnecessarily in make_user_info_map() but
1938 that is how the current code is designed. Making the change here
1939 is the least disruptive place. -- jerry */
1941 if ( !(sam_account = samu_new( result )) ) {
1942 TALLOC_FREE(result);
1943 return NT_STATUS_NO_MEMORY;
1946 /* this call will try to create the user if necessary */
1948 nt_status = fill_sam_account(result, nt_domain, sent_nt_username,
1949 &found_username, &uid, &gid, sam_account,
1950 &username_was_mapped);
1952 /* if we still don't have a valid unix account check for
1953 'map to guest = bad uid' */
1955 if (!NT_STATUS_IS_OK(nt_status)) {
1956 TALLOC_FREE( result );
1957 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1958 make_server_info_guest(NULL, server_info);
1959 return NT_STATUS_OK;
1961 return nt_status;
1964 if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1965 TALLOC_FREE(result);
1966 return NT_STATUS_NO_MEMORY;
1969 if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1970 TALLOC_FREE(result);
1971 return NT_STATUS_NO_MEMORY;
1974 if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1975 TALLOC_FREE(result);
1976 return NT_STATUS_NO_MEMORY;
1979 if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1980 TALLOC_FREE(result);
1981 return NT_STATUS_UNSUCCESSFUL;
1984 if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1985 TALLOC_FREE(result);
1986 return NT_STATUS_UNSUCCESSFUL;
1989 if (!pdb_set_fullname(sam_account, info->full_name, PDB_CHANGED)) {
1990 TALLOC_FREE(result);
1991 return NT_STATUS_NO_MEMORY;
1994 if (!pdb_set_logon_script(sam_account, info->logon_script, PDB_CHANGED)) {
1995 TALLOC_FREE(result);
1996 return NT_STATUS_NO_MEMORY;
1999 if (!pdb_set_profile_path(sam_account, info->profile_path, PDB_CHANGED)) {
2000 TALLOC_FREE(result);
2001 return NT_STATUS_NO_MEMORY;
2004 if (!pdb_set_homedir(sam_account, info->home_directory, PDB_CHANGED)) {
2005 TALLOC_FREE(result);
2006 return NT_STATUS_NO_MEMORY;
2009 if (!pdb_set_dir_drive(sam_account, info->home_drive, PDB_CHANGED)) {
2010 TALLOC_FREE(result);
2011 return NT_STATUS_NO_MEMORY;
2014 if (!pdb_set_acct_ctrl(sam_account, info->acct_flags, PDB_CHANGED)) {
2015 TALLOC_FREE(result);
2016 return NT_STATUS_NO_MEMORY;
2019 if (!pdb_set_pass_last_set_time(
2020 sam_account,
2021 nt_time_to_unix(info->pass_last_set_time),
2022 PDB_CHANGED)) {
2023 TALLOC_FREE(result);
2024 return NT_STATUS_NO_MEMORY;
2027 if (!pdb_set_pass_can_change_time(
2028 sam_account,
2029 nt_time_to_unix(info->pass_can_change_time),
2030 PDB_CHANGED)) {
2031 TALLOC_FREE(result);
2032 return NT_STATUS_NO_MEMORY;
2035 if (!pdb_set_pass_must_change_time(
2036 sam_account,
2037 nt_time_to_unix(info->pass_must_change_time),
2038 PDB_CHANGED)) {
2039 TALLOC_FREE(result);
2040 return NT_STATUS_NO_MEMORY;
2043 /* save this here to _net_sam_logon() doesn't fail (it assumes a
2044 valid struct samu) */
2046 result->sam_account = sam_account;
2047 result->unix_name = talloc_strdup(result, found_username);
2049 result->sanitized_username = sanitize_username(result,
2050 result->unix_name);
2051 result->login_server = talloc_strdup(result, info->logon_server);
2053 if ((result->unix_name == NULL)
2054 || (result->sanitized_username == NULL)
2055 || (result->login_server == NULL)) {
2056 TALLOC_FREE(result);
2057 return NT_STATUS_NO_MEMORY;
2060 /* Fill in the unix info we found on the way */
2062 result->utok.uid = uid;
2063 result->utok.gid = gid;
2065 /* Create a 'combined' list of all SIDs we might want in the SD */
2067 result->num_sids = info->num_sids - 2;
2068 result->sids = talloc_array(result, DOM_SID, result->num_sids);
2069 if (result->sids == NULL) {
2070 TALLOC_FREE(result);
2071 return NT_STATUS_NO_MEMORY;
2074 for (i=0; i < result->num_sids; i++) {
2075 memcpy(&result->sids[i], &info->sids[i+2].sid, sizeof(result->sids[i]));
2078 /* Ensure the primary group sid is at position 0. */
2079 sort_sid_array_for_smbd(result, &group_sid);
2081 /* ensure we are never given NULL session keys */
2083 if (memcmp(info->user_session_key, zeros, sizeof(zeros)) == 0) {
2084 result->user_session_key = data_blob_null;
2085 } else {
2086 result->user_session_key = data_blob_talloc(
2087 result, info->user_session_key,
2088 sizeof(info->user_session_key));
2091 if (memcmp(info->lm_session_key, zeros, 8) == 0) {
2092 result->lm_session_key = data_blob_null;
2093 } else {
2094 result->lm_session_key = data_blob_talloc(
2095 result, info->lm_session_key,
2096 sizeof(info->lm_session_key));
2099 result->nss_token |= username_was_mapped;
2101 *server_info = result;
2103 return NT_STATUS_OK;
2106 /***************************************************************************
2107 Free a user_info struct
2108 ***************************************************************************/
2110 void free_user_info(struct auth_usersupplied_info **user_info)
2112 DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
2113 if (*user_info != NULL) {
2114 if ((*user_info)->smb_name) {
2115 DEBUG(10,("structure was created for %s\n",
2116 (*user_info)->smb_name));
2118 SAFE_FREE((*user_info)->smb_name);
2119 SAFE_FREE((*user_info)->internal_username);
2120 SAFE_FREE((*user_info)->client_domain);
2121 SAFE_FREE((*user_info)->domain);
2122 SAFE_FREE((*user_info)->wksta_name);
2123 data_blob_free(&(*user_info)->lm_resp);
2124 data_blob_free(&(*user_info)->nt_resp);
2125 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
2126 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
2127 data_blob_clear_free(&(*user_info)->plaintext_password);
2128 ZERO_STRUCT(**user_info);
2130 SAFE_FREE(*user_info);
2133 /***************************************************************************
2134 Make an auth_methods struct
2135 ***************************************************************************/
2137 bool make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method)
2139 if (!auth_context) {
2140 smb_panic("no auth_context supplied to "
2141 "make_auth_methods()!\n");
2144 if (!auth_method) {
2145 smb_panic("make_auth_methods: pointer to auth_method pointer "
2146 "is NULL!\n");
2149 *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
2150 if (!*auth_method) {
2151 DEBUG(0,("make_auth_method: malloc failed!\n"));
2152 return False;
2154 ZERO_STRUCTP(*auth_method);
2156 return True;
2160 * Verify whether or not given domain is trusted.
2162 * @param domain_name name of the domain to be verified
2163 * @return true if domain is one of the trusted ones or
2164 * false if otherwise
2167 bool is_trusted_domain(const char* dom_name)
2169 DOM_SID trustdom_sid;
2170 bool ret;
2172 /* no trusted domains for a standalone server */
2174 if ( lp_server_role() == ROLE_STANDALONE )
2175 return False;
2177 if (dom_name == NULL || dom_name[0] == '\0') {
2178 return false;
2181 if (strequal(dom_name, get_global_sam_name())) {
2182 return false;
2185 /* if we are a DC, then check for a direct trust relationships */
2187 if ( IS_DC ) {
2188 become_root();
2189 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2190 "[%s]\n", dom_name ));
2191 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
2192 unbecome_root();
2193 if (ret)
2194 return True;
2196 else {
2197 wbcErr result;
2199 /* If winbind is around, ask it */
2201 result = wb_is_trusted_domain(dom_name);
2203 if (result == WBC_ERR_SUCCESS) {
2204 return True;
2207 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
2208 /* winbind could not find the domain */
2209 return False;
2212 /* The only other possible result is that winbind is not up
2213 and running. We need to update the trustdom_cache
2214 ourselves */
2216 update_trustdom_cache();
2219 /* now the trustdom cache should be available a DC could still
2220 * have a transitive trust so fall back to the cache of trusted
2221 * domains (like a domain member would use */
2223 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
2224 return True;
2227 return False;