#include <sys/types.h>
#include <sys/cred.h>
#include <sys/cred_impl.h>
#include <sys/sid.h>
#include <sys/priv_names.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <smbsrv/smb_idmap.h>
#include <smbsrv/smb_kproto.h>
#include <smbsrv/smb_token.h>
static void smb_cred_set_sid(smb_id_t *id, ksid_t *ksid);
static ksidlist_t *smb_cred_set_sidlist(smb_ids_t *token_grps);
cred_t *
smb_cred_create(smb_token_t *token)
{
ksid_t ksid;
ksidlist_t *ksidlist = NULL;
smb_posix_grps_t *posix_grps;
cred_t *cr;
gid_t gid;
ASSERT(token);
ASSERT(token->tkn_posix_grps);
posix_grps = token->tkn_posix_grps;
cr = crget();
ASSERT(cr != NULL);
priv_addset(&CR_PPRIV(cr), PRIV_SYS_SMB);
if (!IDMAP_ID_IS_EPHEMERAL(token->tkn_user.i_id) &&
(posix_grps->pg_ngrps != 0)) {
gid = posix_grps->pg_grps[0];
} else {
gid = token->tkn_primary_grp.i_id;
}
if (crsetugid(cr, token->tkn_user.i_id, gid) != 0) {
crfree(cr);
return (NULL);
}
if (crsetgroups(cr, posix_grps->pg_ngrps, posix_grps->pg_grps) != 0) {
crfree(cr);
return (NULL);
}
smb_cred_set_sid(&token->tkn_user, &ksid);
crsetsid(cr, &ksid, KSID_USER);
smb_cred_set_sid(&token->tkn_primary_grp, &ksid);
crsetsid(cr, &ksid, KSID_GROUP);
smb_cred_set_sid(&token->tkn_owner, &ksid);
crsetsid(cr, &ksid, KSID_OWNER);
ksidlist = smb_cred_set_sidlist(&token->tkn_win_grps);
crsetsidlist(cr, ksidlist);
return (cr);
}
static void
smb_cred_set_sid(smb_id_t *id, ksid_t *ksid)
{
char sidstr[SMB_SID_STRSZ];
int rc;
ASSERT(id);
ASSERT(id->i_sid);
ksid->ks_id = id->i_id;
smb_sid_tostr(id->i_sid, sidstr);
rc = smb_sid_splitstr(sidstr, &ksid->ks_rid);
ASSERT(rc == 0);
ksid->ks_attr = id->i_attrs;
ksid->ks_domain = ksid_lookupdomain(sidstr);
}
static ksidlist_t *
smb_cred_set_sidlist(smb_ids_t *token_grps)
{
int i;
ksidlist_t *lp;
lp = kmem_zalloc(KSIDLIST_MEM(token_grps->i_cnt), KM_SLEEP);
lp->ksl_ref = 1;
lp->ksl_nsid = token_grps->i_cnt;
lp->ksl_neid = 0;
for (i = 0; i < lp->ksl_nsid; i++) {
smb_cred_set_sid(&token_grps->i_ids[i], &lp->ksl_sids[i]);
if (lp->ksl_sids[i].ks_id > IDMAP_WK__MAX_GID)
lp->ksl_neid++;
}
return (lp);
}
cred_t *
smb_kcred_create(void)
{
cred_t *cr;
cr = crget();
ASSERT(cr != NULL);
return (cr);
}