diff options
author | Gerald Carter <jerry@samba.org> | 2005-09-30 17:13:37 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:04:48 -0500 |
commit | 54abd2aa66069e6baf7769c496f46d9dba18db39 (patch) | |
tree | 9cf8e88168011797319ba9e9866749201b1eac1e /source3/auth | |
parent | 4a2cc231d22a82ed21771a72508f15d21ed63227 (diff) | |
download | samba-54abd2aa66069e6baf7769c496f46d9dba18db39.tar.gz samba-54abd2aa66069e6baf7769c496f46d9dba18db39.tar.bz2 samba-54abd2aa66069e6baf7769c496f46d9dba18db39.zip |
r10656: BIG merge from trunk. Features not copied over
* \PIPE\unixinfo
* winbindd's {group,alias}membership new functions
* winbindd's lookupsids() functionality
* swat (trunk changes to be reverted as per discussion with Deryck)
(This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3)
Diffstat (limited to 'source3/auth')
-rw-r--r-- | source3/auth/auth.c | 2 | ||||
-rw-r--r-- | source3/auth/auth_domain.c | 204 | ||||
-rw-r--r-- | source3/auth/auth_ntlmssp.c | 6 | ||||
-rw-r--r-- | source3/auth/auth_util.c | 95 | ||||
-rw-r--r-- | source3/auth/auth_winbind.c | 2 |
5 files changed, 208 insertions, 101 deletions
diff --git a/source3/auth/auth.c b/source3/auth/auth.c index 9886526cf9..92c90b6241 100644 --- a/source3/auth/auth.c +++ b/source3/auth/auth.c @@ -235,7 +235,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context, #ifdef DEBUG_PASSWORD DEBUG(100, ("user_info has passwords of length %d and %d\n", - user_info->lm_resp.length, user_info->nt_resp.length)); + (int)user_info->lm_resp.length, (int)user_info->nt_resp.length)); DEBUG(100, ("lm:\n")); dump_data(100, user_info->lm_resp.data, user_info->lm_resp.length); DEBUG(100, ("nt:\n")); diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index cdf87adebb..4abc6c6656 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -40,15 +40,17 @@ extern BOOL global_machine_password_needs_changing; * **/ -static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, - const char *domain, const char *dc_name, - struct in_addr dc_ip, - const char *setup_creds_as, - uint16 sec_chan, - const unsigned char *trust_passwd, - BOOL *retry) +static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, + const char *domain, + const char *dc_name, + struct in_addr dc_ip, + struct rpc_pipe_client **pipe_ret, + BOOL *retry) { NTSTATUS result; + struct rpc_pipe_client *netlogon_pipe = NULL; + + *pipe_ret = NULL; /* TODO: Send a SAMLOGON request to determine whether this is a valid logonserver. We can avoid a 30-second timeout if the DC is down @@ -64,8 +66,9 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, * ACCESS_DENIED errors if 2 auths are done from the same machine. JRA. */ - if (!grab_server_mutex(dc_name)) + if (!grab_server_mutex(dc_name)) { return NT_STATUS_NO_LOGON_SERVERS; + } /* Attempt connection */ *retry = True; @@ -95,36 +98,65 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, * into account also. This patch from "Bjart Kvarme" <bjart.kvarme@usit.uio.no>. */ - if(cli_nt_session_open(*cli, PI_NETLOGON) == False) { + /* open the netlogon pipe. */ + if (lp_client_schannel()) { + /* We also setup the creds chain in the open_schannel call. */ + netlogon_pipe = cli_rpc_pipe_open_schannel(*cli, PI_NETLOGON, + PIPE_AUTH_LEVEL_PRIVACY, domain, &result); + } else { + netlogon_pipe = cli_rpc_pipe_open_noauth(*cli, PI_NETLOGON, &result); + } + + if(!netlogon_pipe) { DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \ -machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli))); - cli_nt_session_close(*cli); - cli_ulogoff(*cli); +machine %s. Error was : %s.\n", dc_name, nt_errstr(result))); cli_shutdown(*cli); release_server_mutex(); - return NT_STATUS_NO_LOGON_SERVERS; + return result; } - fstr_sprintf((*cli)->mach_acct, "%s$", setup_creds_as); - - /* This must be the remote domain (not ours) for schannel */ - - fstrcpy( (*cli)->domain, domain ); + if (!lp_client_schannel()) { + /* We need to set up a creds chain on an unauthenticated netlogon pipe. */ + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS; + uint32 sec_chan_type = 0; + char machine_pwd[16]; + + if (!get_trust_pw(domain, machine_pwd, &sec_chan_type)) { + DEBUG(0, ("connect_to_domain_password_server: could not fetch " + "trust account password for domain '%s'\n", + domain)); + cli_shutdown(*cli); + release_server_mutex(); + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } - result = cli_nt_establish_netlogon(*cli, sec_chan, trust_passwd); + result = rpccli_netlogon_setup_creds(netlogon_pipe, + dc_name, + domain, + global_myname(), + machine_pwd, + sec_chan_type, + &neg_flags); + + if (!NT_STATUS_IS_OK(result)) { + cli_shutdown(*cli); + release_server_mutex(); + return result; + } + } - if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("connect_to_domain_password_server: unable to setup the NETLOGON credentials to machine \ -%s. Error was : %s.\n", dc_name, nt_errstr(result))); - cli_nt_session_close(*cli); - cli_ulogoff(*cli); + if(!netlogon_pipe) { + DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \ +machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli))); cli_shutdown(*cli); release_server_mutex(); - return result; + return NT_STATUS_NO_LOGON_SERVERS; } /* We exit here with the mutex *locked*. JRA */ + *pipe_ret = netlogon_pipe; + return NT_STATUS_OK; } @@ -135,18 +167,17 @@ machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli))); ************************************************************************/ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, - const auth_usersupplied_info *user_info, - const char *domain, - uchar chal[8], - auth_serversupplied_info **server_info, - const char *dc_name, struct in_addr dc_ip, - const char *setup_creds_as, - uint16 sec_chan, - unsigned char trust_passwd[16], - time_t last_change_time) + const auth_usersupplied_info *user_info, + const char *domain, + uchar chal[8], + auth_serversupplied_info **server_info, + const char *dc_name, + struct in_addr dc_ip) + { NET_USER_INFO_3 info3; struct cli_state *cli = NULL; + struct rpc_pipe_client *netlogon_pipe = NULL; NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS; int i; BOOL retry = True; @@ -162,8 +193,12 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, /* rety loop for robustness */ for (i = 0; !NT_STATUS_IS_OK(nt_status) && retry && (i < 3); i++) { - nt_status = connect_to_domain_password_server(&cli, domain, dc_name, - dc_ip, setup_creds_as, sec_chan, trust_passwd, &retry); + nt_status = connect_to_domain_password_server(&cli, + domain, + dc_name, + dc_ip, + &netlogon_pipe, + &retry); } if ( !NT_STATUS_IS_OK(nt_status) ) { @@ -181,13 +216,19 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, * in the info3 structure. */ - nt_status = cli_netlogon_sam_network_logon(cli, mem_ctx, - NULL, user_info->smb_name.str, user_info->domain.str, - user_info->wksta_name.str, chal, user_info->lm_resp, - user_info->nt_resp, &info3); - - /* let go as soon as possible so we avoid any potential deadlocks - with winbind lookup up users or groups */ + nt_status = rpccli_netlogon_sam_network_logon(netlogon_pipe, + mem_ctx, + dc_name, /* server name */ + user_info->smb_name.str, /* user name logging on. */ + user_info->domain.str, /* domain name */ + user_info->wksta_name.str, /* workstation name */ + chal, /* 8 byte challenge. */ + user_info->lm_resp, /* lanman 24 byte response */ + user_info->nt_resp, /* nt 24 byte response */ + &info3); /* info3 out */ + + /* Let go as soon as possible so we avoid any potential deadlocks + with winbind lookup up users or groups. */ release_server_mutex(); @@ -195,7 +236,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, DEBUG(0,("domain_client_validate: unable to validate password " "for user %s in domain %s to Domain controller %s. " "Error was %s.\n", user_info->smb_name.str, - user_info->domain.str, cli->srv_name_slash, + user_info->domain.str, dc_name, nt_errstr(nt_status))); /* map to something more useful */ @@ -203,32 +244,18 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, nt_status = NT_STATUS_NO_LOGON_SERVERS; } } else { - nt_status = make_server_info_info3(mem_ctx, user_info->internal_username.str, - user_info->smb_name.str, domain, server_info, &info3); + nt_status = make_server_info_info3(mem_ctx, + user_info->internal_username.str, + user_info->smb_name.str, + domain, + server_info, + &info3); } -#if 0 - /* - * We don't actually need to do this - plus it fails currently with - * NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to - * send here. JRA. - */ - - if (NT_STATUS_IS_OK(status)) { - if(cli_nt_logoff(&cli, &ctr) == False) { - DEBUG(0,("domain_client_validate: unable to log off user %s in domain \ -%s to Domain controller %s. Error was %s.\n", user, domain, dc_name, cli_errstr(&cli))); - nt_status = NT_STATUS_LOGON_FAILURE; - } - } -#endif /* 0 */ - /* Note - once the cli stream is shutdown the mem_ctx used to allocate the other_sids and gids structures has been deleted - so these pointers are no longer valid..... */ - cli_nt_session_close(cli); - cli_ulogoff(cli); cli_shutdown(cli); return nt_status; } @@ -244,10 +271,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context, auth_serversupplied_info **server_info) { NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE; - unsigned char trust_passwd[16]; - time_t last_change_time; const char *domain = lp_workgroup(); - uint32 sec_channel_type = 0; fstring dc_name; struct in_addr dc_ip; @@ -273,26 +297,6 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context, return NT_STATUS_NOT_IMPLEMENTED; } - /* - * Get the machine account password for our primary domain - * No need to become_root() as secrets_init() is done at startup. - */ - - if (!secrets_fetch_trust_account_password(domain, trust_passwd, &last_change_time, &sec_channel_type)) - { - DEBUG(0, ("check_ntdomain_security: could not fetch trust account password for domain '%s'\n", domain)); - return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - } - - /* Test if machine password has expired and needs to be changed */ - if (lp_machine_password_timeout()) { - if (last_change_time > 0 && - time(NULL) > (last_change_time + - lp_machine_password_timeout())) { - global_machine_password_needs_changing = True; - } - } - /* we need our DC to send the net_sam_logon() request to */ if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) { @@ -301,9 +305,13 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context, return NT_STATUS_NO_LOGON_SERVERS; } - nt_status = domain_client_validate(mem_ctx, user_info, domain, - (uchar *)auth_context->challenge.data, server_info, dc_name, dc_ip, - global_myname(), sec_channel_type,trust_passwd, last_change_time); + nt_status = domain_client_validate(mem_ctx, + user_info, + domain, + (uchar *)auth_context->challenge.data, + server_info, + dc_name, + dc_ip); return nt_status; } @@ -357,7 +365,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte /* No point is bothering if this is not a trusted domain. This return makes "map to guest = bad user" work again. The logic is that if we know nothing about the domain, that - user is known to us and does not exist */ + user is not known to us and does not exist */ if ( !is_trusted_domain( user_info->domain.str ) ) return NT_STATUS_NOT_IMPLEMENTED; @@ -367,8 +375,8 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte * No need to become_root() as secrets_init() is done at startup. */ - if (!secrets_fetch_trusted_domain_password(user_info->domain.str, &trust_password, &sid, &last_change_time)) - { + if (!secrets_fetch_trusted_domain_password(user_info->domain.str, &trust_password, + &sid, &last_change_time)) { DEBUG(0, ("check_trustdomain_security: could not fetch trust account password for domain %s\n", user_info->domain.str)); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } @@ -396,9 +404,13 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte return NT_STATUS_NO_LOGON_SERVERS; } - nt_status = domain_client_validate(mem_ctx, user_info, user_info->domain.str, - (uchar *)auth_context->challenge.data, server_info, dc_name, dc_ip, - lp_workgroup(), SEC_CHAN_DOMAIN, trust_md4_password, last_change_time); + nt_status = domain_client_validate(mem_ctx, + user_info, + user_info->domain.str, + (uchar *)auth_context->challenge.data, + server_info, + dc_name, + dc_ip); return nt_status; } diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c index 11d9aa09c4..738af73f49 100644 --- a/source3/auth/auth_ntlmssp.c +++ b/source3/auth/auth_ntlmssp.c @@ -114,13 +114,15 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, return nt_status; } if (auth_ntlmssp_state->server_info->user_session_key.length) { - DEBUG(10, ("Got NT session key of length %u\n", auth_ntlmssp_state->server_info->user_session_key.length)); + DEBUG(10, ("Got NT session key of length %u\n", + (unsigned int)auth_ntlmssp_state->server_info->user_session_key.length)); *user_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx, auth_ntlmssp_state->server_info->user_session_key.data, auth_ntlmssp_state->server_info->user_session_key.length); } if (auth_ntlmssp_state->server_info->lm_session_key.length) { - DEBUG(10, ("Got LM session key of length %u\n", auth_ntlmssp_state->server_info->lm_session_key.length)); + DEBUG(10, ("Got LM session key of length %u\n", + (unsigned int)auth_ntlmssp_state->server_info->lm_session_key.length)); *lm_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx, auth_ntlmssp_state->server_info->lm_session_key.data, auth_ntlmssp_state->server_info->lm_session_key.length); diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 6624631b53..194a1ad532 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -372,7 +372,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, unsigned char local_lm_response[24]; #ifdef DEBUG_PASSWORD - DEBUG(10,("Unencrypted password (len %d):\n",plaintext_password.length)); + DEBUG(10,("Unencrypted password (len %d):\n",(int)plaintext_password.length)); dump_data(100, plaintext_password.data, plaintext_password.length); #endif @@ -641,6 +641,44 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, } /****************************************************************************** + Create a token for the root user to be used internally by smbd. + This is similar to running under the context of the LOCAL_SYSTEM account + in Windows. This is a read-only token. Do not modify it or free() it. + Create a copy if your need to change it. +******************************************************************************/ + +NT_USER_TOKEN *get_root_nt_token( void ) +{ + static NT_USER_TOKEN *token = NULL; + DOM_SID u_sid, g_sid; + DOM_SID g_sids[1]; + struct passwd *pw; + NTSTATUS result; + + if ( token ) + return token; + + if ( !(pw = getpwnam( "root" )) ) { + DEBUG(0,("create_root_nt_token: getpwnam\"root\") failed!\n")); + return NULL; + } + + /* get the user and primary group SIDs; although the + BUILTIN\Administrators SId is really the one that matters here */ + + if ( !NT_STATUS_IS_OK(uid_to_sid(&u_sid, pw->pw_uid)) ) + return NULL; + if ( !NT_STATUS_IS_OK(gid_to_sid(&g_sid, pw->pw_gid)) ) + return NULL; + + sid_copy( &g_sids[0], &global_sid_Builtin_Administrators ); + + result = create_nt_user_token( &u_sid, &g_sid, 1, g_sids, False, &token); + + return NT_STATUS_IS_OK(result) ? token : NULL; +} + +/****************************************************************************** * this function returns the groups (SIDs) of the local SAM the user is in. * If this samba server is a DC of the domain the user belongs to, it returns * both domain groups and local / builtin groups. If the user is in a trusted @@ -832,6 +870,61 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, } /*************************************************************************** + Make (and fill) a user_info struct from a Kerberos PAC logon_info by conversion + to a SAM_ACCOUNT +***************************************************************************/ + +NTSTATUS make_server_info_pac(auth_serversupplied_info **server_info, + char *unix_username, + struct passwd *pwd, + PAC_LOGON_INFO *logon_info) +{ + NTSTATUS nt_status; + SAM_ACCOUNT *sampass = NULL; + DOM_SID user_sid, group_sid; + fstring dom_name; + + if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) { + return nt_status; + } + if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) { + return nt_status; + } + + /* only copy user_sid, group_sid and domain name out of the PAC for + * now, we will benefit from more later - Guenther */ + + sid_copy(&user_sid, &logon_info->info3.dom_sid.sid); + sid_append_rid(&user_sid, logon_info->info3.user_rid); + pdb_set_user_sid(sampass, &user_sid, PDB_SET); + + sid_copy(&group_sid, &logon_info->info3.dom_sid.sid); + sid_append_rid(&group_sid, logon_info->info3.group_rid); + pdb_set_group_sid(sampass, &group_sid, PDB_SET); + + unistr2_to_ascii(dom_name, &logon_info->info3.uni_logon_dom, -1); + pdb_set_domain(sampass, dom_name, PDB_SET); + + pdb_set_logon_count(sampass, logon_info->info3.logon_count, PDB_SET); + + (*server_info)->sam_account = sampass; + + if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, unix_username, + sampass, pwd->pw_uid, pwd->pw_gid))) + { + return nt_status; + } + + (*server_info)->unix_name = smb_xstrdup(unix_username); + + (*server_info)->sam_fill_level = SAM_FILL_ALL; + (*server_info)->uid = pwd->pw_uid; + (*server_info)->gid = pwd->pw_gid; + return nt_status; +} + + +/*************************************************************************** Make (and fill) a user_info struct from a 'struct passwd' by conversion to a SAM_ACCOUNT ***************************************************************************/ diff --git a/source3/auth/auth_winbind.c b/source3/auth/auth_winbind.c index 3a81cba626..0c263b6ab3 100644 --- a/source3/auth/auth_winbind.c +++ b/source3/auth/auth_winbind.c @@ -38,7 +38,7 @@ static NTSTATUS get_info3_from_ndr(TALLOC_CTX *mem_ctx, struct winbindd_response } prs_copy_data_in(&ps, (char *)info3_ndr, len); prs_set_offset(&ps,0); - if (!net_io_user_info3("", info3, &ps, 1, 3)) { + if (!net_io_user_info3("", info3, &ps, 1, 3, False)) { DEBUG(2, ("get_info3_from_ndr: could not parse info3 struct!\n")); return NT_STATUS_UNSUCCESSFUL; } |