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/>.
25 #include "../libcli/auth/libcli_auth.h"
28 #define DBGC_CLASS DBGC_AUTH
30 /****************************************************************************
31 Ensure primary group SID is always at position 0 in a
32 auth_serversupplied_info struct.
33 ****************************************************************************/
35 static void sort_sid_array_for_smbd(auth_serversupplied_info *result,
36 const DOM_SID *pgroup_sid)
44 if (sid_compare(&result->sids[0], pgroup_sid)==0) {
48 for (i = 1; i < result->num_sids; i++) {
49 if (sid_compare(pgroup_sid,
50 &result->sids[i]) == 0) {
51 sid_copy(&result->sids[i], &result->sids[0]);
52 sid_copy(&result->sids[0], pgroup_sid);
58 /****************************************************************************
59 Create a UNIX user on demand.
60 ****************************************************************************/
62 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
64 TALLOC_CTX *ctx = talloc_tos();
68 add_script = talloc_strdup(ctx, lp_adduser_script());
69 if (!add_script || !*add_script) {
72 add_script = talloc_all_string_sub(ctx,
80 add_script = talloc_all_string_sub(ctx,
89 add_script = talloc_all_string_sub(ctx,
97 ret = smbrun(add_script,NULL);
100 ("smb_create_user: Running the command `%s' gave %d\n",
105 /****************************************************************************
106 Create an auth_usersupplied_data structure
107 ****************************************************************************/
109 static NTSTATUS make_user_info(auth_usersupplied_info **user_info,
110 const char *smb_name,
111 const char *internal_username,
112 const char *client_domain,
114 const char *wksta_name,
115 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
116 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
117 DATA_BLOB *plaintext,
121 DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
123 *user_info = SMB_MALLOC_P(auth_usersupplied_info);
124 if (*user_info == NULL) {
125 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
126 return NT_STATUS_NO_MEMORY;
129 ZERO_STRUCTP(*user_info);
131 DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
133 (*user_info)->smb_name = SMB_STRDUP(smb_name);
134 if ((*user_info)->smb_name == NULL) {
135 free_user_info(user_info);
136 return NT_STATUS_NO_MEMORY;
139 (*user_info)->internal_username = SMB_STRDUP(internal_username);
140 if ((*user_info)->internal_username == NULL) {
141 free_user_info(user_info);
142 return NT_STATUS_NO_MEMORY;
145 (*user_info)->domain = SMB_STRDUP(domain);
146 if ((*user_info)->domain == NULL) {
147 free_user_info(user_info);
148 return NT_STATUS_NO_MEMORY;
151 (*user_info)->client_domain = SMB_STRDUP(client_domain);
152 if ((*user_info)->client_domain == NULL) {
153 free_user_info(user_info);
154 return NT_STATUS_NO_MEMORY;
157 (*user_info)->wksta_name = SMB_STRDUP(wksta_name);
158 if ((*user_info)->wksta_name == NULL) {
159 free_user_info(user_info);
160 return NT_STATUS_NO_MEMORY;
163 DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
166 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
168 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
169 if (lm_interactive_pwd)
170 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
171 if (nt_interactive_pwd)
172 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
175 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
177 (*user_info)->encrypted = encrypted;
179 (*user_info)->logon_parameters = 0;
181 DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
186 /****************************************************************************
187 Create an auth_usersupplied_data structure after appropriate mapping.
188 ****************************************************************************/
190 NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
191 const char *smb_name,
192 const char *client_domain,
193 const char *wksta_name,
196 DATA_BLOB *lm_interactive_pwd,
197 DATA_BLOB *nt_interactive_pwd,
198 DATA_BLOB *plaintext,
204 fstring internal_username;
205 fstrcpy(internal_username, smb_name);
206 was_mapped = map_username(internal_username);
208 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
209 client_domain, smb_name, wksta_name));
211 /* don't allow "" as a domain, fixes a Win9X bug
212 where it doens't supply a domain for logon script
213 'net use' commands. */
215 if ( *client_domain )
216 domain = client_domain;
218 domain = lp_workgroup();
220 /* If you connect to a Windows domain member using a bogus domain name,
221 * the Windows box will map the BOGUS\user to SAMNAME\user. Thus, if
222 * the Windows box is a DC the name will become DOMAIN\user and be
223 * authenticated against AD, if the Windows box is a member server but
224 * not a DC the name will become WORKSTATION\user. A standalone
225 * non-domain member box will also map to WORKSTATION\user. */
227 if (!is_trusted_domain(domain) &&
228 !strequal(domain, get_global_sam_name()) )
230 if (lp_map_untrusted_to_domain())
231 domain = my_sam_name();
233 domain = get_global_sam_name();
234 DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
235 "workstation [%s]\n",
236 client_domain, domain, smb_name, wksta_name));
239 /* We know that the given domain is trusted (and we are allowing them),
240 * it is our global SAM name, or for legacy behavior it is our
241 * primary domain name */
243 result = make_user_info(user_info, smb_name, internal_username,
244 client_domain, domain, wksta_name,
246 lm_interactive_pwd, nt_interactive_pwd,
247 plaintext, encrypted);
248 if (NT_STATUS_IS_OK(result)) {
249 (*user_info)->was_mapped = was_mapped;
254 /****************************************************************************
255 Create an auth_usersupplied_data, making the DATA_BLOBs here.
256 Decrypt and encrypt the passwords.
257 ****************************************************************************/
259 bool make_user_info_netlogon_network(auth_usersupplied_info **user_info,
260 const char *smb_name,
261 const char *client_domain,
262 const char *wksta_name,
263 uint32 logon_parameters,
264 const uchar *lm_network_pwd,
266 const uchar *nt_network_pwd,
271 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
272 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
274 status = make_user_info_map(user_info,
275 smb_name, client_domain,
277 lm_pwd_len ? &lm_blob : NULL,
278 nt_pwd_len ? &nt_blob : NULL,
282 if (NT_STATUS_IS_OK(status)) {
283 (*user_info)->logon_parameters = logon_parameters;
285 ret = NT_STATUS_IS_OK(status) ? True : False;
287 data_blob_free(&lm_blob);
288 data_blob_free(&nt_blob);
292 /****************************************************************************
293 Create an auth_usersupplied_data, making the DATA_BLOBs here.
294 Decrypt and encrypt the passwords.
295 ****************************************************************************/
297 bool make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
298 const char *smb_name,
299 const char *client_domain,
300 const char *wksta_name,
301 uint32 logon_parameters,
303 const uchar lm_interactive_pwd[16],
304 const uchar nt_interactive_pwd[16],
305 const uchar *dc_sess_key)
307 unsigned char lm_pwd[16];
308 unsigned char nt_pwd[16];
309 unsigned char local_lm_response[24];
310 unsigned char local_nt_response[24];
311 unsigned char key[16];
313 memcpy(key, dc_sess_key, 16);
315 if (lm_interactive_pwd)
316 memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
318 if (nt_interactive_pwd)
319 memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
321 #ifdef DEBUG_PASSWORD
323 dump_data(100, key, sizeof(key));
325 DEBUG(100,("lm owf password:"));
326 dump_data(100, lm_pwd, sizeof(lm_pwd));
328 DEBUG(100,("nt owf password:"));
329 dump_data(100, nt_pwd, sizeof(nt_pwd));
332 if (lm_interactive_pwd)
333 arcfour_crypt(lm_pwd, key, sizeof(lm_pwd));
335 if (nt_interactive_pwd)
336 arcfour_crypt(nt_pwd, key, sizeof(nt_pwd));
338 #ifdef DEBUG_PASSWORD
339 DEBUG(100,("decrypt of lm owf password:"));
340 dump_data(100, lm_pwd, sizeof(lm_pwd));
342 DEBUG(100,("decrypt of nt owf password:"));
343 dump_data(100, nt_pwd, sizeof(nt_pwd));
346 if (lm_interactive_pwd)
347 SMBOWFencrypt(lm_pwd, chal,
350 if (nt_interactive_pwd)
351 SMBOWFencrypt(nt_pwd, chal,
354 /* Password info paranoia */
360 DATA_BLOB local_lm_blob;
361 DATA_BLOB local_nt_blob;
363 DATA_BLOB lm_interactive_blob;
364 DATA_BLOB nt_interactive_blob;
366 if (lm_interactive_pwd) {
367 local_lm_blob = data_blob(local_lm_response,
368 sizeof(local_lm_response));
369 lm_interactive_blob = data_blob(lm_pwd,
374 if (nt_interactive_pwd) {
375 local_nt_blob = data_blob(local_nt_response,
376 sizeof(local_nt_response));
377 nt_interactive_blob = data_blob(nt_pwd,
382 nt_status = make_user_info_map(
384 smb_name, client_domain, wksta_name,
385 lm_interactive_pwd ? &local_lm_blob : NULL,
386 nt_interactive_pwd ? &local_nt_blob : NULL,
387 lm_interactive_pwd ? &lm_interactive_blob : NULL,
388 nt_interactive_pwd ? &nt_interactive_blob : NULL,
391 if (NT_STATUS_IS_OK(nt_status)) {
392 (*user_info)->logon_parameters = logon_parameters;
395 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
396 data_blob_free(&local_lm_blob);
397 data_blob_free(&local_nt_blob);
398 data_blob_free(&lm_interactive_blob);
399 data_blob_free(&nt_interactive_blob);
405 /****************************************************************************
406 Create an auth_usersupplied_data structure
407 ****************************************************************************/
409 bool make_user_info_for_reply(auth_usersupplied_info **user_info,
410 const char *smb_name,
411 const char *client_domain,
413 DATA_BLOB plaintext_password)
416 DATA_BLOB local_lm_blob;
417 DATA_BLOB local_nt_blob;
418 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
421 * Not encrypted - do so.
424 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
427 if (plaintext_password.data) {
428 unsigned char local_lm_response[24];
430 #ifdef DEBUG_PASSWORD
431 DEBUG(10,("Unencrypted password (len %d):\n",
432 (int)plaintext_password.length));
433 dump_data(100, plaintext_password.data,
434 plaintext_password.length);
437 SMBencrypt( (const char *)plaintext_password.data,
438 (const uchar*)chal, local_lm_response);
439 local_lm_blob = data_blob(local_lm_response, 24);
441 /* We can't do an NT hash here, as the password needs to be
443 local_nt_blob = data_blob_null;
446 local_lm_blob = data_blob_null;
447 local_nt_blob = data_blob_null;
450 ret = make_user_info_map(
451 user_info, smb_name, client_domain,
452 get_remote_machine_name(),
453 local_lm_blob.data ? &local_lm_blob : NULL,
454 local_nt_blob.data ? &local_nt_blob : NULL,
456 plaintext_password.data ? &plaintext_password : NULL,
459 data_blob_free(&local_lm_blob);
460 return NT_STATUS_IS_OK(ret) ? True : False;
463 /****************************************************************************
464 Create an auth_usersupplied_data structure
465 ****************************************************************************/
467 NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
468 const char *smb_name,
469 const char *client_domain,
470 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
472 return make_user_info_map(user_info, smb_name,
474 get_remote_machine_name(),
475 lm_resp.data ? &lm_resp : NULL,
476 nt_resp.data ? &nt_resp : NULL,
481 /****************************************************************************
482 Create a guest user_info blob, for anonymous authenticaion.
483 ****************************************************************************/
485 bool make_user_info_guest(auth_usersupplied_info **user_info)
489 nt_status = make_user_info(user_info,
498 return NT_STATUS_IS_OK(nt_status) ? True : False;
501 static int server_info_dtor(auth_serversupplied_info *server_info)
503 TALLOC_FREE(server_info->sam_account);
504 ZERO_STRUCTP(server_info);
508 /***************************************************************************
509 Make a server_info struct. Free with TALLOC_FREE().
510 ***************************************************************************/
512 static auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
514 struct auth_serversupplied_info *result;
516 result = TALLOC_ZERO_P(mem_ctx, auth_serversupplied_info);
517 if (result == NULL) {
518 DEBUG(0, ("talloc failed\n"));
522 talloc_set_destructor(result, server_info_dtor);
524 /* Initialise the uid and gid values to something non-zero
525 which may save us from giving away root access if there
526 is a bug in allocating these fields. */
528 result->utok.uid = -1;
529 result->utok.gid = -1;
533 static char *sanitize_username(TALLOC_CTX *mem_ctx, const char *username)
537 alpha_strcpy(tmp, username, ". _-$", sizeof(tmp));
538 return talloc_strdup(mem_ctx, tmp);
541 /***************************************************************************
542 Is the incoming username our own machine account ?
543 If so, the connection is almost certainly from winbindd.
544 ***************************************************************************/
546 static bool is_our_machine_account(const char *username)
549 char *truncname = NULL;
550 size_t ulen = strlen(username);
552 if (ulen == 0 || username[ulen-1] != '$') {
555 truncname = SMB_STRDUP(username);
559 truncname[ulen-1] = '\0';
560 ret = strequal(truncname, global_myname());
561 SAFE_FREE(truncname);
565 /***************************************************************************
566 Make (and fill) a user_info struct from a struct samu
567 ***************************************************************************/
569 NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
570 struct samu *sampass)
574 auth_serversupplied_info *result;
575 const char *username = pdb_get_username(sampass);
578 if ( !(result = make_server_info(NULL)) ) {
579 return NT_STATUS_NO_MEMORY;
582 if ( !(pwd = getpwnam_alloc(result, username)) ) {
583 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
584 pdb_get_username(sampass)));
586 return NT_STATUS_NO_SUCH_USER;
589 result->sam_account = sampass;
590 result->unix_name = pwd->pw_name;
591 /* Ensure that we keep pwd->pw_name, because we will free pwd below */
592 talloc_steal(result, pwd->pw_name);
593 result->utok.gid = pwd->pw_gid;
594 result->utok.uid = pwd->pw_uid;
598 result->sanitized_username = sanitize_username(result,
600 if (result->sanitized_username == NULL) {
602 return NT_STATUS_NO_MEMORY;
605 if (IS_DC && is_our_machine_account(username)) {
607 * Ensure for a connection from our own
608 * machine account (from winbindd on a DC)
609 * there are no supplementary groups.
610 * Prevents loops in calling gid_to_sid().
614 result->num_sids = 0;
617 * This is a hack of monstrous proportions.
618 * If we know it's winbindd talking to us,
619 * we know we must never recurse into it,
620 * so turn off contacting winbindd for this
621 * entire process. This will get fixed when
622 * winbindd doesn't need to talk to smbd on
628 DEBUG(10, ("make_server_info_sam: our machine account %s "
629 "setting supplementary group list empty and "
630 "turning off winbindd requests.\n",
633 status = pdb_enum_group_memberships(result, sampass,
634 &result->sids, &gids,
637 if (!NT_STATUS_IS_OK(status)) {
638 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
640 result->sam_account = NULL; /* Don't free on error exit. */
646 /* For now we throw away the gids and convert via sid_to_gid
647 * later. This needs fixing, but I'd like to get the code straight and
652 DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
653 pdb_get_username(sampass), result->unix_name));
655 *server_info = result;
656 /* Ensure that the sampass will be freed with the result */
657 talloc_steal(result, sampass);
662 static NTSTATUS log_nt_token(NT_USER_TOKEN *token)
664 TALLOC_CTX *frame = talloc_stackframe();
669 if ((lp_log_nt_token_command() == NULL) ||
670 (strlen(lp_log_nt_token_command()) == 0)) {
675 group_sidstr = talloc_strdup(frame, "");
676 for (i=1; i<token->num_sids; i++) {
677 group_sidstr = talloc_asprintf(
678 frame, "%s %s", group_sidstr,
679 sid_string_talloc(frame, &token->user_sids[i]));
682 command = talloc_string_sub(
683 frame, lp_log_nt_token_command(),
684 "%s", sid_string_talloc(frame, &token->user_sids[0]));
685 command = talloc_string_sub(frame, command, "%t", group_sidstr);
687 if (command == NULL) {
689 return NT_STATUS_NO_MEMORY;
692 DEBUG(8, ("running command: [%s]\n", command));
693 if (smbrun(command, NULL) != 0) {
694 DEBUG(0, ("Could not log NT token\n"));
696 return NT_STATUS_ACCESS_DENIED;
704 * Create the token to use from server_info->sam_account and
705 * server_info->sids (the info3/sam groups). Find the unix gids.
708 NTSTATUS create_local_token(auth_serversupplied_info *server_info)
712 struct dom_sid tmp_sid;
715 * If winbind is not around, we can not make much use of the SIDs the
716 * domain controller provided us with. Likewise if the user name was
717 * mapped to some local unix user.
720 if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
721 (server_info->nss_token)) {
722 status = create_token_from_username(server_info,
723 server_info->unix_name,
725 &server_info->utok.uid,
726 &server_info->utok.gid,
727 &server_info->unix_name,
731 server_info->ptok = create_local_nt_token(
733 pdb_get_user_sid(server_info->sam_account),
735 server_info->num_sids, server_info->sids);
736 status = server_info->ptok ?
737 NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
740 if (!NT_STATUS_IS_OK(status)) {
744 /* Convert the SIDs to gids. */
746 server_info->utok.ngroups = 0;
747 server_info->utok.groups = NULL;
749 /* Start at index 1, where the groups start. */
751 for (i=1; i<server_info->ptok->num_sids; i++) {
753 DOM_SID *sid = &server_info->ptok->user_sids[i];
755 if (!sid_to_gid(sid, &gid)) {
756 DEBUG(10, ("Could not convert SID %s to gid, "
757 "ignoring it\n", sid_string_dbg(sid)));
760 add_gid_to_array_unique(server_info, gid,
761 &server_info->utok.groups,
762 &server_info->utok.ngroups);
766 * Add the "Unix Group" SID for each gid to catch mapped groups
767 * and their Unix equivalent. This is to solve the backwards
768 * compatibility problem of 'valid users = +ntadmin' where
769 * ntadmin has been paired with "Domain Admins" in the group
770 * mapping table. Otherwise smb.conf would need to be changed
771 * to 'valid user = "Domain Admins"'. --jerry
773 * For consistency we also add the "Unix User" SID,
774 * so that the complete unix token is represented within
778 if (!uid_to_unix_users_sid(server_info->utok.uid, &tmp_sid)) {
779 DEBUG(1,("create_local_token: Failed to create SID "
780 "for uid %u!\n", (unsigned int)server_info->utok.uid));
782 add_sid_to_array_unique(server_info->ptok, &tmp_sid,
783 &server_info->ptok->user_sids,
784 &server_info->ptok->num_sids);
786 for ( i=0; i<server_info->utok.ngroups; i++ ) {
787 if (!gid_to_unix_groups_sid( server_info->utok.groups[i], &tmp_sid ) ) {
788 DEBUG(1,("create_local_token: Failed to create SID "
789 "for gid %u!\n", (unsigned int)server_info->utok.groups[i]));
792 add_sid_to_array_unique(server_info->ptok, &tmp_sid,
793 &server_info->ptok->user_sids,
794 &server_info->ptok->num_sids);
797 debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
798 debug_unix_user_token(DBGC_AUTH, 10,
799 server_info->utok.uid,
800 server_info->utok.gid,
801 server_info->utok.ngroups,
802 server_info->utok.groups);
804 status = log_nt_token(server_info->ptok);
809 * Create an artificial NT token given just a username. (Initially intended
812 * We go through lookup_name() to avoid problems we had with 'winbind use
817 * unmapped unix users: Go directly to nss to find the user's group.
819 * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
821 * If the user is provided by winbind, the primary gid is set to "domain
822 * users" of the user's domain. For an explanation why this is necessary, see
823 * the thread starting at
824 * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
827 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
829 uid_t *uid, gid_t *gid,
830 char **found_username,
831 struct nt_user_token **token)
833 NTSTATUS result = NT_STATUS_NO_SUCH_USER;
836 enum lsa_SidType type;
839 DOM_SID unix_group_sid;
840 size_t num_group_sids;
844 tmp_ctx = talloc_new(NULL);
845 if (tmp_ctx == NULL) {
846 DEBUG(0, ("talloc_new failed\n"));
847 return NT_STATUS_NO_MEMORY;
850 if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,
851 NULL, NULL, &user_sid, &type)) {
852 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));
856 if (type != SID_NAME_USER) {
857 DEBUG(1, ("%s is a %s, not a user\n", username,
858 sid_type_lookup(type)));
862 if (sid_check_is_in_our_domain(&user_sid)) {
865 /* This is a passdb user, so ask passdb */
867 struct samu *sam_acct = NULL;
869 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
870 result = NT_STATUS_NO_MEMORY;
875 ret = pdb_getsampwsid(sam_acct, &user_sid);
879 DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
880 sid_string_dbg(&user_sid), username));
881 DEBUGADD(1, ("Fall back to unix user %s\n", username));
885 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
888 if (!NT_STATUS_IS_OK(result)) {
889 DEBUG(1, ("enum_group_memberships failed for %s (%s): "
890 "%s\n", username, sid_string_dbg(&user_sid),
892 DEBUGADD(1, ("Fall back to unix user %s\n", username));
896 /* see the smb_panic() in pdb_default_enum_group_memberships */
897 SMB_ASSERT(num_group_sids > 0);
901 /* Ensure we're returning the found_username on the right context. */
902 *found_username = talloc_strdup(mem_ctx,
903 pdb_get_username(sam_acct));
906 * If the SID from lookup_name() was the guest sid, passdb knows
907 * about the mapping of guest sid to lp_guestaccount()
908 * username and will return the unix_pw info for a guest
909 * user. Use it if it's there, else lookup the *uid details
910 * using getpwnam_alloc(). See bug #6291 for details. JRA.
913 /* We must always assign the *uid. */
914 if (sam_acct->unix_pw == NULL) {
915 struct passwd *pwd = getpwnam_alloc(sam_acct, *found_username );
917 DEBUG(10, ("getpwnam_alloc failed for %s\n",
919 result = NT_STATUS_NO_SUCH_USER;
922 result = samu_set_unix(sam_acct, pwd );
923 if (!NT_STATUS_IS_OK(result)) {
924 DEBUG(10, ("samu_set_unix failed for %s\n",
926 result = NT_STATUS_NO_SUCH_USER;
930 *uid = sam_acct->unix_pw->pw_uid;
932 } else if (sid_check_is_in_unix_users(&user_sid)) {
934 /* This is a unix user not in passdb. We need to ask nss
935 * directly, without consulting passdb */
940 * This goto target is used as a fallback for the passdb
941 * case. The concrete bug report is when passdb gave us an
947 if (!sid_to_uid(&user_sid, uid)) {
948 DEBUG(1, ("unix_user case, sid_to_uid for %s (%s) failed\n",
949 username, sid_string_dbg(&user_sid)));
950 result = NT_STATUS_NO_SUCH_USER;
954 uid_to_unix_users_sid(*uid, &user_sid);
956 pass = getpwuid_alloc(tmp_ctx, *uid);
958 DEBUG(1, ("getpwuid(%u) for user %s failed\n",
959 (unsigned int)*uid, username));
963 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
964 &gids, &num_group_sids)) {
965 DEBUG(1, ("getgroups_unix_user for user %s failed\n",
970 if (num_group_sids) {
971 group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
972 if (group_sids == NULL) {
973 DEBUG(1, ("TALLOC_ARRAY failed\n"));
974 result = NT_STATUS_NO_MEMORY;
981 for (i=0; i<num_group_sids; i++) {
982 gid_to_sid(&group_sids[i], gids[i]);
985 /* In getgroups_unix_user we always set the primary gid */
986 SMB_ASSERT(num_group_sids > 0);
990 /* Ensure we're returning the found_username on the right context. */
991 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
994 /* This user is from winbind, force the primary gid to the
995 * user's "domain users" group. Under certain circumstances
996 * (user comes from NT4), this might be a loss of
997 * information. But we can not rely on winbind getting the
998 * correct info. AD might prohibit winbind looking up that
1003 /* We must always assign the *uid. */
1004 if (!sid_to_uid(&user_sid, uid)) {
1005 DEBUG(1, ("winbindd case, sid_to_uid for %s (%s) failed\n",
1006 username, sid_string_dbg(&user_sid)));
1007 result = NT_STATUS_NO_SUCH_USER;
1012 group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
1013 if (group_sids == NULL) {
1014 DEBUG(1, ("TALLOC_ARRAY failed\n"));
1015 result = NT_STATUS_NO_MEMORY;
1019 sid_copy(&group_sids[0], &user_sid);
1020 sid_split_rid(&group_sids[0], &dummy);
1021 sid_append_rid(&group_sids[0], DOMAIN_GROUP_RID_USERS);
1023 if (!sid_to_gid(&group_sids[0], gid)) {
1024 DEBUG(1, ("sid_to_gid(%s) failed\n",
1025 sid_string_dbg(&group_sids[0])));
1031 /* Ensure we're returning the found_username on the right context. */
1032 *found_username = talloc_strdup(mem_ctx, username);
1035 /* Add the "Unix Group" SID for each gid to catch mapped groups
1036 and their Unix equivalent. This is to solve the backwards
1037 compatibility problem of 'valid users = +ntadmin' where
1038 ntadmin has been paired with "Domain Admins" in the group
1039 mapping table. Otherwise smb.conf would need to be changed
1040 to 'valid user = "Domain Admins"'. --jerry */
1042 num_gids = num_group_sids;
1043 for ( i=0; i<num_gids; i++ ) {
1046 /* don't pickup anything managed by Winbind */
1048 if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) )
1051 if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {
1052 DEBUG(1,("create_token_from_username: Failed to create SID "
1053 "for gid %u!\n", (unsigned int)gids[i]));
1056 result = add_sid_to_array_unique(tmp_ctx, &unix_group_sid,
1057 &group_sids, &num_group_sids);
1058 if (!NT_STATUS_IS_OK(result)) {
1063 /* Ensure we're creating the nt_token on the right context. */
1064 *token = create_local_nt_token(mem_ctx, &user_sid,
1065 is_guest, num_group_sids, group_sids);
1067 if ((*token == NULL) || (*found_username == NULL)) {
1068 result = NT_STATUS_NO_MEMORY;
1072 result = NT_STATUS_OK;
1074 TALLOC_FREE(tmp_ctx);
1078 /***************************************************************************
1079 Build upon create_token_from_username:
1081 Expensive helper function to figure out whether a user given its name is
1082 member of a particular group.
1083 ***************************************************************************/
1085 bool user_in_group_sid(const char *username, const DOM_SID *group_sid)
1090 char *found_username;
1091 struct nt_user_token *token;
1094 TALLOC_CTX *mem_ctx;
1096 mem_ctx = talloc_new(NULL);
1097 if (mem_ctx == NULL) {
1098 DEBUG(0, ("talloc_new failed\n"));
1102 status = create_token_from_username(mem_ctx, username, False,
1103 &uid, &gid, &found_username,
1106 if (!NT_STATUS_IS_OK(status)) {
1107 DEBUG(10, ("could not create token for %s\n", username));
1111 result = nt_token_check_sid(group_sid, token);
1113 TALLOC_FREE(mem_ctx);
1118 bool user_in_group(const char *username, const char *groupname)
1120 TALLOC_CTX *mem_ctx;
1124 mem_ctx = talloc_new(NULL);
1125 if (mem_ctx == NULL) {
1126 DEBUG(0, ("talloc_new failed\n"));
1130 ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1131 NULL, NULL, &group_sid, NULL);
1132 TALLOC_FREE(mem_ctx);
1135 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
1139 return user_in_group_sid(username, &group_sid);
1142 /***************************************************************************
1143 Make (and fill) a server_info struct from a 'struct passwd' by conversion
1145 ***************************************************************************/
1147 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,
1148 char *unix_username,
1152 struct samu *sampass = NULL;
1154 char *qualified_name = NULL;
1155 TALLOC_CTX *mem_ctx = NULL;
1157 enum lsa_SidType type;
1158 auth_serversupplied_info *result;
1160 if ( !(sampass = samu_new( NULL )) ) {
1161 return NT_STATUS_NO_MEMORY;
1164 status = samu_set_unix( sampass, pwd );
1165 if (!NT_STATUS_IS_OK(status)) {
1169 result = make_server_info(NULL);
1170 if (result == NULL) {
1171 TALLOC_FREE(sampass);
1172 return NT_STATUS_NO_MEMORY;
1175 result->sam_account = sampass;
1177 result->unix_name = talloc_strdup(result, unix_username);
1178 result->sanitized_username = sanitize_username(result, unix_username);
1180 if ((result->unix_name == NULL)
1181 || (result->sanitized_username == NULL)) {
1182 TALLOC_FREE(sampass);
1183 TALLOC_FREE(result);
1184 return NT_STATUS_NO_MEMORY;
1187 result->utok.uid = pwd->pw_uid;
1188 result->utok.gid = pwd->pw_gid;
1190 status = pdb_enum_group_memberships(result, sampass,
1191 &result->sids, &gids,
1194 if (!NT_STATUS_IS_OK(status)) {
1195 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
1196 nt_errstr(status)));
1197 TALLOC_FREE(result);
1202 * The SID returned in server_info->sam_account is based
1203 * on our SAM sid even though for a pure UNIX account this should
1204 * not be the case as it doesn't really exist in the SAM db.
1205 * This causes lookups on "[in]valid users" to fail as they
1206 * will lookup this name as a "Unix User" SID to check against
1207 * the user token. Fix this by adding the "Unix User"\unix_username
1208 * SID to the sid array. The correct fix should probably be
1209 * changing the server_info->sam_account user SID to be a
1210 * S-1-22 Unix SID, but this might break old configs where
1211 * plaintext passwords were used with no SAM backend.
1214 mem_ctx = talloc_init("make_server_info_pw_tmp");
1216 TALLOC_FREE(result);
1217 return NT_STATUS_NO_MEMORY;
1220 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
1221 unix_users_domain_name(),
1223 if (!qualified_name) {
1224 TALLOC_FREE(result);
1225 TALLOC_FREE(mem_ctx);
1226 return NT_STATUS_NO_MEMORY;
1229 if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
1232 TALLOC_FREE(result);
1233 TALLOC_FREE(mem_ctx);
1234 return NT_STATUS_NO_SUCH_USER;
1237 TALLOC_FREE(mem_ctx);
1239 if (type != SID_NAME_USER) {
1240 TALLOC_FREE(result);
1241 return NT_STATUS_NO_SUCH_USER;
1244 status = add_sid_to_array_unique(result, &u_sid,
1247 if (!NT_STATUS_IS_OK(status)) {
1248 TALLOC_FREE(result);
1252 /* For now we throw away the gids and convert via sid_to_gid
1253 * later. This needs fixing, but I'd like to get the code straight and
1257 *server_info = result;
1259 return NT_STATUS_OK;
1262 /***************************************************************************
1263 Make (and fill) a user_info struct for a guest login.
1264 This *must* succeed for smbd to start. If there is no mapping entry for
1265 the guest gid, then create one.
1266 ***************************************************************************/
1268 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
1271 struct samu *sampass = NULL;
1277 if ( !(sampass = samu_new( NULL )) ) {
1278 return NT_STATUS_NO_MEMORY;
1281 sid_copy(&guest_sid, get_global_sam_sid());
1282 sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
1285 ret = pdb_getsampwsid(sampass, &guest_sid);
1289 TALLOC_FREE(sampass);
1290 return NT_STATUS_NO_SUCH_USER;
1293 status = make_server_info_sam(server_info, sampass);
1294 if (!NT_STATUS_IS_OK(status)) {
1295 TALLOC_FREE(sampass);
1299 (*server_info)->guest = True;
1301 status = create_local_token(*server_info);
1302 if (!NT_STATUS_IS_OK(status)) {
1303 DEBUG(10, ("create_local_token failed: %s\n",
1304 nt_errstr(status)));
1308 /* annoying, but the Guest really does have a session key, and it is
1311 (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1312 (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1314 alpha_strcpy(tmp, pdb_get_username(sampass), ". _-$", sizeof(tmp));
1315 (*server_info)->sanitized_username = talloc_strdup(*server_info, tmp);
1317 return NT_STATUS_OK;
1320 /****************************************************************************
1321 Fake a auth_serversupplied_info just from a username
1322 ****************************************************************************/
1324 NTSTATUS make_serverinfo_from_username(TALLOC_CTX *mem_ctx,
1325 const char *username,
1327 struct auth_serversupplied_info **presult)
1329 struct auth_serversupplied_info *result;
1333 pwd = getpwnam_alloc(talloc_tos(), username);
1335 return NT_STATUS_NO_SUCH_USER;
1338 status = make_server_info_pw(&result, pwd->pw_name, pwd);
1342 if (!NT_STATUS_IS_OK(status)) {
1346 result->nss_token = true;
1347 result->guest = is_guest;
1349 status = create_local_token(result);
1351 if (!NT_STATUS_IS_OK(status)) {
1352 TALLOC_FREE(result);
1357 return NT_STATUS_OK;
1361 struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
1362 const auth_serversupplied_info *src)
1364 auth_serversupplied_info *dst;
1366 dst = make_server_info(mem_ctx);
1371 dst->guest = src->guest;
1372 dst->utok.uid = src->utok.uid;
1373 dst->utok.gid = src->utok.gid;
1374 dst->utok.ngroups = src->utok.ngroups;
1375 if (src->utok.ngroups != 0) {
1376 dst->utok.groups = (gid_t *)TALLOC_MEMDUP(
1377 dst, src->utok.groups,
1378 sizeof(gid_t)*dst->utok.ngroups);
1380 dst->utok.groups = NULL;
1384 dst->ptok = dup_nt_token(dst, src->ptok);
1391 dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
1392 src->user_session_key.length);
1394 dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
1395 src->lm_session_key.length);
1397 dst->sam_account = samu_new(NULL);
1398 if (!dst->sam_account) {
1403 if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) {
1408 dst->pam_handle = NULL;
1409 dst->unix_name = talloc_strdup(dst, src->unix_name);
1410 if (!dst->unix_name) {
1415 dst->sanitized_username = talloc_strdup(dst, src->sanitized_username);
1416 if (!dst->sanitized_username) {
1425 * Set a new session key. Used in the rpc server where we have to override the
1426 * SMB level session key with SystemLibraryDTC
1429 bool server_info_set_session_key(struct auth_serversupplied_info *info,
1430 DATA_BLOB session_key)
1432 TALLOC_FREE(info->user_session_key.data);
1434 info->user_session_key = data_blob_talloc(
1435 info, session_key.data, session_key.length);
1437 return (info->user_session_key.data != NULL);
1440 static auth_serversupplied_info *guest_info = NULL;
1442 bool init_guest_info(void)
1444 if (guest_info != NULL)
1447 return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1450 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1451 auth_serversupplied_info **server_info)
1453 *server_info = copy_serverinfo(mem_ctx, guest_info);
1454 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1457 bool copy_current_user(struct current_user *dst, struct current_user *src)
1460 NT_USER_TOKEN *nt_token;
1462 groups = (gid_t *)memdup(src->ut.groups,
1463 sizeof(gid_t) * src->ut.ngroups);
1464 if ((src->ut.ngroups != 0) && (groups == NULL)) {
1468 nt_token = dup_nt_token(NULL, src->nt_user_token);
1469 if (nt_token == NULL) {
1474 dst->conn = src->conn;
1475 dst->vuid = src->vuid;
1476 dst->ut.uid = src->ut.uid;
1477 dst->ut.gid = src->ut.gid;
1478 dst->ut.ngroups = src->ut.ngroups;
1479 dst->ut.groups = groups;
1480 dst->nt_user_token = nt_token;
1484 /***************************************************************************
1485 Purely internal function for make_server_info_info3
1486 Fill the sam account from getpwnam
1487 ***************************************************************************/
1488 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx,
1490 const char *username,
1491 char **found_username,
1492 uid_t *uid, gid_t *gid,
1493 struct samu *account,
1494 bool *username_was_mapped)
1497 fstring dom_user, lower_username;
1498 fstring real_username;
1499 struct passwd *passwd;
1501 fstrcpy( lower_username, username );
1502 strlower_m( lower_username );
1504 fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(),
1507 /* Get the passwd struct. Try to create the account is necessary. */
1509 *username_was_mapped = map_username( dom_user );
1511 if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1512 return NT_STATUS_NO_SUCH_USER;
1514 *uid = passwd->pw_uid;
1515 *gid = passwd->pw_gid;
1517 /* This is pointless -- there is no suport for differing
1518 unix and windows names. Make sure to always store the
1519 one we actually looked up and succeeded. Have I mentioned
1520 why I hate the 'winbind use default domain' parameter?
1523 *found_username = talloc_strdup( mem_ctx, real_username );
1525 DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1527 nt_status = samu_set_unix( account, passwd );
1529 TALLOC_FREE(passwd);
1534 /****************************************************************************
1535 Wrapper to allow the getpwnam() call to strip the domain name and
1536 try again in case a local UNIX user is already there. Also run through
1537 the username if we fallback to the username only.
1538 ****************************************************************************/
1540 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
1541 fstring save_username, bool create )
1543 struct passwd *pw = NULL;
1547 /* we only save a copy of the username it has been mangled
1548 by winbindd use default domain */
1550 save_username[0] = '\0';
1552 /* don't call map_username() here since it has to be done higher
1553 up the stack so we don't call it mutliple times */
1555 fstrcpy( username, domuser );
1557 p = strchr_m( username, *lp_winbind_separator() );
1559 /* code for a DOMAIN\user string */
1562 fstring strip_username;
1564 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1566 /* make sure we get the case of the username correct */
1567 /* work around 'winbind use default domain = yes' */
1569 if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1572 /* split the domain and username into 2 strings */
1576 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1579 fstrcpy( save_username, pw->pw_name );
1585 /* setup for lookup of just the username */
1586 /* remember that p and username are overlapping memory */
1589 fstrcpy( strip_username, p );
1590 fstrcpy( username, strip_username );
1593 /* just lookup a plain username */
1595 pw = Get_Pwnam_alloc(mem_ctx, username);
1597 /* Create local user if requested but only if winbindd
1598 is not running. We need to protect against cases
1599 where winbindd is failing and then prematurely
1600 creating users in /etc/passwd */
1602 if ( !pw && create && !winbind_ping() ) {
1603 /* Don't add a machine account. */
1604 if (username[strlen(username)-1] == '$')
1607 _smb_create_user(NULL, username, NULL);
1608 pw = Get_Pwnam_alloc(mem_ctx, username);
1611 /* one last check for a valid passwd struct */
1614 fstrcpy( save_username, pw->pw_name );
1619 /***************************************************************************
1620 Make a server_info struct from the info3 returned by a domain logon
1621 ***************************************************************************/
1623 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1624 const char *sent_nt_username,
1626 auth_serversupplied_info **server_info,
1627 struct netr_SamInfo3 *info3)
1631 NTSTATUS nt_status = NT_STATUS_OK;
1632 char *found_username = NULL;
1633 const char *nt_domain;
1634 const char *nt_username;
1635 struct samu *sam_account = NULL;
1638 bool username_was_mapped;
1640 uid_t uid = (uid_t)-1;
1641 gid_t gid = (gid_t)-1;
1643 auth_serversupplied_info *result;
1646 Here is where we should check the list of
1647 trusted domains, and verify that the SID
1651 sid_copy(&user_sid, info3->base.domain_sid);
1652 if (!sid_append_rid(&user_sid, info3->base.rid)) {
1653 return NT_STATUS_INVALID_PARAMETER;
1656 sid_copy(&group_sid, info3->base.domain_sid);
1657 if (!sid_append_rid(&group_sid, info3->base.primary_gid)) {
1658 return NT_STATUS_INVALID_PARAMETER;
1661 nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1663 /* If the server didn't give us one, just use the one we sent
1665 nt_username = sent_nt_username;
1668 nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1670 /* If the server didn't give us one, just use the one we sent
1675 /* try to fill the SAM account.. If getpwnam() fails, then try the
1676 add user script (2.2.x behavior).
1678 We use the _unmapped_ username here in an attempt to provide
1679 consistent username mapping behavior between kerberos and NTLM[SSP]
1680 authentication in domain mode security. I.E. Username mapping
1681 should be applied to the fully qualified username
1682 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1683 called map_username() unnecessarily in make_user_info_map() but
1684 that is how the current code is designed. Making the change here
1685 is the least disruptive place. -- jerry */
1687 if ( !(sam_account = samu_new( NULL )) ) {
1688 return NT_STATUS_NO_MEMORY;
1691 /* this call will try to create the user if necessary */
1693 nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1694 &found_username, &uid, &gid, sam_account,
1695 &username_was_mapped);
1698 /* if we still don't have a valid unix account check for
1699 'map to guest = bad uid' */
1701 if (!NT_STATUS_IS_OK(nt_status)) {
1702 TALLOC_FREE( sam_account );
1703 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1704 make_server_info_guest(NULL, server_info);
1705 return NT_STATUS_OK;
1710 if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1711 TALLOC_FREE(sam_account);
1712 return NT_STATUS_NO_MEMORY;
1715 if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1716 TALLOC_FREE(sam_account);
1717 return NT_STATUS_NO_MEMORY;
1720 if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1721 TALLOC_FREE(sam_account);
1722 return NT_STATUS_NO_MEMORY;
1725 if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1726 TALLOC_FREE(sam_account);
1727 return NT_STATUS_UNSUCCESSFUL;
1730 if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1731 TALLOC_FREE(sam_account);
1732 return NT_STATUS_UNSUCCESSFUL;
1735 if (!pdb_set_fullname(sam_account,
1736 info3->base.full_name.string,
1738 TALLOC_FREE(sam_account);
1739 return NT_STATUS_NO_MEMORY;
1742 if (!pdb_set_logon_script(sam_account,
1743 info3->base.logon_script.string,
1745 TALLOC_FREE(sam_account);
1746 return NT_STATUS_NO_MEMORY;
1749 if (!pdb_set_profile_path(sam_account,
1750 info3->base.profile_path.string,
1752 TALLOC_FREE(sam_account);
1753 return NT_STATUS_NO_MEMORY;
1756 if (!pdb_set_homedir(sam_account,
1757 info3->base.home_directory.string,
1759 TALLOC_FREE(sam_account);
1760 return NT_STATUS_NO_MEMORY;
1763 if (!pdb_set_dir_drive(sam_account,
1764 info3->base.home_drive.string,
1766 TALLOC_FREE(sam_account);
1767 return NT_STATUS_NO_MEMORY;
1770 if (!pdb_set_acct_ctrl(sam_account, info3->base.acct_flags, PDB_CHANGED)) {
1771 TALLOC_FREE(sam_account);
1772 return NT_STATUS_NO_MEMORY;
1775 if (!pdb_set_pass_last_set_time(
1777 nt_time_to_unix(info3->base.last_password_change),
1779 TALLOC_FREE(sam_account);
1780 return NT_STATUS_NO_MEMORY;
1783 if (!pdb_set_pass_can_change_time(
1785 nt_time_to_unix(info3->base.allow_password_change),
1787 TALLOC_FREE(sam_account);
1788 return NT_STATUS_NO_MEMORY;
1791 if (!pdb_set_pass_must_change_time(
1793 nt_time_to_unix(info3->base.force_password_change),
1795 TALLOC_FREE(sam_account);
1796 return NT_STATUS_NO_MEMORY;
1799 result = make_server_info(NULL);
1800 if (result == NULL) {
1801 DEBUG(4, ("make_server_info failed!\n"));
1802 TALLOC_FREE(sam_account);
1803 return NT_STATUS_NO_MEMORY;
1806 /* save this here to _net_sam_logon() doesn't fail (it assumes a
1807 valid struct samu) */
1809 result->sam_account = sam_account;
1810 result->unix_name = talloc_strdup(result, found_username);
1812 result->sanitized_username = sanitize_username(result,
1814 if (result->sanitized_username == NULL) {
1815 TALLOC_FREE(result);
1816 return NT_STATUS_NO_MEMORY;
1819 /* Fill in the unix info we found on the way */
1821 result->utok.uid = uid;
1822 result->utok.gid = gid;
1824 /* Create a 'combined' list of all SIDs we might want in the SD */
1826 result->num_sids = 0;
1827 result->sids = NULL;
1829 nt_status = sid_array_from_info3(result, info3,
1833 if (!NT_STATUS_IS_OK(nt_status)) {
1834 TALLOC_FREE(result);
1838 /* Ensure the primary group sid is at position 0. */
1839 sort_sid_array_for_smbd(result, &group_sid);
1841 result->login_server = talloc_strdup(result,
1842 info3->base.logon_server.string);
1844 /* ensure we are never given NULL session keys */
1848 if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1849 result->user_session_key = data_blob_null;
1851 result->user_session_key = data_blob_talloc(
1852 result, info3->base.key.key,
1853 sizeof(info3->base.key.key));
1856 if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1857 result->lm_session_key = data_blob_null;
1859 result->lm_session_key = data_blob_talloc(
1860 result, info3->base.LMSessKey.key,
1861 sizeof(info3->base.LMSessKey.key));
1864 result->nss_token |= username_was_mapped;
1866 *server_info = result;
1868 return NT_STATUS_OK;
1871 /*****************************************************************************
1872 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1873 ******************************************************************************/
1875 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1876 const char *sent_nt_username,
1878 const struct wbcAuthUserInfo *info,
1879 auth_serversupplied_info **server_info)
1883 NTSTATUS nt_status = NT_STATUS_OK;
1884 char *found_username = NULL;
1885 const char *nt_domain;
1886 const char *nt_username;
1887 struct samu *sam_account = NULL;
1890 bool username_was_mapped;
1893 uid_t uid = (uid_t)-1;
1894 gid_t gid = (gid_t)-1;
1896 auth_serversupplied_info *result;
1898 result = make_server_info(NULL);
1899 if (result == NULL) {
1900 DEBUG(4, ("make_server_info failed!\n"));
1901 return NT_STATUS_NO_MEMORY;
1905 Here is where we should check the list of
1906 trusted domains, and verify that the SID
1910 memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid));
1911 memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid));
1913 if (info->account_name) {
1914 nt_username = talloc_strdup(result, info->account_name);
1916 /* If the server didn't give us one, just use the one we sent
1918 nt_username = talloc_strdup(result, sent_nt_username);
1921 TALLOC_FREE(result);
1922 return NT_STATUS_NO_MEMORY;
1925 if (info->domain_name) {
1926 nt_domain = talloc_strdup(result, info->domain_name);
1928 /* If the server didn't give us one, just use the one we sent
1930 nt_domain = talloc_strdup(result, domain);
1933 TALLOC_FREE(result);
1934 return NT_STATUS_NO_MEMORY;
1937 /* try to fill the SAM account.. If getpwnam() fails, then try the
1938 add user script (2.2.x behavior).
1940 We use the _unmapped_ username here in an attempt to provide
1941 consistent username mapping behavior between kerberos and NTLM[SSP]
1942 authentication in domain mode security. I.E. Username mapping
1943 should be applied to the fully qualified username
1944 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1945 called map_username() unnecessarily in make_user_info_map() but
1946 that is how the current code is designed. Making the change here
1947 is the least disruptive place. -- jerry */
1949 if ( !(sam_account = samu_new( result )) ) {
1950 TALLOC_FREE(result);
1951 return NT_STATUS_NO_MEMORY;
1954 /* this call will try to create the user if necessary */
1956 nt_status = fill_sam_account(result, nt_domain, sent_nt_username,
1957 &found_username, &uid, &gid, sam_account,
1958 &username_was_mapped);
1960 /* if we still don't have a valid unix account check for
1961 'map to guest = bad uid' */
1963 if (!NT_STATUS_IS_OK(nt_status)) {
1964 TALLOC_FREE( result );
1965 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1966 make_server_info_guest(NULL, server_info);
1967 return NT_STATUS_OK;
1972 if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1973 TALLOC_FREE(result);
1974 return NT_STATUS_NO_MEMORY;
1977 if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1978 TALLOC_FREE(result);
1979 return NT_STATUS_NO_MEMORY;
1982 if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1983 TALLOC_FREE(result);
1984 return NT_STATUS_NO_MEMORY;
1987 if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1988 TALLOC_FREE(result);
1989 return NT_STATUS_UNSUCCESSFUL;
1992 if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1993 TALLOC_FREE(result);
1994 return NT_STATUS_UNSUCCESSFUL;
1997 if (!pdb_set_fullname(sam_account, info->full_name, PDB_CHANGED)) {
1998 TALLOC_FREE(result);
1999 return NT_STATUS_NO_MEMORY;
2002 if (!pdb_set_logon_script(sam_account, info->logon_script, PDB_CHANGED)) {
2003 TALLOC_FREE(result);
2004 return NT_STATUS_NO_MEMORY;
2007 if (!pdb_set_profile_path(sam_account, info->profile_path, PDB_CHANGED)) {
2008 TALLOC_FREE(result);
2009 return NT_STATUS_NO_MEMORY;
2012 if (!pdb_set_homedir(sam_account, info->home_directory, PDB_CHANGED)) {
2013 TALLOC_FREE(result);
2014 return NT_STATUS_NO_MEMORY;
2017 if (!pdb_set_dir_drive(sam_account, info->home_drive, PDB_CHANGED)) {
2018 TALLOC_FREE(result);
2019 return NT_STATUS_NO_MEMORY;
2022 if (!pdb_set_acct_ctrl(sam_account, info->acct_flags, PDB_CHANGED)) {
2023 TALLOC_FREE(result);
2024 return NT_STATUS_NO_MEMORY;
2027 if (!pdb_set_pass_last_set_time(
2029 nt_time_to_unix(info->pass_last_set_time),
2031 TALLOC_FREE(result);
2032 return NT_STATUS_NO_MEMORY;
2035 if (!pdb_set_pass_can_change_time(
2037 nt_time_to_unix(info->pass_can_change_time),
2039 TALLOC_FREE(result);
2040 return NT_STATUS_NO_MEMORY;
2043 if (!pdb_set_pass_must_change_time(
2045 nt_time_to_unix(info->pass_must_change_time),
2047 TALLOC_FREE(result);
2048 return NT_STATUS_NO_MEMORY;
2051 /* save this here to _net_sam_logon() doesn't fail (it assumes a
2052 valid struct samu) */
2054 result->sam_account = sam_account;
2055 result->unix_name = talloc_strdup(result, found_username);
2057 result->sanitized_username = sanitize_username(result,
2059 result->login_server = talloc_strdup(result, info->logon_server);
2061 if ((result->unix_name == NULL)
2062 || (result->sanitized_username == NULL)
2063 || (result->login_server == NULL)) {
2064 TALLOC_FREE(result);
2065 return NT_STATUS_NO_MEMORY;
2068 /* Fill in the unix info we found on the way */
2070 result->utok.uid = uid;
2071 result->utok.gid = gid;
2073 /* Create a 'combined' list of all SIDs we might want in the SD */
2075 result->num_sids = info->num_sids - 2;
2076 result->sids = talloc_array(result, DOM_SID, result->num_sids);
2077 if (result->sids == NULL) {
2078 TALLOC_FREE(result);
2079 return NT_STATUS_NO_MEMORY;
2082 for (i=0; i < result->num_sids; i++) {
2083 memcpy(&result->sids[i], &info->sids[i+2].sid, sizeof(result->sids[i]));
2086 /* Ensure the primary group sid is at position 0. */
2087 sort_sid_array_for_smbd(result, &group_sid);
2089 /* ensure we are never given NULL session keys */
2093 if (memcmp(info->user_session_key, zeros, sizeof(zeros)) == 0) {
2094 result->user_session_key = data_blob_null;
2096 result->user_session_key = data_blob_talloc(
2097 result, info->user_session_key,
2098 sizeof(info->user_session_key));
2101 if (memcmp(info->lm_session_key, zeros, 8) == 0) {
2102 result->lm_session_key = data_blob_null;
2104 result->lm_session_key = data_blob_talloc(
2105 result, info->lm_session_key,
2106 sizeof(info->lm_session_key));
2109 result->nss_token |= username_was_mapped;
2111 *server_info = result;
2113 return NT_STATUS_OK;
2116 /***************************************************************************
2117 Free a user_info struct
2118 ***************************************************************************/
2120 void free_user_info(auth_usersupplied_info **user_info)
2122 DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
2123 if (*user_info != NULL) {
2124 if ((*user_info)->smb_name) {
2125 DEBUG(10,("structure was created for %s\n",
2126 (*user_info)->smb_name));
2128 SAFE_FREE((*user_info)->smb_name);
2129 SAFE_FREE((*user_info)->internal_username);
2130 SAFE_FREE((*user_info)->client_domain);
2131 SAFE_FREE((*user_info)->domain);
2132 SAFE_FREE((*user_info)->wksta_name);
2133 data_blob_free(&(*user_info)->lm_resp);
2134 data_blob_free(&(*user_info)->nt_resp);
2135 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
2136 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
2137 data_blob_clear_free(&(*user_info)->plaintext_password);
2138 ZERO_STRUCT(**user_info);
2140 SAFE_FREE(*user_info);
2143 /***************************************************************************
2144 Make an auth_methods struct
2145 ***************************************************************************/
2147 bool make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method)
2149 if (!auth_context) {
2150 smb_panic("no auth_context supplied to "
2151 "make_auth_methods()!\n");
2155 smb_panic("make_auth_methods: pointer to auth_method pointer "
2159 *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
2160 if (!*auth_method) {
2161 DEBUG(0,("make_auth_method: malloc failed!\n"));
2164 ZERO_STRUCTP(*auth_method);
2170 * Verify whether or not given domain is trusted.
2172 * @param domain_name name of the domain to be verified
2173 * @return true if domain is one of the trusted once or
2174 * false if otherwise
2177 bool is_trusted_domain(const char* dom_name)
2179 DOM_SID trustdom_sid;
2182 /* no trusted domains for a standalone server */
2184 if ( lp_server_role() == ROLE_STANDALONE )
2187 /* if we are a DC, then check for a direct trust relationships */
2191 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2192 "[%s]\n", dom_name ));
2193 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
2201 /* If winbind is around, ask it */
2203 result = wb_is_trusted_domain(dom_name);
2205 if (result == WBC_ERR_SUCCESS) {
2209 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
2210 /* winbind could not find the domain */
2214 /* The only other possible result is that winbind is not up
2215 and running. We need to update the trustdom_cache
2218 update_trustdom_cache();
2221 /* now the trustdom cache should be available a DC could still
2222 * have a transitive trust so fall back to the cache of trusted
2223 * domains (like a domain member would use */
2225 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {