server.c revision 71590c90e239661c113497da3ca8b7301dfbe24c
/*
* 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"
/*
* Service routines
*/
#include "idmapd.h"
#include "idmap_priv.h"
#include "nldaputils.h"
#include <signal.h>
#include <thread.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <assert.h>
#include <ucred.h>
#include <pwd.h>
#include <auth_attr.h>
#include <secdb.h>
#include <sys/u8_textprep.h>
if (retcode == IDMAP_NEXT) {\
return (0);\
} else if (retcode < 0) {\
return (1);\
}
if (rcode == IDMAP_ERR_BUSY)\
else { \
return (1); \
}
/* ARGSUSED */
{
return (TRUE);
}
/*
* RPC layer allocates empty strings to replace NULL char *.
* This utility function frees these empty strings.
*/
static
void
{
}
static
int
{
int e;
return (IDMAP_SUCCESS);
NULL, U8_VALIDATE_ENTIRE, &e) < 0)
return (IDMAP_ERR_BAD_UTF8);
NULL, U8_VALIDATE_ENTIRE, &e) < 0)
return (IDMAP_ERR_BAD_UTF8);
}
return (IDMAP_SUCCESS);
}
static
int
{
int e;
NULL, U8_VALIDATE_ENTIRE, &e) < 0)
return (IDMAP_ERR_BAD_UTF8);
NULL, U8_VALIDATE_ENTIRE, &e) < 0)
return (IDMAP_ERR_BAD_UTF8);
return (IDMAP_SUCCESS);
}
static
{
int i;
for (i = 0; i < batch->idmap_update_batch_len; i++) {
!= IDMAP_SUCCESS)
return (IDMAP_ERR_BAD_UTF8);
}
return (IDMAP_SUCCESS);
}
/* ARGSUSED */
{
uint_t i;
/* Init */
/* Return success if nothing was requested */
goto out;
/* Get cache handle */
goto out;
/* Get db handle */
goto out;
/* Allocate result array */
sizeof (idmap_id_res));
goto out;
}
/* Allocate hash table to check for duplicate sids */
sizeof (*state.sid_history));
goto out;
}
for (i = 0; i < state.sid_history_size; i++) {
}
/* Get directory-based name mapping info */
goto out;
/* Init our 'done' flags */
/* First stage */
for (i = 0; i < batch.idmap_mapping_batch_len; i++) {
(void) sanitize_mapping_request(
&batch.idmap_mapping_batch_val[i]);
if (IS_BATCH_SID(batch, i)) {
&state,
} else if (IS_BATCH_UID(batch, i)) {
&state,
} else if (IS_BATCH_GID(batch, i)) {
&state,
} else {
continue;
}
if (IDMAP_FATAL_ERROR(retcode)) {
goto out;
}
}
/* Check if we are done */
goto out;
/*
* native LDAP lookups:
* If nldap or mixed mode is enabled then pid2sid mapping requests
* winname and unixname.
*/
if (state.nldap_nqueries) {
if (IDMAP_FATAL_ERROR(retcode)) {
goto out;
}
}
/*
* AD lookups:
* 1. The pid2sid requests in the preceding step which successfully
* retrieved winname from native LDAP objects will now need to
* lookup AD by winname to get sid.
* 2. The sid2pid requests will need to lookup AD by sid to get
* winname and unixname (AD or mixed mode).
* 3. If AD-based name mapping is enabled then pid2sid mapping
* requests need to lookup AD by unixname to get winname and sid.
*/
if (state.ad_nqueries) {
if (IDMAP_FATAL_ERROR(retcode)) {
goto out;
}
}
/*
* native LDAP lookups:
* If nldap mode is enabled then sid2pid mapping requests
* which successfully retrieved winname from AD objects in the
* preceding step, will now need to lookup native LDAP directory
* service by winname to get unixname and pid.
*/
if (state.nldap_nqueries) {
if (IDMAP_FATAL_ERROR(retcode)) {
goto out;
}
}
/* Reset 'done' flags */
/* Second stage */
for (i = 0; i < batch.idmap_mapping_batch_len; i++) {
if (IS_BATCH_SID(batch, i)) {
&state,
db,
} else if (IS_BATCH_UID(batch, i)) {
&state,
db,
} else if (IS_BATCH_GID(batch, i)) {
&state,
db,
} else {
/* First stage has already set the error */
continue;
}
if (IDMAP_FATAL_ERROR(retcode)) {
goto out;
}
}
/* Check if we are done */
goto out;
/* Reset our 'done' flags */
/* Update cache in a single transaction */
!= IDMAP_SUCCESS)
goto out;
for (i = 0; i < batch.idmap_mapping_batch_len; i++) {
if (IS_BATCH_SID(batch, i)) {
(void) update_cache_sid2pid(
&state,
} else if ((IS_BATCH_UID(batch, i)) ||
(IS_BATCH_GID(batch, i))) {
(void) update_cache_pid2sid(
&state,
}
}
/* Commit if we have at least one successful update */
"COMMIT TRANSACTION;");
else
"END TRANSACTION;");
out:
}
return (TRUE);
}
/* ARGSUSED */
static
int
{
char *str;
char *end;
static int validated_column_names = 0;
if (!validated_column_names) {
}
sizeof (idmap_mapping));
return (1);
str;
else
argv[6]);
argv[7]);
argv[8]);
return (0);
}
/* ARGSUSED */
{
/* Get cache handle */
goto out;
/* Create LIMIT expression. */
if (limit > 0)
/*
* Combine all the above into a giant SELECT statement that
* will return the requested mappings
*/
"windomain, canon_winname, unixname, is_user, is_wuser "
" FROM idmap_cache WHERE "
" %s %s;",
goto out;
}
/* Execute the SQL statement and update the return buffer */
out:
if (sql)
return (TRUE);
}
/* ARGSUSED */
static
int
{
char *end;
static int validated_column_names = 0;
if (!validated_column_names) {
}
sizeof (idmap_namerule));
argv[3]);
argv[4]);
argv[6]);
else
return (0);
}
/* ARGSUSED */
{
goto out;
/* Get db handle */
goto out;
"AND (u2w_order = 0 OR u2w_order ISNULL)");
"AND (w2u_order = 0 OR w2u_order ISNULL)");
}
goto out;
/* Create LIMIT expression. */
if (limit > 0)
/*
* Combine all the above into a giant SELECT statement that
* will return the requested rules
*/
"winname_display, is_nt4, unixname, w2u_order, u2w_order "
"FROM namerules WHERE "
" %s %s %s %s %s;",
goto out;
}
/* Execute the SQL statement and update the return buffer */
out:
if (expr)
if (sql)
return (TRUE);
}
#define IDMAP_RULES_AUTH "solaris.admin.idmap.rules"
static int
{
char buf[1024];
return (-1);
}
ucred_free(uc);
return (-1);
}
ucred_free(uc);
return (-1);
}
ucred_free(uc);
return (-1);
}
ucred_free(uc);
return (1);
}
/*
* Meaning of the return values is the following: For retcode ==
* IDMAP_SUCCESS, everything went OK and error_index is
* undefined. Otherwise, error_index >=0 shows the failed batch
* element. errro_index == -1 indicates failure at the beginning,
* error_index == -2 at the end.
*/
/* ARGSUSED */
{
int i;
if (verify_rules_auth(rqstp) < 0) {
goto out;
}
if (batch.idmap_update_batch_len == 0 ||
goto out;
}
goto out;
/* Get db handle */
goto out;
goto out;
for (i = 0; i < batch.idmap_update_batch_len; i++) {
case OP_NONE:
break;
case OP_ADD_NAMERULE:
break;
case OP_RM_NAMERULE:
break;
case OP_FLUSH_NAMERULES:
break;
default:
break;
};
res->error_index = i;
idmap_stat r2 =
if (r2 != IDMAP_SUCCESS)
}
goto out;
}
}
out:
if (trans) {
"COMMIT TRANSACTION;");
}
else
"ROLLBACK TRANSACTION;");
}
return (TRUE);
}
/* ARGSUSED */
{
/* Init */
goto out;
/* Get cache handle */
goto out;
/* Get db handle */
goto out;
/* Allocate result */
goto out;
}
db,
&request,
} else if (IS_REQUEST_UID(request)) {
db,
&request,
1);
} else if (IS_REQUEST_GID(request)) {
db,
&request,
0);
} else {
}
out:
}
return (TRUE);
}
/* ARGSUSED */
int
{
return (TRUE);
}