DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
- *user_info = malloc(sizeof(**user_info));
+ *user_info = SMB_MALLOC_P(auth_usersupplied_info);
if (!user_info) {
DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
return NT_STATUS_NO_MEMORY;
DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
- (*user_info)->smb_name.str = strdup(smb_name);
+ (*user_info)->smb_name.str = SMB_STRDUP(smb_name);
if ((*user_info)->smb_name.str) {
(*user_info)->smb_name.len = strlen(smb_name);
} else {
return NT_STATUS_NO_MEMORY;
}
- (*user_info)->internal_username.str = strdup(internal_username);
+ (*user_info)->internal_username.str = SMB_STRDUP(internal_username);
if ((*user_info)->internal_username.str) {
(*user_info)->internal_username.len = strlen(internal_username);
} else {
return NT_STATUS_NO_MEMORY;
}
- (*user_info)->domain.str = strdup(domain);
+ (*user_info)->domain.str = SMB_STRDUP(domain);
if ((*user_info)->domain.str) {
(*user_info)->domain.len = strlen(domain);
} else {
return NT_STATUS_NO_MEMORY;
}
- (*user_info)->client_domain.str = strdup(client_domain);
+ (*user_info)->client_domain.str = SMB_STRDUP(client_domain);
if ((*user_info)->client_domain.str) {
(*user_info)->client_domain.len = strlen(client_domain);
} else {
return NT_STATUS_NO_MEMORY;
}
- (*user_info)->wksta_name.str = strdup(wksta_name);
+ (*user_info)->wksta_name.str = SMB_STRDUP(wksta_name);
if ((*user_info)->wksta_name.str) {
(*user_info)->wksta_name.len = strlen(wksta_name);
} else {
for (i = 0; i < token->num_sids; i++)
DEBUGADDC(dbg_class, dbg_lev, ("SID[%3lu]: %s\n", (unsigned long)i,
sid_to_string(sid_str, &token->user_sids[i])));
+
+ dump_se_priv( dbg_class, dbg_lev, &token->privileges );
}
/****************************************************************************
int i;
int sid_ndx;
- if ((ptoken = malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) {
+ if ((ptoken = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL) {
DEBUG(0, ("create_nt_token: Out of memory allocating token\n"));
nt_status = NT_STATUS_NO_MEMORY;
return nt_status;
ptoken->num_sids = n_groupSIDs + 5;
- if ((ptoken->user_sids = (DOM_SID *)malloc( sizeof(DOM_SID) * ptoken->num_sids )) == NULL) {
+ if ((ptoken->user_sids = SMB_MALLOC_ARRAY( DOM_SID, ptoken->num_sids )) == NULL) {
DEBUG(0, ("create_nt_token: Out of memory allocating SIDs\n"));
nt_status = NT_STATUS_NO_MEMORY;
return nt_status;
ptoken->num_sids--;
}
}
+
+ /* add privileges assigned to this user */
+
+ get_privileges_for_sids( &ptoken->privileges, ptoken->user_sids, ptoken->num_sids );
debug_nt_user_token(DBGC_AUTH, 10, ptoken);
return NULL;
}
- group_sids = malloc(sizeof(DOM_SID) * ngroups);
+ group_sids = SMB_MALLOC_ARRAY(DOM_SID, ngroups);
if (!group_sids) {
DEBUG(0, ("create_nt_token: malloc() failed for DOM_SID list!\n"));
return NULL;
*n_groups = 0;
*groups = NULL;
-
- /* Try winbind first */
- if ( strchr(username, *lp_winbind_separator()) ) {
- n_unix_groups = winbind_getgroups( username, unix_groups );
+ if (strchr(username, *lp_winbind_separator()) == NULL) {
+ NTSTATUS result;
- DEBUG(10,("get_user_groups: winbind_getgroups(%s): result = %s\n", username,
- n_unix_groups == -1 ? "FAIL" : "SUCCESS"));
-
- if ( n_unix_groups == -1 )
- return NT_STATUS_NO_SUCH_USER; /* what should this return value be? */
+ become_root();
+ result = pdb_enum_group_memberships(username, gid, groups,
+ unix_groups, n_groups);
+ unbecome_root();
+ return result;
}
- else {
- /* fallback to getgrouplist() */
-
- n_unix_groups = groups_max();
-
- if ((*unix_groups = malloc( sizeof(gid_t) * n_unix_groups ) ) == NULL) {
- DEBUG(0, ("get_user_groups: Out of memory allocating unix group list\n"));
- return NT_STATUS_NO_MEMORY;
- }
+
+ /* We have the separator, this must be winbind */
- if (sys_getgrouplist(username, gid, *unix_groups, &n_unix_groups) == -1) {
-
- gid_t *groups_tmp;
-
- groups_tmp = Realloc(*unix_groups, sizeof(gid_t) * n_unix_groups);
-
- if (!groups_tmp) {
- SAFE_FREE(*unix_groups);
- return NT_STATUS_NO_MEMORY;
- }
- *unix_groups = groups_tmp;
+ n_unix_groups = winbind_getgroups( username, unix_groups );
- if (sys_getgrouplist(username, gid, *unix_groups, &n_unix_groups) == -1) {
- DEBUG(0, ("get_user_groups: failed to get the unix group list\n"));
- SAFE_FREE(*unix_groups);
- return NT_STATUS_NO_SUCH_USER; /* what should this return value be? */
- }
- }
- }
+ DEBUG(10,("get_user_groups: winbind_getgroups(%s): result = %s\n",
+ username, n_unix_groups == -1 ? "FAIL" : "SUCCESS"));
+
+ if ( n_unix_groups == -1 )
+ return NT_STATUS_NO_SUCH_USER; /* what should this return
+ * value be? */
debug_unix_user_token(DBGC_CLASS, 5, uid, gid, n_unix_groups, *unix_groups);
if (n_unix_groups > 0) {
- *groups = malloc(sizeof(DOM_SID) * n_unix_groups);
+ *groups = SMB_MALLOC_ARRAY(DOM_SID, n_unix_groups);
if (!*groups) {
DEBUG(0, ("get_user_group: malloc() failed for DOM_SID list!\n"));
static NTSTATUS make_server_info(auth_serversupplied_info **server_info)
{
- *server_info = malloc(sizeof(**server_info));
+ *server_info = SMB_MALLOC_P(auth_serversupplied_info);
if (!*server_info) {
DEBUG(0,("make_server_info: malloc failed!\n"));
return NT_STATUS_NO_MEMORY;
Make (and fill) a user_info struct for a guest login.
***************************************************************************/
-NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
+static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
{
NTSTATUS nt_status;
SAM_ACCOUNT *sampass = NULL;
return nt_status;
}
+static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
+{
+ auth_serversupplied_info *dst;
+
+ if (!NT_STATUS_IS_OK(make_server_info(&dst)))
+ return NULL;
+
+ dst->guest = src->guest;
+ dst->uid = src->uid;
+ dst->gid = src->gid;
+ dst->n_groups = src->n_groups;
+ if (src->n_groups != 0)
+ dst->groups = memdup(src->groups, sizeof(gid_t)*dst->n_groups);
+ else
+ dst->groups = NULL;
+ dst->ptok = dup_nt_token(src->ptok);
+ dst->user_session_key = data_blob(src->user_session_key.data,
+ src->user_session_key.length);
+ dst->lm_session_key = data_blob(src->lm_session_key.data,
+ src->lm_session_key.length);
+ pdb_copy_sam_account(src->sam_account, &dst->sam_account);
+ dst->pam_handle = NULL;
+ dst->unix_name = smb_xstrdup(src->unix_name);
+
+ return dst;
+}
+
+static auth_serversupplied_info *guest_info = NULL;
+
+BOOL init_guest_info(void)
+{
+ if (guest_info != NULL)
+ return True;
+
+ return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
+}
+
+NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
+{
+ *server_info = copy_serverinfo(guest_info);
+ return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
+}
+
/***************************************************************************
Purely internal function for make_server_info_info3
Fill the sam account from getpwnam
uid_t *uid, gid_t *gid,
SAM_ACCOUNT **sam_account)
{
- fstring dom_user;
+ fstring dom_user, lower_username;
fstring real_username;
struct passwd *passwd;
- fstr_sprintf(dom_user, "%s%s%s", domain, lp_winbind_separator(),
- username);
+ fstrcpy( lower_username, username );
+ strlower_m( 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 */
+ map_username( dom_user );
+
if ( !(passwd = smb_getpwnam( dom_user, real_username, True )) )
return NT_STATUS_NO_SUCH_USER;
}
/* try to fill the SAM account.. If getpwnam() fails, then try the
- add user script (2.2.x behavior) */
+ add user script (2.2.x behavior).
+
+ We use the _unmapped_ username here in an attempt to provide
+ consistent username mapping behavior between kerberos and NTLM[SSP]
+ authentication in domain mode security. I.E. Username mapping should
+ be applied to the fully qualified username (e.g. DOMAIN\user) and
+ no just the login name. Yes this mean swe called map_username()
+ unnecessarily in make_user_info_map() but that is how the current
+ code is designed. Making the change here is the least disruptive
+ place. -- jerry */
- nt_status = fill_sam_account(mem_ctx, nt_domain, internal_username,
+ nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
&found_username, &uid, &gid, &sam_account);
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));
- auth_add_user_script(nt_domain, internal_username);
- nt_status = fill_sam_account(mem_ctx, nt_domain,
- internal_username, &found_username,
- &uid, &gid, &sam_account);
+ DEBUG(3,("User %s does not exist, trying to add it\n", internal_username));
+ auth_add_user_script( nt_domain, sent_nt_username );
+ nt_status = fill_sam_account( mem_ctx, nt_domain, sent_nt_username,
+ &found_username, &uid, &gid, &sam_account );
}
if (!NT_STATUS_IS_OK(nt_status)) {
/* Create a 'combined' list of all SIDs we might want in the SD */
- all_group_SIDs = malloc(sizeof(DOM_SID) * (info3->num_groups2 + info3->num_other_sids + n_lgroupSIDs));
+ all_group_SIDs = SMB_MALLOC_ARRAY(DOM_SID,info3->num_groups2 + info3->num_other_sids + n_lgroupSIDs);
if (!all_group_SIDs) {
DEBUG(0, ("malloc() failed for DOM_SID list!\n"));
(*server_info)->user_session_key = data_blob(info3->user_sess_key, sizeof(info3->user_sess_key));
}
- if (memcmp(info3->padding, zeros, sizeof(zeros)) == 0) {
+ if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {
(*server_info)->lm_session_key = data_blob(NULL, 0);
} else {
- (*server_info)->lm_session_key = data_blob(info3->padding, 16);
- }
+ (*server_info)->lm_session_key = data_blob(info3->lm_sess_key, sizeof(info3->lm_sess_key));
+ }
+
return NT_STATUS_OK;
}
smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n");
}
- *auth_method = talloc(auth_context->mem_ctx, sizeof(**auth_method));
+ *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
if (!*auth_method) {
DEBUG(0,("make_auth_method: malloc failed!\n"));
return False;
void delete_nt_token(NT_USER_TOKEN **pptoken)
{
- if (*pptoken) {
- NT_USER_TOKEN *ptoken = *pptoken;
- SAFE_FREE( ptoken->user_sids );
- ZERO_STRUCTP(ptoken);
- }
- SAFE_FREE(*pptoken);
+ if (*pptoken) {
+ NT_USER_TOKEN *ptoken = *pptoken;
+
+ SAFE_FREE( ptoken->user_sids );
+ ZERO_STRUCTP(ptoken);
+ }
+ SAFE_FREE(*pptoken);
}
/****************************************************************************
if (!ptoken)
return NULL;
- if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL)
- return NULL;
-
- ZERO_STRUCTP(token);
+ if ((token = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL)
+ return NULL;
- if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) {
- SAFE_FREE(token);
- return NULL;
- }
+ ZERO_STRUCTP(token);
+
+ token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids );
+
+ if ( !token ) {
+ SAFE_FREE(token);
+ return NULL;
+ }
- token->num_sids = ptoken->num_sids;
+ token->num_sids = ptoken->num_sids;
+
+ /* copy the privileges; don't consider failure to be critical here */
+
+ if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
+ DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!. Continuing with 0 privileges assigned.\n"));
+ }
return token;
}
+/****************************************************************************
+ Check for a SID in an NT_USER_TOKEN
+****************************************************************************/
+
+BOOL nt_token_check_sid ( DOM_SID *sid, NT_USER_TOKEN *token )
+{
+ int i;
+
+ if ( !sid || !token )
+ return False;
+
+ for ( i=0; i<token->num_sids; i++ ) {
+ if ( sid_equal( sid, &token->user_sids[i] ) )
+ return True;
+ }
+
+ return False;
+}
+
+BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
+{
+ DOM_SID domain_sid;
+
+ sid_copy( &domain_sid, get_global_sam_sid() );
+ sid_append_rid( &domain_sid, rid );
+
+ return nt_token_check_sid( &domain_sid, token );\
+}
+
/**
* Verify whether or not given domain is trusted.
*