struct auth_usersupplied_info *user_info = NULL;
NTSTATUS nt_status;
- unsigned char chal[8];
-
- ZERO_STRUCT(chal);
+ static unsigned char chal[8] = { 0, };
DEBUG(3,("Got anonymous request\n"));
- if (!NT_STATUS_IS_OK(nt_status = make_auth_context_fixed(&auth_context,
- chal))) {
+ nt_status = make_auth_context_fixed(talloc_tos(), &auth_context, chal);
+ if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
{
TALLOC_CTX *mem_ctx;
DATA_BLOB ticket;
- char *client, *p, *domain;
- fstring netbios_domain_name;
struct passwd *pw;
- fstring user;
int sess_vuid = req->vuid;
NTSTATUS ret = NT_STATUS_OK;
DATA_BLOB ap_rep, ap_rep_wrapped, response;
DATA_BLOB session_key = data_blob_null;
uint8 tok_id[2];
DATA_BLOB nullblob = data_blob_null;
- fstring real_username;
bool map_domainuser_to_guest = False;
bool username_was_mapped;
struct PAC_LOGON_INFO *logon_info = NULL;
struct smbd_server_connection *sconn = req->sconn;
+ char *principal;
+ char *user;
+ char *domain;
+ char *real_username;
ZERO_STRUCT(ticket);
ZERO_STRUCT(ap_rep);
}
ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket,
- &client, &logon_info, &ap_rep,
+ &principal, &logon_info, &ap_rep,
&session_key, True);
data_blob_free(&ticket);
return;
}
- DEBUG(3,("Ticket name is [%s]\n", client));
-
- p = strchr_m(client, '@');
- if (!p) {
- DEBUG(3,("Doesn't look like a valid principal\n"));
+ ret = get_user_from_kerberos_info(talloc_tos(),
+ sconn->client_id.name,
+ principal, logon_info,
+ &username_was_mapped,
+ &map_domainuser_to_guest,
+ &user, &domain,
+ &real_username, &pw);
+ if (!NT_STATUS_IS_OK(ret)) {
data_blob_free(&ap_rep);
data_blob_free(&session_key);
talloc_destroy(mem_ctx);
return;
}
- *p = 0;
-
/* save the PAC data if we have it */
-
if (logon_info) {
- netsamlogon_cache_store( client, &logon_info->info3 );
- }
-
- if (!strequal(p+1, lp_realm())) {
- DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1));
- if (!lp_allow_trusted_domains()) {
- data_blob_free(&ap_rep);
- data_blob_free(&session_key);
- talloc_destroy(mem_ctx);
- reply_nterror(req, nt_status_squash(
- NT_STATUS_LOGON_FAILURE));
- return;
- }
- }
-
- /* this gives a fully qualified user name (ie. with full realm).
- that leads to very long usernames, but what else can we do? */
-
- domain = p+1;
-
- if (logon_info && logon_info->info3.base.domain.string) {
- fstrcpy(netbios_domain_name,
- logon_info->info3.base.domain.string);
- domain = netbios_domain_name;
- DEBUG(10, ("Mapped to [%s] (using PAC)\n", domain));
-
- } else {
-
- /* If we have winbind running, we can (and must) shorten the
- username by using the short netbios name. Otherwise we will
- have inconsistent user names. With Kerberos, we get the
- fully qualified realm, with ntlmssp we get the short
- name. And even w2k3 does use ntlmssp if you for example
- connect to an ip address. */
-
- wbcErr wbc_status;
- struct wbcDomainInfo *info = NULL;
-
- DEBUG(10, ("Mapping [%s] to short name\n", domain));
-
- wbc_status = wbcDomainInfo(domain, &info);
-
- if (WBC_ERROR_IS_OK(wbc_status)) {
-
- fstrcpy(netbios_domain_name,
- info->short_name);
-
- wbcFreeMemory(info);
- domain = netbios_domain_name;
- DEBUG(10, ("Mapped to [%s] (using Winbind)\n", domain));
- } else {
- DEBUG(3, ("Could not find short name: %s\n",
- wbcErrorString(wbc_status)));
- }
- }
-
- fstr_sprintf(user, "%s%c%s", domain, *lp_winbind_separator(), client);
-
- /* lookup the passwd struct, create a new user if necessary */
-
- username_was_mapped = map_username(user);
-
- pw = smb_getpwnam( mem_ctx, user, real_username, True );
-
- if (pw) {
- /* if a real user check pam account restrictions */
- /* only really perfomed if "obey pam restriction" is true */
- /* do this before an eventual mapping to guest occurs */
- ret = smb_pam_accountcheck(pw->pw_name);
- if ( !NT_STATUS_IS_OK(ret)) {
- DEBUG(1,("PAM account restriction "
- "prevents user login\n"));
- data_blob_free(&ap_rep);
- data_blob_free(&session_key);
- TALLOC_FREE(mem_ctx);
- reply_nterror(req, nt_status_squash(ret));
- return;
- }
- }
-
- if (!pw) {
-
- /* this was originally the behavior of Samba 2.2, if a user
- did not have a local uid but has been authenticated, then
- map them to a guest account */
-
- if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID){
- map_domainuser_to_guest = True;
- fstrcpy(user,lp_guestaccount());
- pw = smb_getpwnam( mem_ctx, user, real_username, True );
- }
-
- /* extra sanity check that the guest account is valid */
-
- if ( !pw ) {
- DEBUG(1,("Username %s is invalid on this system\n",
- user));
- data_blob_free(&ap_rep);
- data_blob_free(&session_key);
- TALLOC_FREE(mem_ctx);
- reply_nterror(req, nt_status_squash(
- NT_STATUS_LOGON_FAILURE));
- return;
- }
+ netsamlogon_cache_store(user, &logon_info->info3);
}
/* setup the string used by %U */
+ sub_set_smb_name(real_username);
- sub_set_smb_name( real_username );
- reload_services(sconn->msg_ctx, True);
-
- if ( map_domainuser_to_guest ) {
- make_server_info_guest(NULL, &server_info);
- } else if (logon_info) {
- /* pass the unmapped username here since map_username()
- will be called again from inside make_server_info_info3() */
+ /* reload services so that the new %U is taken into account */
+ reload_services(sconn->msg_ctx, sconn->sock, True);
- ret = make_server_info_info3(mem_ctx, client, domain,
- &server_info, &logon_info->info3);
- if ( !NT_STATUS_IS_OK(ret) ) {
- DEBUG(1,("make_server_info_info3 failed: %s!\n",
- nt_errstr(ret)));
- data_blob_free(&ap_rep);
- data_blob_free(&session_key);
- TALLOC_FREE(mem_ctx);
- reply_nterror(req, nt_status_squash(ret));
- return;
- }
-
- } else {
- /*
- * We didn't get a PAC, we have to make up the user
- * ourselves. Try to ask the pdb backend to provide
- * SID consistency with ntlmssp session setup
- */
- struct samu *sampass;
-
- sampass = samu_new(talloc_tos());
- if (sampass == NULL) {
- ret = NT_STATUS_NO_MEMORY;
- data_blob_free(&ap_rep);
- data_blob_free(&session_key);
- TALLOC_FREE(mem_ctx);
- reply_nterror(req, nt_status_squash(ret));
- return;
- }
-
- if (pdb_getsampwnam(sampass, real_username)) {
- DEBUG(10, ("found user %s in passdb, calling "
- "make_server_info_sam\n", real_username));
- ret = make_server_info_sam(&server_info, sampass);
- TALLOC_FREE(sampass);
- } else {
- /*
- * User not in passdb, make it up artificially
- */
- TALLOC_FREE(sampass);
- DEBUG(10, ("didn't find user %s in passdb, calling "
- "make_server_info_pw\n", real_username));
- ret = make_server_info_pw(&server_info, real_username,
- pw);
- }
-
- if ( !NT_STATUS_IS_OK(ret) ) {
- DEBUG(1,("make_server_info_[sam|pw] failed: %s!\n",
- nt_errstr(ret)));
- data_blob_free(&ap_rep);
- data_blob_free(&session_key);
- TALLOC_FREE(mem_ctx);
- reply_nterror(req, nt_status_squash(ret));
- return;
- }
-
- /* make_server_info_pw does not set the domain. Without this
- * we end up with the local netbios name in substitutions for
- * %D. */
-
- if (server_info->info3 != NULL) {
- server_info->info3->base.domain.string =
- talloc_strdup(server_info->info3, domain);
- }
+ ret = make_server_info_krb5(mem_ctx,
+ user, domain, real_username, pw,
+ logon_info, map_domainuser_to_guest,
+ &server_info);
+ if (!NT_STATUS_IS_OK(ret)) {
+ DEBUG(1, ("make_server_info_krb5 failed!\n"));
+ data_blob_free(&ap_rep);
+ data_blob_free(&session_key);
+ TALLOC_FREE(mem_ctx);
+ reply_nterror(req, nt_status_squash(ret));
+ return;
}
server_info->nss_token |= username_was_mapped;
}
data_blob_free(&server_info->user_session_key);
+ /* Set the kerberos-derived session key onto the server_info */
server_info->user_session_key = session_key;
talloc_steal(server_info, session_key.data);
* no need to free after this on success. A better interface would copy
* it.... */
- sess_vuid = register_existing_vuid(sconn,
- sess_vuid,
- server_info,
- nullblob,
- client);
+ sess_vuid = register_existing_vuid(sconn, sess_vuid,
+ server_info, nullblob, user);
reply_outbuf(req, 4, 0);
SSVAL(req->outbuf,smb_uid,sess_vuid);
ret = NT_STATUS_LOGON_FAILURE;
} else {
/* current_user_info is changed on new vuid */
- reload_services(sconn->msg_ctx, True);
+ reload_services(sconn->msg_ctx, sconn->sock, True);
SSVAL(req->outbuf, smb_vwv3, 0);
}
/* current_user_info is changed on new vuid */
- reload_services(sconn->msg_ctx, True);
+ reload_services(sconn->msg_ctx, sconn->sock, True);
SSVAL(req->outbuf, smb_vwv3, 0);
*kerb_mechOID = NULL;
/* parse out the OIDs and the first sec blob */
- if (!spnego_parse_negTokenInit(ctx, blob_in, OIDs, NULL, pblob_out)) {
+ if (!spnego_parse_negTokenInit(ctx, blob_in, OIDs, NULL, pblob_out) ||
+ (OIDs[0] == NULL)) {
return NT_STATUS_LOGON_FAILURE;
}
return 0;
}
- DEBUG(0,("shutdown_other_smbds: shutting down pid %u "
- "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid),
- state->ip));
+ DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
+ "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid),
+ state->ip));
messaging_send(state->msg_ctx, crec->pid, MSG_SHUTDOWN,
&data_blob_null);
return 0;
}
-static void setup_new_vc_session(struct messaging_context *msg_ctx)
+static void setup_new_vc_session(struct smbd_server_connection *sconn)
{
DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
"compatible we would close all old resources.\n"));
invalidate_all_vuids();
#endif
if (lp_reset_on_zero_vc()) {
- char addr[INET6_ADDRSTRLEN];
+ char *addr;
struct shutdown_state state;
- state.ip = client_addr(get_client_fd(),addr,sizeof(addr));
- state.msg_ctx = msg_ctx;
+ addr = tsocket_address_inet_addr_string(
+ sconn->remote_address, talloc_tos());
+ if (addr == NULL) {
+ return;
+ }
+ state.ip = addr;
+ state.msg_ctx = sconn->msg_ctx;
connections_forall_read(shutdown_other_smbds, &state);
+ TALLOC_FREE(addr);
}
}
}
if (SVAL(req->vwv+4, 0) == 0) {
- setup_new_vc_session(req->sconn->msg_ctx);
+ setup_new_vc_session(req->sconn);
}
reply_sesssetup_and_X_spnego(req);
}
if (SVAL(req->vwv+4, 0) == 0) {
- setup_new_vc_session(req->sconn->msg_ctx);
+ setup_new_vc_session(req->sconn);
}
DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
sub_set_smb_name(sub_user);
- reload_services(sconn->msg_ctx, True);
+ reload_services(sconn->msg_ctx, sconn->sock, True);
if (lp_security() == SEC_SHARE) {
+ char *sub_user_mapped = NULL;
/* In share level we should ignore any passwords */
data_blob_free(&lm_resp);
data_blob_free(&nt_resp);
data_blob_clear_free(&plaintext_password);
- map_username(sub_user);
+ (void)map_username(talloc_tos(), sub_user, &sub_user_mapped);
+ if (!sub_user_mapped) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ END_PROFILE(SMBsesssetupX);
+ return;
+ }
+ fstrcpy(sub_user, sub_user_mapped);
add_session_user(sconn, sub_user);
add_session_workgroup(sconn, domain);
/* Then force it to null for the benfit of the code below */
struct auth_context *plaintext_auth_context = NULL;
nt_status = make_auth_context_subsystem(
- &plaintext_auth_context);
+ talloc_tos(), &plaintext_auth_context);
if (NT_STATUS_IS_OK(nt_status)) {
uint8_t chal[8];
}
/* current_user_info is changed on new vuid */
- reload_services(sconn->msg_ctx, True);
+ reload_services(sconn->msg_ctx, sconn->sock, True);
}
data_blob_free(&nt_resp);