samr_open.c revision dc20a3024900c47dd2ee44b9707e6df38f7d62a5
/*
* 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.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Security Access Manager RPC (SAMR) library interface functions for
* connect, open and close calls. The SAM is a hierarchical database.
* If you want to talk to the SAM you need a SAM handle, if you want
* to work with a domain, you need to use the SAM handle to obtain a
* domain handle. Then you can use the domain handle to obtain a user
* handle etc. Be careful about returning null handles to the
* application. Use of a null handle may crash the domain controller
* if you attempt to use it.
*/
#include <stdio.h>
#include <strings.h>
#include <unistd.h>
#include <netdb.h>
#include <smbsrv/libsmbrdr.h>
#include <smbsrv/ntstatus.h>
#include <smbsrv/ntaccess.h>
/*LINTED E_STATIC_UNUSED*/
/*
* samr_open
*
* This is a wrapper round samr_connect to ensure that we connect using
* the appropriate session and logon. We default to the resource domain
* information if the caller doesn't supply a server name and a domain
* name. We store the remote server's native OS type - we may need it
* due to differences between platforms like NT and Windows 2000.
*
* If username argument is NULL, an anonymous connection will be established.
* Otherwise, an authenticated connection will be established.
*
* On success 0 is returned. Otherwise a -ve error code.
*/
int
{
int remote_os;
int remote_lm;
int rc;
return (-1);
}
if (rc != 0)
return (-1);
if (rc == 0) {
}
return (rc);
}
/*
* samr_connect
*
* Connect to the SAM on the specified server (domain controller).
* This is the entry point for the various SAM connect calls. We do
* parameter validation and open the samr named pipe here. The actual
* RPC is based on the native OS of the server.
*
* Returns 0 on success. Otherwise returns a -ve error code.
*/
int
{
int remote_os;
int remote_lm;
int fid;
int rc = 0;
return (-1);
return (-1);
(void) mlsvc_close_pipe(fid);
return (-1);
}
switch (remote_os) {
case NATIVE_OS_NT5_1:
break;
case NATIVE_OS_NT5_0:
break;
case NATIVE_OS_NT4_0:
default:
break;
}
if (status != NT_STATUS_SUCCESS) {
(void) mlsvc_close_pipe(fid);
rc = -1;
}
return (rc);
}
/*
* samr_connect1
*
* Original SAMR connect call; probably used on Windows NT 3.51.
* Windows 95 uses this call with the srvmgr tools update.
* Servername appears to be a dword rather than a string.
* The first word contains '\' and the second word contains 0x001,
* (which is probably uninitialized junk: 0x0001005c.
*/
/*ARGSUSED*/
static DWORD
{
struct samr_ConnectAnon arg;
int opnum;
(void) mlsvc_rpc_init(&heapref);
sizeof (DWORD));
} else {
sizeof (ms_handle_t));
}
return (status);
}
/*
* samr_connect2
*
* Connect to the SAM on a Windows NT 4.0 server (domain controller).
* We need the domain controller name and, if everything works, we
* return a handle. This function adds the double backslash prefx to
* make it easy for applications.
*
* Returns 0 on success. Otherwise returns a -ve error code.
*/
/*ARGSUSED*/
static DWORD
{
struct samr_Connect arg;
int opnum;
int len;
(void) mlsvc_rpc_init(&heapref);
} else {
sizeof (ms_handle_t));
}
return (status);
}
/*
* samr_connect3
*
* Connect to the SAM on a Windows 2000 domain controller.
*/
/*ARGSUSED*/
static DWORD
{
struct samr_Connect3 arg;
int opnum;
int len;
(void) mlsvc_rpc_init(&heapref);
} else {
sizeof (ms_handle_t));
}
return (status);
}
/*
* samr_connect4
*
* Connect to the SAM on a Windows XP domain controller. On Windows
* XP, the server should be the fully qualified DNS domain name with
* a double backslash prefix. At this point, it is assumed that we
* need to add the prefix and the DNS domain name here.
*
* If this call succeeds, a SAMR handle is placed in samr_handle and
* zero is returned. Otherwise, a -ve error code is returned.
*/
/*ARGSUSED*/
static DWORD
{
struct samr_Connect4 arg;
char dns_name[MAXHOSTNAMELEN];
int len;
int opnum;
return (NT_STATUS_UNSUCCESSFUL);
(void) mlsvc_rpc_init(&heapref);
} else {
}
} else {
sizeof (ms_handle_t));
}
return (status);
}
/*
* samr_close_handle
*
* This is function closes any valid handle, i.e. sam, domain, user etc.
* Just to be safe we check for, and reject, null handles. The handle
* returned by the SAM server is all null. If the handle being closed is
* the top level connect handle, we also close the pipe. Then we zero
* out the handle to invalidate it. Things go badly if you attempt to
* use an invalid handle, i.e. the DC crashes.
*/
int
{
struct samr_CloseHandle arg;
int opnum;
int rc;
if (mlsvc_is_null_handle(desc))
return (-1);
(void) mlsvc_rpc_init(&heap);
}
return (rc);
}
/*
* samr_open_domain
*
* We use a SAM handle to obtain a handle for a domain, specified by
* the SID. The SID can be obtain via the LSA interface. A handle for
* the domain is returned in domain_handle.
*/
{
struct samr_OpenDomain arg;
struct mlsvc_rpc_context *context;
int opnum;
if (mlsvc_is_null_handle(samr_handle) ||
sid == 0 || domain_handle == 0) {
return (NT_STATUS_INVALID_PARAMETER);
}
(void) mlsvc_rpc_init(&heap);
} else {
sizeof (ms_handle_t));
}
if (status != NT_STATUS_SUCCESS)
return (status);
}
/*
* samr_open_user
*
* Use a domain handle to obtain a handle for a user, specified by the
* user RID. A user RID (effectively a uid) can be obtained via the
* LSA interface. A handle for the user is returned in user_handle.
* Once you have a user handle it should be possible to query the SAM
* for information on that user.
*/
{
struct samr_OpenUser arg;
struct mlsvc_rpc_context *context;
return (NT_STATUS_INVALID_PARAMETER);
sizeof (ms_handle_t));
(void) mlsvc_rpc_init(&heap);
if (rc != 0) {
} else {
sizeof (ms_handle_t));
}
return (status);
}
/*
* samr_delete_user
*
* Delete the user specified by the user_handle.
*/
{
struct samr_DeleteUser arg;
struct mlsvc_rpc_context *context;
int opnum;
return (NT_STATUS_INVALID_PARAMETER);
sizeof (ms_handle_t));
(void) mlsvc_rpc_init(&heap);
} else {
status = 0;
}
return (status);
}
/*
* samr_open_group
*
* Use a domain handle to obtain a handle for a group, specified by the
* group RID. A group RID (effectively a gid) can be obtained via the
* LSA interface. A handle for the group is returned in group_handle.
* Once you have a group handle it should be possible to query the SAM
* for information on that group.
*/
int
{
struct samr_OpenGroup arg;
struct mlsvc_rpc_context *context;
int opnum;
int rc;
return (-1);
sizeof (ms_handle_t));
(void) mlsvc_rpc_init(&heap);
if (rc == 0) {
rc = -1;
} else {
sizeof (ms_handle_t));
rc = -1;
}
}
return (rc);
}
/*
* samr_create_user
*
* Create a user in the domain specified by the domain handle. If this
* call is successful, the server will return the RID for the user and
* a user handle, which may be used to set or query the SAM.
*
* Observed status codes:
* NT_STATUS_INVALID_PARAMETER
* NT_STATUS_INVALID_ACCOUNT_NAME
* NT_STATUS_ACCESS_DENIED
* NT_STATUS_USER_EXISTS
*
* Returns 0 on success. Otherwise returns an NT status code.
*/
{
struct samr_CreateUser arg;
struct mlsvc_rpc_context *context;
int opnum;
int rc;
if (mlsvc_is_null_handle(domain_handle) ||
return (NT_STATUS_INVALID_PARAMETER);
}
sizeof (ms_handle_t));
(void) mlsvc_rpc_init(&heap);
if (rc != 0) {
if (status != NT_STATUS_USER_EXISTS) {
}
} else {
sizeof (ms_handle_t));
else
status = 0;
}
return (status);
}