smb_pass.c revision 02d09e03eb27f3a2dc299de704e45dae5173f43f
/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Password Keychain storage mechanism.
*/
#include <sys/sysmacros.h>
#include <sys/pathname.h>
#include <sys/avl_impl.h>
#include <sys/u8_textprep.h>
#include <netsmb/smb_osdep.h>
#include <netsmb/smb_conn.h>
#include <netsmb/smb_subr.h>
#include <netsmb/smb_pass.h>
/*
* The smb_ptd is a cache of Uid's, User names, passwords and domain names.
* It will be used for storing the password information for a user and will
* be used to for connections without entering the pasword again if its
* already keyed in by the user. Its a kind of Key-Chain mechanism
* implemented by Apple folks.
*/
/*
* Information stored in the nodes:
* UID: Uid of the person who initiated the login request.
* ZoneID: ZoneID of the zone from where the login request is initiated.
* Username: Username in the CIFS server.
* Srvdom: Domain name/ Server name of the CIFS server.
* Password: Password of the user.
* For more information, see smb_pass.h and sys/avl.h
*/
/*
* Information retrieved from the node.
* to smb_pkey_getpw(). Password never gets copied to the userspace.
* It will be copied to the Kernel data structure smbioc_ossn->ioc_password
* when needed for doing the "Session Setup". All other calls will return
* either a success or a failure.
*/
unsigned int smb_list_len = 0; /* No. of elements in the tree. */
/*
* This routine is called by AVL tree calls when they want to find a
* node, find the next position in the tree to add or for deletion.
* Compare nodes from the tree to find the actual node based on
*/
int
smb_pkey_cmp(const void *a, const void *b)
{
/*
* The nodes are added sorted on the uid/zoneid/domainname/username
* We will do this:
* Compare uid's. The owner who stored the node gets access.
* Then zoneid to check if the access is from the same zone.
* Compare usernames.
*/
return (-1);
return (+1);
return (-1);
return (+1);
if (dsrv < 0)
return (-1);
if (dsrv > 0)
return (+1);
if (duser < 0)
return (-1);
if (duser > 0)
return (+1);
return (0);
}
/*
* Initialization of the code that deals with uid and passwords.
*/
void
{
sizeof (smb_passid_t),
cpnode));
}
/*
* Destroy the full AVL tree.
* Called just before unload.
*/
void
{
}
/*
* Driver unload calls this to ask if we
* have any stored passwords
*/
int
{
int n;
n = avl_numnodes(&smb_ptd);
return ((n) ? EBUSY : 0);
}
static void
{
}
/*
* Remove a node from the AVL tree identified by cpid.
*/
int
{
else {
return (EPERM);
}
}
return (0);
}
/*
* Delete the entries owned by a particular user
* based on uid. We go through all the nodes and
* delete the nodes whereever the uid matches.
*
* Also implements "delete all" when uid == -1.
*
* You must have privilege to use any uid other
* than your real uid.
*/
int
{
return (EPERM);
/*
* Delete the node.
*/
}
}
return (0);
}
/*
* Add entry or modify existing.
* Check for existing entry..
* If present, delete.
* Now, add the new entry.
*/
int
{
avl_tree_t *t = &smb_ptd;
int ret;
else {
return (EPERM);
}
/*
* XXX: Instead of calling smb_pkey_check here,
* should call avl_find directly, and hold the
* lock across: avl_find, avl_remove, avl_insert.
*/
/* If it already exists, delete it. */
if (ret == 0) {
}
} else {
}
return (0);
}
/*
* Determine if a node with uid,zoneid, uname & dname exists in the tree
* given the information, and if found, return the hashes.
*/
int
{
avl_tree_t *t = &smb_ptd;
else {
return (EPERM);
}
error = 0;
}
return (error);
}
int
{
int err = 0;
switch (cmd) {
case SMBIOC_PK_ADD:
case SMBIOC_PK_DEL:
case SMBIOC_PK_CHK:
goto out;
}
/* Make strlen (etc) on these safe. */
break;
}
switch (cmd) {
case SMBIOC_PK_ADD:
break;
case SMBIOC_PK_DEL:
break;
case SMBIOC_PK_CHK:
/* This is just a hash now. */
break;
case SMBIOC_PK_DEL_OWNER:
break;
case SMBIOC_PK_DEL_EVERYONE:
break;
default:
}
out:
return (err);
}