diff options
Diffstat (limited to 'usr/src/lib')
23 files changed, 740 insertions, 1336 deletions
diff --git a/usr/src/lib/libadutils/common/addisc.c b/usr/src/lib/libadutils/common/addisc.c index b32f9d7694..187981b5a2 100644 --- a/usr/src/lib/libadutils/common/addisc.c +++ b/usr/src/lib/libadutils/common/addisc.c @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -103,6 +102,16 @@ #include "adutils_impl.h" #include "addisc.h" +/* + * These set some sanity policies for discovery. After a discovery + * cycle, we will consider the results (successful or unsuccessful) + * to be valid for at least MINIMUM_TTL seconds, and for at most + * MAXIMUM_TTL seconds. Note that the caller is free to request + * discovery cycles sooner than MINIMUM_TTL if it has reason to believe + * that the situation has changed. + */ +#define MINIMUM_TTL (5 * 60) +#define MAXIMUM_TTL (20 * 60) enum ad_item_state { AD_STATE_INVALID = 0, /* The value is not valid */ @@ -127,7 +136,7 @@ typedef struct ad_item { enum ad_item_state state; enum ad_data_type type; void *value; - time_t ttl; + time_t expires; unsigned int version; /* Version is only changed */ /* if the value changes */ #define PARAM1 0 @@ -144,6 +153,8 @@ typedef struct ad_disc { ad_subnet_t *subnets; boolean_t subnets_changed; time_t subnets_last_check; + time_t expires_not_before; + time_t expires_not_after; ad_item_t domain_name; /* DNS hostname string */ ad_item_t domain_controller; /* Directory hostname and */ /* port array */ @@ -216,7 +227,7 @@ is_valid(ad_item_t *item) if (item->state == AD_STATE_FIXED) return (B_TRUE); if (item->state == AD_STATE_AUTO && - (item->ttl == 0 || item->ttl > time(NULL))) + (item->expires == 0 || item->expires > time(NULL))) return (B_TRUE); } return (B_FALSE); @@ -247,9 +258,9 @@ update_item(ad_item_t *item, void *value, enum ad_item_state state, item->state = state; if (ttl == 0) - item->ttl = 0; + item->expires = 0; else - item->ttl = time(NULL) + ttl; + item->expires = time(NULL) + ttl; } @@ -593,26 +604,6 @@ DN_to_DNS(const char *dn_name) } -/* Format the DN of an AD LDAP subnet object for some subnet */ -static char * -subnet_to_DN(const char *subnet, const char *baseDN) -{ - char *result; - int len; - - len = snprintf(NULL, 0, - "CN=%s,CN=Subnets,CN=Sites,%s", - subnet, baseDN) + 1; - - result = malloc(len); - if (result != NULL) - (void) snprintf(result, len, - "CN=%s,CN=Subnets,CN=Sites,%s", - subnet, baseDN); - return (result); -} - - /* Make a list of subnet object DNs from a list of subnets */ static char ** subnets_to_DNs(ad_subnet_t *subnets, const char *base_dn) @@ -628,8 +619,9 @@ subnets_to_DNs(ad_subnet_t *subnets, const char *base_dn) return (NULL); for (i = 0; subnets[i].subnet[0] != '\0'; i++) { - if ((results[i] = subnet_to_DN(subnets[i].subnet, base_dn)) - == NULL) { + (void) asprintf(&results[i], "CN=%s,CN=Subnets,CN=Sites,%s", + subnets[i].subnet, base_dn); + if (results[i] == NULL) { for (j = 0; j < i; j++) free(results[j]); free(results); @@ -828,7 +820,8 @@ err: * A utility function to bind to a Directory server */ -static LDAP* +static +LDAP * ldap_lookup_init(idmap_ad_disc_ds_t *ds) { int i; @@ -988,15 +981,17 @@ ldap_lookup_trusted_domains(LDAP **ld, idmap_ad_disc_ds_t *globalCatalog, if (partner != NULL && direction != NULL) { num++; - trusted_domains = realloc(trusted_domains, + void *tmp = realloc(trusted_domains, (num + 1) * sizeof (ad_disc_trusteddomains_t)); - if (trusted_domains == NULL) { + if (tmp == NULL) { + free(trusted_domains); ldap_value_free(partner); ldap_value_free(direction); ldap_msgfree(results); return (NULL); } + trusted_domains = tmp; /* Last element should be zero */ memset(&trusted_domains[num], 0, sizeof (ad_disc_trusteddomains_t)); @@ -1221,6 +1216,22 @@ ad_disc_refresh(ad_disc_t ctx) } +/* + * Called when the discovery cycle is done. Sets a master TTL + * that will avoid doing new time-based discoveries too soon after + * the last discovery cycle. Most interesting when the discovery + * cycle failed, because then the TTLs on the individual items will + * not be updated and may go stale. + */ +void +ad_disc_done(ad_disc_t ctx) +{ + time_t now = time(NULL); + + ctx->expires_not_before = now + MINIMUM_TTL; + ctx->expires_not_after = now + MAXIMUM_TTL; +} + /* Discover joined Active Directory domainName */ static ad_item_t * @@ -1425,12 +1436,13 @@ validate_SiteName(ad_disc_t ctx) return (NULL); if (!is_valid(&ctx->site_name) || - is_changed(&ctx->site_name, PARAM1, &ctx->domain_controller) || + is_changed(&ctx->site_name, PARAM1, domain_controller_item) || ctx->subnets == NULL || ctx->subnets_changed) { subnets = find_subnets(); ctx->subnets_last_check = time(NULL); update_required = B_TRUE; } else if (ctx->subnets_last_check + 60 < time(NULL)) { + /* NEEDSWORK magic constant 60 above */ subnets = find_subnets(); ctx->subnets_last_check = time(NULL); if (cmpsubnets(ctx->subnets, subnets) != 0) @@ -1471,6 +1483,8 @@ validate_SiteName(ad_disc_t ctx) forest_name = DN_to_DNS(config_naming_context + len); update_item(&ctx->forest_name, forest_name, AD_STATE_AUTO, 0); + update_version(&ctx->forest_name, PARAM1, + domain_controller_item); } } @@ -1495,6 +1509,8 @@ validate_SiteName(ad_disc_t ctx) site_name[len] = '\0'; update_item(&ctx->site_name, site_name, AD_STATE_AUTO, 0); + update_version(&ctx->site_name, PARAM1, + domain_controller_item); } } @@ -1997,17 +2013,33 @@ ad_disc_unset(ad_disc_t ctx) int ad_disc_get_TTL(ad_disc_t ctx) { + time_t expires; int ttl; - ttl = MIN_GT_ZERO(ctx->domain_controller.ttl, ctx->global_catalog.ttl); - ttl = MIN_GT_ZERO(ttl, ctx->site_domain_controller.ttl); - ttl = MIN_GT_ZERO(ttl, ctx->site_global_catalog.ttl); + expires = MIN_GT_ZERO(ctx->domain_controller.expires, + ctx->global_catalog.expires); + expires = MIN_GT_ZERO(expires, ctx->site_domain_controller.expires); + expires = MIN_GT_ZERO(expires, ctx->site_global_catalog.expires); - if (ttl == -1) + if (expires == -1) { return (-1); - ttl -= time(NULL); - if (ttl < 0) + } + + if (ctx->expires_not_before != 0 && + expires < ctx->expires_not_before) { + expires = ctx->expires_not_before; + } + + if (ctx->expires_not_after != 0 && + expires > ctx->expires_not_after) { + expires = ctx->expires_not_after; + } + + ttl = expires - time(NULL); + + if (ttl < 0) { return (0); + } return (ttl); } diff --git a/usr/src/lib/libadutils/common/addisc.h b/usr/src/lib/libadutils/common/addisc.h index faf3393523..c8a3ca17d2 100644 --- a/usr/src/lib/libadutils/common/addisc.h +++ b/usr/src/lib/libadutils/common/addisc.h @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _ADINFO_H @@ -125,6 +124,12 @@ ad_disc_set_GlobalCatalog(ad_disc_t ctx, */ void ad_disc_refresh(ad_disc_t); +/* + * This routine marks the end of a discovery cycle and sets + * the sanity limits on the time before the next cycle. + */ +void ad_disc_done(ad_disc_t); + /* This routine unsets all overridden values */ int ad_disc_unset(ad_disc_t ctx); diff --git a/usr/src/lib/libadutils/common/mapfile-vers b/usr/src/lib/libadutils/common/mapfile-vers index d7e1687ef2..e1e580bd9a 100644 --- a/usr/src/lib/libadutils/common/mapfile-vers +++ b/usr/src/lib/libadutils/common/mapfile-vers @@ -19,8 +19,7 @@ # CDDL HEADER END # # -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. # # @@ -67,6 +66,7 @@ SUNWprivate { ad_disc_compare_ds; ad_disc_compare_trusteddomains; ad_disc_compare_domainsinforest; + ad_disc_done; ad_disc_SubnetChanged; ad_disc_get_GlobalCatalog; ad_disc_set_GlobalCatalog; diff --git a/usr/src/lib/libidmap/Makefile.com b/usr/src/lib/libidmap/Makefile.com index c38ff0bd02..5f5f3363b0 100644 --- a/usr/src/lib/libidmap/Makefile.com +++ b/usr/src/lib/libidmap/Makefile.com @@ -19,8 +19,7 @@ # CDDL HEADER END # # -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. # # @@ -36,7 +35,6 @@ LINT_OBJECTS = \ idmap_api.o \ idmap_cache.o \ miscutils.o \ - namemaps.o \ utils.o OBJECTS = $(LINT_OBJECTS) \ @@ -46,18 +44,15 @@ include ../../Makefile.lib C99MODE = $(C99_ENABLE) LIBS = $(DYNLIB) $(LINTLIB) -LDLIBS += -lc -lldap -lsldap -lavl -ladutils -lnsl -CPPFLAGS += -I$(SRC)/lib/libsldap/common +LDLIBS += -lc -lavl -lnsl SRCDIR = ../common $(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) IDMAP_PROT_X = $(SRC)/uts/common/rpcsvc/idmap_prot.x -ADUTILS_DIR = $(SRC)/lib/libadutils/common - CFLAGS += $(CCVERBOSE) -CPPFLAGS += -D_REENTRANT -I$(SRCDIR) -I$(ADUTILS_DIR) +CPPFLAGS += -D_REENTRANT -I$(SRCDIR) CLOBBERFILES += idmap_xdr.c diff --git a/usr/src/lib/libidmap/common/directory_helper.c b/usr/src/lib/libidmap/common/directory_helper.c index f98512d88e..a7c94f9aeb 100644 --- a/usr/src/lib/libidmap/common/directory_helper.c +++ b/usr/src/lib/libidmap/common/directory_helper.c @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -34,7 +33,6 @@ #include <stdio.h> #include <string.h> -#include <libadutils.h> #include <rpcsvc/idmap_prot.h> #include "directory.h" #include "directory_private.h" diff --git a/usr/src/lib/libidmap/common/idmap.h b/usr/src/lib/libidmap/common/idmap.h index f22fc43092..400f67c755 100644 --- a/usr/src/lib/libidmap/common/idmap.h +++ b/usr/src/lib/libidmap/common/idmap.h @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -54,7 +53,7 @@ typedef struct idmap_handle idmap_handle_t; typedef struct idmap_get_handle idmap_get_handle_t; /* Logger prototype which is based on syslog */ -typedef void (*idmap_logger)(int, const char *, ...); +typedef void (*idmap_logger_t)(int, const char *, ...); /* * Setup API @@ -132,7 +131,7 @@ extern idmap_stat idmap_getgidbywinname(const char *, const char *, /* Logger */ -extern void idmap_set_logger(idmap_logger funct); +extern void idmap_set_logger(idmap_logger_t funct); #ifdef __cplusplus } diff --git a/usr/src/lib/libidmap/common/idmap_api.c b/usr/src/lib/libidmap/common/idmap_api.c index c58e2c00cd..6566de1db9 100644 --- a/usr/src/lib/libidmap/common/idmap_api.c +++ b/usr/src/lib/libidmap/common/idmap_api.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ @@ -40,6 +39,7 @@ #include <dlfcn.h> #include <libintl.h> #include <ucontext.h> +#include <syslog.h> #include "idmap_impl.h" #include "idmap_cache.h" @@ -2581,3 +2581,18 @@ idmap_flush(idmap_handle_t *handle, idmap_flush_op op) } return (res); } + + +/* + * syslog is the default logger. + * It can be overwritten by supplying a logger + * with idmap_set_logger() + */ +idmap_logger_t logger = syslog; + + +void +idmap_set_logger(idmap_logger_t funct) +{ + logger = funct; +} diff --git a/usr/src/lib/libidmap/common/idmap_impl.h b/usr/src/lib/libidmap/common/idmap_impl.h index 570b69834c..0c4aba0abb 100644 --- a/usr/src/lib/libidmap/common/idmap_impl.h +++ b/usr/src/lib/libidmap/common/idmap_impl.h @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -129,12 +128,7 @@ extern idmap_stat _iter_get_next_list(int, idmap_iter_t *, void *, uchar_t **, size_t, xdrproc_t, xdrproc_t); extern idmap_stat _idmap_rpc2stat(CLIENT *); -extern idmap_stat idmap_get_prop_ds(idmap_handle_t *, idmap_prop_type, - idmap_ad_disc_ds_t *); -extern idmap_stat idmap_get_prop_str(idmap_handle_t *, idmap_prop_type, - char **); - -extern idmap_logger logger; +extern idmap_logger_t logger; #ifdef __cplusplus } diff --git a/usr/src/lib/libidmap/common/idmap_priv.h b/usr/src/lib/libidmap/common/idmap_priv.h index d044225730..c3a68b76c9 100644 --- a/usr/src/lib/libidmap/common/idmap_priv.h +++ b/usr/src/lib/libidmap/common/idmap_priv.h @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -65,29 +64,6 @@ typedef struct idmap_iter idmap_iter_t; /* - * Directory based name map API - */ - -typedef struct idmap_nm_handle idmap_nm_handle_t; - -/* Set namemap */ -extern idmap_stat idmap_set_namemap(idmap_nm_handle_t *, char *, char *, - int, int, int); - -/* Unset namemap */ -extern idmap_stat idmap_unset_namemap(idmap_nm_handle_t *, char *, char *, - int, int, int); - -extern idmap_stat idmap_get_namemap(idmap_nm_handle_t *p, int *, char **, - char **, int *, char **, char **); - -extern void idmap_fini_namemaps(idmap_nm_handle_t *); - -extern idmap_stat idmap_init_namemaps(idmap_handle_t *, idmap_nm_handle_t **, - char *, char *, char *, char *, int); - - -/* * Update API */ @@ -213,6 +189,11 @@ extern idmap_stat idmap_getext_sidbyuid(idmap_get_handle_t *, uid_t, int, extern idmap_stat idmap_getext_sidbygid(idmap_get_handle_t *, gid_t, int, char **, idmap_rid_t *, idmap_info *, idmap_stat *); +/* Properties */ +extern idmap_stat idmap_get_prop_ds(idmap_handle_t *, idmap_prop_type, + idmap_ad_disc_ds_t *); +extern idmap_stat idmap_get_prop_str(idmap_handle_t *, idmap_prop_type, + char **); #ifdef __cplusplus } diff --git a/usr/src/lib/libidmap/common/mapfile-vers b/usr/src/lib/libidmap/common/mapfile-vers index b0fc8c9cec..e52fa5da30 100644 --- a/usr/src/lib/libidmap/common/mapfile-vers +++ b/usr/src/lib/libidmap/common/mapfile-vers @@ -19,8 +19,7 @@ # CDDL HEADER END # # -# Copyright 2010 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. # # @@ -61,7 +60,6 @@ SUNWprivate { directory_sid_from_user_name; idmap_cache_get_data; idmap_fini; - idmap_fini_namemaps; idmap_flush; idmap_free; idmap_getext_gidbysid; @@ -77,8 +75,9 @@ SUNWprivate { idmap_get_destroy; idmap_get_gidbysid; idmap_get_mappings; - idmap_get_namemap; idmap_get_pidbysid; + idmap_get_prop_ds; + idmap_get_prop_str; idmap_get_sidbygid; idmap_get_sidbyuid; idmap_get_u2w_mapping; @@ -88,7 +87,6 @@ SUNWprivate { idmap_info_free; idmap_info_mov; idmap_init; - idmap_init_namemaps; idmap_iter_destroy; idmap_iter_mappings; idmap_iter_namerules; @@ -96,7 +94,6 @@ SUNWprivate { idmap_iter_next_namerule; idmap_namerule_cpy; idmap_set_logger; - idmap_set_namemap; idmap_stat2string; idmap_stat4prot; idmap_string2stat; @@ -109,7 +106,6 @@ SUNWprivate { idmap_udt_get_error_index; idmap_udt_get_error_rule; idmap_udt_rm_namerule; - idmap_unset_namemap; memdup; sid_free; sid_from_le; diff --git a/usr/src/lib/libidmap/common/namemaps.c b/usr/src/lib/libidmap/common/namemaps.c deleted file mode 100644 index 95e47ddd6c..0000000000 --- a/usr/src/lib/libidmap/common/namemaps.c +++ /dev/null @@ -1,1066 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - - -#include <errno.h> -#include <ldap.h> -#include <sasl/sasl.h> -#include <libintl.h> -#include <strings.h> -#include <syslog.h> - -#include "addisc.h" -#include "libadutils.h" -#include "idmap_impl.h" -#include "ns_sldap.h" - -/* - * syslog is the default logger. - * It can be overwritten by supplying a logger - * with idmap_set_logger() - */ -idmap_logger logger = syslog; - - -void -idmap_set_logger(idmap_logger funct) -{ - logger = funct; - adutils_set_logger(funct); -} - - -/* From adutils.c: */ - -/* A single DS */ -struct idmap_nm_handle { - LDAP *ad; /* LDAP connection */ - /* LDAP DS info */ - char *ad_host; - int ad_port; - - /* hardwired to SASL GSSAPI only for now */ - char *saslmech; - unsigned saslflags; - char *windomain; - char *ad_unixuser_attr; - char *ad_unixgroup_attr; - char *nldap_winname_attr; - char *default_domain; - bool_t is_nldap; - bool_t is_ad; - int direction; - ns_cred_t nsc; -}; - -static -idmap_stat -string2auth(const char *from, ns_auth_t *na) -{ - if (from == NULL) { - na->type = NS_LDAP_AUTH_SASL; - na->tlstype = NS_LDAP_TLS_SASL; - na->saslmech = NS_LDAP_SASL_GSSAPI; - na->saslopt = NS_LDAP_SASLOPT_PRIV | - NS_LDAP_SASLOPT_INT; - return (IDMAP_SUCCESS); - } - - if (strcasecmp(from, "simple") == 0) { - na->type = NS_LDAP_AUTH_SIMPLE; - na->tlstype = NS_LDAP_TLS_NONE; - na->saslmech = NS_LDAP_SASL_NONE; - na->saslopt = NS_LDAP_SASLOPT_NONE; - } else if (strcasecmp(from, "sasl/CRAM-MD5") == 0) { - na->type = NS_LDAP_AUTH_SASL; - na->tlstype = NS_LDAP_TLS_SASL; - na->saslmech = NS_LDAP_SASL_CRAM_MD5; - na->saslopt = NS_LDAP_SASLOPT_NONE; - } else if (strcasecmp(from, "sasl/DIGEST-MD5") == 0) { - na->type = NS_LDAP_AUTH_SASL; - na->tlstype = NS_LDAP_TLS_SASL; - na->saslmech = NS_LDAP_SASL_DIGEST_MD5; - na->saslopt = NS_LDAP_SASLOPT_NONE; - } else if (strcasecmp(from, "sasl/GSSAPI") == 0) { - na->type = NS_LDAP_AUTH_SASL; - na->tlstype = NS_LDAP_TLS_SASL; - na->saslmech = NS_LDAP_SASL_GSSAPI; - na->saslopt = NS_LDAP_SASLOPT_PRIV | - NS_LDAP_SASLOPT_INT; - } else if (strcasecmp(from, "tls:simple") == 0) { - na->type = NS_LDAP_AUTH_TLS; - na->tlstype = NS_LDAP_TLS_SIMPLE; - na->saslmech = NS_LDAP_SASL_NONE; - na->saslopt = NS_LDAP_SASLOPT_NONE; - } else if (strcasecmp(from, "tls:sasl/CRAM-MD5") == 0) { - na->type = NS_LDAP_AUTH_TLS; - na->tlstype = NS_LDAP_TLS_SASL; - na->saslmech = NS_LDAP_SASL_CRAM_MD5; - na->saslopt = NS_LDAP_SASLOPT_NONE; - } else if (strcasecmp(from, "tls:sasl/DIGEST-MD5") == 0) { - na->type = NS_LDAP_AUTH_TLS; - na->tlstype = NS_LDAP_TLS_SASL; - na->saslmech = NS_LDAP_SASL_DIGEST_MD5; - na->saslopt = NS_LDAP_SASLOPT_NONE; - } else { - logger(LOG_ERR, - gettext("Invalid authentication method \"%s\" specified\n"), - from); - return (IDMAP_ERR_ARG); - } - - return (IDMAP_SUCCESS); -} - - - -static -idmap_stat -strings2cred(ns_cred_t *nsc, char *user, char *passwd, char *auth) -{ - idmap_stat rc; - (void) memset(nsc, 0, sizeof (ns_cred_t)); - - if ((rc = string2auth(auth, &nsc->auth)) != IDMAP_SUCCESS) - return (rc); - - if (user != NULL) { - nsc->cred.unix_cred.userID = strdup(user); - if (nsc->cred.unix_cred.userID == NULL) - return (IDMAP_ERR_MEMORY); - } - - if (passwd != NULL) { - nsc->cred.unix_cred.passwd = strdup(passwd); - if (nsc->cred.unix_cred.passwd == NULL) { - free(nsc->cred.unix_cred.userID); - return (IDMAP_ERR_MEMORY); - } - } - - return (IDMAP_SUCCESS); -} - - - - - -/*ARGSUSED*/ -static int -idmap_saslcallback(LDAP *ld, unsigned flags, void *defaults, void *prompts) -{ - sasl_interact_t *interact; - - if (prompts == NULL || flags != LDAP_SASL_INTERACTIVE) - return (LDAP_PARAM_ERROR); - - /* There should be no extra arguemnts for SASL/GSSAPI authentication */ - for (interact = prompts; interact->id != SASL_CB_LIST_END; - interact++) { - interact->result = NULL; - interact->len = 0; - } - return (LDAP_SUCCESS); -} - -static -idmap_stat -idmap_open_ad_conn(idmap_nm_handle_t *adh) -{ - int zero = 0; - int timeoutms = 30 * 1000; - int ldversion, ldap_rc; - idmap_stat rc = IDMAP_SUCCESS; - - /* Open and bind an LDAP connection */ - adh->ad = ldap_init(adh->ad_host, adh->ad_port); - if (adh->ad == NULL) { - logger(LOG_INFO, "ldap_init() to server " - "%s port %d failed. (%s)", CHECK_NULL(adh->ad_host), - adh->ad_port, strerror(errno)); - rc = IDMAP_ERR_INTERNAL; - goto out; - } - ldversion = LDAP_VERSION3; - (void) ldap_set_option(adh->ad, LDAP_OPT_PROTOCOL_VERSION, &ldversion); - (void) ldap_set_option(adh->ad, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - (void) ldap_set_option(adh->ad, LDAP_OPT_TIMELIMIT, &zero); - (void) ldap_set_option(adh->ad, LDAP_OPT_SIZELIMIT, &zero); - (void) ldap_set_option(adh->ad, LDAP_X_OPT_CONNECT_TIMEOUT, &timeoutms); - (void) ldap_set_option(adh->ad, LDAP_OPT_RESTART, LDAP_OPT_ON); - ldap_rc = ldap_sasl_interactive_bind_s(adh->ad, "" /* binddn */, - adh->saslmech, NULL, NULL, adh->saslflags, &idmap_saslcallback, - NULL); - - if (ldap_rc != LDAP_SUCCESS) { - (void) ldap_unbind(adh->ad); - adh->ad = NULL; - logger(LOG_INFO, "ldap_sasl_interactive_bind_s() to server " - "%s port %d failed. (%s)", CHECK_NULL(adh->ad_host), - adh->ad_port, ldap_err2string(ldap_rc)); - rc = IDMAP_ERR_INTERNAL; - } - -out: - return (rc); -} - -static -idmap_stat -idmap_init_nldap(idmap_nm_handle_t *p) -{ -/* - * For now, there is nothing to initialize in nldap. This is just to - * make it future-proof, especially standalone libsldap-proof - */ - p->is_nldap = TRUE; - return (0); -} - -static -idmap_stat -idmap_init_ad(idmap_nm_handle_t *p) -{ - idmap_stat rc = IDMAP_SUCCESS; - idmap_ad_disc_ds_t *dc = NULL; - ad_disc_t ad_ctx; - - ad_ctx = ad_disc_init(); - if (ad_ctx == NULL) { - logger(LOG_ERR, - gettext("AD autodiscovery initialization failed")); - return (IDMAP_ERR_INTERNAL); - } - ad_disc_refresh(ad_ctx); - - - /* Based on the supplied or default domain, find the proper AD: */ - if (ad_disc_set_DomainName(ad_ctx, p->windomain)) { - rc = IDMAP_ERR_INTERNAL; - logger(LOG_ERR, - gettext("Setting a domain name \"%s\" for autodiscovery" - " failed, most likely not enough memory"), p->windomain); - goto cleanup; - } - - dc = ad_disc_get_DomainController(ad_ctx, AD_DISC_GLOBAL, NULL); - if (dc == NULL) { - rc = IDMAP_ERR_ARG; - logger(LOG_ERR, - gettext("A domain controller for the " - "domain \"%s\" not found."), p->windomain); - goto cleanup; - } - - - p->ad_port = dc->port; - p->ad_host = strdup(dc->host); - - if (p->ad_host == NULL) { - rc = IDMAP_ERR_MEMORY; - goto cleanup; - } - - p->saslflags = LDAP_SASL_INTERACTIVE; - p->saslmech = strdup("GSSAPI"); - - if (p->saslmech == NULL) { - rc = IDMAP_ERR_MEMORY; - goto cleanup; - } - - rc = idmap_open_ad_conn(p); - - if (rc != IDMAP_SUCCESS) - goto cleanup; - - p->is_ad = TRUE; - -cleanup: - ad_disc_fini(ad_ctx); - free(dc); - return (rc); -} - -void -idmap_fini_namemaps(idmap_nm_handle_t *p) -{ - if (p == NULL) - return; - - if (p->ad_unixgroup_attr != NULL) - free(p->ad_unixgroup_attr); - - if (p->ad_unixuser_attr != NULL) - free(p->ad_unixuser_attr); - - if (p->nldap_winname_attr) - free(p->nldap_winname_attr); - - if (p->windomain != NULL) - free(p->windomain); - - if (p->default_domain != NULL) - free(p->default_domain); - - if (p->saslmech != NULL) - free(p->saslmech); - - if (p->ad_host != NULL) - free(p->ad_host); - - if (p->nsc.cred.unix_cred.userID != NULL) { - free(p->nsc.cred.unix_cred.userID); - } - - if (p->nsc.cred.unix_cred.passwd != NULL) { - /* No archeology: */ - (void) memset(p->nsc.cred.unix_cred.passwd, 0, - strlen(p->nsc.cred.unix_cred.passwd)); - free(p->nsc.cred.unix_cred.passwd); - } - - if (p->ad) - (void) ldap_unbind(p->ad); - free(p); - -} - - - -idmap_stat -idmap_init_namemaps(idmap_handle_t *handle, idmap_nm_handle_t **adh, - char *user, char *passwd, char *auth, char *windomain, - int direction) -{ - idmap_stat rc; - idmap_nm_handle_t *p; - - p = (idmap_nm_handle_t *)calloc(1, sizeof (idmap_nm_handle_t)); - if (p == NULL) - return (IDMAP_ERR_MEMORY); - - rc = idmap_get_prop_str(handle, PROP_DEFAULT_DOMAIN, - &p->default_domain); - if (rc != IDMAP_SUCCESS) { - logger(LOG_ERR, - gettext("Error obtaining default domain from idmapd (%s)"), - idmap_stat2string(NULL, rc)); - goto cleanup; - } - - rc = idmap_get_prop_str(handle, PROP_AD_UNIXUSER_ATTR, - &p->ad_unixuser_attr); - if (rc != IDMAP_SUCCESS) { - logger(LOG_ERR, - gettext("Error obtaining AD unixuser attribute (%s)"), - idmap_stat2string(NULL, rc)); - goto cleanup; - } - - rc = idmap_get_prop_str(handle, PROP_AD_UNIXGROUP_ATTR, - &p->ad_unixgroup_attr); - if (rc != IDMAP_SUCCESS) { - logger(LOG_ERR, - gettext("Error obtaining AD unixgroup attribute (%s)"), - idmap_stat2string(NULL, rc)); - goto cleanup; - } - - - rc = idmap_get_prop_str(handle, PROP_NLDAP_WINNAME_ATTR, - &p->nldap_winname_attr); - if (rc != IDMAP_SUCCESS) { - logger(LOG_ERR, - gettext("Error obtaining AD unixgroup attribute (%s)"), - idmap_stat2string(NULL, rc)); - goto cleanup; - } - - if (windomain != NULL) { - p->windomain = strdup(windomain); - if (p->windomain == NULL) { - rc = IDMAP_ERR_MEMORY; - goto cleanup; - } - } else if (!EMPTY_STRING(p->default_domain)) { - p->windomain = strdup(p->default_domain); - if (p->windomain == NULL) { - rc = IDMAP_ERR_MEMORY; - goto cleanup; - } - } else if (direction == IDMAP_DIRECTION_W2U) { - logger(LOG_ERR, - gettext("Windows domain not given and idmapd daemon" - " didn't provide a default one")); - rc = IDMAP_ERR_ARG; - goto cleanup; - } - - p->direction = direction; - - if ((p->ad_unixuser_attr != NULL || p->ad_unixgroup_attr != NULL) && - direction != IDMAP_DIRECTION_U2W) { - rc = idmap_init_ad(p); - if (rc != IDMAP_SUCCESS) { - goto cleanup; - } - } - - if (p->nldap_winname_attr != NULL && direction != IDMAP_DIRECTION_W2U) { - rc = idmap_init_nldap(p); - if (rc != IDMAP_SUCCESS) { - goto cleanup; - } - - rc = strings2cred(&p->nsc, user, passwd, auth); - if (rc != IDMAP_SUCCESS) { - goto cleanup; - } - } - -cleanup: - - if (rc == IDMAP_SUCCESS) { - *adh = p; - return (IDMAP_SUCCESS); - } - - /* There was an error: */ - idmap_fini_namemaps(*adh); - return (rc); -} - -static -char * -dns2dn(const char *dns, const char *prefix) -{ - int num_lvl = 1; - char *buf; - const char *it, *new_it; - - for (it = dns; it != NULL; it = strchr(it, '.')) { - it ++; - num_lvl ++; - } - - buf = (char *)malloc(strlen(prefix) + strlen(dns) + 4 * num_lvl); - (void) strcpy(buf, prefix); - - - it = dns; - for (;;) { - new_it = strchr(it, '.'); - (void) strcat(buf, "DC="); - if (new_it == NULL) { - (void) strcat(buf, it); - break; - } else { - (void) strncat(buf, it, new_it - it); - (void) strcat(buf, ","); - } - - it = new_it + 1; - } - - return (buf); -} - - -static -idmap_stat -extract_attribute(idmap_nm_handle_t *p, LDAPMessage *entry, char *name, - char **value) -{ - char **values = NULL; - idmap_stat rc = IDMAP_SUCCESS; - /* No value means it is not requested */ - if (value == NULL) - return (IDMAP_SUCCESS); - - values = ldap_get_values(p->ad, entry, name); - if (values == NULL || values[0] == NULL) - *value = NULL; - else { - *value = strdup(values[0]); - if (*value == NULL) - rc = IDMAP_ERR_MEMORY; - } -errout: - ldap_value_free(values); - return (rc); -} - - -/* Split winname to its name and domain part */ -static -idmap_stat -split_fqwn(char *fqwn, char **name, char **domain) -{ - char *at; - - *name = NULL; - *domain = NULL; - - at = strchr(fqwn, '@'); - if (at == NULL) { - at = strchr(fqwn, '\\'); - } - if (at == NULL) { - /* There is no domain - leave domain NULL */ - *name = strdup(fqwn); - if (*name == NULL) - goto errout; - return (IDMAP_SUCCESS); - } - - - *domain = strdup(at+1); - if (*domain == NULL) - goto errout; - *name = (char *)malloc(at - fqwn + 1); - if (*name == NULL) - goto errout; - (void) strlcpy(*name, fqwn, at - fqwn + 1); - - if (*at == '\\') { - char *it = *name; - *name = *domain; - *domain = it; - } - - return (IDMAP_SUCCESS); - - -errout: - free(*name); - *name = NULL; - free(*domain); - *domain = NULL; - return (IDMAP_ERR_MEMORY); -} - -static -idmap_stat -unixname2dn(idmap_nm_handle_t *p, char *unixname, int is_user, char **dn, - char **winname, char **windomain) -{ - idmap_stat rc = IDMAP_SUCCESS; - int rc_ns; - - - char filter[255]; - static const char *attribs[3]; - ns_ldap_result_t *res; - ns_ldap_error_t *errorp = NULL; - char **attrs; - - - attribs[0] = p->nldap_winname_attr; - attribs[1] = "dn"; - attribs[2] = NULL; - - (void) snprintf(filter, sizeof (filter), is_user ? "uid=%s" : "cn=%s", - unixname); - - rc_ns = __ns_ldap_list(is_user ? "passwd" : "group", - filter, NULL, attribs, NULL, 0, &res, &errorp, NULL, NULL); - - - if (rc_ns == NS_LDAP_NOTFOUND) { - logger(LOG_ERR, is_user ? gettext("User \"%s\" not found.") - : gettext("Group %s not found."), unixname); - return (IDMAP_ERR_NOTFOUND); - } else if (rc_ns != NS_LDAP_SUCCESS) { - char *msg = "Cause unidentified"; - if (errorp != NULL) { - (void) __ns_ldap_err2str(errorp->status, &msg); - } - logger(LOG_ERR, gettext("Ldap list failed (%s)."), msg); - return (IDMAP_ERR_ARG); - } - - if (res == NULL) { - logger(LOG_ERR, gettext("User %s not found"), unixname); - return (IDMAP_ERR_ARG); - } - - if (winname != NULL && windomain != NULL) { - attrs = __ns_ldap_getAttr(&res->entry[0], - p->nldap_winname_attr); - if (attrs != NULL && attrs[0] != NULL) { - rc = split_fqwn(attrs[0], winname, windomain); - } else { - *winname = *windomain = NULL; - } - } - - if (dn != NULL) { - attrs = __ns_ldap_getAttr(&res->entry[0], "dn"); - if (attrs == NULL || attrs[0] == NULL) { - logger(LOG_ERR, gettext("dn for %s not found"), - unixname); - return (IDMAP_ERR_ARG); - } - *dn = strdup(attrs[0]); - } - - - return (rc); - -} - -#define FILTER "(sAMAccountName=%s)" - -/* Puts the values of attributes to unixuser and unixgroup, unless NULL */ - -static -idmap_stat -winname2dn(idmap_nm_handle_t *p, char *winname, - int *is_wuser, char **dn, char **unixuser, char **unixgroup) -{ - idmap_stat rc = IDMAP_SUCCESS; - char *base; - char *filter; - int flen; - char *attribs[4]; - int i; - LDAPMessage *results = NULL; - LDAPMessage *entry; - int ldap_rc; - - /* Query: */ - - base = dns2dn(p->windomain, ""); - if (base == NULL) { - return (IDMAP_ERR_MEMORY); - } - - i = 0; - attribs[i++] = "objectClass"; - if (unixuser != NULL) - attribs[i++] = p->ad_unixuser_attr; - if (unixgroup != NULL) - attribs[i++] = p->ad_unixgroup_attr; - attribs[i] = NULL; - - flen = snprintf(NULL, 0, FILTER, winname) + 1; - if ((filter = (char *)malloc(flen)) == NULL) { - free(base); - return (IDMAP_ERR_MEMORY); - } - (void) snprintf(filter, flen, FILTER, winname); - - ldap_rc = ldap_search_s(p->ad, base, LDAP_SCOPE_SUBTREE, filter, - attribs, 0, &results); - - free(base); - free(filter); - - if (ldap_rc != LDAP_SUCCESS) { - logger(LOG_ERR, - "Ldap query to server %s port %d failed. (%s)", - p->ad_host, p->ad_port, ldap_err2string(ldap_rc)); - (void) ldap_msgfree(results); - return (IDMAP_ERR_OTHER); - } - - - for (entry = ldap_first_entry(p->ad, results), *dn = NULL; - entry != NULL; - entry = ldap_next_entry(p->ad, entry)) { - char **values = NULL; - int i = 0; - values = ldap_get_values(p->ad, entry, "objectClass"); - - if (values == NULL) { - (void) ldap_msgfree(results); - return (IDMAP_ERR_MEMORY); - } - - for (i = 0; i < ldap_count_values(values); i++) { - /* - * is_wuser can be IDMAP_UNKNOWN, in that case we accept - * both User/Group - */ - if (*is_wuser != IDMAP_NO && - strcasecmp(values[i], "User") == 0 || - *is_wuser != IDMAP_YES && - strcasecmp(values[i], "Group") == 0) { - *dn = ldap_get_dn(p->ad, entry); - if (*dn == NULL) { - ldap_value_free(values); - (void) ldap_msgfree(results); - return (IDMAP_ERR_MEMORY); - } - *is_wuser = strcasecmp(values[i], "User") == 0 - ? IDMAP_YES : IDMAP_NO; - break; - } - } - - ldap_value_free(values); - if (*dn != NULL) - break; - } - - if (*dn == NULL) { - logger(LOG_ERR, - *is_wuser == IDMAP_YES ? gettext("User %s@%s not found") : - *is_wuser == IDMAP_NO ? gettext("Group %s@%s not found") : - gettext("%s@%s not found"), winname, p->windomain); - return (IDMAP_ERR_NOTFOUND); - } - - if (unixuser != NULL) - rc = extract_attribute(p, entry, p->ad_unixuser_attr, - unixuser); - - if (rc == IDMAP_SUCCESS && unixgroup != NULL) - rc = extract_attribute(p, entry, p->ad_unixgroup_attr, - unixgroup); - - (void) ldap_msgfree(results); - - return (rc); -} - - -/* set the given attribute to the given value. If value is NULL, unset it */ -static -idmap_stat -idmap_ad_set(idmap_nm_handle_t *p, char *dn, char *attr, char *value) -{ - idmap_stat rc = IDMAP_SUCCESS; - int ldap_rc; - char *new_values[2] = {NULL, NULL}; - LDAPMod *mods[2] = {NULL, NULL}; - - mods[0] = (LDAPMod *)calloc(1, sizeof (LDAPMod)); - mods[0]->mod_type = strdup(attr); - if (value != NULL) { - mods[0]->mod_op = LDAP_MOD_REPLACE; - new_values[0] = strdup(value); - mods[0]->mod_values = new_values; - } else { - mods[0]->mod_op = LDAP_MOD_DELETE; - mods[0]->mod_values = NULL; - } - - ldap_rc = ldap_modify_s(p->ad, dn, mods); - if (ldap_rc != LDAP_SUCCESS) { - logger(LOG_ERR, - "Ldap modify of %s, attribute %s failed. (%s)", - dn, attr, ldap_err2string(ldap_rc)); - rc = IDMAP_ERR_INTERNAL; - } - - - ldap_mods_free(mods, 0); - return (rc); -} - - -/* - * This function takes the p argument just for the beauty of the symmetry - * with idmap_ad_set (and for future enhancements). - */ -static -idmap_stat -/* LINTED E_FUNC_ARG_UNUSED */ -idmap_nldap_set(idmap_nm_handle_t *p, ns_cred_t *nsc, char *dn, char *attr, - char *value, bool_t is_new, int is_user) -{ - int ldaprc; - ns_ldap_error_t *errorp = NULL; - ns_ldap_attr_t *attrs[2]; - - - - attrs[0] = (ns_ldap_attr_t *)malloc(sizeof (ns_ldap_attr_t)); - if (attrs == NULL) - return (IDMAP_ERR_MEMORY); - - attrs[0]->attrname = attr; - - if (value != NULL) { - char **newattr = (char **)calloc(2, sizeof (char *)); - if (newattr == NULL) { - free(attrs[0]); - return (IDMAP_ERR_MEMORY); - } - newattr[0] = value; - newattr[1] = NULL; - - attrs[0]->attrvalue = newattr; - attrs[0]->value_count = 1; - } else { - attrs[0]->attrvalue = NULL; - attrs[0]->value_count = 0; - } - - - attrs[1] = NULL; - - if (value == NULL) { - ldaprc = __ns_ldap_delAttr( - is_user == IDMAP_YES ? "passwd": "group", - dn, (const ns_ldap_attr_t * const *)attrs, - nsc, 0, &errorp); - } else if (is_new) - ldaprc = __ns_ldap_addAttr( - is_user == IDMAP_YES ? "passwd": "group", - dn, (const ns_ldap_attr_t * const *)attrs, - nsc, 0, &errorp); - else - ldaprc = __ns_ldap_repAttr( - is_user == IDMAP_YES ? "passwd": "group", - dn, (const ns_ldap_attr_t * const *)attrs, - nsc, 0, &errorp); - - if (ldaprc != NS_LDAP_SUCCESS) { - char *msg = "Cause unidentified"; - if (errorp != NULL) { - (void) __ns_ldap_err2str(errorp->status, &msg); - } - logger(LOG_ERR, gettext("__ns_ldap_addAttr/rep/delAttr" - " failed (%s)"), msg); - return (IDMAP_ERR_ARG); - } - - return (IDMAP_SUCCESS); -} - -idmap_stat -idmap_set_namemap(idmap_nm_handle_t *p, char *winname, char *unixname, - int is_user, int is_wuser, int direction) -{ - idmap_stat rc = IDMAP_SUCCESS; - char *dn = NULL; - char *oldwinname = NULL; - char *oldwindomain = NULL; - - if (direction == IDMAP_DIRECTION_W2U) { - if (!p->is_ad) { - rc = IDMAP_ERR_ARG; - logger(LOG_ERR, - gettext("AD namemaps aren't set up.")); - goto cleanup; - } - - rc = winname2dn(p, winname, &is_wuser, - &dn, NULL, NULL); - if (rc != IDMAP_SUCCESS) - goto cleanup; - - rc = idmap_ad_set(p, dn, is_user ? p->ad_unixuser_attr : - p->ad_unixgroup_attr, unixname); - if (rc != IDMAP_SUCCESS) - goto cleanup; - - } - - - if (direction == IDMAP_DIRECTION_U2W) { - char *fullname; - - if (!p->is_nldap) { - rc = IDMAP_ERR_ARG; - logger(LOG_ERR, - gettext("Native ldap namemaps aren't set up.")); - goto cleanup; - } - - - rc = unixname2dn(p, unixname, is_user, &dn, - &oldwinname, &oldwindomain); - if (rc != IDMAP_SUCCESS) - goto cleanup; - - if (p->windomain == NULL) { - fullname = strdup(winname); - if (fullname == NULL) - rc = IDMAP_ERR_MEMORY; - goto cleanup; - } else { - fullname = malloc(strlen(winname) + - strlen(p->windomain) + 2); - if (fullname == NULL) { - rc = IDMAP_ERR_MEMORY; - goto cleanup; - } - - (void) snprintf(fullname, - strlen(winname) + strlen(p->windomain) + 2, - "%s\\%s", p->windomain, winname); - } - rc = idmap_nldap_set(p, &p->nsc, dn, p->nldap_winname_attr, - fullname, oldwinname == NULL ? TRUE : FALSE, is_user); - - free(fullname); - free(oldwindomain); - free(oldwinname); - - if (rc != IDMAP_SUCCESS) - goto cleanup; - - } - -cleanup: - if (dn != NULL) - free(dn); - - if (oldwindomain != NULL) - free(oldwindomain); - - if (oldwinname != NULL) - free(oldwinname); - - return (rc); - -} - - -idmap_stat -idmap_unset_namemap(idmap_nm_handle_t *p, char *winname, char *unixname, - int is_user, int is_wuser, int direction) -{ - idmap_stat rc = IDMAP_SUCCESS; - char *dn = NULL; - char *oldwinname = NULL; - char *oldwindomain = NULL; - - if (direction == IDMAP_DIRECTION_W2U) { - if (!p->is_ad) { - rc = IDMAP_ERR_ARG; - logger(LOG_ERR, - gettext("AD namemaps aren't set up.")); - goto cleanup; - } - - rc = winname2dn(p, winname, &is_wuser, - &dn, NULL, NULL); - if (rc != IDMAP_SUCCESS) - goto cleanup; - - rc = idmap_ad_set(p, dn, is_user ? p->ad_unixuser_attr : - p->ad_unixgroup_attr, unixname); - if (rc != IDMAP_SUCCESS) - goto cleanup; - - } else { /* direction == IDMAP_DIRECTION_U2W */ - if (!p->is_nldap) { - rc = IDMAP_ERR_ARG; - logger(LOG_ERR, - gettext("Native ldap namemaps aren't set up.")); - goto cleanup; - } - - rc = unixname2dn(p, unixname, is_user, &dn, NULL, NULL); - if (rc != IDMAP_SUCCESS) - goto cleanup; - - rc = idmap_nldap_set(p, &p->nsc, dn, p->nldap_winname_attr, - NULL, TRUE, is_user); - if (rc != IDMAP_SUCCESS) - goto cleanup; - - } - -cleanup: - if (oldwindomain != NULL) - free(oldwindomain); - if (oldwinname != NULL) - free(oldwinname); - if (dn != NULL) - free(dn); - return (rc); -} - -idmap_stat -idmap_get_namemap(idmap_nm_handle_t *p, int *is_source_ad, char **winname, - char **windomain, int *is_wuser, char **unixuser, char **unixgroup) -{ - idmap_stat rc = IDMAP_SUCCESS; - char *dn = NULL; - - *is_source_ad = IDMAP_UNKNOWN; - if (*winname != NULL) { - *is_source_ad = IDMAP_YES; - - if (p->is_ad == NULL) { - rc = IDMAP_ERR_ARG; - logger(LOG_ERR, - gettext("AD namemaps are not active.")); - goto cleanup; - /* In future maybe resolve winname and try nldap? */ - } - - rc = winname2dn(p, *winname, is_wuser, &dn, unixuser, - unixgroup); - if (rc != IDMAP_SUCCESS) { - logger(LOG_ERR, - gettext("Winname %s@%s not found in AD."), - *winname, p->windomain); - } - } else if (*unixuser != NULL || *unixgroup != NULL) { - char *unixname; - int is_user; - - *is_source_ad = IDMAP_NO; - - if (p->is_nldap == NULL) { - rc = IDMAP_ERR_ARG; - logger(LOG_ERR, - gettext("Native ldap namemaps aren't active.")); - goto cleanup; - /* In future maybe resolve unixname and try AD? */ - } - - if (*unixuser != NULL) { - is_user = IDMAP_YES; - unixname = *unixuser; - } else if (*unixgroup != NULL) { - is_user = IDMAP_NO; - unixname = *unixgroup; - } - - rc = unixname2dn(p, unixname, is_user, NULL, winname, - windomain); - if (rc != IDMAP_SUCCESS) { - logger(LOG_ERR, - gettext("%s %s not found in native ldap."), - is_user == IDMAP_YES ? "UNIX user" : "UNIX group", - unixname); - goto cleanup; - } - } else { - rc = IDMAP_ERR_ARG; - goto cleanup; - } - -cleanup: - return (rc); -} diff --git a/usr/src/lib/libshare/smb/libshare_smb.c b/usr/src/lib/libshare/smb/libshare_smb.c index 0994b48bb5..2fd55603fa 100644 --- a/usr/src/lib/libshare/smb/libshare_smb.c +++ b/usr/src/lib/libshare/smb/libshare_smb.c @@ -20,8 +20,7 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -2312,6 +2311,9 @@ disposition_validator(int index, char *value) * The properties are given as a list of name-value pair. * The name argument should be the optionset property name and the value * should be a valid value for the specified property. + * + * When calling this function for permanent shares, the caller must also + * call sa_commit_properties() to commit the changes to SMF. */ static int smb_update_optionset_props(sa_handle_t handle, sa_resource_t resource, @@ -2361,9 +2363,6 @@ smb_update_optionset_props(sa_handle_t handle, sa_resource_t resource, cur = nvlist_next_nvpair(nvl, cur); } - if (err == SA_OK) - err = sa_commit_properties(opts, 0); - return (err); } diff --git a/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h b/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h index 5ab647c0eb..7a5f3627f7 100644 --- a/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h +++ b/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _LIBMLRPC_H @@ -159,18 +158,21 @@ extern "C" { #define NDR_DRC_FAULT_OUT_OF_MEMORY 0xF000 /* RPCHDR */ +#define NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH 0x81FF +#define NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT 0x83FF +#define NDR_DRC_FAULT_RPCHDR_DECODE_FAILED 0x86FF #define NDR_DRC_FAULT_RPCHDR_PTYPE_INVALID 0xC0FF /* PARAM_0_INVALID */ -#define NDR_DRC_FAULT_RPCHDR_PTYPE_UNIMPLEMENTED 0xD0FF /* PARAM_0_UNIMP */ +#define NDR_DRC_FAULT_RPCHDR_PTYPE_UNIMPLEMENTED 0xD0FF /* PARAM_0_UNIMP */ /* Request */ #define NDR_DRC_FAULT_REQUEST_PCONT_INVALID 0xC000 /* PARAM_0_INVALID */ #define NDR_DRC_FAULT_REQUEST_OPNUM_INVALID 0xC100 /* PARAM_1_INVALID */ /* Bind */ +#define NDR_DRC_BINDING_MADE 0x000B /* OK */ #define NDR_DRC_FAULT_BIND_PCONT_BUSY 0xC00B /* PARAM_0_INVALID */ #define NDR_DRC_FAULT_BIND_UNKNOWN_SERVICE 0xC10B /* PARAM_1_INVALID */ #define NDR_DRC_FAULT_BIND_NO_SLOTS 0x910B /* RESOURCE_1 */ -#define NDR_DRC_BINDING_MADE 0x000B /* OK */ /* API */ #define NDR_DRC_FAULT_API_SERVICE_INVALID 0xC0AA /* PARAM_0_INVALID */ @@ -502,7 +504,8 @@ void ndr_clnt_free_heap(ndr_client_t *); /* ndr_marshal.c */ ndr_buf_t *ndr_buf_init(ndr_typeinfo_t *); void ndr_buf_fini(ndr_buf_t *); -int ndr_buf_decode(ndr_buf_t *, unsigned, const char *data, size_t, void *); +int ndr_buf_decode(ndr_buf_t *, unsigned, unsigned, const char *data, size_t, + void *); int ndr_decode_call(ndr_xa_t *, void *); int ndr_encode_return(ndr_xa_t *, void *); int ndr_encode_call(ndr_xa_t *, void *); diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c index 12fd0c0d52..a690dfb2e9 100644 --- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c +++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <assert.h> @@ -37,6 +36,7 @@ static const int ndr_native_byte_order = NDR_REPLAB_INTG_LITTLE_ENDIAN; #endif static int ndr_decode_hdr_common(ndr_stream_t *, ndr_common_header_t *); +static int ndr_decode_pac_hdr(ndr_stream_t *, ndr_pac_hdr_t *); static int ndr_encode_decode_common(ndr_stream_t *nds, unsigned opnum, @@ -122,10 +122,11 @@ ndr_buf_fini(ndr_buf_t *nbuf) * } */ int -ndr_buf_decode(ndr_buf_t *nbuf, unsigned opnum, const char *data, - size_t datalen, void *result) +ndr_buf_decode(ndr_buf_t *nbuf, unsigned hdr_type, unsigned opnum, + const char *data, size_t datalen, void *result) { ndr_common_header_t hdr; + ndr_pac_hdr_t pac_hdr; unsigned pdu_size_hint; int rc; @@ -145,12 +146,28 @@ ndr_buf_decode(ndr_buf_t *nbuf, unsigned opnum, const char *data, bcopy(data, nbuf->nb_nds.pdu_base_addr, datalen); - rc = ndr_decode_hdr_common(&nbuf->nb_nds, &hdr); - if (NDR_DRC_IS_FAULT(rc)) - return (rc); + switch (hdr_type) { + case NDR_PTYPE_COMMON: + rc = ndr_decode_hdr_common(&nbuf->nb_nds, &hdr); + if (NDR_DRC_IS_FAULT(rc)) + return (rc); + + if (!NDR_IS_SINGLE_FRAG(hdr.pfc_flags)) + return (NDR_DRC_FAULT_DECODE_FAILED); + break; + + case NDR_PTYPE_PAC: + rc = ndr_decode_pac_hdr(&nbuf->nb_nds, &pac_hdr); + if (NDR_DRC_IS_FAULT(rc)) + return (rc); - if (!NDR_IS_SINGLE_FRAG(hdr.pfc_flags)) - return (NDR_DRC_FAULT_DECODE_FAILED); + if (pac_hdr.common_hdr.hdrlen != sizeof (ndr_serialtype1_hdr_t)) + return (NDR_DRC_FAULT_DECODE_FAILED); + break; + + default: + return (NDR_ERR_UNIMPLEMENTED); + } rc = ndr_encode_decode_common(&nbuf->nb_nds, opnum, nbuf->nb_ti, result); @@ -244,7 +261,7 @@ ndr_decode_pdu_hdr(ndr_xa_t *mxa) * Verify the protocol version. */ if ((hdr->rpc_vers != 5) || (hdr->rpc_vers_minor != 0)) - return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_DECODE_FAILED)); + return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED); mxa->ptype = hdr->ptype; return (NDR_DRC_OK); @@ -259,21 +276,21 @@ ndr_decode_hdr_common(ndr_stream_t *nds, ndr_common_header_t *hdr) int byte_order; if (nds->m_op != NDR_M_OP_UNMARSHALL) - return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_MODE_MISMATCH)); + return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH); /* * All PDU headers are at least this big */ rc = NDS_GROW_PDU(nds, sizeof (ndr_common_header_t), 0); if (!rc) - return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_RECEIVED_RUNT)); + return (NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT); /* * Peek at the first eight bytes to figure out what we're doing. */ rc = NDS_GET_PDU(nds, 0, 8, (char *)hdr, 0, 0); if (!rc) - return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_DECODE_FAILED)); + return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED); /* * Check for ASCII as the character set. This is an ASCII @@ -281,7 +298,7 @@ ndr_decode_hdr_common(ndr_stream_t *nds, ndr_common_header_t *hdr) */ charset = hdr->packed_drep.intg_char_rep & NDR_REPLAB_CHAR_MASK; if (charset != NDR_REPLAB_CHAR_ASCII) - return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_DECODE_FAILED)); + return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED); /* * Set the byte swap flag if the PDU byte-order @@ -301,6 +318,45 @@ ndr_decode_hdr_common(ndr_stream_t *nds, ndr_common_header_t *hdr) return (NDR_DRC_PTYPE_RPCHDR(rc)); } +static int +ndr_decode_pac_hdr(ndr_stream_t *nds, ndr_pac_hdr_t *hdr) +{ + int rc; + + if (nds->m_op != NDR_M_OP_UNMARSHALL) + return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH); + + /* + * All PDU headers are at least this big + */ + rc = NDS_GROW_PDU(nds, sizeof (ndr_pac_hdr_t), 0); + if (!rc) + return (NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT); + + /* + * Peek at the first eight bytes to figure out what we're doing. + */ + rc = NDS_GET_PDU(nds, 0, 8, (char *)hdr, 0, 0); + if (!rc) + return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED); + + /* Must be set to 1 to indicate type serialization version 1. */ + if (hdr->common_hdr.version != 1) + return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED); + + /* + * Set the byte swap flag if the PDU byte-order + * is different from the local byte-order. + */ + nds->swap = + (hdr->common_hdr.endianness != ndr_native_byte_order) ? 1 : 0; + + rc = ndr_encode_decode_common(nds, NDR_PTYPE_PAC, + &TYPEINFO(ndr_hdr), hdr); + + return (NDR_DRC_PTYPE_RPCHDR(rc)); +} + /* * Decode an RPC fragment header. Use ndr_decode_pdu_hdr() to process * the first fragment header then this function to process additional @@ -400,7 +456,7 @@ ndr_encode_pdu_hdr(ndr_xa_t *mxa) int rc; if (nds->m_op != NDR_M_OP_MARSHALL) - return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_MODE_MISMATCH)); + return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH); ptype = hdr->ptype; if (ptype == NDR_PTYPE_REQUEST && diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c index e4c1f50eae..109a29801f 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -37,7 +36,7 @@ #include <unistd.h> #include <netdb.h> #include <assert.h> - +#include <grp.h> #include <smbsrv/libsmb.h> #include <smbsrv/libmlrpc.h> #include <smbsrv/libmlsvc.h> @@ -897,6 +896,193 @@ samr_s_OpenGroup(void *arg, ndr_xa_t *mxa) } /* + * samr_s_AddAliasMember + * + * Add a member to a local SAM group. + * The caller must supply a valid group handle. + * The member is specified by the sid in the request. + */ +static int +samr_s_AddAliasMember(void *arg, ndr_xa_t *mxa) +{ + struct samr_AddAliasMember *param = arg; + ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; + ndr_handle_t *hd; + samr_keydata_t *data; + smb_group_t grp; + uint32_t rc; + uint32_t status = NT_STATUS_SUCCESS; + + if (param->sid == NULL) { + bzero(param, sizeof (struct samr_AddAliasMember)); + param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); + return (NDR_DRC_OK); + } + + if (!ndr_is_admin(mxa)) { + bzero(param, sizeof (struct samr_AddAliasMember)); + param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); + return (NDR_DRC_OK); + } + + + if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { + bzero(param, sizeof (struct samr_AddAliasMember)); + param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); + return (NDR_DRC_OK); + } + + data = (samr_keydata_t *)hd->nh_data; + rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp); + if (rc != SMB_LGRP_SUCCESS) { + bzero(param, sizeof (struct samr_AddAliasMember)); + status = smb_lgrp_err_to_ntstatus(rc); + param->status = NT_SC_ERROR(status); + return (NDR_DRC_OK); + } + + rc = smb_lgrp_add_member(grp.sg_name, + (smb_sid_t *)param->sid, SidTypeUser); + if (rc != SMB_LGRP_SUCCESS) { + bzero(param, sizeof (struct samr_AddAliasMember)); + status = smb_lgrp_err_to_ntstatus(rc); + param->status = NT_SC_ERROR(status); + } + smb_lgrp_free(&grp); + + param->status = status; + return (NDR_DRC_OK); +} + +/* + * samr_s_DeleteAliasMember + * + * Delete a member from a local SAM group. + * The caller must supply a valid group handle. + * The member is specified by the sid in the request. + */ +static int +samr_s_DeleteAliasMember(void *arg, ndr_xa_t *mxa) +{ + struct samr_DeleteAliasMember *param = arg; + ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; + ndr_handle_t *hd; + samr_keydata_t *data; + smb_group_t grp; + uint32_t rc; + uint32_t status = NT_STATUS_SUCCESS; + + if (param->sid == NULL) { + bzero(param, sizeof (struct samr_DeleteAliasMember)); + param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); + return (NDR_DRC_OK); + } + + if (!ndr_is_admin(mxa)) { + bzero(param, sizeof (struct samr_DeleteAliasMember)); + param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); + return (NDR_DRC_OK); + } + + if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { + bzero(param, sizeof (struct samr_DeleteAliasMember)); + param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); + return (NDR_DRC_OK); + } + + data = (samr_keydata_t *)hd->nh_data; + rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp); + if (rc != SMB_LGRP_SUCCESS) { + bzero(param, sizeof (struct samr_DeleteAliasMember)); + status = smb_lgrp_err_to_ntstatus(rc); + param->status = NT_SC_ERROR(status); + return (NDR_DRC_OK); + } + + rc = smb_lgrp_del_member(grp.sg_name, + (smb_sid_t *)param->sid, SidTypeUser); + if (rc != SMB_LGRP_SUCCESS) { + bzero(param, sizeof (struct samr_DeleteAliasMember)); + status = smb_lgrp_err_to_ntstatus(rc); + param->status = NT_SC_ERROR(status); + } + smb_lgrp_free(&grp); + + param->status = status; + return (NDR_DRC_OK); +} + +/* + * samr_s_ListAliasMembers + * + * List members from a local SAM group. + * The caller must supply a valid group handle. + * A list of user SIDs in the specified group is returned to the caller. + */ +static int +samr_s_ListAliasMembers(void *arg, ndr_xa_t *mxa) +{ + struct samr_ListAliasMembers *param = arg; + ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; + ndr_handle_t *hd; + samr_keydata_t *data; + smb_group_t grp; + smb_gsid_t *members; + struct samr_SidInfo info; + struct samr_SidList *user; + uint32_t num = 0, size; + int i; + uint32_t rc; + uint32_t status = NT_STATUS_SUCCESS; + + if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { + bzero(param, sizeof (struct samr_ListAliasMembers)); + param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); + return (NDR_DRC_OK); + } + + bzero(&info, sizeof (struct samr_SidInfo)); + data = (samr_keydata_t *)hd->nh_data; + rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp); + if (rc != SMB_LGRP_SUCCESS) { + bzero(param, sizeof (struct samr_ListAliasMembers)); + status = smb_lgrp_err_to_ntstatus(rc); + param->status = NT_SC_ERROR(status); + return (NDR_DRC_OK); + } + + num = grp.sg_nmembers; + members = grp.sg_members; + size = num * sizeof (struct samr_SidList); + info.sidlist = NDR_MALLOC(mxa, size); + if (info.sidlist == NULL) { + bzero(param, sizeof (struct samr_ListAliasMembers)); + param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); + smb_lgrp_free(&grp); + return (NDR_DRC_OK); + } + + info.n_entry = num; + user = info.sidlist; + for (i = 0; i < num; i++) { + user->sid = (struct samr_sid *)NDR_SIDDUP(mxa, + members[i].gs_sid); + if (user->sid == NULL) { + bzero(param, sizeof (struct samr_ListAliasMembers)); + param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); + smb_lgrp_free(&grp); + return (NDR_DRC_OK); + } + user++; + } + smb_lgrp_free(&grp); + + param->info = info; + param->status = status; + return (NDR_DRC_OK); +} + +/* * samr_s_Connect * * This is a request to connect to the local SAM database. @@ -1220,7 +1406,7 @@ samr_s_OpenAlias(void *arg, ndr_xa_t *mxa) goto open_alias_err; } - if (param->access_mask != SAMR_ALIAS_ACCESS_GET_INFO) { + if ((param->access_mask & SAMR_ALIAS_ACCESS_ALL_ACCESS) == 0) { status = NT_STATUS_ACCESS_DENIED; goto open_alias_err; } @@ -1278,70 +1464,75 @@ open_alias_err: /* * samr_s_CreateDomainAlias * - * Creates a local group in the security database, which is the - * security accounts manager (SAM) - * For more information you can look at MSDN page for NetLocalGroupAdd. - * This RPC is used by CMC and right now it returns access denied. - * The peice of code that creates a local group doesn't get compiled. + * Create a local group in the security accounts manager (SAM) database. + * A local SAM group can only be added if a Solaris group already exists + * with the same name. On success, a valid group handle is returned. + * + * The caller must have administrator rights to execute this function. */ -/*ARGSUSED*/ static int samr_s_CreateDomainAlias(void *arg, ndr_xa_t *mxa) { struct samr_CreateDomainAlias *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; + uint32_t status = NT_STATUS_SUCCESS; + smb_group_t grp; + uint32_t rc; + char *gname; - if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL) { + if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) != NULL) { bzero(param, sizeof (struct samr_CreateDomainAlias)); param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); return (NDR_DRC_OK); } - bzero(param, sizeof (struct samr_CreateDomainAlias)); - param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (NDR_DRC_OK); - -#ifdef SAMR_SUPPORT_ADD_ALIAS - DWORD status = NT_STATUS_SUCCESS; - nt_group_t *grp; - char *alias_name; - - alias_name = param->alias_name.str; - if (alias_name == 0) { - status = NT_STATUS_INVALID_PARAMETER; - goto create_alias_err; + gname = (char *)param->alias_name.str; + if (gname == NULL) { + bzero(¶m->alias_handle, sizeof (samr_handle_t)); + param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); + return (NDR_DRC_OK); } - /* - * Check access mask. User should be member of - * Administrators or Account Operators local group. - */ - status = nt_group_add(alias_name, 0, - NT_GROUP_AF_ADD | NT_GROUP_AF_LOCAL); + if ((!ndr_is_admin(mxa)) || + ((param->access_mask & SAMR_ALIAS_ACCESS_WRITE_ACCOUNT) == 0)) { + bzero(¶m->alias_handle, sizeof (samr_handle_t)); + param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); + return (NDR_DRC_OK); + } - if (status != NT_STATUS_SUCCESS) - goto create_alias_err; + if (getgrnam(gname) == NULL) { + bzero(¶m->alias_handle, sizeof (samr_handle_t)); + param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); + return (NDR_DRC_OK); + } - grp = nt_group_getinfo(alias_name, RWLOCK_READER); - if (grp == NULL) { - status = NT_STATUS_INTERNAL_ERROR; - goto create_alias_err; + rc = smb_lgrp_add(gname, ""); + if (rc != SMB_LGRP_SUCCESS) { + bzero(¶m->alias_handle, sizeof (samr_handle_t)); + status = smb_lgrp_err_to_ntstatus(rc); + param->status = NT_SC_ERROR(status); + return (NDR_DRC_OK); } - (void) smb_sid_getrid(grp->sid, ¶m->rid); - nt_group_putinfo(grp); - handle = mlsvc_get_handle(MLSVC_IFSPEC_SAMR, SAMR_ALIAS_KEY, - param->rid); - bcopy(handle, ¶m->alias_handle, sizeof (samr_handle_t)); + rc = smb_lgrp_getbyname((char *)gname, &grp); + if (rc != SMB_LGRP_SUCCESS) { + bzero(¶m->alias_handle, sizeof (samr_handle_t)); + status = smb_lgrp_err_to_ntstatus(rc); + param->status = NT_SC_ERROR(status); + return (NDR_DRC_OK); + } - param->status = 0; - return (NDR_DRC_OK); + id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, SMB_DOMAIN_LOCAL, grp.sg_rid); + smb_lgrp_free(&grp); + if (id) { + bcopy(id, ¶m->alias_handle, sizeof (samr_handle_t)); + param->status = status; + } else { + bzero(¶m->alias_handle, sizeof (samr_handle_t)); + param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); + } -create_alias_err: - bzero(¶m->alias_handle, sizeof (samr_handle_t)); - param->status = NT_SC_ERROR(status); return (NDR_DRC_OK); -#endif } /* @@ -1471,60 +1662,72 @@ query_alias_err: /* * samr_s_DeleteDomainAlias * - * Deletes a local group account and all its members from the - * security database, which is the security accounts manager (SAM) database. - * Only members of the Administrators or Account Operators local group can - * execute this function. - * For more information you can look at MSDN page for NetLocalGroupSetInfo. + * Deletes a local group in the security database, which is the + * security accounts manager (SAM). A valid group handle is returned + * to the caller upon success. * - * This RPC is used by CMC and right now it returns access denied. - * The peice of code that removes a local group doesn't get compiled. + * The caller must have administrator rights to execute this function. */ static int samr_s_DeleteDomainAlias(void *arg, ndr_xa_t *mxa) { struct samr_DeleteDomainAlias *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; + ndr_handle_t *hd; + smb_group_t grp; + samr_keydata_t *data; + smb_domain_type_t gd_type; + uint32_t rid; + uint32_t rc; + uint32_t status = NT_STATUS_SUCCESS; - if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL) { + if (!ndr_is_admin(mxa)) { bzero(param, sizeof (struct samr_DeleteDomainAlias)); - param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); + param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); return (NDR_DRC_OK); } - bzero(param, sizeof (struct samr_DeleteDomainAlias)); - param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (NDR_DRC_OK); + if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { + bzero(param, sizeof (struct samr_DeleteDomainAlias)); + param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); + return (NDR_DRC_OK); + } -#ifdef SAMR_SUPPORT_DEL_ALIAS - nt_group_t *grp; - char *alias_name; - DWORD status; + data = (samr_keydata_t *)hd->nh_data; + gd_type = (smb_domain_type_t)data->kd_type; + rid = data->kd_rid; - grp = nt_groups_lookup_rid(desc->discrim); - if (grp == 0) { - status = NT_STATUS_NO_SUCH_ALIAS; - goto delete_alias_err; - } + switch (gd_type) { + case SMB_DOMAIN_BUILTIN: + bzero(param, sizeof (struct samr_DeleteDomainAlias)); + status = NT_SC_ERROR(NT_STATUS_NOT_SUPPORTED); + break; - alias_name = strdup(grp->name); - if (alias_name == 0) { - status = NT_STATUS_NO_MEMORY; - goto delete_alias_err; - } + case SMB_DOMAIN_LOCAL: + rc = smb_lgrp_getbyrid(rid, gd_type, &grp); + if (rc != SMB_LGRP_SUCCESS) { + bzero(param, sizeof (struct samr_DeleteDomainAlias)); + status = smb_lgrp_err_to_ntstatus(rc); + status = NT_SC_ERROR(status); + break; + } - status = nt_group_delete(alias_name); - free(alias_name); - if (status != NT_STATUS_SUCCESS) - goto delete_alias_err; + rc = smb_lgrp_delete(grp.sg_name); + if (rc != SMB_LGRP_SUCCESS) { + bzero(param, sizeof (struct samr_DeleteDomainAlias)); + status = smb_lgrp_err_to_ntstatus(rc); + status = NT_SC_ERROR(status); + } + smb_lgrp_free(&grp); + break; - param->status = 0; - return (NDR_DRC_OK); + default: + bzero(param, sizeof (struct samr_DeleteDomainAlias)); + status = NT_SC_ERROR(NT_STATUS_NO_SUCH_ALIAS); + } -delete_alias_err: - param->status = NT_SC_ERROR(status); + param->status = status; return (NDR_DRC_OK); -#endif } /* @@ -1677,6 +1880,9 @@ static ndr_stub_table_t samr_stub_table[] = { { samr_s_DeleteDomainAlias, SAMR_OPNUM_DeleteDomainAlias }, { samr_s_EnumDomainAliases, SAMR_OPNUM_EnumDomainAliases }, { samr_s_EnumDomainGroups, SAMR_OPNUM_EnumDomainGroups }, + { samr_s_AddAliasMember, SAMR_OPNUM_AddAliasMember }, + { samr_s_DeleteAliasMember, SAMR_OPNUM_DeleteAliasMember }, + { samr_s_ListAliasMembers, SAMR_OPNUM_ListAliasMembers }, {0} }; diff --git a/usr/src/lib/smbsrv/libmlsvc/common/smb_autohome.c b/usr/src/lib/smbsrv/libmlsvc/common/smb_autohome.c index 47633a26d4..a82bbae956 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/smb_autohome.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/smb_autohome.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <sys/param.h> @@ -28,9 +27,11 @@ #include <stdlib.h> #include <stdio.h> #include <pwd.h> +#include <nss_dbdefs.h> #include <assert.h> #include <strings.h> #include <sys/stat.h> +#include <sys/idmap.h> #include <smbsrv/libsmb.h> #include <smbsrv/libmlsvc.h> #include <smbsrv/smbinfo.h> @@ -59,6 +60,7 @@ static void smb_autohome_setent(void); static void smb_autohome_endent(void); static smb_autohome_t *smb_autohome_getent(const char *); static void smb_autohome_parse_options(smb_share_t *); +static int smb_autohome_add_private(const char *, uid_t, gid_t); /* * Add an autohome share. See smb_autohome(4) for details. @@ -73,32 +75,85 @@ static void smb_autohome_parse_options(smb_share_t *); void smb_autohome_add(const smb_token_t *token) { + + char *username; + struct passwd pw; + char buf[NSS_LINELEN_PASSWD]; + uid_t uid; + gid_t gid; + + uid = token->tkn_user.i_id; + gid = token->tkn_primary_grp.i_id; + + if (IDMAP_ID_IS_EPHEMERAL(uid)) { + username = token->tkn_account_name; + assert(username); + } else { + if (getpwuid_r(uid, &pw, buf, sizeof (buf)) == NULL) { + syslog(LOG_ERR, "unable to determine name for " \ + "UID: %u\n", uid); + return; + } + username = pw.pw_name; + } + + if (smb_autohome_add_private(username, uid, gid) != NERR_Success) { + if (!smb_isstrlwr(username)) { + (void) smb_strlwr(username); + (void) smb_autohome_add_private(username, uid, gid); + } + } +} + +/* + * Remove an autohome share. + */ +void +smb_autohome_remove(const char *username) +{ + smb_share_t si; + + assert(username); + + if (smb_shr_get((char *)username, &si) == NERR_Success) { + if (si.shr_flags & SMB_SHRF_AUTOHOME) + (void) smb_shr_remove((char *)username); + } +} + +/* + * An autohome share is not created if a static share using the same name + * already exists. Autohome shares will be added for each login attempt. + * + * Calling smb_shr_get() may return the first argument in all lower case so + * a copy is passed in instead. + * + * We need to serialize calls to smb_autohome_lookup because it + * operates on the global smb_ai structure. + */ +static int +smb_autohome_add_private(const char *username, uid_t uid, gid_t gid) +{ static mutex_t autohome_mutex; smb_share_t si; smb_autohome_t *ai; - char *username = token->tkn_account_name; + char shr_name[MAXNAMELEN]; - assert(username); + (void) strlcpy(shr_name, username, sizeof (shr_name)); - if (smb_shr_get((char *)username, &si) == NERR_Success) { - /* - * A static share with this name already exists - */ + if (smb_shr_get(shr_name, &si) == NERR_Success) { if ((si.shr_flags & SMB_SHRF_AUTOHOME) == 0) - return; + return (NERR_Success); - /* - * autohome shares will be added for each login attempt - */ (void) smb_shr_add(&si); - return; + return (NERR_Success); } (void) mutex_lock(&autohome_mutex); if ((ai = smb_autohome_lookup(username)) == NULL) { (void) mutex_unlock(&autohome_mutex); - return; + return (NERR_ItemNotFound); } bzero(&si, sizeof (smb_share_t)); @@ -110,28 +165,12 @@ smb_autohome_add(const smb_token_t *token) (void) strlcpy(si.shr_cmnt, "Autohome", SMB_SHARE_CMNT_MAX); smb_autohome_parse_options(&si); si.shr_flags |= SMB_SHRF_TRANS | SMB_SHRF_AUTOHOME; - si.shr_uid = token->tkn_user.i_id; - si.shr_gid = token->tkn_primary_grp.i_id; + si.shr_uid = uid; + si.shr_gid = gid; (void) mutex_unlock(&autohome_mutex); - (void) smb_shr_add(&si); -} - -/* - * Remove an autohome share. - */ -void -smb_autohome_remove(const char *username) -{ - smb_share_t si; - - assert(username); - - if (smb_shr_get((char *)username, &si) == NERR_Success) { - if (si.shr_flags & SMB_SHRF_AUTOHOME) - (void) smb_shr_remove((char *)username); - } + return (smb_shr_add(&si)); } /* diff --git a/usr/src/lib/smbsrv/libmlsvc/common/smb_quota.c b/usr/src/lib/smbsrv/libmlsvc/common/smb_quota.c index 6d99db1764..9f3932d5d1 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/smb_quota.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/smb_quota.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. */ #include <stdio.h> #include <stdlib.h> @@ -132,7 +131,7 @@ typedef struct smb_quota_tree { static list_t smb_quota_fs_list; static boolean_t smb_quota_list_init = B_FALSE; static boolean_t smb_quota_shutdown = B_FALSE; -static mutex_t smb_quota_list_mutex; +static mutex_t smb_quota_list_mutex = DEFAULTMUTEX; static cond_t smb_quota_list_condvar; static uint32_t smb_quota_tree_cnt = 0; static int smb_quota_fini_timeout = 1; /* seconds */ @@ -238,7 +237,7 @@ smb_quota_fini(void) (void) cond_broadcast(&smb_quota_list_condvar); - while (smb_quota_tree_cnt != 0) { + while (!list_is_empty(&smb_quota_fs_list)) { qtree = list_head(&smb_quota_fs_list); while (qtree != NULL) { qtree_next = list_next(&smb_quota_fs_list, qtree); @@ -257,7 +256,7 @@ smb_quota_fini(void) qtree = qtree_next; } - if (smb_quota_tree_cnt != 0) { + if (!list_is_empty(&smb_quota_fs_list)) { if (cond_reltimedwait(&smb_quota_list_condvar, &smb_quota_list_mutex, &tswait) == ETIME) { syslog(LOG_WARNING, @@ -823,7 +822,7 @@ smb_quota_tree_create(const char *path) assert(MUTEX_HELD(&smb_quota_list_mutex)); - qtree = malloc(sizeof (smb_quota_tree_t)); + qtree = calloc(sizeof (smb_quota_tree_t), 1); if (qtree == NULL) return (NULL); diff --git a/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c b/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c index a2ce2eb8c0..5c7154b82d 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -43,6 +42,7 @@ #include <unistd.h> #include <pwd.h> #include <signal.h> +#include <dirent.h> #include <smbsrv/libsmb.h> #include <smbsrv/libsmbns.h> @@ -55,6 +55,20 @@ #define SMB_SHR_ERROR_THRESHOLD 3 #define SMB_SHR_CSC_BUFSZ 64 +typedef struct smb_transient { + char *name; + char *cmnt; + char *path; + char drive; + boolean_t check; +} smb_transient_t; + +static smb_transient_t tshare[] = { + { "IPC$", "Remote IPC", NULL, '\0', B_FALSE }, + { "c$", "Default Share", SMB_CVOL, 'C', B_FALSE }, + { "vss$", "VSS", SMB_VSS, 'V', B_TRUE } +}; + static struct { char *value; uint32_t flag; @@ -117,6 +131,9 @@ static uint32_t smb_shr_cache_addent(smb_share_t *); static void smb_shr_cache_delent(char *); static void smb_shr_cache_freent(HT_ITEM *); +static boolean_t smb_shr_is_empty(const char *); +static boolean_t smb_shr_is_dot_or_dotdot(const char *); + /* * sharemgr functions */ @@ -219,16 +236,9 @@ static sema_t smb_proc_sem = DEFAULTSEMA; int smb_shr_start(void) { - int i; - static struct tshare { - char *name; - char *cmnt; - char *path; - } tshare[] = { - { "IPC$", "Remote IPC", NULL }, - { "c$", "Default Share", SMB_CVOL }, - { "vss$", "VSS Share", SMB_VSS } - }; + smb_transient_t *ts; + uint32_t nerr; + int i; (void) mutex_lock(&smb_sa_handle.sa_mtx); smb_sa_handle.sa_in_service = B_TRUE; @@ -238,8 +248,13 @@ smb_shr_start(void) return (ENOMEM); for (i = 0; i < sizeof (tshare)/sizeof (tshare[0]); ++i) { - if (smb_shr_add_transient(tshare[i].name, - tshare[i].cmnt, tshare[i].path) != NERR_Success) + ts = &tshare[i]; + + if (ts->check && smb_shr_is_empty(ts->path)) + continue; + + nerr = smb_shr_add_transient(ts->name, ts->cmnt, ts->path); + if (nerr != NERR_Success) return (ENOMEM); } @@ -850,6 +865,68 @@ smb_shr_is_admin(char *sharename) return (B_FALSE); } +char +smb_shr_drive_letter(const char *path) +{ + smb_transient_t *ts; + int i; + + if (path == NULL) + return ('\0'); + + for (i = 0; i < sizeof (tshare)/sizeof (tshare[0]); ++i) { + ts = &tshare[i]; + + if (ts->path == NULL) + continue; + + if (strcasecmp(ts->path, path) == 0) + return (ts->drive); + } + + return ('\0'); +} + +/* + * Returns true if the specified directory is empty, + * otherwise returns false. + */ +static boolean_t +smb_shr_is_empty(const char *path) +{ + DIR *dirp; + struct dirent *dp; + + if (path == NULL) + return (B_TRUE); + + if ((dirp = opendir(path)) == NULL) + return (B_TRUE); + + while ((dp = readdir(dirp)) != NULL) { + if (!smb_shr_is_dot_or_dotdot(dp->d_name)) + return (B_FALSE); + } + + (void) closedir(dirp); + return (B_TRUE); +} + +/* + * Returns true if name is "." or "..", otherwise returns false. + */ +static boolean_t +smb_shr_is_dot_or_dotdot(const char *name) +{ + if (*name != '.') + return (B_FALSE); + + if ((name[1] == '\0') || (name[1] == '.' && name[2] == '\0')) + return (B_TRUE); + + return (B_FALSE); +} + /* * smb_shr_get_realpath * diff --git a/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_svc.c index 8aee0c09e9..dba55e7ffb 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_svc.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_svc.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -47,6 +46,9 @@ #include <arpa/inet.h> #include <libshare.h> #include <libnvpair.h> +#include <sys/idmap.h> +#include <pwd.h> +#include <nss_dbdefs.h> #include <smbsrv/libsmb.h> #include <smbsrv/libmlsvc.h> #include <smbsrv/lmerr.h> @@ -2669,9 +2671,21 @@ static boolean_t srvsvc_add_autohome(ndr_xa_t *mxa, smb_svcenum_t *se, void *infop) { smb_netuserinfo_t *user = &mxa->pipe->np_user; - char *username = user->ui_account; + char *username; smb_share_t si; DWORD status; + struct passwd pw; + char buf[NSS_LINELEN_PASSWD]; + + if (IDMAP_ID_IS_EPHEMERAL(user->ui_posix_uid)) { + username = user->ui_account; + } else { + if (getpwuid_r(user->ui_posix_uid, &pw, buf, sizeof (buf)) == + NULL) + return (B_FALSE); + + username = pw.pw_name; + } if (smb_shr_get(username, &si) != NERR_Success) return (B_FALSE); @@ -2706,10 +2720,17 @@ srvsvc_share_mkpath(ndr_xa_t *mxa, char *path) { char tmpbuf[MAXPATHLEN]; char *p; + char drive_letter; if (strlen(path) == 0) return (NDR_STRDUP(mxa, path)); + drive_letter = smb_shr_drive_letter(path); + if (drive_letter != '\0') { + (void) snprintf(tmpbuf, MAXPATHLEN, "%c:\\", drive_letter); + return (NDR_STRDUP(mxa, tmpbuf)); + } + /* * Strip the volume name from the path (/vol1/home -> /home). */ diff --git a/usr/src/lib/smbsrv/libsmb/common/libsmb.h b/usr/src/lib/smbsrv/libsmb/common/libsmb.h index 93a1371c07..a99b7eacf5 100644 --- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h +++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _LIBSMB_H @@ -696,6 +695,7 @@ int smb_lgrp_del_member(char *, smb_sid_t *, uint16_t); int smb_lgrp_getbyname(char *, smb_group_t *); int smb_lgrp_getbyrid(uint32_t, smb_domain_type_t, smb_group_t *); void smb_lgrp_free(smb_group_t *); +uint32_t smb_lgrp_err_to_ntstatus(uint32_t); boolean_t smb_lgrp_is_member(smb_group_t *, smb_sid_t *); char *smb_lgrp_strerror(int); int smb_lgrp_iteropen(smb_giter_t *); diff --git a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers index 5c6075131c..cb103606f1 100644 --- a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers +++ b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers @@ -18,8 +18,7 @@ # CDDL HEADER END # # -# Copyright 2010 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. # # @@ -248,6 +247,7 @@ SUNWprivate { smb_lgrp_add_member; smb_lgrp_delete; smb_lgrp_del_member; + smb_lgrp_err_to_ntstatus; smb_lgrp_free; smb_lgrp_getbyname; smb_lgrp_getbyrid; diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c b/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c index 257d23d33b..096526f20b 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <stdlib.h> @@ -937,6 +936,62 @@ smb_lgrp_strerror(int errnum) } /* + * smb_lgrp_err_to_ntstatus + * + * This routine maps Local group operation errors to NT Status error codes. + */ +uint32_t +smb_lgrp_err_to_ntstatus(uint32_t lgrp_err) +{ + int i; + static struct err_map { + uint32_t lgrp_err; + uint32_t nt_status; + } err_map[] = { + { SMB_LGRP_SUCCESS, NT_STATUS_SUCCESS }, + { SMB_LGRP_INVALID_ARG, NT_STATUS_INVALID_PARAMETER }, + { SMB_LGRP_INVALID_MEMBER, NT_STATUS_INVALID_MEMBER }, + { SMB_LGRP_INVALID_NAME, NT_STATUS_INVALID_PARAMETER }, + { SMB_LGRP_NOT_FOUND, NT_STATUS_NO_SUCH_ALIAS }, + { SMB_LGRP_EXISTS, NT_STATUS_ALIAS_EXISTS }, + { SMB_LGRP_NO_SID, NT_STATUS_INVALID_SID }, + { SMB_LGRP_NO_LOCAL_SID, NT_STATUS_INVALID_SID }, + { SMB_LGRP_SID_NOTLOCAL, NT_STATUS_INVALID_SID }, + { SMB_LGRP_WKSID, NT_STATUS_INVALID_SID }, + { SMB_LGRP_NO_MEMORY, NT_STATUS_NO_MEMORY }, + { SMB_LGRP_DB_ERROR, NT_STATUS_INTERNAL_DB_ERROR }, + { SMB_LGRP_DBINIT_ERROR, NT_STATUS_INTERNAL_DB_ERROR }, + { SMB_LGRP_INTERNAL_ERROR, NT_STATUS_INTERNAL_ERROR }, + { SMB_LGRP_MEMBER_IN_GROUP, NT_STATUS_MEMBER_IN_ALIAS }, + { SMB_LGRP_MEMBER_NOT_IN_GROUP, NT_STATUS_MEMBER_NOT_IN_ALIAS }, + { SMB_LGRP_NO_SUCH_PRIV, NT_STATUS_NO_SUCH_PRIVILEGE }, + { SMB_LGRP_NO_SUCH_DOMAIN, NT_STATUS_NO_SUCH_DOMAIN }, + { SMB_LGRP_PRIV_HELD, NT_STATUS_SUCCESS }, + { SMB_LGRP_PRIV_NOT_HELD, NT_STATUS_PRIVILEGE_NOT_HELD }, + { SMB_LGRP_BAD_DATA, NT_STATUS_DATA_ERROR }, + { SMB_LGRP_NO_MORE, NT_STATUS_NO_MORE_DATA }, + { SMB_LGRP_DBOPEN_FAILED, NT_STATUS_INTERNAL_DB_ERROR }, + { SMB_LGRP_DBEXEC_FAILED, NT_STATUS_INTERNAL_DB_ERROR }, + { SMB_LGRP_DBINIT_FAILED, NT_STATUS_INTERNAL_DB_ERROR }, + { SMB_LGRP_DOMLKP_FAILED, NT_STATUS_INTERNAL_DB_ERROR }, + { SMB_LGRP_DOMINS_FAILED, NT_STATUS_INTERNAL_DB_ERROR }, + { SMB_LGRP_INSERT_FAILED, NT_STATUS_INTERNAL_DB_ERROR }, + { SMB_LGRP_DELETE_FAILED, NT_STATUS_INTERNAL_DB_ERROR }, + { SMB_LGRP_UPDATE_FAILED, NT_STATUS_INTERNAL_DB_ERROR }, + { SMB_LGRP_LOOKUP_FAILED, NT_STATUS_INTERNAL_DB_ERROR }, + { SMB_LGRP_NOT_SUPPORTED, NT_STATUS_NOT_SUPPORTED }, + { SMB_LGRP_OFFLINE, NT_STATUS_INTERNAL_ERROR } + }; + + for (i = 0; i < sizeof (err_map)/sizeof (err_map[0]); ++i) { + if (err_map[i].lgrp_err == lgrp_err) + return (err_map[i].nt_status); + } + + return (NT_STATUS_INTERNAL_ERROR); +} + +/* * smb_lgrp_chkmember * * Determines valid account types for being member of diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c index 9e211368b3..0a8d570b3a 100644 --- a/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c +++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <sys/param.h> @@ -562,6 +561,7 @@ smb_ads_decode_host_ip(int addit_cnt, int ans_cnt, uchar_t **ptr, [IN6ADDRSZ-1-i] = *(*ptr+i); #endif ipaddr.a_family = AF_INET6; + *ptr += size; } /* |
