smb_logon.c revision 8d7e41661dc4633488e93b13363137523ce59977
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Security database interface.
*/
#include <unistd.h>
#include <strings.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <syslog.h>
#include <assert.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/smb_token.h>
#include <lsalib.h>
/* Consolidation private function from Network Repository */
extern int _getgroupsbymember(const char *, gid_t[], int, int);
static idmap_stat
{
int i;
return (IDMAP_ERR_ARG);
} else {
/* User SID */
if (stat != IDMAP_SUCCESS)
return (stat);
/* Owner SID */
if (stat != IDMAP_SUCCESS)
return (stat);
}
/* Primary Group SID */
if (stat != IDMAP_SUCCESS)
return (stat);
/* Other Windows Group SIDs */
if (stat != IDMAP_SUCCESS)
break;
}
return (stat);
}
/*
* smb_token_sids2ids
*
*
* Returns 0 upon success. Otherwise, returns -1.
*/
static int
{
/*
* Number of idmap lookups: user SID, owner SID, primary group SID,
* and all Windows group SIDs
*/
/*
* Don't include user and owner SID, they're Anonymous
*/
nmaps = 1;
else
nmaps = 3;
do {
if (stat != IDMAP_SUCCESS)
return (-1);
if (stat != IDMAP_SUCCESS) {
return (-1);
}
if (stat == IDMAP_ERR_RPC_HANDLE)
if (smb_idmap_restart() < 0)
break;
}
/*
* smb_token_create_pxgrps
*
* Setup the POSIX group membership of the access token if the given UID is
* a POSIX UID (non-ephemeral). Both the user's primary group and
* supplementary groups will be added to the POSIX group array of the access
* token.
*/
static smb_posix_grps_t *
{
int ngroups_max, num;
return (NULL);
}
return (NULL);
return (pgrps);
}
return (NULL);
return (pgrps);
}
return (NULL);
}
/*
* Setup the groups starting at index 1 (the last arg)
* of gids array.
*/
if (num == -1) {
"to get user's supplementary groups");
num = 1;
}
if (pgrps) {
}
return (pgrps);
}
/*
* smb_token_destroy
*
* Release all of the memory associated with a token structure. Ensure
* that the token has been unlinked before calling.
*/
void
{
int i;
return;
}
}
if (token->tkn_primary_grp) {
}
}
}
static smb_id_t *
{
return (NULL);
}
return (id);
}
/*
* Token owner should be set to local Administrators group
* in two cases:
* 1. The logged on user is a member of Domain Admins group
*/
static smb_id_t *
{
#ifdef SMB_SUPPORT_GROUP_OWNER
} else {
}
return (smb_token_create_id(owner_sid));
#endif
}
static smb_privset_t *
{
int rc;
privs = smb_privset_new();
return (NULL);
return (NULL);
}
}
smb_lgrp_free(&grp);
}
if (rc == SMB_LGRP_SUCCESS) {
smb_lgrp_free(&grp);
}
/*
*/
}
return (privs);
}
static void
{
return;
}
return;
}
}
/*
* smb_token_create
*
* Build an access token based on the given user information (user_info).
*
* If everything is successful, a pointer to an access token is
* returned. Otherwise a null pointer is returned.
*/
static smb_token_t *
{
return (NULL);
return (NULL);
}
/* User */
return (NULL);
}
/* Owner */
return (NULL);
}
/* Primary Group */
return (NULL);
}
/* Privileges */
return (NULL);
}
/* Windows Groups */
/*
* IMPORTANT
*
* This function has to be called after all the SIDs in the
* token are setup (i.e. user, owner, primary and supplementary
* groups) and before setting up Solaris groups.
*/
if (smb_token_sids2ids(token) != 0) {
return (NULL);
}
/* Solaris Groups */
if (user_info->session_key) {
return (NULL);
}
}
if (!smb_token_is_valid(token)) {
return (NULL);
}
return (token);
}
/*
* smb_token_create_wingrps
*
* This private function supports smb_token_create() by mapping the group
* information in the user_info structure to the form required in an
* access token. The main difference is that the user_info contains
* RIDs while and access token contains full SIDs. Memory allocated
* here will be deallocated as part of smb_token_destroy().
*
* If everything is successful, a pointer to a smb_win_grps_t
* structure is returned. Otherwise a null pointer is returned.
*/
static smb_win_grps_t *
{
static char *wk_grps[] =
{"Authenticated Users", "NETWORK", "Administrators"};
uint32_t i, j;
return (NULL);
/* Local Groups */
/* Well known Groups */
/* if user is a domain admin but not a local admin */
n_wg = 3;
n_wg = 0;
else
n_wg = 2;
return (NULL);
/* Add global groups */
for (i = 0; i < n_gg; i++) {
break;
}
if (n_gg == 0) {
/*
* if there's no global group should add the
* primary group.
*/
i++;
}
}
/* Add domain local groups */
for (j = 0; j < n_dlg; j++, i++) {
break;
}
/* Add local groups */
j = 0;
if ((j < n_lg) &&
break;
}
i++;
j++;
}
}
}
/* Add well known groups */
for (j = 0; j < n_wg; j++, i++) {
if (builtin_sid == NULL)
break;
}
return (tkn_grps);
}
/*
* smb_logon
*
* Performs user authentication and creates a token if the
* authentication is successful.
*
* Returns pointer to the created token.
*/
{
if ((uinfo = mlsvc_alloc_user_info()) == 0)
return (NULL);
case NETR_CFLG_DOMAIN:
/* Pass through authentication with DC */
break;
case NETR_CFLG_LOCAL:
/* Local authentication */
break;
case NETR_CFLG_ANON:
/* Anonymous user; no authentication */
break;
default:
break;
}
if (status == NT_STATUS_SUCCESS)
return (token);
}
/*
* smb_logon_domain
*
* Performs pass through authentication with PDC.
*/
static uint32_t
{
if (status == NT_STATUS_CANT_ACCESS_DOMAIN_INFO) {
return (status);
}
}
}
return (status);
}
/*
* smb_logon_local
*
* Check to see if connected user has an entry in the local
* smbpasswd database. If it has, tries both LM hash and NT
* hash with user's password(s) to authenticate the user.
*/
static uint32_t
{
/*
* If user doesn't have entry either in smbpasswd
* or passwd it's considered as an invalid user.
*/
return (status);
}
return (NT_STATUS_ACCOUNT_DISABLED);
&smbpw,
}
if ((uinfo->session_key =
return (NT_STATUS_NO_MEMORY);
&smbpw,
}
return (status);
}
return (status);
}
/*
* smb_logon_none
*
* Setup user information for anonymous user.
* No authentication is required.
*/
static uint32_t
{
}
/*
* smb_setup_luinfo
*
* Setup local user information based on the client information and
* user's record in the local password file.
*/
static uint32_t
{
char pwbuf[1024];
char nbname[NETBIOS_NAME_SZ];
lui->n_other_grps = 0;
return (NT_STATUS_INVALID_PARAMETER);
return (NT_STATUS_NO_MEMORY);
return (NT_STATUS_SUCCESS);
}
return (NT_STATUS_NO_SUCH_USER);
/* Get the SID for user's uid & gid */
if (stat != IDMAP_SUCCESS) {
return (NT_STATUS_INTERNAL_ERROR);
}
if (stat != IDMAP_SUCCESS) {
return (NT_STATUS_INTERNAL_ERROR);
}
if (stat != IDMAP_SUCCESS) {
return (NT_STATUS_INTERNAL_ERROR);
}
if (stat != IDMAP_SUCCESS) {
return (NT_STATUS_INTERNAL_ERROR);
}
return (NT_STATUS_NO_MEMORY);
smb_lgrp_free(&grp);
}
return (NT_STATUS_SUCCESS);
}
/*
* smb_token_is_valid
*
* check to see if specified fields of the given access
* token are valid.
* Returns 1 if all of them are valid; otherwise 0.
*/
static int
{
int valid;
(token->tkn_privileges != 0) &&
(token->tkn_win_grps != 0) &&
(token->tkn_primary_grp != 0) &&
return (valid);
}
/*
* smb_token_user_sid
*
* Return a pointer to the user SID in the specified token. A null
* pointer indicates an error.
*/
static smb_sid_t *
{
return (NULL);
}
/*
* smb_token_group_sid
*
* Return a pointer to the group SID as indicated by the iterator.
* Setting the iterator to 0 before calling this function will return
* the first group, which will always be the primary group. The
* iterator will be incremented before returning the SID so that this
* function can be used to cycle through the groups. The caller can
* adjust the iterator as required between calls to obtain any specific
* group.
*
* On success a pointer to the appropriate group SID will be returned.
* Otherwise a null pointer will be returned.
*/
static smb_sid_t *
{
int index;
return (NULL);
}
return (NULL);
}
return (NULL);
}
++(*iterator);
}
/*
* smb_token_is_member
*
* This function will determine whether or not the specified SID is a
* member of a token. The user SID and all group SIDs are tested.
* Returns 1 if the SID is a member of the token. Otherwise returns 0.
*/
static int
{
int iterator = 0;
while (tsid) {
return (1);
}
return (0);
}
/*
* smb_token_log
*
* Diagnostic routine to write the contents of a token to the log.
*/
void
{
char sidstr[SMB_SID_STRSZ];
int i;
return;
sidstr);
if (w_grps) {
" Grp[%d].Sid: %s (id=%u)", i, sidstr,
}
}
}
else
if (x_grps) {
}
else
if (token->tkn_privileges)
else
}