DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
*user_info = SMB_MALLOC_P(auth_usersupplied_info);
- if (!user_info) {
+ if (*user_info == NULL) {
DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
return NT_STATUS_NO_MEMORY;
}
BOOL encrypted)
{
const char *domain;
+ NTSTATUS result;
+ BOOL was_mapped;
fstring internal_username;
fstrcpy(internal_username, smb_name);
- map_username(internal_username);
+ was_mapped = map_username(internal_username);
DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
client_domain, smb_name, wksta_name));
/* we know that it is a trusted domain (and we are allowing them) or it is our domain */
- return make_user_info(user_info, smb_name, internal_username,
+ result = make_user_info(user_info, smb_name, internal_username,
client_domain, domain, wksta_name,
lm_pwd, nt_pwd,
lm_interactive_pwd, nt_interactive_pwd,
plaintext, encrypted);
+ if (NT_STATUS_IS_OK(result)) {
+ (*user_info)->was_mapped = was_mapped;
+ }
+ return result;
}
/****************************************************************************
return NT_STATUS_OK;
}
-/*
- * Create a NT token for the user, expanding local aliases
- */
+/*******************************************************************
+*******************************************************************/
+
+static NTSTATUS add_builtin_administrators( TALLOC_CTX *ctx, struct nt_user_token *token )
+{
+ DOM_SID domadm;
+
+ /* nothing to do if we aren't in a domain */
+
+ if ( !(IS_DC || lp_server_role()==ROLE_DOMAIN_MEMBER) ) {
+ return NT_STATUS_OK;
+ }
+
+ /* Find the Domain Admins SID */
+
+ if ( IS_DC ) {
+ sid_copy( &domadm, get_global_sam_sid() );
+ } else {
+ if ( !secrets_fetch_domain_sid( lp_workgroup(), &domadm ) )
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+ sid_append_rid( &domadm, DOMAIN_GROUP_RID_ADMINS );
+
+ /* Add Administrators if the user beloongs to Domain Admins */
+
+ if ( nt_token_check_sid( &domadm, token ) ) {
+ add_sid_to_array(token, &global_sid_Builtin_Administrators,
+ &token->user_sids, &token->num_sids);
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+static NTSTATUS create_builtin_users( void )
+{
+ NTSTATUS status;
+ DOM_SID dom_users;
+
+ status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_USERS );
+ if ( !NT_STATUS_IS_OK(status) ) {
+ DEBUG(0,("create_builtin_users: Failed to create Users\n"));
+ return status;
+ }
+
+ /* add domain users */
+ if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER))
+ && secrets_fetch_domain_sid(lp_workgroup(), &dom_users))
+ {
+ sid_append_rid(&dom_users, DOMAIN_GROUP_RID_USERS );
+ status = pdb_add_aliasmem( &global_sid_Builtin_Users, &dom_users);
+ if ( !NT_STATUS_IS_OK(status) ) {
+ DEBUG(0,("create_builtin_administrators: Failed to add Domain Users to"
+ " Users\n"));
+ return status;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+static NTSTATUS create_builtin_administrators( void )
+{
+ NTSTATUS status;
+ DOM_SID dom_admins, root_sid;
+ fstring root_name;
+ enum SID_NAME_USE type;
+ TALLOC_CTX *ctx;
+ BOOL ret;
+
+ status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_ADMINS );
+ if ( !NT_STATUS_IS_OK(status) ) {
+ DEBUG(0,("create_builtin_administrators: Failed to create Administrators\n"));
+ return status;
+ }
+
+ /* add domain admins */
+ if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER))
+ && secrets_fetch_domain_sid(lp_workgroup(), &dom_admins))
+ {
+ sid_append_rid(&dom_admins, DOMAIN_GROUP_RID_ADMINS);
+ status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &dom_admins );
+ if ( !NT_STATUS_IS_OK(status) ) {
+ DEBUG(0,("create_builtin_administrators: Failed to add Domain Admins"
+ " Administrators\n"));
+ return status;
+ }
+ }
+
+ /* add root */
+ if ( (ctx = talloc_init(NULL)) == NULL ) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ fstr_sprintf( root_name, "%s\\root", get_global_sam_name() );
+ ret = lookup_name( ctx, root_name, 0, NULL, NULL, &root_sid, &type );
+ TALLOC_FREE( ctx );
+
+ if ( ret ) {
+ status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &root_sid );
+ if ( !NT_STATUS_IS_OK(status) ) {
+ DEBUG(0,("create_builtin_administrators: Failed to add root"
+ " Administrators\n"));
+ return status;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ Create a NT token for the user, expanding local aliases
+*******************************************************************/
static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
const DOM_SID *user_sid,
struct nt_user_token *result = NULL;
int i;
NTSTATUS status;
+ gid_t gid;
tmp_ctx = talloc_new(mem_ctx);
if (tmp_ctx == NULL) {
goto done;
}
- /* First create the default SIDs */
+ /* Add the user and primary group sid */
add_sid_to_array(result, user_sid,
&result->user_sids, &result->num_sids);
add_sid_to_array(result, group_sid,
&result->user_sids, &result->num_sids);
+
+ /* Add in BUILTIN sids */
+
add_sid_to_array(result, &global_sid_World,
&result->user_sids, &result->num_sids);
add_sid_to_array(result, &global_sid_Network,
add_sid_to_array(result, &global_sid_Authenticated_Users,
&result->user_sids, &result->num_sids);
}
-
+
/* Now the SIDs we got from authentication. These are the ones from
* the info3 struct or from the pdb_enum_group_memberships, depending
* on who authenticated the user. */
add_sid_to_array_unique(result, &groupsids[i],
&result->user_sids, &result->num_sids);
}
+
+ /* Deal with the BUILTIN\Administrators group. If the SID can
+ be resolved then assume that the add_aliasmem( S-1-5-32 )
+ handled it. */
+
+ if ( !sid_to_gid( &global_sid_Builtin_Administrators, &gid ) ) {
+ /* We can only create a mapping if winbind is running
+ and the nested group functionality has been enabled */
+
+ if ( lp_winbind_nested_groups() && winbind_ping() ) {
+ become_root();
+ status = create_builtin_administrators( );
+ if ( !NT_STATUS_IS_OK(status) ) {
+ DEBUG(0,("create_local_nt_token: Failed to create BUILTIN\\Administrators group!\n"));
+ /* don't fail, just log the message */
+ }
+ unbecome_root();
+ }
+ else {
+ status = add_builtin_administrators( tmp_ctx, result );
+ if ( !NT_STATUS_IS_OK(status) ) {
+ /* just log a complaint but do not fail */
+ DEBUG(3,("create_local_nt_token: failed to check for local Administrators"
+ " membership (%s)\n", nt_errstr(status)));
+ }
+ }
+ }
+
+ /* Deal with the BUILTIN\Users group. If the SID can
+ be resolved then assume that the add_aliasmem( S-1-5-32 )
+ handled it. */
+
+ if ( !sid_to_gid( &global_sid_Builtin_Users, &gid ) ) {
+ /* We can only create a mapping if winbind is running
+ and the nested group functionality has been enabled */
+
+ if ( lp_winbind_nested_groups() && winbind_ping() ) {
+ become_root();
+ status = create_builtin_users( );
+ if ( !NT_STATUS_IS_OK(status) ) {
+ DEBUG(0,("create_local_nt_token: Failed to create BUILTIN\\Administrators group!\n"));
+ /* don't fail, just log the message */
+ }
+ unbecome_root();
+ }
+ }
+ /* Deal with local groups */
+
if (lp_winbind_nested_groups()) {
/* Now add the aliases. First the one from our local SAM */
result = NULL;
goto done;
}
- } else {
-
- /* Play jerry's trick to auto-add local admins if we're a
- * domain admin. */
-
- DOM_SID dom_admins;
- BOOL domain_mode = False;
-
- if (IS_DC) {
- sid_compose(&dom_admins, get_global_sam_sid(),
- DOMAIN_GROUP_RID_ADMINS);
- domain_mode = True;
- }
- if ((lp_server_role() == ROLE_DOMAIN_MEMBER) &&
- (secrets_fetch_domain_sid(lp_workgroup(), &dom_admins))) {
- sid_append_rid(&dom_admins, DOMAIN_GROUP_RID_ADMINS);
- domain_mode = True;
- }
+ }
- if (domain_mode) {
- for (i=0; i<result->num_sids; i++) {
- if (sid_equal(&dom_admins,
- &result->user_sids[i])) {
- add_sid_to_array_unique(
- result,
- &global_sid_Builtin_Administrators,
- &result->user_sids,
- &result->num_sids);
- break;
- }
- }
-
- }
- }
get_privileges_for_sids(&result->privileges, result->user_sids,
result->num_sids);
return NT_STATUS_NO_MEMORY;
}
- server_info->ptok = create_local_nt_token(
- server_info,
- pdb_get_user_sid(server_info->sam_account),
- pdb_get_group_sid(server_info->sam_account),
- server_info->guest,
- server_info->num_sids, server_info->sids);
+ if (server_info->was_mapped) {
+ status = create_token_from_username(server_info,
+ server_info->unix_name,
+ server_info->guest,
+ &server_info->uid,
+ &server_info->gid,
+ &server_info->unix_name,
+ &server_info->ptok);
+
+ } else {
+ server_info->ptok = create_local_nt_token(
+ server_info,
+ pdb_get_user_sid(server_info->sam_account),
+ pdb_get_group_sid(server_info->sam_account),
+ server_info->guest,
+ server_info->num_sids, server_info->sids);
+ status = server_info->ptok ?
+ NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(mem_ctx);
+ return status;
+ }
/* Convert the SIDs to gids. */
/* This is a passdb user, so ask passdb */
struct samu *sam_acct = NULL;
+ const DOM_SID *gr_sid = NULL;
if ( !(sam_acct = samu_new( tmp_ctx )) ) {
+ result = NT_STATUS_NO_MEMORY;
goto done;
}
goto done;
}
- sid_copy(&primary_group_sid, pdb_get_group_sid(sam_acct));
+ gr_sid = pdb_get_group_sid(sam_acct);
+ if (!gr_sid) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ sid_copy(&primary_group_sid, gr_sid);
+
+ if (!sid_to_gid(&primary_group_sid, gid)) {
+ DEBUG(1, ("sid_to_gid(%s) failed\n",
+ sid_string_static(&primary_group_sid)));
+ goto done;
+ }
result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
&group_sids, &gids,
{
TALLOC_CTX *mem_ctx;
DOM_SID group_sid;
- NTSTATUS status;
BOOL ret;
mem_ctx = talloc_new(NULL);
TALLOC_FREE(mem_ctx);
if (!ret) {
- DEBUG(10, ("lookup_name(%s) failed: %s\n", groupname,
- nt_errstr(status)));
+ DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
return False;
}
}
-/***************************************************************************
- Make (and fill) a user_info struct from a Kerberos PAC logon_info by
- conversion to a struct samu
-***************************************************************************/
-
-NTSTATUS make_server_info_pac(auth_serversupplied_info **server_info,
- char *unix_username,
- struct passwd *pwd,
- PAC_LOGON_INFO *logon_info)
-{
- NTSTATUS status;
- struct samu *sampass = NULL;
- DOM_SID user_sid, group_sid;
- fstring dom_name;
- auth_serversupplied_info *result;
-
- if ( !(sampass = samu_new( NULL )) ) {
- return NT_STATUS_NO_MEMORY;
- }
-
- status = samu_set_unix( sampass, pwd );
- if ( !NT_STATUS_IS_OK(status) ) {
- return status;
- }
-
- result = make_server_info(NULL);
- if (result == NULL) {
- TALLOC_FREE(sampass);
- return NT_STATUS_NO_MEMORY;
- }
-
- /* 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);
-
- result->sam_account = sampass;
- result->unix_name = talloc_strdup(result, unix_username);
- result->uid = pwd->pw_uid;
- result->gid = pwd->pw_gid;
-
- /* TODO: Add groups from pac */
- result->sids = NULL;
- result->num_sids = 0;
-
- *server_info = result;
-
- return NT_STATUS_OK;
-}
-
-
/***************************************************************************
Make (and fill) a user_info struct from a 'struct passwd' by conversion
to a struct samu
}
result = make_server_info(NULL);
-
- if (!NT_STATUS_IS_OK(status)) {
+ if (result == NULL) {
TALLOC_FREE(sampass);
- return status;
+ return NT_STATUS_NO_MEMORY;
}
result->sam_account = sampass;
Make (and fill) a user_info struct for a guest login.
This *must* succeed for smbd to start. If there is no mapping entry for
the guest gid, then create one.
-**********************
-*****************************************************/
+***************************************************************************/
static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
{
dst->uid = src->uid;
dst->gid = src->gid;
dst->n_groups = src->n_groups;
- if (src->n_groups != 0)
+ if (src->n_groups != 0) {
dst->groups = talloc_memdup(dst, src->groups,
sizeof(gid_t)*dst->n_groups);
- else
+ } else {
dst->groups = NULL;
-
- dst->ptok = dup_nt_token(dst, src->ptok);
+ }
+
+ if (src->ptok) {
+ dst->ptok = dup_nt_token(dst, src->ptok);
+ if (!dst->ptok) {
+ TALLOC_FREE(dst);
+ return NULL;
+ }
+ }
dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
- src->user_session_key.length);
-
+ src->user_session_key.length);
+
dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
- src->lm_session_key.length);
-
- if ( (dst->sam_account = samu_new( NULL )) != NULL )
- pdb_copy_sam_account(dst->sam_account, src->sam_account);
+ src->lm_session_key.length);
+
+ dst->sam_account = samu_new(NULL);
+ if (!dst->sam_account) {
+ TALLOC_FREE(dst);
+ return NULL;
+ }
+
+ if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) {
+ TALLOC_FREE(dst);
+ return NULL;
+ }
dst->pam_handle = NULL;
dst->unix_name = talloc_strdup(dst, src->unix_name);
+ if (!dst->unix_name) {
+ TALLOC_FREE(dst);
+ return NULL;
+ }
return dst;
}
{
if (guest_info != NULL)
return True;
-
-
return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
}
const char *username,
char **found_username,
uid_t *uid, gid_t *gid,
- struct samu *account)
+ struct samu *account,
+ BOOL *username_was_mapped)
{
NTSTATUS nt_status;
fstring dom_user, lower_username;
fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(),
lower_username);
- /* get the passwd struct but don't create the user if he/she
- does not exist. We were explicitly called from a following
- a winbindd authentication request so we should assume that
- nss_winbindd is working */
+ /* Get the passwd struct. Try to create the account is necessary. */
- map_username( dom_user );
+ *username_was_mapped = map_username( dom_user );
if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
return NT_STATUS_NO_SUCH_USER;
pw = Get_Pwnam_alloc(mem_ctx, username);
- /* Create local user if requested. */
+ /* Create local user if requested but only if winbindd
+ is not running. We need to protect against cases
+ where winbindd is failing and then prematurely
+ creating users in /etc/passwd */
- if ( !pw && create ) {
+ if ( !pw && create && !winbind_ping() ) {
/* Don't add a machine account. */
if (username[strlen(username)-1] == '$')
return NULL;
***************************************************************************/
NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
- const char *internal_username,
const char *sent_nt_username,
const char *domain,
auth_serversupplied_info **server_info,
struct samu *sam_account = NULL;
DOM_SID user_sid;
DOM_SID group_sid;
+ BOOL username_was_mapped;
uid_t uid;
gid_t gid;
return NT_STATUS_NO_MEMORY;
}
+ /* this call will try to create the user if necessary */
+
nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
- &found_username, &uid, &gid, sam_account);
+ &found_username, &uid, &gid, sam_account,
+ &username_was_mapped);
- if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
- DEBUG(3,("User %s does not exist, trying to add it\n",
- internal_username));
- smb_create_user( nt_domain, sent_nt_username, NULL);
- nt_status = fill_sam_account( mem_ctx, nt_domain, sent_nt_username,
- &found_username, &uid, &gid, sam_account );
- }
/* if we still don't have a valid unix account check for
- 'map to guest = bad user' */
+ 'map to guest = bad uid' */
if (!NT_STATUS_IS_OK(nt_status)) {
TALLOC_FREE( sam_account );
return NT_STATUS_NO_MEMORY;
}
+ if (!pdb_set_acct_ctrl(sam_account, info3->acct_flags, PDB_CHANGED)) {
+ TALLOC_FREE(sam_account);
+ return NT_STATUS_NO_MEMORY;
+ }
+
result = make_server_info(NULL);
if (result == NULL) {
DEBUG(4, ("make_server_info failed!\n"));
sizeof(info3->lm_sess_key));
}
+ result->was_mapped = username_was_mapped;
+
*server_info = result;
return NT_STATUS_OK;