diff options
author | jose borrego <Jose.Borrego@Sun.COM> | 2008-12-10 22:16:19 -0700 |
---|---|---|
committer | jose borrego <Jose.Borrego@Sun.COM> | 2008-12-10 22:16:19 -0700 |
commit | 8d7e41661dc4633488e93b13363137523ce59977 (patch) | |
tree | f99aaf6e18e0f90100fa87a97e13137f5800b089 /usr/src/lib | |
parent | f85c7842adab30da40b7225f83b02f9df9fbb1f0 (diff) | |
download | illumos-joyent-8d7e41661dc4633488e93b13363137523ce59977.tar.gz |
6762162 $DATA appended to streams when stream type != $DATA
6736548 After switching the security mode, sometimes smb/server enters maintenance state
6764225 First domain join attempt after smb/server restarts could fail
6764343 Unable to map a share in a new domain
6673517 Appliance\Share becomes unbrowseable for ~10 mins after CIFS client leaves/rejoins the workgroup
6765259 multiple refreshes may not pick up most recent configuration
6764275 need to check with sharemgr when there's a cache miss
6765313 System panic occurred in smb_node_fini+0x16a()
6769943 Purge mlrpc from from types, functions and definitions
6765390 Deprecate smb_wins.c
6771815 ndr_server.c should not include libmlsvc.h
6732763 smbadm takes invalid workgroup name
6749515 Unable to grant domain users/groups access to files
6765156 Active Directory setup has problems if the NETBIOS domain name does not match AD FQDN
6735548 Domain users cannot connect to CIFS shares from MacOS 10.5
6631366 Able to join W2K3 domain with wrong domain name after joined with correct domain name.
6768067 The "smbadm list" should display FQDN
6768061 SMB daemon turned into maintenance mode while updating ddns
6773309 smbd can miss SIGTERM and fail to exit since some threads allow SIGTERM
6775912 smbd: idmap handle access is not thread safe
6775155 core.smbd dump at smb_shr_sa_loadall+0x1f
6776818 Use of freed memory in smbrdr_logon_user()
6766126 Per-share support to configure/disable client-side caching (offline files)
6778831 smbadm definition of domain is too strict, should allow leading digit
6780207 libumem.so.1`process_free+0x55 crash while running smbtorture base tests.
--HG--
rename : usr/src/uts/common/smbsrv/lsalib.h => usr/src/lib/smbsrv/libmlsvc/common/lsalib.h
rename : usr/src/uts/common/smbsrv/samlib.h => usr/src/lib/smbsrv/libmlsvc/common/samlib.h
Diffstat (limited to 'usr/src/lib')
82 files changed, 6324 insertions, 4415 deletions
diff --git a/usr/src/lib/libshare/common/libsharecore.c b/usr/src/lib/libshare/common/libsharecore.c index 5c92ce4c7c..43b8b44a9d 100644 --- a/usr/src/lib/libshare/common/libsharecore.c +++ b/usr/src/lib/libshare/common/libsharecore.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * core library for common functions across all config store types * and file systems to be exported. This includes legacy dfstab/sharetab @@ -45,7 +43,7 @@ #include "libshare.h" #include "libshare_impl.h" #include <fcntl.h> -#include <sys/stat.h> +#include <thread.h> #include <grp.h> #include <limits.h> #include <sys/param.h> @@ -70,6 +68,8 @@ static char *notice[DFSTAB_NOTICE_LINES] = { /* will be much smaller, but this handles bad syntax in the file */ #define MAXARGSFORSHARE 256 +static mutex_t sharetab_lock = DEFAULTMUTEX; + /* used internally only */ typedef struct sharelist { @@ -85,7 +85,7 @@ struct sharelist { int lineno; } xfs_sharelist_t; static void parse_dfstab(sa_handle_t, char *, xmlNodePtr); -extern char *get_token(char *); +extern char *_sa_get_token(char *); static void dfs_free_list(xfs_sharelist_t *); /* prototypes */ void getlegacyconfig(sa_handle_t, char *, xmlNodePtr *); @@ -247,9 +247,9 @@ getdfstab(FILE *dfs) } item->lineno = line; item->origline = strdup(buff); - (void) get_token(NULL); /* reset to new pointers */ + (void) _sa_get_token(NULL); /* reset to new pointers */ argc = 0; - while ((token = get_token(bp)) != NULL) { + while ((token = _sa_get_token(bp)) != NULL) { if (argc < MAXARGSFORSHARE) args[argc++] = token; } @@ -1361,10 +1361,16 @@ get_share_list(int *errp) if ((fp = fopen(SHARETAB, "r")) != NULL) { struct share *sharetab_entry; + (void) lockf(fileno(fp), F_LOCK, 0); + (void) mutex_lock(&sharetab_lock); + while (getshare(fp, &sharetab_entry) > 0) { newp = alloc_sharelist(); - if (newp == NULL) + if (newp == NULL) { + (void) mutex_unlock(&sharetab_lock); + (void) lockf(fileno(fp), F_ULOCK, 0); goto err; + } /* * Link into the list here so we don't leak @@ -1379,21 +1385,21 @@ get_share_list(int *errp) } newp->path = strdup(sharetab_entry->sh_path); - if (newp->path == NULL) - goto err; newp->resource = strdup(sharetab_entry->sh_res); - if (newp->resource == NULL) - goto err; newp->fstype = strdup(sharetab_entry->sh_fstype); - if (newp->fstype == NULL) - goto err; newp->options = strdup(sharetab_entry->sh_opts); - if (newp->options == NULL) - goto err; newp->description = strdup(sharetab_entry->sh_descr); - if (newp->description == NULL) + + if (newp->path == NULL || newp->resource == NULL || + newp->fstype == NULL || newp->options == NULL || + newp->description == NULL) { + (void) mutex_unlock(&sharetab_lock); + (void) lockf(fileno(fp), F_ULOCK, 0); goto err; + } } + + (void) mutex_unlock(&sharetab_lock); (void) lockf(fileno(fp), F_ULOCK, 0); (void) fclose(fp); } else { diff --git a/usr/src/lib/libshare/common/parser.c b/usr/src/lib/libshare/common/parser.c index 3bd8f9f303..50f98de5b6 100644 --- a/usr/src/lib/libshare/common/parser.c +++ b/usr/src/lib/libshare/common/parser.c @@ -20,12 +20,10 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <ctype.h> @@ -41,7 +39,7 @@ */ char * -get_token(char *string) +_sa_get_token(char *string) { static char *orig = NULL; static char *curp; diff --git a/usr/src/lib/libshare/common/plugin.c b/usr/src/lib/libshare/common/plugin.c index 032793cd79..1dba19ff74 100644 --- a/usr/src/lib/libshare/common/plugin.c +++ b/usr/src/lib/libshare/common/plugin.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -58,15 +56,30 @@ static struct sa_proto_handle sa_proto_handle; void proto_plugin_fini(); /* + * Returns true if name is "." or "..", otherwise returns false. + */ +static boolean_t +proto_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); +} + +/* * proto_plugin_init() * * Initialize the protocol specific plugin modules. * - * Walk /usr/lib/fs/\* for libshare_*.so modules. That is, - * /usr/lib/fs/nfs/libshare_nfs.so. The protocol specific directory - * would have a modules with name libshare_<proto>.so. If one is - * found, initialize it and add to the internal list of - * protocols. These are used for protocol specific operations. + * Walk /usr/lib/fs/\* for libshare_*.so modules, for example, + * /usr/lib/fs/nfs/libshare_nfs.so. A protocol specific directory + * would have modules with names of the form libshare_<proto>.so. + * For each protocol found, initialize it and add it to the internal + * list of protocols. These are used for protocol specific operations. */ int @@ -80,60 +93,69 @@ proto_plugin_init() struct dirent *dent; int ret = SA_OK; struct stat st; - - /* - * Should walk "/usr/lib/fs/" for files of the form: - * libshare_*.so - */ - dir = opendir(SA_LIB_DIR); - if (dir != NULL) { - while (ret == SA_OK && (dent = readdir(dir)) != NULL) { - char path[MAXPATHLEN]; - char isa[MAXISALEN]; + char isa[MAXISALEN]; #if defined(_LP64) - if (sysinfo(SI_ARCHITECTURE_64, isa, MAXISALEN) == -1) - isa[0] = '\0'; + if (sysinfo(SI_ARCHITECTURE_64, isa, MAXISALEN) == -1) + isa[0] = '\0'; #else - isa[0] = '\0'; + isa[0] = '\0'; #endif - (void) snprintf(path, MAXPATHLEN, - "%s/%s/%s/libshare_%s.so.1", SA_LIB_DIR, - dent->d_name, isa, dent->d_name); - /* - * If file doesn't exist, don't try to map it - */ - if (stat(path, &st) < 0) - continue; - - dlhandle = dlopen(path, RTLD_FIRST|RTLD_LAZY); - if (dlhandle != NULL) { - plugin_ops = (struct sa_plugin_ops *) - dlsym(dlhandle, "sa_plugin_ops"); - proto = (struct sa_proto_plugin *) - calloc(1, sizeof (struct sa_proto_plugin)); - if (proto != NULL) { - proto->plugin_ops = plugin_ops; - proto->plugin_handle = dlhandle; - num_protos++; - proto->plugin_next = sap_proto_list; - sap_proto_list = proto; - } else { - ret = SA_NO_MEMORY; - /* Don't leak a dlhandle */ - (void) dlclose(dlhandle); - break; - } - } else { - (void) fprintf(stderr, - dgettext(TEXT_DOMAIN, - "Error in plugin for protocol %s: %s\n"), - dent->d_name, dlerror()); - } + + if ((dir = opendir(SA_LIB_DIR)) == NULL) + return (SA_OK); + + while ((dent = readdir(dir)) != NULL) { + char path[MAXPATHLEN]; + + if (proto_is_dot_or_dotdot(dent->d_name)) + continue; + + (void) snprintf(path, MAXPATHLEN, + "%s/%s/%s/libshare_%s.so.1", SA_LIB_DIR, + dent->d_name, isa, dent->d_name); + + /* + * If file doesn't exist, don't try to map it + */ + if (stat(path, &st) < 0) + continue; + + if ((dlhandle = dlopen(path, RTLD_FIRST|RTLD_LAZY)) == NULL) { + (void) fprintf(stderr, dgettext(TEXT_DOMAIN, + "Error in plugin for protocol %s: %s\n"), + dent->d_name, dlerror()); + continue; + } + + plugin_ops = (struct sa_plugin_ops *) + dlsym(dlhandle, "sa_plugin_ops"); + if (plugin_ops == NULL) { + (void) fprintf(stderr, dgettext(TEXT_DOMAIN, + "Error in plugin ops for protocol %s: %s\n"), + dent->d_name, dlerror()); + (void) dlclose(dlhandle); + continue; } - (void) closedir(dir); + + proto = (struct sa_proto_plugin *) + calloc(1, sizeof (struct sa_proto_plugin)); + if (proto == NULL) { + (void) dlclose(dlhandle); + ret = SA_NO_MEMORY; + continue; + } + + proto->plugin_ops = plugin_ops; + proto->plugin_handle = dlhandle; + num_protos++; + proto->plugin_next = sap_proto_list; + sap_proto_list = proto; } - if (ret == SA_OK) { + + (void) closedir(dir); + + if (num_protos != 0) { sa_proto_handle.sa_proto = (char **)calloc(num_protos, sizeof (char *)); sa_proto_handle.sa_ops = diff --git a/usr/src/lib/libshare/nfs/libshare_nfs.c b/usr/src/lib/libshare/nfs/libshare_nfs.c index 28f1c7c06c..a6d3d7802f 100644 --- a/usr/src/lib/libshare/nfs/libshare_nfs.c +++ b/usr/src/lib/libshare/nfs/libshare_nfs.c @@ -1513,7 +1513,7 @@ err: sa_free_attr_string(sectype); if (options != NULL) sa_free_derived_optionset(options); - return (buff); + return (NULL); } /* diff --git a/usr/src/lib/libshare/smb/Makefile.com b/usr/src/lib/libshare/smb/Makefile.com index 38ca0db389..eaa79123b5 100644 --- a/usr/src/lib/libshare/smb/Makefile.com +++ b/usr/src/lib/libshare/smb/Makefile.com @@ -45,7 +45,7 @@ LIBSRCS = $(LIBOBJS:%.o=$(SRCDIR)/%.c) lintcheck := SRCS = $(LIBSRCS) LIBS = $(DYNLIB) -LDLIBS += -lshare -lnsl -lscf -lumem -lc +LDLIBS += -lshare -ldlpi -lnsl -lscf -lumem -lc all install := LDLIBS += -lxml2 CFLAGS += $(CCVERBOSE) diff --git a/usr/src/lib/libshare/smb/libshare_smb.c b/usr/src/lib/libshare/smb/libshare_smb.c index 13d2c968d9..1d461197fa 100644 --- a/usr/src/lib/libshare/smb/libshare_smb.c +++ b/usr/src/lib/libshare/smb/libshare_smb.c @@ -50,6 +50,9 @@ #include <smbsrv/smb_share.h> #include <smbsrv/smbinfo.h> #include <smbsrv/libsmb.h> +#include <libdlpi.h> + +#define SMB_CSC_BUFSZ 64 /* internal functions */ static int smb_share_init(void); @@ -73,7 +76,6 @@ static int range_check_validator_zero_ok(int, char *); static int string_length_check_validator(int, char *); static int true_false_validator(int, char *); static int ip_address_validator_empty_ok(int, char *); -static int ip_address_csv_list_validator_empty_ok(int, char *); static int path_validator(int, char *); static int smb_enable_resource(sa_resource_t); @@ -82,7 +84,9 @@ static uint64_t smb_share_features(void); static int smb_list_transient(sa_handle_t); static int smb_build_shareinfo(sa_share_t, sa_resource_t, smb_share_t *); +static void smb_csc_option(const char *, smb_share_t *); static sa_group_t smb_get_defaultgrp(sa_handle_t); +static int interface_validator(int, char *); /* size of basic format allocation */ #define OPT_CHUNK 1024 @@ -98,6 +102,11 @@ static sa_group_t smb_get_defaultgrp(sa_handle_t); #define PROTO_OPT_WINS1 6 #define PROTO_OPT_WINS_EXCLUDE 8 +typedef struct smb_hostifs_walker { + const char *hiw_ifname; + boolean_t hiw_matchfound; +} smb_hostifs_walker_t; + /* * ops vector that provides the protocol specific info and operations @@ -134,19 +143,14 @@ struct sa_plugin_ops sa_plugin_ops = { NULL /* delete_proto_section */ }; -/* - * option definitions. Make sure to keep the #define for the option - * index just before the entry it is the index for. Changing the order - * can cause breakage. - */ - struct option_defs optdefs[] = { - {SMB_SHROPT_AD_CONTAINER, OPT_TYPE_STRING}, - {SMB_SHROPT_NAME, OPT_TYPE_NAME}, - {SHOPT_RO, OPT_TYPE_ACCLIST}, - {SHOPT_RW, OPT_TYPE_ACCLIST}, - {SHOPT_NONE, OPT_TYPE_ACCLIST}, - {NULL, NULL}, + { SHOPT_AD_CONTAINER, OPT_TYPE_STRING }, + { SHOPT_NAME, OPT_TYPE_NAME }, + { SHOPT_RO, OPT_TYPE_ACCLIST }, + { SHOPT_RW, OPT_TYPE_ACCLIST }, + { SHOPT_NONE, OPT_TYPE_ACCLIST }, + { SHOPT_CSC, OPT_TYPE_CSC }, + { NULL, NULL } }; /* @@ -244,6 +248,23 @@ validresource(const char *name) } /* + * Check that the client-side caching (CSC) option value is valid. + */ +static boolean_t +validcsc(const char *value) +{ + const char *cscopt[] = { "disabled", "manual", "auto", "vdo" }; + int i; + + for (i = 0; i < (sizeof (cscopt) / sizeof (cscopt[0])); ++i) { + if (strcasecmp(value, cscopt[i]) == 0) + return (B_TRUE); + } + + return (B_FALSE); +} + +/* * smb_isonline() * * Determine if the SMF service instance is in the online state or @@ -754,6 +775,10 @@ smb_validate_property(sa_handle_t handle, sa_property_t property, case OPT_TYPE_STRING: /* whatever is here should be ok */ break; + case OPT_TYPE_CSC: + if (validcsc(value) == B_FALSE) + ret = SA_BAD_VALUE; + break; case OPT_TYPE_ACCLIST: { sa_property_t oprop; char *ovalue; @@ -834,7 +859,7 @@ struct smb_proto_option_defs { { SMB_CI_WINS_SRV2, 0, MAX_VALUE_BUFLEN, ip_address_validator_empty_ok, SMB_REFRESH_REFRESH }, { SMB_CI_WINS_EXCL, 0, MAX_VALUE_BUFLEN, - ip_address_csv_list_validator_empty_ok, SMB_REFRESH_REFRESH }, + interface_validator, SMB_REFRESH_REFRESH }, { SMB_CI_SIGNING_ENABLE, 0, 0, true_false_validator, SMB_REFRESH_REFRESH }, { SMB_CI_SIGNING_REQD, 0, 0, true_false_validator, @@ -948,42 +973,76 @@ ip_address_validator_empty_ok(int index, char *value) } /* - * Check IP address list + * Call back function for dlpi_walk. + * Returns TRUE if interface name exists on the host. + */ +static boolean_t +smb_get_interface(const char *ifname, void *arg) +{ + smb_hostifs_walker_t *iterp = arg; + + iterp->hiw_matchfound = (strcmp(ifname, iterp->hiw_ifname) == 0); + + return (iterp->hiw_matchfound); +} + +/* + * Checks to see if the input interface exists on the host. + * Returns B_TRUE if the match is found, B_FALSE otherwise. + */ +static boolean_t +smb_validate_interface(const char *ifname) +{ + smb_hostifs_walker_t iter; + + if ((ifname == NULL) || (*ifname == '\0')) + return (B_FALSE); + + iter.hiw_ifname = ifname; + iter.hiw_matchfound = B_FALSE; + dlpi_walk(smb_get_interface, &iter, 0); + + return (iter.hiw_matchfound); +} + +/* + * Check valid interfaces. Interface names value can be NULL or empty. + * Returns SA_BAD_VALUE if interface cannot be found on the host. */ /*ARGSUSED*/ static int -ip_address_csv_list_validator_empty_ok(int index, char *value) +interface_validator(int index, char *value) { - char sbytes[16]; - char *ip, *tmp, *ctx; + char buf[16]; + int ret = SA_OK; + char *ifname, *tmp, *p; if (value == NULL || *value == '\0') - return (SA_OK); + return (ret); if (strlen(value) > MAX_VALUE_BUFLEN) return (SA_BAD_VALUE); - if ((tmp = strdup(value)) == NULL) + if ((p = strdup(value)) == NULL) return (SA_NO_MEMORY); - ip = strtok_r(tmp, ",", &ctx); - while (ip) { - if (strlen(ip) == 0) { - free(tmp); - return (SA_BAD_VALUE); + tmp = p; + while ((ifname = strsep(&tmp, ",")) != NULL) { + if (*ifname == '\0') { + ret = SA_BAD_VALUE; + break; } - if (*ip != 0) { - if (inet_pton(AF_INET, ip, - (void *)sbytes) != 1) { - free(tmp); - return (SA_BAD_VALUE); + + if (!smb_validate_interface(ifname)) { + if (inet_pton(AF_INET, ifname, (void *)buf) == 0) { + ret = SA_BAD_VALUE; + break; } } - ip = strtok_r(0, ",", &ctx); } - free(tmp); - return (SA_OK); + free(p); + return (ret); } /* @@ -1436,7 +1495,7 @@ smb_add_transient(sa_handle_t handle, smb_share_t *si) /* set resource attributes now */ (void) sa_set_resource_attr(resource, "description", si->shr_cmnt); - (void) sa_set_resource_attr(resource, SMB_SHROPT_AD_CONTAINER, + (void) sa_set_resource_attr(resource, SHOPT_AD_CONTAINER, si->shr_container); return (SA_OK); @@ -1915,7 +1974,7 @@ smb_build_shareinfo(sa_share_t share, sa_resource_t resource, smb_share_t *si) if (opts == NULL) return (SA_OK); - prop = sa_get_property(opts, SMB_SHROPT_AD_CONTAINER); + prop = sa_get_property(opts, SHOPT_AD_CONTAINER); if (prop != NULL) { if ((val = sa_get_property_attr(prop, "value")) != NULL) { (void) strlcpy(si->shr_container, val, @@ -1924,6 +1983,14 @@ smb_build_shareinfo(sa_share_t share, sa_resource_t resource, smb_share_t *si) } } + prop = sa_get_property(opts, SHOPT_CSC); + if (prop != NULL) { + if ((val = sa_get_property_attr(prop, "value")) != NULL) { + smb_csc_option(val, si); + free(val); + } + } + prop = sa_get_property(opts, SHOPT_RO); if (prop != NULL) { if ((val = sa_get_property_attr(prop, "value")) != NULL) { @@ -1959,6 +2026,63 @@ smb_build_shareinfo(sa_share_t share, sa_resource_t resource, smb_share_t *si) } /* + * Map a client-side caching (CSC) option to the appropriate share + * flag. Only one option is allowed; an error will be logged if + * multiple options have been specified. We don't need to do anything + * about multiple values here because the SRVSVC will not recognize + * a value containing multiple flags and will return the default value. + * + * If the option value is not recognized, it will be ignored: invalid + * values will typically be caught and rejected by sharemgr. + */ +static void +smb_csc_option(const char *value, smb_share_t *si) +{ + struct { + char *value; + uint32_t flag; + } cscopt[] = { + { "disabled", SMB_SHRF_CSC_DISABLED }, + { "manual", SMB_SHRF_CSC_MANUAL }, + { "auto", SMB_SHRF_CSC_AUTO }, + { "vdo", SMB_SHRF_CSC_VDO } + }; + + char buf[SMB_CSC_BUFSZ]; + int i; + + for (i = 0; i < (sizeof (cscopt) / sizeof (cscopt[0])); ++i) { + if (strcasecmp(value, cscopt[i].value) == 0) { + si->shr_flags |= cscopt[i].flag; + break; + } + } + + switch (si->shr_flags & SMB_SHRF_CSC_MASK) { + case 0: + case SMB_SHRF_CSC_DISABLED: + case SMB_SHRF_CSC_MANUAL: + case SMB_SHRF_CSC_AUTO: + case SMB_SHRF_CSC_VDO: + break; + + default: + buf[0] = '\0'; + + for (i = 0; i < (sizeof (cscopt) / sizeof (cscopt[0])); ++i) { + if (si->shr_flags & cscopt[i].flag) { + (void) strlcat(buf, " ", SMB_CSC_BUFSZ); + (void) strlcat(buf, cscopt[i].value, + SMB_CSC_BUFSZ); + } + } + + syslog(LOG_ERR, "csc option conflict:%s", buf); + break; + } +} + +/* * smb_get_defaultgrp * * If default group for CIFS shares (i.e. "smb") exists diff --git a/usr/src/lib/libshare/smb/libshare_smb.h b/usr/src/lib/libshare/smb/libshare_smb.h index 0ddc5cf4b7..1a46d08270 100644 --- a/usr/src/lib/libshare/smb/libshare_smb.h +++ b/usr/src/lib/libshare/smb/libshare_smb.h @@ -50,6 +50,7 @@ extern "C" { #define OPT_TYPE_PROTOCOL 5 #define OPT_TYPE_NAME 6 #define OPT_TYPE_ACCLIST 7 +#define OPT_TYPE_CSC 8 struct option_defs { char *tag; diff --git a/usr/src/lib/smbsrv/libmlrpc/Makefile.com b/usr/src/lib/smbsrv/libmlrpc/Makefile.com index d4776174cd..fa45211464 100644 --- a/usr/src/lib/smbsrv/libmlrpc/Makefile.com +++ b/usr/src/lib/smbsrv/libmlrpc/Makefile.com @@ -22,8 +22,6 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# LIBRARY = libmlrpc.a VERS = .1 @@ -47,7 +45,7 @@ include ../../Makefile.lib INCS += -I$(SRC)/common/smbsrv LDLIBS += $(MACH_LDLIBS) -LDLIBS += -lsmb -lc +LDLIBS += -lsmb -luuid -lc CPPFLAGS += $(INCS) -D_REENTRANT diff --git a/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h b/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h index 69f593f9ee..66bc621829 100644 --- a/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h +++ b/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h @@ -26,18 +26,502 @@ #ifndef _LIBMLRPC_H #define _LIBMLRPC_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> +#include <sys/uio.h> +#include <smbsrv/wintypes.h> +#include <smbsrv/ndr.h> +#include <smbsrv/smb_sid.h> +#include <smbsrv/smb_xdr.h> #ifdef __cplusplus extern "C" { #endif -int ndr_s_open(int, uint8_t *, uint32_t); -int ndr_s_close(int); -int ndr_s_read(int, uint8_t *, uint32_t *, uint32_t *); -int ndr_s_write(int, uint8_t *, uint32_t); +/* + * An MSRPC compatible implementation of OSF DCE RPC. DCE RPC is derived + * from the Apollo Network Computing Architecture (NCA) RPC implementation. + * + * CAE Specification (1997) + * DCE 1.1: Remote Procedure Call + * Document Number: C706 + * The Open Group + * ogspecs@opengroup.org + * + * This implementation is based on the DCE Remote Procedure Call spec with + * enhancements to support Unicode strings. The diagram below shows the + * DCE RPC layers compared against ONC SUN RPC. + * + * NDR RPC Layers Sun RPC Layers Remark + * +---------------+ +---------------+ +---------------+ + * +---------------+ +---------------+ + * | Application | | Application | The application + * +---------------+ +---------------+ + * | Hand coded | | RPCGEN gen'd | Where the real + * | client/server | | client/server | work happens + * | srvsvc.ndl | | *_svc.c *_clnt| + * | srvsvc.c | | | + * +---------------+ +---------------+ + * | RPC Library | | RPC Library | Calls/Return + * | ndr_*.c | | | Binding/PMAP + * +---------------+ +---------------+ + * | RPC Protocol | | RPC Protocol | Headers, Auth, + * | rpcpdu.ndl | | | + * +---------------+ +---------------+ + * | IDL gen'd | | RPCGEN gen'd | Aggregate + * | NDR stubs | | XDR stubs | Composition + * | *__ndr.c | | *_xdr.c | + * +---------------+ +---------------+ + * | NDR Represen | | XDR Represen | Byte order, padding + * +---------------+ +---------------+ + * | Packet Heaps | | Network Conn | DCERPC does not talk + * | ndo_*.c | | clnt_{tcp,udp}| directly to network. + * +---------------+ +---------------+ + * + * There are two major differences between the DCE RPC and ONC RPC: + * + * 1. NDR RPC only generates or processes packets from buffers. Other + * layers must take care of packet transmission and reception. + * The packet heaps are managed through a simple interface provided + * by the Network Data Representation (NDR) module called ndr_stream_t. + * ndo_*.c modules implement the different flavors (operations) of + * packet heaps. + * + * ONC RPC communicates directly with the network. You have to do + * something special for the RPC packet to be placed in a buffer + * rather than sent to the wire. + * + * 2. NDR RPC uses application provided heaps to support operations. + * A heap is a single, monolithic chunk of memory that NDR RPC manages + * as it allocates. When the operation and its result are done, the + * heap is disposed of as a single item. The transaction, which + * is the anchor of most operations, contains the necessary book- + * keeping for the heap. + * + * ONC RPC uses malloc() liberally throughout its run-time system. + * To free results, ONC RPC supports an XDR_FREE operation that + * traverses data structures freeing memory as it goes, whether + * it was malloc'd or not. + */ + +/* + * Dispatch Return Code (DRC) + * + * 0x8000 15:01 Set to indicate a fault, clear indicates status + * 0x7F00 08:07 Status/Fault specific + * 0x00FF 00:08 PTYPE_... of PDU, 0xFF for header + */ +#define NDR_DRC_OK 0x0000 +#define NDR_DRC_MASK_FAULT 0x8000 +#define NDR_DRC_MASK_SPECIFIER 0xFF00 +#define NDR_DRC_MASK_PTYPE 0x00FF + +/* Fake PTYPE DRC discriminators */ +#define NDR_DRC_PTYPE_RPCHDR(DRC) ((DRC) | 0x00FF) +#define NDR_DRC_PTYPE_API(DRC) ((DRC) | 0x00AA) + +/* DRC Recognizers */ +#define NDR_DRC_IS_OK(DRC) (((DRC) & NDR_DRC_MASK_SPECIFIER) == 0) +#define NDR_DRC_IS_FAULT(DRC) (((DRC) & NDR_DRC_MASK_FAULT) != 0) + +/* + * (Un)Marshalling category specifiers + */ +#define NDR_DRC_FAULT_MODE_MISMATCH 0x8100 +#define NDR_DRC_RECEIVED 0x0200 +#define NDR_DRC_FAULT_RECEIVED_RUNT 0x8300 +#define NDR_DRC_FAULT_RECEIVED_MALFORMED 0x8400 +#define NDR_DRC_DECODED 0x0500 +#define NDR_DRC_FAULT_DECODE_FAILED 0x8600 +#define NDR_DRC_ENCODED 0x0700 +#define NDR_DRC_FAULT_ENCODE_FAILED 0x8800 +#define NDR_DRC_FAULT_ENCODE_TOO_BIG 0x8900 +#define NDR_DRC_SENT 0x0A00 +#define NDR_DRC_FAULT_SEND_FAILED 0x8B00 + +/* + * Resource category specifier + */ +#define NDR_DRC_FAULT_RESOURCE_1 0x9100 +#define NDR_DRC_FAULT_RESOURCE_2 0x9200 + +/* + * Parameters. Usually #define'd with useful alias + */ +#define NDR_DRC_FAULT_PARAM_0_INVALID 0xC000 +#define NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED 0xD000 +#define NDR_DRC_FAULT_PARAM_1_INVALID 0xC100 +#define NDR_DRC_FAULT_PARAM_1_UNIMPLEMENTED 0xD100 +#define NDR_DRC_FAULT_PARAM_2_INVALID 0xC200 +#define NDR_DRC_FAULT_PARAM_2_UNIMPLEMENTED 0xD200 +#define NDR_DRC_FAULT_PARAM_3_INVALID 0xC300 +#define NDR_DRC_FAULT_PARAM_3_UNIMPLEMENTED 0xD300 + +#define NDR_DRC_FAULT_OUT_OF_MEMORY 0xF000 + +/* RPCHDR */ +#define NDR_DRC_FAULT_RPCHDR_PTYPE_INVALID 0xC0FF /* PARAM_0_INVALID */ +#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_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 */ +#define NDR_DRC_FAULT_API_BIND_NO_SLOTS 0x91AA /* RESOURCE_1 */ +#define NDR_DRC_FAULT_API_OPNUM_INVALID 0xC1AA /* PARAM_1_INVALID */ + +struct ndr_xa; +struct ndr_client; + +typedef struct ndr_stub_table { + int (*func)(void *, struct ndr_xa *); + unsigned short opnum; +} ndr_stub_table_t; + +typedef struct ndr_service { + char *name; + char *desc; + char *endpoint; + char *sec_addr_port; + char *abstract_syntax_uuid; + int abstract_syntax_version; + char *transfer_syntax_uuid; + int transfer_syntax_version; + unsigned bind_instance_size; + int (*bind_req)(); + int (*unbind_and_close)(); + int (*call_stub)(struct ndr_xa *); + ndr_typeinfo_t *interface_ti; + ndr_stub_table_t *stub_table; +} ndr_service_t; + +/* + * The list of bindings is anchored at a connection. Nothing in the + * RPC mechanism allocates them. Binding elements which have service==0 + * indicate free elements. When a connection is instantiated, at least + * one free binding entry should also be established. Something like + * this should suffice for most (all) situations: + * + * struct connection { + * .... + * ndr_binding_t *binding_list_head; + * ndr_binding_t binding_pool[N_BINDING_POOL]; + * .... + * }; + * + * init_connection(struct connection *conn) { + * .... + * ndr_svc_binding_pool_init(&conn->binding_list_head, + * conn->binding_pool, N_BINDING_POOL); + */ +typedef struct ndr_binding { + struct ndr_binding *next; + ndr_p_context_id_t p_cont_id; + unsigned char which_side; + struct ndr_client *clnt; + ndr_service_t *service; + void *instance_specific; +} ndr_binding_t; + +#define NDR_BIND_SIDE_CLIENT 1 +#define NDR_BIND_SIDE_SERVER 2 + +#define NDR_BINDING_TO_SPECIFIC(BINDING, TYPE) \ + ((TYPE *) (BINDING)->instance_specific) + +/* + * The binding list space must be provided by the application library + * for use by the underlying RPC library. We need at least two binding + * slots per connection. + */ +#define NDR_N_BINDING_POOL 2 + +typedef struct ndr_pipe { + int np_fid; + smb_opipe_context_t np_ctx; + char *np_buf; + struct uio np_uio; + iovec_t np_iov; + ndr_fraglist_t np_frags; + int np_refcnt; + uint16_t np_max_xmit_frag; + uint16_t np_max_recv_frag; + ndr_binding_t *np_binding; + ndr_binding_t np_binding_pool[NDR_N_BINDING_POOL]; +} ndr_pipe_t; + +/* + * Number of bytes required to align SIZE on the next dword/4-byte + * boundary. + */ +#define NDR_ALIGN4(SIZE) ((4 - (SIZE)) & 3); + +/* + * DCE RPC strings (CAE section 14.3.4) are represented as varying or varying + * and conformant one-dimensional arrays. Characters can be single-byte + * or multi-byte as long as all characters conform to a fixed element size, + * i.e. UCS-2 is okay but UTF-8 is not a valid DCE RPC string format. The + * string is terminated by a null character of the appropriate element size. + * + * MSRPC strings should always be varying/conformant and not null terminated. + * This format uses the size_is, first_is and length_is attributes (CAE + * section 4.2.18). + * + * typedef struct string { + * DWORD size_is; + * DWORD first_is; + * DWORD length_is; + * wchar_t string[ANY_SIZE_ARRAY]; + * } string_t; + * + * The size_is attribute is used to specify the number of data elements in + * each dimension of an array. + * + * The first_is attribute is used to define the lower bound for significant + * elements in each dimension of an array. For strings this is always 0. + * + * The length_is attribute is used to define the number of significant + * elements in each dimension of an array. For strings this is typically + * the same as size_is. Although it might be (size_is - 1) if the string + * is null terminated. + * + * 4 bytes 4 bytes 4 bytes 2bytes 2bytes 2bytes 2bytes + * +---------+---------+---------+------+------+------+------+ + * |size_is |first_is |length_is| char | char | char | char | + * +---------+---------+---------+------+------+------+------+ + * + * Unfortunately, not all MSRPC Unicode strings are null terminated, which + * means that the recipient has to manually null-terminate the string after + * it has been unmarshalled. There may be a wide-char pad following a + * string, and it may sometimes contains zero, but it's not guaranteed. + * + * To deal with this, MSRPC sometimes uses an additional wrapper with two + * more fields, as shown below. + * length: the array length in bytes excluding terminating null bytes + * maxlen: the array length in bytes including null terminator bytes + * LPTSTR: converted to a string_t by NDR + * + * typedef struct ms_string { + * WORD length; + * WORD maxlen; + * LPTSTR str; + * } ms_string_t; + */ +typedef struct ndr_mstring { + uint16_t length; + uint16_t allosize; + LPTSTR str; +} ndr_mstring_t; + +/* + * A number of heap areas are used during marshalling and unmarshalling. + * Under some circumstances these areas can be discarded by the library + * code, i.e. on the server side before returning to the client and on + * completion of a client side bind. In the case of a client side RPC + * call, these areas must be preserved after an RPC returns to give the + * caller time to take a copy of the data. In this case the client must + * call ndr_clnt_free_heap to free the memory. + * + * The heap management data definition looks a bit like this: + * + * heap -> +---------------+ +------------+ + * | iovec[0].base | --> | data block | + * | iovec[0].len | +------------+ + * +---------------+ + * :: + * :: + * iov -> +---------------+ +------------+ + * | iovec[n].base | --> | data block | + * | iovec[n].len | +------------+ + * +---------------+ ^ ^ + * | | + * next ----------------------+ | + * top -----------------------------------+ + * + */ + +/* + * Setting MAXIOV to 384 will use ((8 * 384) + 16) = 3088 bytes + * of the first heap block. + */ +#define NDR_HEAP_MAXIOV 384 +#define NDR_HEAP_BLKSZ 8192 + +typedef struct ndr_heap { + struct iovec iovec[NDR_HEAP_MAXIOV]; + struct iovec *iov; + int iovcnt; + char *top; + char *next; +} ndr_heap_t; + +/* + * Alternate varying/conformant string definition + * - for non-null-terminated strings. + */ +typedef struct ndr_vcs { + /* + * size_is (actually a copy of length_is) will + * be inserted here by the marshalling library. + */ + uint32_t vc_first_is; + uint32_t vc_length_is; + uint16_t buffer[ANY_SIZE_ARRAY]; +} ndr_vcs_t; + +typedef struct ndr_vcstr { + uint16_t wclen; + uint16_t wcsize; + ndr_vcs_t *vcs; +} ndr_vcstr_t; + +typedef struct ndr_vcb { + /* + * size_is (actually a copy of length_is) will + * be inserted here by the marshalling library. + */ + uint32_t vc_first_is; + uint32_t vc_length_is; + uint8_t buffer[ANY_SIZE_ARRAY]; +} ndr_vcb_t; + +typedef struct ndr_vcbuf { + uint16_t len; + uint16_t size; + ndr_vcb_t *vcb; +} ndr_vcbuf_t; + +ndr_heap_t *ndr_heap_create(void); +void ndr_heap_destroy(ndr_heap_t *); +void *ndr_heap_malloc(ndr_heap_t *, unsigned); +void *ndr_heap_strdup(ndr_heap_t *, const char *); +int ndr_heap_mstring(ndr_heap_t *, const char *, ndr_mstring_t *); +void ndr_heap_mkvcs(ndr_heap_t *, char *, ndr_vcstr_t *); +void ndr_heap_mkvcb(ndr_heap_t *, uint8_t *, uint32_t, ndr_vcbuf_t *); +smb_sid_t *ndr_heap_siddup(ndr_heap_t *, smb_sid_t *); +int ndr_heap_used(ndr_heap_t *); +int ndr_heap_avail(ndr_heap_t *); + +#define NDR_MALLOC(XA, SZ) ndr_heap_malloc((XA)->heap, SZ) +#define NDR_NEW(XA, T) ndr_heap_malloc((XA)->heap, sizeof (T)) +#define NDR_NEWN(XA, T, N) ndr_heap_malloc((XA)->heap, sizeof (T)*(N)) +#define NDR_STRDUP(XA, S) ndr_heap_strdup((XA)->heap, (S)) +#define NDR_MSTRING(XA, S, OUT) ndr_heap_mstring((XA)->heap, (S), (OUT)) +#define NDR_SIDDUP(XA, S) ndr_heap_siddup((XA)->heap, (S)) + +typedef struct ndr_xa { + int fid; + unsigned short ptype; /* high bits special */ + unsigned short opnum; + ndr_stream_t recv_nds; + ndr_hdr_t recv_hdr; + ndr_stream_t send_nds; + ndr_hdr_t send_hdr; + ndr_binding_t *binding; /* what we're using */ + ndr_binding_t *binding_list; /* from connection */ + ndr_heap_t *heap; + ndr_pipe_t *pipe; +} ndr_xa_t; + +/* + * 20-byte opaque id used by various RPC services. + */ +CONTEXT_HANDLE(ndr_hdid) ndr_hdid_t; + +typedef struct ndr_client { + int (*xa_init)(struct ndr_client *, ndr_xa_t *); + int (*xa_exchange)(struct ndr_client *, ndr_xa_t *); + int (*xa_read)(struct ndr_client *, ndr_xa_t *); + void (*xa_preserve)(struct ndr_client *, ndr_xa_t *); + void (*xa_destruct)(struct ndr_client *, ndr_xa_t *); + void (*xa_release)(struct ndr_client *); + + int fid; + ndr_hdid_t *handle; + ndr_binding_t *binding; + ndr_binding_t *binding_list; + ndr_binding_t binding_pool[NDR_N_BINDING_POOL]; + + boolean_t heap_preserved; + ndr_heap_t *heap; + ndr_stream_t *recv_nds; + ndr_stream_t *send_nds; + + uint32_t next_call_id; + unsigned next_p_cont_id; +} ndr_client_t; + +typedef struct ndr_handle { + ndr_hdid_t nh_id; + struct ndr_handle *nh_next; + int nh_fid; + int nh_remote_os; + const ndr_service_t *nh_svc; + ndr_client_t *nh_clnt; + void *nh_data; +} ndr_handle_t; + +/* ndr_ops.c */ +void nds_initialize(ndr_stream_t *, unsigned, int, ndr_heap_t *); +void nds_finalize(ndr_stream_t *, ndr_fraglist_t *); +void nds_destruct(ndr_stream_t *); + +/* ndr_client.c */ +int ndr_clnt_bind(ndr_client_t *, const char *, ndr_binding_t **); +int ndr_clnt_call(ndr_binding_t *, int, void *); +void ndr_clnt_free_heap(ndr_client_t *); + +/* ndr_marshal.c */ +int ndr_encode_decode_common(ndr_xa_t *, int, unsigned, ndr_typeinfo_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 *); +int ndr_decode_return(ndr_xa_t *, void *); +int ndr_decode_pdu_hdr(ndr_xa_t *); +int ndr_encode_pdu_hdr(ndr_xa_t *); +void ndr_decode_frag_hdr(ndr_stream_t *, ndr_common_header_t *); +unsigned ndr_bind_ack_hdr_size(ndr_xa_t *); +unsigned ndr_alter_context_rsp_hdr_size(void); + +/* ndr_server.c */ +int ndr_pipe_open(int, uint8_t *, uint32_t); +int ndr_pipe_close(int); +int ndr_pipe_read(int, uint8_t *, uint32_t *, uint32_t *); +int ndr_pipe_write(int, uint8_t *, uint32_t); + +int ndr_generic_call_stub(ndr_xa_t *); + +boolean_t ndr_is_admin(ndr_xa_t *); +boolean_t ndr_is_poweruser(ndr_xa_t *); +int32_t ndr_native_os(ndr_xa_t *); + +/* ndr_svc.c */ +ndr_stub_table_t *ndr_svc_find_stub(ndr_service_t *, int); +ndr_service_t *ndr_svc_lookup_name(const char *); +ndr_service_t *ndr_svc_lookup_uuid(ndr_uuid_t *, int, ndr_uuid_t *, int); +int ndr_svc_register(ndr_service_t *); +void ndr_svc_unregister(ndr_service_t *); +void ndr_svc_binding_pool_init(ndr_binding_t **, ndr_binding_t pool[], int); +ndr_binding_t *ndr_svc_find_binding(ndr_xa_t *, ndr_p_context_id_t); +ndr_binding_t *ndr_svc_new_binding(ndr_xa_t *); + +int ndr_uuid_parse(char *, ndr_uuid_t *); +void ndr_uuid_unparse(ndr_uuid_t *, char *); + +ndr_hdid_t *ndr_hdalloc(const ndr_xa_t *, const void *); +void ndr_hdfree(const ndr_xa_t *, const ndr_hdid_t *); +ndr_handle_t *ndr_hdlookup(const ndr_xa_t *, const ndr_hdid_t *); +void ndr_hdclose(int fid); + +ssize_t ndr_uiomove(caddr_t, size_t, enum uio_rw, struct uio *); #ifdef __cplusplus } diff --git a/usr/src/lib/smbsrv/libmlrpc/common/mapfile-vers b/usr/src/lib/smbsrv/libmlrpc/common/mapfile-vers index 4b635f81f4..3ac75176bb 100644 --- a/usr/src/lib/smbsrv/libmlrpc/common/mapfile-vers +++ b/usr/src/lib/smbsrv/libmlrpc/common/mapfile-vers @@ -26,39 +26,42 @@ SUNWprivate { global: - mlndr_inner; - mlndr_params; - mlndr_topmost; - mlnds_destruct; - mlnds_initialize; - mlrpc_binding_pool_initialize; - mlrpc_c_bind; - mlrpc_c_call; - mlrpc_c_free_heap; - mlrpc_generic_call_stub; - mlrpc_heap_avail; - mlrpc_heap_create; - mlrpc_heap_destroy; - mlrpc_heap_malloc; - mlrpc_heap_mkvcb; - mlrpc_heap_mkvcs; - mlrpc_heap_strsave; - mlrpc_heap_used; - mlrpc_register_service; - mlrpc_str_to_uuid; - mlrpc_uuid_to_str; + ndr_clnt_bind; + ndr_clnt_call; + ndr_clnt_free_heap; + ndr_generic_call_stub; + ndr_heap_avail; + ndr_heap_create; + ndr_heap_destroy; + ndr_heap_malloc; + ndr_heap_mkvcb; + ndr_heap_mkvcs; + ndr_heap_mstring; + ndr_heap_siddup; + ndr_heap_strdup; + ndr_heap_used; ndr_hdalloc; ndr_hdfree; ndr_hdlookup; + ndr_inner; ndr_is_admin; ndr_is_poweruser; ndr_mbstowcs; ndr_mbtowc; ndr_native_os; - ndr_s_open; - ndr_s_close; - ndr_s_read; - ndr_s_write; + ndr_params; + ndr_pipe_open; + ndr_pipe_close; + ndr_pipe_read; + ndr_pipe_write; + ndr_svc_binding_pool_init; + ndr_svc_lookup_name; + ndr_svc_register; + ndr_topmost; + ndr_uuid_parse; + ndr_uuid_unparse; + nds_destruct; + nds_initialize; ndt__char; ndt_s_wchar; ndt__uchar; diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_client.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_client.c index f4f6969d01..645d501b2b 100644 --- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_client.c +++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_client.c @@ -28,183 +28,181 @@ #include <strings.h> #include <smbsrv/libsmb.h> -#include <smbsrv/ndr.h> -#include <smbsrv/mlrpc.h> +#include <smbsrv/libmlrpc.h> -#define MLRPC_IS_LAST_FRAG(F) ((F) & MLRPC_PFC_LAST_FRAG) -#define MLRPC_DEFAULT_FRAGSZ 8192 +#define NDR_IS_LAST_FRAG(F) ((F) & NDR_PFC_LAST_FRAG) +#define NDR_DEFAULT_FRAGSZ 8192 -static void mlrpc_c_init_hdr(struct mlrpc_client *, struct mlrpc_xaction *); -static int mlrpc_c_get_frags(struct mlrpc_client *, struct mlrpc_xaction *); -static void mlrpc_c_remove_hdr(struct mlndr_stream *, int *); +static void ndr_clnt_init_hdr(ndr_client_t *, ndr_xa_t *); +static int ndr_clnt_get_frags(ndr_client_t *, ndr_xa_t *); +static void ndr_clnt_remove_hdr(ndr_stream_t *, int *); int -mlrpc_c_bind(struct mlrpc_client *mcli, char *service_name, - struct mlrpc_binding **ret_binding_p) +ndr_clnt_bind(ndr_client_t *clnt, const char *service_name, + ndr_binding_t **ret_binding_p) { - struct mlrpc_service *msvc; - struct mlrpc_binding *mbind; - struct mlrpc_xaction mxa; + ndr_service_t *msvc; + ndr_binding_t *mbind; + ndr_xa_t mxa; ndr_bind_hdr_t *bhdr; - mlrpc_p_cont_elem_t *pce; + ndr_p_cont_elem_t *pce; ndr_bind_ack_hdr_t *bahdr; - mlrpc_p_result_t *pre; + ndr_p_result_t *pre; int rc; bzero(&mxa, sizeof (mxa)); - msvc = mlrpc_find_service_by_name(service_name); + msvc = ndr_svc_lookup_name(service_name); if (msvc == NULL) - return (MLRPC_DRC_FAULT_API_SERVICE_INVALID); + return (NDR_DRC_FAULT_API_SERVICE_INVALID); - mxa.binding_list = mcli->binding_list; - if ((mbind = mlrpc_new_binding(&mxa)) == NULL) - return (MLRPC_DRC_FAULT_API_BIND_NO_SLOTS); + mxa.binding_list = clnt->binding_list; + if ((mbind = ndr_svc_new_binding(&mxa)) == NULL) + return (NDR_DRC_FAULT_API_BIND_NO_SLOTS); - mlrpc_c_init_hdr(mcli, &mxa); + ndr_clnt_init_hdr(clnt, &mxa); bhdr = &mxa.send_hdr.bind_hdr; - bhdr->common_hdr.ptype = MLRPC_PTYPE_BIND; + bhdr->common_hdr.ptype = NDR_PTYPE_BIND; bhdr->common_hdr.frag_length = sizeof (*bhdr); - bhdr->max_xmit_frag = MLRPC_DEFAULT_FRAGSZ; - bhdr->max_recv_frag = MLRPC_DEFAULT_FRAGSZ; + bhdr->max_xmit_frag = NDR_DEFAULT_FRAGSZ; + bhdr->max_recv_frag = NDR_DEFAULT_FRAGSZ; bhdr->assoc_group_id = 0; bhdr->p_context_elem.n_context_elem = 1; /* Assign presentation context id */ pce = &bhdr->p_context_elem.p_cont_elem[0]; - pce->p_cont_id = mcli->next_p_cont_id++; + pce->p_cont_id = clnt->next_p_cont_id++; pce->n_transfer_syn = 1; /* Set up UUIDs and versions from the service */ pce->abstract_syntax.if_version = msvc->abstract_syntax_version; - rc = mlrpc_str_to_uuid(msvc->abstract_syntax_uuid, + rc = ndr_uuid_parse(msvc->abstract_syntax_uuid, &pce->abstract_syntax.if_uuid); - if (!rc) - return (MLRPC_DRC_FAULT_API_SERVICE_INVALID); + if (rc != 0) + return (NDR_DRC_FAULT_API_SERVICE_INVALID); pce->transfer_syntaxes[0].if_version = msvc->transfer_syntax_version; - rc = mlrpc_str_to_uuid(msvc->transfer_syntax_uuid, + rc = ndr_uuid_parse(msvc->transfer_syntax_uuid, &pce->transfer_syntaxes[0].if_uuid); - if (!rc) - return (MLRPC_DRC_FAULT_API_SERVICE_INVALID); + if (rc != 0) + return (NDR_DRC_FAULT_API_SERVICE_INVALID); /* Format and exchange the PDU */ - rc = (*mcli->xa_init)(mcli, &mxa, 0); - if (MLRPC_DRC_IS_FAULT(rc)) - return (rc); + if ((*clnt->xa_init)(clnt, &mxa) < 0) + return (NDR_DRC_FAULT_OUT_OF_MEMORY); - rc = mlrpc_encode_pdu_hdr(&mxa); - if (MLRPC_DRC_IS_FAULT(rc)) + rc = ndr_encode_pdu_hdr(&mxa); + if (NDR_DRC_IS_FAULT(rc)) goto fault_exit; - rc = (*mcli->xa_exchange)(mcli, &mxa); - if (MLRPC_DRC_IS_FAULT(rc)) + if ((*clnt->xa_exchange)(clnt, &mxa) < 0) { + rc = NDR_DRC_FAULT_SEND_FAILED; goto fault_exit; + } - rc = mlrpc_decode_pdu_hdr(&mxa); - if (MLRPC_DRC_IS_FAULT(rc)) + rc = ndr_decode_pdu_hdr(&mxa); + if (NDR_DRC_IS_FAULT(rc)) goto fault_exit; /* done with buffers */ - (*mcli->xa_destruct)(mcli, &mxa); + (*clnt->xa_destruct)(clnt, &mxa); bahdr = &mxa.recv_hdr.bind_ack_hdr; - if (mxa.ptype != MLRPC_PTYPE_BIND_ACK) - return (MLRPC_DRC_FAULT_RECEIVED_MALFORMED); + if (mxa.ptype != NDR_PTYPE_BIND_ACK) + return (NDR_DRC_FAULT_RECEIVED_MALFORMED); if (bahdr->p_result_list.n_results != 1) - return (MLRPC_DRC_FAULT_RECEIVED_MALFORMED); + return (NDR_DRC_FAULT_RECEIVED_MALFORMED); pre = &bahdr->p_result_list.p_results[0]; - if (pre->result != MLRPC_PCDR_ACCEPTANCE) - return (MLRPC_DRC_FAULT_RECEIVED_MALFORMED); + if (pre->result != NDR_PCDR_ACCEPTANCE) + return (NDR_DRC_FAULT_RECEIVED_MALFORMED); mbind->p_cont_id = pce->p_cont_id; - mbind->which_side = MLRPC_BIND_SIDE_CLIENT; - mbind->context = mcli; + mbind->which_side = NDR_BIND_SIDE_CLIENT; + mbind->clnt = clnt; mbind->service = msvc; mbind->instance_specific = 0; *ret_binding_p = mbind; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); fault_exit: - (*mcli->xa_destruct)(mcli, &mxa); + (*clnt->xa_destruct)(clnt, &mxa); return (rc); } int -mlrpc_c_call(struct mlrpc_binding *mbind, int opnum, void *params, - mlrpc_heapref_t *heapref) +ndr_clnt_call(ndr_binding_t *mbind, int opnum, void *params) { - struct mlrpc_client *mcli = mbind->context; - struct mlrpc_service *msvc = mbind->service; - struct mlrpc_xaction mxa; + ndr_client_t *clnt = mbind->clnt; + ndr_service_t *msvc = mbind->service; + ndr_xa_t mxa; ndr_request_hdr_t *reqhdr; ndr_common_header_t *rsphdr; - unsigned long recv_pdu_scan_offset; + unsigned long recv_pdu_scan_offset; int rc; - if (mlrpc_find_stub_in_svc(msvc, opnum) == NULL) - return (MLRPC_DRC_FAULT_API_OPNUM_INVALID); + if (ndr_svc_find_stub(msvc, opnum) == NULL) + return (NDR_DRC_FAULT_API_OPNUM_INVALID); bzero(&mxa, sizeof (mxa)); - mxa.ptype = MLRPC_PTYPE_REQUEST; + mxa.ptype = NDR_PTYPE_REQUEST; mxa.opnum = opnum; mxa.binding = mbind; - mlrpc_c_init_hdr(mcli, &mxa); + ndr_clnt_init_hdr(clnt, &mxa); reqhdr = &mxa.send_hdr.request_hdr; - reqhdr->common_hdr.ptype = MLRPC_PTYPE_REQUEST; + reqhdr->common_hdr.ptype = NDR_PTYPE_REQUEST; reqhdr->p_cont_id = mbind->p_cont_id; reqhdr->opnum = opnum; - rc = (*mcli->xa_init)(mcli, &mxa, heapref->heap); - if (MLRPC_DRC_IS_FAULT(rc)) + rc = (*clnt->xa_init)(clnt, &mxa); + if (NDR_DRC_IS_FAULT(rc)) return (rc); /* Reserve room for hdr */ - mxa.send_mlnds.pdu_scan_offset = sizeof (*reqhdr); + mxa.send_nds.pdu_scan_offset = sizeof (*reqhdr); - rc = mlrpc_encode_call(&mxa, params); - if (!MLRPC_DRC_IS_OK(rc)) + rc = ndr_encode_call(&mxa, params); + if (!NDR_DRC_IS_OK(rc)) goto fault_exit; - mxa.send_mlnds.pdu_scan_offset = 0; + mxa.send_nds.pdu_scan_offset = 0; /* * Now we have the PDU size, we need to set up the * frag_length and calculate the alloc_hint. */ - mxa.send_hdr.common_hdr.frag_length = mxa.send_mlnds.pdu_size; - reqhdr->alloc_hint = mxa.send_mlnds.pdu_size - + mxa.send_hdr.common_hdr.frag_length = mxa.send_nds.pdu_size; + reqhdr->alloc_hint = mxa.send_nds.pdu_size - sizeof (ndr_request_hdr_t); - rc = mlrpc_encode_pdu_hdr(&mxa); - if (MLRPC_DRC_IS_FAULT(rc)) + rc = ndr_encode_pdu_hdr(&mxa); + if (NDR_DRC_IS_FAULT(rc)) goto fault_exit; - rc = (*mcli->xa_exchange)(mcli, &mxa); - if (MLRPC_DRC_IS_FAULT(rc)) + rc = (*clnt->xa_exchange)(clnt, &mxa); + if (NDR_DRC_IS_FAULT(rc)) goto fault_exit; - rc = mlrpc_decode_pdu_hdr(&mxa); - if (MLRPC_DRC_IS_FAULT(rc)) + rc = ndr_decode_pdu_hdr(&mxa); + if (NDR_DRC_IS_FAULT(rc)) goto fault_exit; - if (mxa.ptype != MLRPC_PTYPE_RESPONSE) { - rc = MLRPC_DRC_FAULT_RECEIVED_MALFORMED; + if (mxa.ptype != NDR_PTYPE_RESPONSE) { + rc = NDR_DRC_FAULT_RECEIVED_MALFORMED; goto fault_exit; } rsphdr = &mxa.recv_hdr.common_hdr; - if (!MLRPC_IS_LAST_FRAG(rsphdr->pfc_flags)) { + if (!NDR_IS_LAST_FRAG(rsphdr->pfc_flags)) { /* * This is a multi-fragment response. * Preserve the current scan offset while getting @@ -212,59 +210,54 @@ mlrpc_c_call(struct mlrpc_binding *mbind, int opnum, void *params, * as if we had received the entire response as * a single PDU. */ - recv_pdu_scan_offset = mxa.recv_mlnds.pdu_scan_offset; + recv_pdu_scan_offset = mxa.recv_nds.pdu_scan_offset; - if (mlrpc_c_get_frags(mcli, &mxa) < 0) { - rc = MLRPC_DRC_FAULT_RECEIVED_MALFORMED; + if (ndr_clnt_get_frags(clnt, &mxa) < 0) { + rc = NDR_DRC_FAULT_RECEIVED_MALFORMED; goto fault_exit; } - mxa.recv_mlnds.pdu_scan_offset = recv_pdu_scan_offset; + mxa.recv_nds.pdu_scan_offset = recv_pdu_scan_offset; } - rc = mlrpc_decode_return(&mxa, params); - if (MLRPC_DRC_IS_FAULT(rc)) + rc = ndr_decode_return(&mxa, params); + if (NDR_DRC_IS_FAULT(rc)) goto fault_exit; - rc = (*mcli->xa_preserve)(mcli, &mxa, heapref); - if (MLRPC_DRC_IS_FAULT(rc)) - goto fault_exit; - - (*mcli->xa_destruct)(mcli, &mxa); - return (MLRPC_DRC_OK); + (*clnt->xa_preserve)(clnt, &mxa); + (*clnt->xa_destruct)(clnt, &mxa); + return (NDR_DRC_OK); fault_exit: - (*mcli->xa_destruct)(mcli, &mxa); + (*clnt->xa_destruct)(clnt, &mxa); return (rc); } void -mlrpc_c_free_heap(struct mlrpc_binding *mbind, mlrpc_heapref_t *heapref) +ndr_clnt_free_heap(ndr_client_t *clnt) { - struct mlrpc_client *mcli = mbind->context; - - (*mcli->xa_release)(mcli, heapref); + (*clnt->xa_release)(clnt); } static void -mlrpc_c_init_hdr(struct mlrpc_client *mcli, struct mlrpc_xaction *mxa) +ndr_clnt_init_hdr(ndr_client_t *clnt, ndr_xa_t *mxa) { ndr_common_header_t *hdr = &mxa->send_hdr.common_hdr; hdr->rpc_vers = 5; hdr->rpc_vers_minor = 0; - hdr->pfc_flags = MLRPC_PFC_FIRST_FRAG + MLRPC_PFC_LAST_FRAG; - hdr->packed_drep.intg_char_rep = MLRPC_REPLAB_CHAR_ASCII; + hdr->pfc_flags = NDR_PFC_FIRST_FRAG + NDR_PFC_LAST_FRAG; + hdr->packed_drep.intg_char_rep = NDR_REPLAB_CHAR_ASCII; #ifndef _BIG_ENDIAN - hdr->packed_drep.intg_char_rep |= MLRPC_REPLAB_INTG_LITTLE_ENDIAN; + hdr->packed_drep.intg_char_rep |= NDR_REPLAB_INTG_LITTLE_ENDIAN; #endif /* hdr->frag_length */ hdr->auth_length = 0; - hdr->call_id = mcli->next_call_id++; + hdr->call_id = clnt->next_call_id++; } /* - * mlrpc_c_remove_hdr + * ndr_clnt_remove_hdr * * Remove an RPC fragment header from the received data stream. * @@ -293,21 +286,21 @@ mlrpc_c_init_hdr(struct mlrpc_client *mcli, struct mlrpc_xaction *mxa) * +=====+============+=============+----+===========+ */ static void -mlrpc_c_remove_hdr(struct mlndr_stream *mlnds, int *nbytes) +ndr_clnt_remove_hdr(ndr_stream_t *nds, int *nbytes) { char *hdr; char *data; - hdr = (char *)mlnds->pdu_base_offset + mlnds->pdu_scan_offset; - data = hdr + MLRPC_RSP_HDR_SIZE; - *nbytes -= MLRPC_RSP_HDR_SIZE; + hdr = (char *)nds->pdu_base_offset + nds->pdu_scan_offset; + data = hdr + NDR_RSP_HDR_SIZE; + *nbytes -= NDR_RSP_HDR_SIZE; bcopy(data, hdr, *nbytes); - mlnds->pdu_size -= MLRPC_RSP_HDR_SIZE; + nds->pdu_size -= NDR_RSP_HDR_SIZE; } /* - * mlrpc_c_get_frags + * ndr_clnt_get_frags * * A DCE RPC message that is larger than a single fragment is transmitted * as a series of fragments: 5280 bytes for Windows NT and 4280 bytes for @@ -325,9 +318,9 @@ mlrpc_c_remove_hdr(struct mlndr_stream *mlnds, int *nbytes) * complete RPC response upon success. */ static int -mlrpc_c_get_frags(struct mlrpc_client *mcli, struct mlrpc_xaction *mxa) +ndr_clnt_get_frags(ndr_client_t *clnt, ndr_xa_t *mxa) { - struct mlndr_stream *mlnds = &mxa->recv_mlnds; + ndr_stream_t *nds = &mxa->recv_nds; ndr_common_header_t hdr; int frag_rcvd; int frag_size; @@ -337,24 +330,23 @@ mlrpc_c_get_frags(struct mlrpc_client *mcli, struct mlrpc_xaction *mxa) /* * The scan offest will be used to locate the frag header. */ - mlnds->pdu_scan_offset = mlnds->pdu_base_offset + mlnds->pdu_size; + nds->pdu_scan_offset = nds->pdu_base_offset + nds->pdu_size; do { frag_rcvd = 0; do { - if ((nbytes = (*mcli->xa_read)(mcli, mxa)) < 0) + if ((nbytes = (*clnt->xa_read)(clnt, mxa)) < 0) return (-1); if (frag_rcvd == 0) { - mlrpc_decode_frag_hdr(mlnds, &hdr); + ndr_decode_frag_hdr(nds, &hdr); - last_frag = MLRPC_IS_LAST_FRAG(hdr.pfc_flags); - frag_size = hdr.frag_length - - MLRPC_RSP_HDR_SIZE; + last_frag = NDR_IS_LAST_FRAG(hdr.pfc_flags); + frag_size = hdr.frag_length - NDR_RSP_HDR_SIZE; - mlrpc_c_remove_hdr(mlnds, &nbytes); - mlnds->pdu_scan_offset += frag_size; + ndr_clnt_remove_hdr(nds, &nbytes); + nds->pdu_scan_offset += frag_size; } frag_rcvd += nbytes; diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_heap.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_heap.c index fc250f3d45..ae10a98848 100644 --- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_heap.c +++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_heap.c @@ -24,7 +24,7 @@ */ /* - * MLRPC heap management. The heap is used for temporary storage by + * NDR heap management. The heap is used for temporary storage by * both the client and server side library routines. In order to * support the different requirements of the various RPCs, the heap * can grow dynamically if required. We start with a single block @@ -47,40 +47,41 @@ #include <sys/uio.h> #include <smbsrv/libsmb.h> -#include <smbsrv/mlrpc.h> +#include <smbsrv/libmlrpc.h> +#include <smbsrv/smb_sid.h> /* * Allocate a heap structure and the first heap block. For many RPC * operations this will be the only time we need to malloc memory * in this instance of the heap. The only point of note here is that * we put the heap management data in the first block to avoid a - * second malloc. Make sure that sizeof(mlrpc_heap_t) is smaller - * than MLRPC_HEAP_BLKSZ. + * second malloc. Make sure that sizeof(ndr_heap_t) is smaller + * than NDR_HEAP_BLKSZ. * * Note that the heap management data is at the start of the first block. * * Returns a pointer to the newly created heap, which is used like an * opaque handle with the rest of the heap management interface.. */ -mlrpc_heap_t * -mlrpc_heap_create(void) +ndr_heap_t * +ndr_heap_create(void) { - mlrpc_heap_t *heap; + ndr_heap_t *heap; char *base; - if ((base = (char *)malloc(MLRPC_HEAP_BLKSZ)) == NULL) + if ((base = (char *)malloc(NDR_HEAP_BLKSZ)) == NULL) return (NULL); /*LINTED E_BAD_PTR_CAST_ALIGN*/ - heap = (mlrpc_heap_t *)base; - bzero(heap, sizeof (mlrpc_heap_t)); + heap = (ndr_heap_t *)base; + bzero(heap, sizeof (ndr_heap_t)); - heap->iovcnt = MLRPC_HEAP_MAXIOV; + heap->iovcnt = NDR_HEAP_MAXIOV; heap->iov = heap->iovec; heap->iov->iov_base = base; - heap->iov->iov_len = sizeof (mlrpc_heap_t); - heap->top = base + MLRPC_HEAP_BLKSZ; - heap->next = base + sizeof (mlrpc_heap_t); + heap->iov->iov_len = sizeof (ndr_heap_t); + heap->top = base + NDR_HEAP_BLKSZ; + heap->next = base + sizeof (ndr_heap_t); return (heap); } @@ -94,13 +95,13 @@ mlrpc_heap_create(void) * is deleted last. */ void -mlrpc_heap_destroy(mlrpc_heap_t *heap) +ndr_heap_destroy(ndr_heap_t *heap) { int i; char *p; if (heap) { - for (i = 1; i < MLRPC_HEAP_MAXIOV; ++i) { + for (i = 1; i < NDR_HEAP_MAXIOV; ++i) { if ((p = heap->iovec[i].iov_base) != NULL) free(p); } @@ -120,14 +121,12 @@ mlrpc_heap_destroy(mlrpc_heap_t *heap) * returned. Otherwise a null pointer is returned. */ void * -mlrpc_heap_malloc(mlrpc_heap_t *heap, unsigned size) +ndr_heap_malloc(ndr_heap_t *heap, unsigned size) { char *p; - int align; int incr_size; - align = (4 - size) & 3; - size += align; + size += NDR_ALIGN4(size); if (heap == NULL || size == 0) return (NULL); @@ -138,7 +137,7 @@ mlrpc_heap_malloc(mlrpc_heap_t *heap, unsigned size) if ((heap->iovcnt == 0) || ((--heap->iovcnt) == 0)) return (NULL); - incr_size = (size < MLRPC_HEAP_BLKSZ) ? MLRPC_HEAP_BLKSZ : size; + incr_size = (size < NDR_HEAP_BLKSZ) ? NDR_HEAP_BLKSZ : size; if ((p = (char *)malloc(incr_size)) == NULL) return (NULL); @@ -158,7 +157,7 @@ mlrpc_heap_malloc(mlrpc_heap_t *heap, unsigned size) * Convenience function to do heap strdup. */ void * -mlrpc_heap_strsave(mlrpc_heap_t *heap, char *s) +ndr_heap_strdup(ndr_heap_t *heap, const char *s) { int len; void *p; @@ -172,13 +171,31 @@ mlrpc_heap_strsave(mlrpc_heap_t *heap, char *s) if ((len = strlen(s)) == 0) return (""); - if ((p = mlrpc_heap_malloc(heap, len+1)) != NULL) + if ((p = ndr_heap_malloc(heap, len+1)) != NULL) (void) strcpy((char *)p, s); return (p); } /* + * Make an ndr_mstring_t from a regular string. + */ +int +ndr_heap_mstring(ndr_heap_t *heap, const char *s, ndr_mstring_t *out) +{ + if (s == NULL || out == NULL) + return (-1); + + out->length = mts_wcequiv_strlen(s); + out->allosize = out->length + sizeof (mts_wchar_t); + + if ((out->str = ndr_heap_strdup(heap, s)) == NULL) + return (-1); + + return (0); +} + +/* * Our regular string marshalling always creates null terminated strings * but some Windows clients and servers are pedantic about the string * formats they will accept and require non-null terminated strings. @@ -188,16 +205,16 @@ mlrpc_heap_strsave(mlrpc_heap_t *heap, char *s) * aware that this is really a string. */ void -mlrpc_heap_mkvcs(mlrpc_heap_t *heap, char *s, mlrpc_vcstr_t *vc) +ndr_heap_mkvcs(ndr_heap_t *heap, char *s, ndr_vcstr_t *vc) { int mlen; vc->wclen = mts_wcequiv_strlen(s); vc->wcsize = vc->wclen; - mlen = sizeof (struct mlrpc_vcs) + vc->wcsize + sizeof (mts_wchar_t); + mlen = sizeof (ndr_vcs_t) + vc->wcsize + sizeof (mts_wchar_t); - vc->vcs = mlrpc_heap_malloc(heap, mlen); + vc->vcs = ndr_heap_malloc(heap, mlen); if (vc->vcs) { vc->vcs->vc_first_is = 0; @@ -208,22 +225,22 @@ mlrpc_heap_mkvcs(mlrpc_heap_t *heap, char *s, mlrpc_vcstr_t *vc) } void -mlrpc_heap_mkvcb(mlrpc_heap_t *heap, uint8_t *data, uint32_t datalen, - mlrpc_vcbuf_t *vcbuf) +ndr_heap_mkvcb(ndr_heap_t *heap, uint8_t *data, uint32_t datalen, + ndr_vcbuf_t *vcbuf) { int mlen; if (data == NULL || datalen == 0) { - bzero(vcbuf, sizeof (mlrpc_vcbuf_t)); + bzero(vcbuf, sizeof (ndr_vcbuf_t)); return; } vcbuf->len = datalen; vcbuf->size = datalen; - mlen = sizeof (mlrpc_vcbuf_t) + datalen; + mlen = sizeof (ndr_vcbuf_t) + datalen; - vcbuf->vcb = mlrpc_heap_malloc(heap, mlen); + vcbuf->vcb = ndr_heap_malloc(heap, mlen); if (vcbuf->vcb) { vcbuf->vcb->vc_first_is = 0; @@ -232,27 +249,48 @@ mlrpc_heap_mkvcb(mlrpc_heap_t *heap, uint8_t *data, uint32_t datalen, } } +/* + * Duplcate a SID in the heap. + */ +smb_sid_t * +ndr_heap_siddup(ndr_heap_t *heap, smb_sid_t *sid) +{ + smb_sid_t *new_sid; + unsigned size; + + if (sid == NULL) + return (NULL); + + size = smb_sid_len(sid); + + if ((new_sid = ndr_heap_malloc(heap, size)) == NULL) + return (NULL); + + bcopy(sid, new_sid, size); + return (new_sid); +} + int -mlrpc_heap_used(mlrpc_heap_t *heap) +ndr_heap_used(ndr_heap_t *heap) { int used = 0; int i; - for (i = 0; i < MLRPC_HEAP_MAXIOV; ++i) + for (i = 0; i < NDR_HEAP_MAXIOV; ++i) used += heap->iovec[i].iov_len; return (used); } int -mlrpc_heap_avail(mlrpc_heap_t *heap) +ndr_heap_avail(ndr_heap_t *heap) { int avail; int count; count = (heap->iovcnt == 0) ? 0 : (heap->iovcnt - 1); - avail = count * MLRPC_HEAP_BLKSZ; + avail = count * NDR_HEAP_BLKSZ; avail += (heap->top - heap->next); return (avail); diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c index 8aff410b2e..478cd128a2 100644 --- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c +++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c @@ -27,62 +27,61 @@ #include <sys/param.h> #include <smbsrv/libsmb.h> -#include <smbsrv/ndr.h> -#include <smbsrv/mlrpc.h> +#include <smbsrv/libmlrpc.h> #ifdef _BIG_ENDIAN -static const int mlrpc_native_byte_order = MLRPC_REPLAB_INTG_BIG_ENDIAN; +static const int ndr_native_byte_order = NDR_REPLAB_INTG_BIG_ENDIAN; #else -static const int mlrpc_native_byte_order = MLRPC_REPLAB_INTG_LITTLE_ENDIAN; +static const int ndr_native_byte_order = NDR_REPLAB_INTG_LITTLE_ENDIAN; #endif int -mlrpc_encode_decode_common(struct mlrpc_xaction *mxa, int mode, unsigned opnum, - struct ndr_typeinfo *ti, void *datum) +ndr_encode_decode_common(ndr_xa_t *mxa, int mode, unsigned opnum, + ndr_typeinfo_t *ti, void *datum) { - struct mlndr_stream *mlnds; - int m_op = NDR_MODE_TO_M_OP(mode); - int rc; + ndr_stream_t *nds; + int m_op = NDR_MODE_TO_M_OP(mode); + int rc; if (m_op == NDR_M_OP_MARSHALL) - mlnds = &mxa->send_mlnds; + nds = &mxa->send_nds; else - mlnds = &mxa->recv_mlnds; + nds = &mxa->recv_nds; /* - * Make sure that mlnds is in the correct mode + * Make sure that nds is in the correct mode */ - if (!NDR_MODE_MATCH(mlnds, mode)) - return (MLRPC_DRC_FAULT_MODE_MISMATCH); + if (!NDR_MODE_MATCH(nds, mode)) + return (NDR_DRC_FAULT_MODE_MISMATCH); /* * Perform the (un)marshalling */ - if (mlndo_operation(mlnds, ti, opnum, datum)) - return (MLRPC_DRC_OK); + if (ndo_operation(nds, ti, opnum, datum)) + return (NDR_DRC_OK); - switch (mlnds->error) { + switch (nds->error) { case NDR_ERR_MALLOC_FAILED: - rc = MLRPC_DRC_FAULT_OUT_OF_MEMORY; + rc = NDR_DRC_FAULT_OUT_OF_MEMORY; break; case NDR_ERR_SWITCH_VALUE_INVALID: - rc = MLRPC_DRC_FAULT_PARAM_0_INVALID; + rc = NDR_DRC_FAULT_PARAM_0_INVALID; break; case NDR_ERR_UNDERFLOW: - rc = MLRPC_DRC_FAULT_RECEIVED_RUNT; + rc = NDR_DRC_FAULT_RECEIVED_RUNT; break; case NDR_ERR_GROW_FAILED: - rc = MLRPC_DRC_FAULT_ENCODE_TOO_BIG; + rc = NDR_DRC_FAULT_ENCODE_TOO_BIG; break; default: if (m_op == NDR_M_OP_MARSHALL) - rc = MLRPC_DRC_FAULT_ENCODE_FAILED; + rc = NDR_DRC_FAULT_ENCODE_FAILED; else - rc = MLRPC_DRC_FAULT_DECODE_FAILED; + rc = NDR_DRC_FAULT_DECODE_FAILED; break; } @@ -90,167 +89,167 @@ mlrpc_encode_decode_common(struct mlrpc_xaction *mxa, int mode, unsigned opnum, } int -mlrpc_decode_call(struct mlrpc_xaction *mxa, void *params) +ndr_decode_call(ndr_xa_t *mxa, void *params) { int rc; - rc = mlrpc_encode_decode_common(mxa, NDR_MODE_CALL_RECV, + rc = ndr_encode_decode_common(mxa, NDR_MODE_CALL_RECV, mxa->opnum, mxa->binding->service->interface_ti, params); - return (rc + MLRPC_PTYPE_REQUEST); + return (rc + NDR_PTYPE_REQUEST); } int -mlrpc_encode_return(struct mlrpc_xaction *mxa, void *params) +ndr_encode_return(ndr_xa_t *mxa, void *params) { int rc; - rc = mlrpc_encode_decode_common(mxa, NDR_MODE_RETURN_SEND, + rc = ndr_encode_decode_common(mxa, NDR_MODE_RETURN_SEND, mxa->opnum, mxa->binding->service->interface_ti, params); - return (rc + MLRPC_PTYPE_RESPONSE); + return (rc + NDR_PTYPE_RESPONSE); } int -mlrpc_encode_call(struct mlrpc_xaction *mxa, void *params) +ndr_encode_call(ndr_xa_t *mxa, void *params) { int rc; - rc = mlrpc_encode_decode_common(mxa, NDR_MODE_CALL_SEND, + rc = ndr_encode_decode_common(mxa, NDR_MODE_CALL_SEND, mxa->opnum, mxa->binding->service->interface_ti, params); - return (rc + MLRPC_PTYPE_REQUEST); + return (rc + NDR_PTYPE_REQUEST); } int -mlrpc_decode_return(struct mlrpc_xaction *mxa, void *params) +ndr_decode_return(ndr_xa_t *mxa, void *params) { int rc; - rc = mlrpc_encode_decode_common(mxa, NDR_MODE_RETURN_RECV, + rc = ndr_encode_decode_common(mxa, NDR_MODE_RETURN_RECV, mxa->opnum, mxa->binding->service->interface_ti, params); - return (rc + MLRPC_PTYPE_RESPONSE); + return (rc + NDR_PTYPE_RESPONSE); } int -mlrpc_decode_pdu_hdr(struct mlrpc_xaction *mxa) +ndr_decode_pdu_hdr(ndr_xa_t *mxa) { - ndr_common_header_t *hdr = &mxa->recv_hdr.common_hdr; - struct mlndr_stream *mlnds = &mxa->recv_mlnds; + ndr_common_header_t *hdr = &mxa->recv_hdr.common_hdr; + ndr_stream_t *nds = &mxa->recv_nds; int ptype; int rc; int charset; int byte_order; - if (mlnds->m_op != NDR_M_OP_UNMARSHALL) - return (MLRPC_DRC_FAULT_MODE_MISMATCH + 0xFF); + if (nds->m_op != NDR_M_OP_UNMARSHALL) + return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_MODE_MISMATCH)); /* * All PDU headers are at least this big */ - rc = MLNDS_GROW_PDU(mlnds, sizeof (ndr_common_header_t), 0); + rc = NDS_GROW_PDU(nds, sizeof (ndr_common_header_t), 0); if (!rc) - return (MLRPC_DRC_FAULT_RECEIVED_RUNT + 0xFF); + return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_RECEIVED_RUNT)); /* * Peek at the first eight bytes to figure out what we're doing. */ - rc = MLNDS_GET_PDU(mlnds, 0, 8, (char *)hdr, 0, 0); + rc = NDS_GET_PDU(nds, 0, 8, (char *)hdr, 0, 0); if (!rc) - return (MLRPC_DRC_FAULT_DECODE_FAILED + 0xFF); + return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_DECODE_FAILED)); /* * Verify the protocol version. */ if ((hdr->rpc_vers != 5) || (hdr->rpc_vers_minor != 0)) - return (MLRPC_DRC_FAULT_DECODE_FAILED + 0xFF); + return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_DECODE_FAILED)); /* * Check for ASCII as the character set. This is an ASCII * versus EBCDIC option and has nothing to do with Unicode. */ - charset = hdr->packed_drep.intg_char_rep & MLRPC_REPLAB_CHAR_MASK; - if (charset != MLRPC_REPLAB_CHAR_ASCII) - return (MLRPC_DRC_FAULT_DECODE_FAILED + 0xFF); + 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)); /* * Set the byte swap flag if the PDU byte-order * is different from the local byte-order. */ - byte_order = hdr->packed_drep.intg_char_rep & MLRPC_REPLAB_INTG_MASK; - mlnds->swap = (byte_order != mlrpc_native_byte_order) ? 1 : 0; + byte_order = hdr->packed_drep.intg_char_rep & NDR_REPLAB_INTG_MASK; + nds->swap = (byte_order != ndr_native_byte_order) ? 1 : 0; ptype = hdr->ptype; - if (ptype == MLRPC_PTYPE_REQUEST && - (hdr->pfc_flags & MLRPC_PFC_OBJECT_UUID) != 0) { - ptype = MLRPC_PTYPE_REQUEST_WITH; /* fake for sizing */ + if (ptype == NDR_PTYPE_REQUEST && + (hdr->pfc_flags & NDR_PFC_OBJECT_UUID) != 0) { + ptype = NDR_PTYPE_REQUEST_WITH; /* fake for sizing */ } mxa->ptype = hdr->ptype; - rc = mlrpc_encode_decode_common(mxa, - NDR_M_OP_AND_DIR_TO_MODE(mlnds->m_op, mlnds->dir), + rc = ndr_encode_decode_common(mxa, + NDR_M_OP_AND_DIR_TO_MODE(nds->m_op, nds->dir), ptype, &TYPEINFO(ndr_hdr), hdr); - return (rc + 0xFF); + return (NDR_DRC_PTYPE_RPCHDR(rc)); } /* - * Decode an RPC fragment header. Use mlrpc_decode_pdu_hdr() to process + * Decode an RPC fragment header. Use ndr_decode_pdu_hdr() to process * the first fragment header then this function to process additional * fragment headers. */ void -mlrpc_decode_frag_hdr(struct mlndr_stream *mlnds, ndr_common_header_t *hdr) +ndr_decode_frag_hdr(ndr_stream_t *nds, ndr_common_header_t *hdr) { ndr_common_header_t *tmp; uint8_t *pdu; int byte_order; - pdu = (uint8_t *)mlnds->pdu_base_offset + mlnds->pdu_scan_offset; - bcopy(pdu, hdr, MLRPC_RSP_HDR_SIZE); + pdu = (uint8_t *)nds->pdu_base_offset + nds->pdu_scan_offset; + bcopy(pdu, hdr, NDR_RSP_HDR_SIZE); /* * Swap non-byte fields if the PDU byte-order * is different from the local byte-order. */ - byte_order = hdr->packed_drep.intg_char_rep & MLRPC_REPLAB_INTG_MASK; + byte_order = hdr->packed_drep.intg_char_rep & NDR_REPLAB_INTG_MASK; - if (byte_order != mlrpc_native_byte_order) { + if (byte_order != ndr_native_byte_order) { /*LINTED E_BAD_PTR_CAST_ALIGN*/ tmp = (ndr_common_header_t *)pdu; - mlnds_bswap(&tmp->frag_length, &hdr->frag_length, + nds_bswap(&tmp->frag_length, &hdr->frag_length, sizeof (WORD)); - mlnds_bswap(&tmp->auth_length, &hdr->auth_length, + nds_bswap(&tmp->auth_length, &hdr->auth_length, sizeof (WORD)); - mlnds_bswap(&tmp->call_id, &hdr->call_id, sizeof (DWORD)); + nds_bswap(&tmp->call_id, &hdr->call_id, sizeof (DWORD)); } } int -mlrpc_encode_pdu_hdr(struct mlrpc_xaction *mxa) +ndr_encode_pdu_hdr(ndr_xa_t *mxa) { - ndr_common_header_t *hdr = &mxa->send_hdr.common_hdr; - struct mlndr_stream *mlnds = &mxa->send_mlnds; + ndr_common_header_t *hdr = &mxa->send_hdr.common_hdr; + ndr_stream_t *nds = &mxa->send_nds; int ptype; int rc; - if (mlnds->m_op != NDR_M_OP_MARSHALL) - return (MLRPC_DRC_FAULT_MODE_MISMATCH + 0xFF); + if (nds->m_op != NDR_M_OP_MARSHALL) + return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_MODE_MISMATCH)); ptype = hdr->ptype; - if (ptype == MLRPC_PTYPE_REQUEST && - (hdr->pfc_flags & MLRPC_PFC_OBJECT_UUID) != 0) { - ptype = MLRPC_PTYPE_REQUEST_WITH; /* fake for sizing */ + if (ptype == NDR_PTYPE_REQUEST && + (hdr->pfc_flags & NDR_PFC_OBJECT_UUID) != 0) { + ptype = NDR_PTYPE_REQUEST_WITH; /* fake for sizing */ } - rc = mlrpc_encode_decode_common(mxa, - NDR_M_OP_AND_DIR_TO_MODE(mlnds->m_op, mlnds->dir), + rc = ndr_encode_decode_common(mxa, + NDR_M_OP_AND_DIR_TO_MODE(nds->m_op, nds->dir), ptype, &TYPEINFO(ndr_hdr), hdr); - return (rc + 0xFF); + return (NDR_DRC_PTYPE_RPCHDR(rc)); } /* @@ -263,12 +262,12 @@ extern struct ndr_typeinfo ndt__uchar; extern struct ndr_typeinfo ndt__ushort; extern struct ndr_typeinfo ndt__ulong; -int mlndr__ndr_bind_ack_hdr(struct ndr_reference *encl_ref); -struct ndr_typeinfo ndt__ndr_bind_ack_hdr = { +int ndr__ndr_bind_ack_hdr(ndr_ref_t *encl_ref); +ndr_typeinfo_t ndt__ndr_bind_ack_hdr = { 1, /* NDR version */ 3, /* alignment */ NDR_F_STRUCT, /* flags */ - mlndr__ndr_bind_ack_hdr, /* ndr_func */ + ndr__ndr_bind_ack_hdr, /* ndr_func */ 68, /* pdu_size_fixed_part */ 0, /* pdu_size_variable_part */ 68, /* c_size_fixed_part */ @@ -279,12 +278,12 @@ struct ndr_typeinfo ndt__ndr_bind_ack_hdr = { * [_no_reorder] */ int -mlndr__ndr_bind_ack_hdr(struct ndr_reference *encl_ref) +ndr__ndr_bind_ack_hdr(ndr_ref_t *encl_ref) { - struct mlndr_stream *mlnds = encl_ref->stream; + ndr_stream_t *nds = encl_ref->stream; struct ndr_bind_ack_hdr *val = /*LINTED E_BAD_PTR_CAST_ALIGN*/ (struct ndr_bind_ack_hdr *)encl_ref->datum; - struct ndr_reference myref; + ndr_ref_t myref; unsigned long offset; bzero(&myref, sizeof (myref)); @@ -301,7 +300,7 @@ mlndr__ndr_bind_ack_hdr(struct ndr_reference *encl_ref) /* port any is the conformant culprit */ offset = 24UL; - switch (mlnds->m_op) { + switch (nds->m_op) { case NDR_M_OP_MARSHALL: val->sec_addr.length = strlen((char *)val->sec_addr.port_spec) + 1; @@ -321,9 +320,9 @@ mlndr__ndr_bind_ack_hdr(struct ndr_reference *encl_ref) offset += 2; offset += val->sec_addr.length; - offset += (4 - offset) & 3; + offset += NDR_ALIGN4(offset); - NDR_MEMBER(_mlrpc_p_result_list, p_result_list, offset); + NDR_MEMBER(_ndr_p_result_list, p_result_list, offset); return (1); } @@ -331,7 +330,7 @@ mlndr__ndr_bind_ack_hdr(struct ndr_reference *encl_ref) * Assume a single presentation context element in the result list. */ unsigned -mlrpc_bind_ack_hdr_size(struct mlrpc_xaction *mxa) +ndr_bind_ack_hdr_size(ndr_xa_t *mxa) { ndr_bind_ack_hdr_t *bahdr = &mxa->send_hdr.bind_ack_hdr; unsigned offset; @@ -344,8 +343,8 @@ mlrpc_bind_ack_hdr_size(struct mlrpc_xaction *mxa) offset += 2; offset += length; - offset += (4 - offset) & 3; - offset += sizeof (mlrpc_p_result_list_t); + offset += NDR_ALIGN4(offset); + offset += sizeof (ndr_p_result_list_t); return (offset); } @@ -355,12 +354,12 @@ mlrpc_bind_ack_hdr_size(struct mlrpc_xaction *mxa) * Alter context response headers have an interior conformant array, * which is inconsistent with IDL/NDR rules. */ -int mlndr__ndr_alter_context_rsp_hdr(struct ndr_reference *encl_ref); -struct ndr_typeinfo ndt__ndr_alter_context_rsp_hdr = { +int ndr__ndr_alter_context_rsp_hdr(ndr_ref_t *encl_ref); +ndr_typeinfo_t ndt__ndr_alter_context_rsp_hdr = { 1, /* NDR version */ 3, /* alignment */ NDR_F_STRUCT, /* flags */ - mlndr__ndr_alter_context_rsp_hdr, /* ndr_func */ + ndr__ndr_alter_context_rsp_hdr, /* ndr_func */ 56, /* pdu_size_fixed_part */ 0, /* pdu_size_variable_part */ 56, /* c_size_fixed_part */ @@ -371,12 +370,12 @@ struct ndr_typeinfo ndt__ndr_alter_context_rsp_hdr = { * [_no_reorder] */ int -mlndr__ndr_alter_context_rsp_hdr(struct ndr_reference *encl_ref) +ndr__ndr_alter_context_rsp_hdr(ndr_ref_t *encl_ref) { - struct mlndr_stream *mlnds = encl_ref->stream; + ndr_stream_t *nds = encl_ref->stream; ndr_alter_context_rsp_hdr_t *val = /*LINTED E_BAD_PTR_CAST_ALIGN*/ (ndr_alter_context_rsp_hdr_t *)encl_ref->datum; - struct ndr_reference myref; + ndr_ref_t myref; unsigned long offset; bzero(&myref, sizeof (myref)); @@ -392,7 +391,7 @@ mlndr__ndr_alter_context_rsp_hdr(struct ndr_reference *encl_ref) offset = 24UL; /* offset of sec_addr */ - switch (mlnds->m_op) { + switch (nds->m_op) { case NDR_M_OP_MARSHALL: val->sec_addr.length = 0; break; @@ -410,9 +409,9 @@ mlndr__ndr_alter_context_rsp_hdr(struct ndr_reference *encl_ref) offset+2UL, val->sec_addr.length); offset += 2; /* sizeof (sec_addr.length) */ - offset += (4 - offset) & 3; + offset += NDR_ALIGN4(offset); - NDR_MEMBER(_mlrpc_p_result_list, p_result_list, offset); + NDR_MEMBER(_ndr_p_result_list, p_result_list, offset); return (1); } @@ -420,13 +419,13 @@ mlndr__ndr_alter_context_rsp_hdr(struct ndr_reference *encl_ref) * Assume a single presentation context element in the result list. */ unsigned -mlrpc_alter_context_rsp_hdr_size(void) +ndr_alter_context_rsp_hdr_size(void) { unsigned offset; offset = 24UL; /* offset of sec_addr */ offset += 2; /* sizeof (sec_addr.length) */ - offset += (4 - offset) & 3; - offset += sizeof (mlrpc_p_result_list_t); + offset += NDR_ALIGN4(offset); + offset += sizeof (ndr_p_result_list_t); return (offset); } diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_ops.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_ops.c index 4380d5da6c..fcf40fe73b 100644 --- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_ops.c +++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_ops.c @@ -23,19 +23,17 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* - * MLRPC server-side NDR stream (PDU) operations. Stream operations - * should return TRUE (non-zero) on success or FALSE (zero or a null - * pointer) on failure. When an operation returns FALSE, including - * mlndo_malloc() returning NULL, it should set the mlnds->error to - * indicate what went wrong. + * Server-side NDR stream (PDU) operations. Stream operations should + * return TRUE (non-zero) on success or FALSE (zero or a null pointer) + * on failure. When an operation returns FALSE, including ndo_malloc() + * returning NULL, it should set the nds->error to indicate what went + * wrong. * - * When available, the relevant ndr_reference is passed to the + * When available, the relevant ndr reference is passed to the * operation but keep in mind that it may be a null pointer. * - * Functions mlndo_get_pdu(), mlndo_put_pdu(), and mlndo_pad_pdu() + * Functions ndo_get_pdu(), ndo_put_pdu(), and ndo_pad_pdu() * must never grow the PDU data. A request for out-of-bounds data is * an error. The swap_bytes flag is 1 if NDR knows that the byte- * order in the PDU is different from the local system. @@ -51,8 +49,7 @@ #include <assert.h> #include <smbsrv/libsmb.h> -#include <smbsrv/mlrpc.h> -#include <smbsrv/ndr.h> +#include <smbsrv/libmlrpc.h> #include <smbsrv/ntstatus.h> #define NDOBUFSZ 128 @@ -63,41 +60,39 @@ (((N) + NDR_PDU_BLOCK_SIZE) & ~NDR_PDU_BLOCK_MASK) #define NDR_PDU_MAX_SIZE (64*1024*1024) -static char *mlndo_malloc(struct mlndr_stream *, unsigned, - struct ndr_reference *); -static int mlndo_free(struct mlndr_stream *, char *, struct ndr_reference *); -static int mlndo_grow_pdu(struct mlndr_stream *, unsigned long, - struct ndr_reference *); -static int mlndo_pad_pdu(struct mlndr_stream *, unsigned long, unsigned long, - struct ndr_reference *); -static int mlndo_get_pdu(struct mlndr_stream *, unsigned long, unsigned long, - char *, int, struct ndr_reference *); -static int mlndo_put_pdu(struct mlndr_stream *, unsigned long, unsigned long, - char *, int, struct ndr_reference *); -static void mlndo_tattle(struct mlndr_stream *, char *, struct ndr_reference *); -static void mlndo_tattle_error(struct mlndr_stream *, struct ndr_reference *); -static int mlndo_reset(struct mlndr_stream *); -static void mlndo_destruct(struct mlndr_stream *); -static void mlndo_hexfmt(uint8_t *, int, int, char *, int); +static char *ndo_malloc(ndr_stream_t *, unsigned, ndr_ref_t *); +static int ndo_free(ndr_stream_t *, char *, ndr_ref_t *); +static int ndo_grow_pdu(ndr_stream_t *, unsigned long, ndr_ref_t *); +static int ndo_pad_pdu(ndr_stream_t *, unsigned long, unsigned long, + ndr_ref_t *); +static int ndo_get_pdu(ndr_stream_t *, unsigned long, unsigned long, + char *, int, ndr_ref_t *); +static int ndo_put_pdu(ndr_stream_t *, unsigned long, unsigned long, + char *, int, ndr_ref_t *); +static void ndo_tattle(ndr_stream_t *, char *, ndr_ref_t *); +static void ndo_tattle_error(ndr_stream_t *, ndr_ref_t *); +static int ndo_reset(ndr_stream_t *); +static void ndo_destruct(ndr_stream_t *); +static void ndo_hexfmt(uint8_t *, int, int, char *, int); /* - * The mlndr stream operations table. + * The ndr stream operations table. */ -static struct mlndr_stream_ops mlnds_ops = { - mlndo_malloc, - mlndo_free, - mlndo_grow_pdu, - mlndo_pad_pdu, - mlndo_get_pdu, - mlndo_put_pdu, - mlndo_tattle, - mlndo_tattle_error, - mlndo_reset, - mlndo_destruct +static ndr_stream_ops_t nds_ops = { + ndo_malloc, + ndo_free, + ndo_grow_pdu, + ndo_pad_pdu, + ndo_get_pdu, + ndo_put_pdu, + ndo_tattle, + ndo_tattle_error, + ndo_reset, + ndo_destruct }; /* - * mlnds_bswap + * nds_bswap * * Copies len bytes from src to dst such that dst contains the bytes * from src in reverse order. @@ -106,7 +101,7 @@ static struct mlndr_stream_ops mlnds_ops = { * length must be non-zero and a power of 2. */ void -mlnds_bswap(void *srcbuf, void *dstbuf, size_t len) +nds_bswap(void *srcbuf, void *dstbuf, size_t len) { uint8_t *src = (uint8_t *)srcbuf; uint8_t *dst = (uint8_t *)dstbuf; @@ -120,45 +115,45 @@ mlnds_bswap(void *srcbuf, void *dstbuf, size_t len) } /* - * mlnds_initialize + * nds_initialize * * Initialize a stream. Sets up the PDU parameters and assigns the stream * operations and the reference to the heap. An external heap is provided * to the stream, rather than each stream creating its own heap. */ void -mlnds_initialize(struct mlndr_stream *mlnds, unsigned pdu_size_hint, - int composite_op, mlrpc_heap_t *heap) +nds_initialize(ndr_stream_t *nds, unsigned pdu_size_hint, + int composite_op, ndr_heap_t *heap) { unsigned size; - assert(mlnds); + assert(nds); assert(heap); - bzero(mlnds, sizeof (*mlnds)); + bzero(nds, sizeof (*nds)); if (pdu_size_hint > NDR_PDU_MAX_SIZE) return; size = (pdu_size_hint == 0) ? NDR_PDU_BLOCK_SIZE : pdu_size_hint; - mlnds->pdu_base_addr = malloc(size); - assert(mlnds->pdu_base_addr); + nds->pdu_base_addr = malloc(size); + assert(nds->pdu_base_addr); - mlnds->pdu_max_size = size; - mlnds->pdu_size = 0; - mlnds->pdu_base_offset = (unsigned long)mlnds->pdu_base_addr; + nds->pdu_max_size = size; + nds->pdu_size = 0; + nds->pdu_base_offset = (unsigned long)nds->pdu_base_addr; - mlnds->mlndo = &mlnds_ops; - mlnds->heap = (struct mlrpc_heap *)heap; + nds->ndo = &nds_ops; + nds->heap = (struct ndr_heap *)heap; - mlnds->m_op = composite_op & 0x0F; - mlnds->dir = composite_op & 0xF0; + nds->m_op = NDR_MODE_TO_M_OP(composite_op); + nds->dir = NDR_MODE_TO_DIR(composite_op); - mlnds->outer_queue_tailp = &mlnds->outer_queue_head; + nds->outer_queue_tailp = &nds->outer_queue_head; } void -mlnds_finalize(struct mlndr_stream *mlnds, ndr_fraglist_t *frags) +nds_finalize(ndr_stream_t *nds, ndr_fraglist_t *frags) { iovec_t *iov; ndr_frag_t *frag; @@ -166,20 +161,20 @@ mlnds_finalize(struct mlndr_stream *mlnds, ndr_fraglist_t *frags) bzero(frags, sizeof (ndr_fraglist_t)); - for (frag = mlnds->frags.head; frag; frag = frag->next) + for (frag = nds->frags.head; frag; frag = frag->next) size += frag->len; if (size == 0 || size >= NDR_PDU_MAX_SIZE) return; - frags->iov = malloc(mlnds->frags.nfrag * sizeof (iovec_t)); + frags->iov = malloc(nds->frags.nfrag * sizeof (iovec_t)); if (frags->iov == NULL) return; - frags->head = mlnds->frags.head; - frags->tail = mlnds->frags.tail; - frags->nfrag = mlnds->frags.nfrag; - bzero(&mlnds->frags, sizeof (ndr_fraglist_t)); + frags->head = nds->frags.head; + frags->tail = nds->frags.tail; + frags->nfrag = nds->frags.nfrag; + bzero(&nds->frags, sizeof (ndr_fraglist_t)); frags->uio.uio_iov = frags->iov; frags->uio.uio_iovcnt = frags->nfrag; @@ -196,44 +191,43 @@ mlnds_finalize(struct mlndr_stream *mlnds, ndr_fraglist_t *frags) } /* - * mlnds_destruct + * nds_destruct * * Destroy a stream. This is an external interface to provide access to * the stream's destruct operation. */ void -mlnds_destruct(struct mlndr_stream *mlnds) +nds_destruct(ndr_stream_t *nds) { - MLNDS_DESTRUCT(mlnds); + NDS_DESTRUCT(nds); } /* - * mlndo_malloc + * ndo_malloc * * Allocate memory from the stream heap. */ /*ARGSUSED*/ static char * -mlndo_malloc(struct mlndr_stream *mlnds, unsigned len, - struct ndr_reference *ref) +ndo_malloc(ndr_stream_t *nds, unsigned len, ndr_ref_t *ref) { - return (mlrpc_heap_malloc((mlrpc_heap_t *)mlnds->heap, len)); + return (ndr_heap_malloc((ndr_heap_t *)nds->heap, len)); } /* - * mlndo_free + * ndo_free * * Always succeeds: cannot free individual stream allocations. */ /*ARGSUSED*/ static int -mlndo_free(struct mlndr_stream *mlnds, char *p, struct ndr_reference *ref) +ndo_free(ndr_stream_t *nds, char *p, ndr_ref_t *ref) { return (1); } /* - * mlndo_grow_pdu + * ndo_grow_pdu * * This is the only place that should change the size of the PDU. If the * desired offset is beyond the current PDU size, we realloc the PDU @@ -244,15 +238,14 @@ mlndo_free(struct mlndr_stream *mlnds, char *p, struct ndr_reference *ref) * Returns 1 to indicate success. Otherwise 0 to indicate failure. */ static int -mlndo_grow_pdu(struct mlndr_stream *mlnds, unsigned long want_end_offset, - struct ndr_reference *ref) +ndo_grow_pdu(ndr_stream_t *nds, unsigned long want_end_offset, ndr_ref_t *ref) { unsigned char *pdu_addr; unsigned pdu_max_size; - mlndo_printf(mlnds, ref, "grow %d", want_end_offset); + ndo_printf(nds, ref, "grow %d", want_end_offset); - pdu_max_size = mlnds->pdu_max_size; + pdu_max_size = nds->pdu_max_size; if (want_end_offset > pdu_max_size) { pdu_max_size = NDR_PDU_ALIGN(want_end_offset); @@ -260,36 +253,36 @@ mlndo_grow_pdu(struct mlndr_stream *mlnds, unsigned long want_end_offset, if (pdu_max_size >= NDR_PDU_MAX_SIZE) return (0); - pdu_addr = realloc(mlnds->pdu_base_addr, pdu_max_size); + pdu_addr = realloc(nds->pdu_base_addr, pdu_max_size); if (pdu_addr == 0) return (0); - mlnds->pdu_max_size = pdu_max_size; - mlnds->pdu_base_addr = pdu_addr; - mlnds->pdu_base_offset = (unsigned long)pdu_addr; + nds->pdu_max_size = pdu_max_size; + nds->pdu_base_addr = pdu_addr; + nds->pdu_base_offset = (unsigned long)pdu_addr; } - mlnds->pdu_size = want_end_offset; + nds->pdu_size = want_end_offset; return (1); } static int -mlndo_pad_pdu(struct mlndr_stream *mlnds, unsigned long pdu_offset, - unsigned long n_bytes, struct ndr_reference *ref) +ndo_pad_pdu(ndr_stream_t *nds, unsigned long pdu_offset, + unsigned long n_bytes, ndr_ref_t *ref) { unsigned char *data; - data = (unsigned char *)mlnds->pdu_base_offset; + data = (unsigned char *)nds->pdu_base_offset; data += pdu_offset; - mlndo_printf(mlnds, ref, "pad %d@%-3d", n_bytes, pdu_offset); + ndo_printf(nds, ref, "pad %d@%-3d", n_bytes, pdu_offset); bzero(data, n_bytes); return (1); } /* - * mlndo_get_pdu + * ndo_get_pdu * * The swap flag is 1 if NDR knows that the byte-order in the PDU * is different from the local system. @@ -297,50 +290,48 @@ mlndo_pad_pdu(struct mlndr_stream *mlnds, unsigned long pdu_offset, * Returns 1 on success or 0 to indicate failure. */ static int -mlndo_get_pdu(struct mlndr_stream *mlnds, unsigned long pdu_offset, - unsigned long n_bytes, char *buf, int swap_bytes, - struct ndr_reference *ref) +ndo_get_pdu(ndr_stream_t *nds, unsigned long pdu_offset, + unsigned long n_bytes, char *buf, int swap_bytes, ndr_ref_t *ref) { unsigned char *data; char hexbuf[NDOBUFSZ]; - data = (unsigned char *)mlnds->pdu_base_offset; + data = (unsigned char *)nds->pdu_base_offset; data += pdu_offset; - mlndo_hexfmt(data, n_bytes, swap_bytes, hexbuf, NDOBUFSZ); + ndo_hexfmt(data, n_bytes, swap_bytes, hexbuf, NDOBUFSZ); - mlndo_printf(mlnds, ref, "get %d@%-3d = %s", + ndo_printf(nds, ref, "get %d@%-3d = %s", n_bytes, pdu_offset, hexbuf); if (!swap_bytes) bcopy(data, buf, n_bytes); else - mlnds_bswap(data, (unsigned char *)buf, n_bytes); + nds_bswap(data, (unsigned char *)buf, n_bytes); return (1); } /* - * mlndo_put_pdu + * ndo_put_pdu * * This is a receiver makes right protocol. So we do not need * to be concerned about the byte-order of an outgoing PDU. */ /*ARGSUSED*/ static int -mlndo_put_pdu(struct mlndr_stream *mlnds, unsigned long pdu_offset, - unsigned long n_bytes, char *buf, int swap_bytes, - struct ndr_reference *ref) +ndo_put_pdu(ndr_stream_t *nds, unsigned long pdu_offset, + unsigned long n_bytes, char *buf, int swap_bytes, ndr_ref_t *ref) { unsigned char *data; char hexbuf[NDOBUFSZ]; - data = (unsigned char *)mlnds->pdu_base_offset; + data = (unsigned char *)nds->pdu_base_offset; data += pdu_offset; - mlndo_hexfmt((uint8_t *)buf, n_bytes, 0, hexbuf, NDOBUFSZ); + ndo_hexfmt((uint8_t *)buf, n_bytes, 0, hexbuf, NDOBUFSZ); - mlndo_printf(mlnds, ref, "put %d@%-3d = %s", + ndo_printf(nds, ref, "put %d@%-3d = %s", n_bytes, pdu_offset, hexbuf); bcopy(buf, data, n_bytes); @@ -348,89 +339,90 @@ mlndo_put_pdu(struct mlndr_stream *mlnds, unsigned long pdu_offset, } static void -mlndo_tattle(struct mlndr_stream *mlnds, char *what, - struct ndr_reference *ref) +ndo_tattle(ndr_stream_t *nds, char *what, ndr_ref_t *ref) { - mlndo_printf(mlnds, ref, what); + ndo_printf(nds, ref, what); } static void -mlndo_tattle_error(struct mlndr_stream *mlnds, struct ndr_reference *ref) +ndo_tattle_error(ndr_stream_t *nds, ndr_ref_t *ref) { unsigned char *data; char hexbuf[NDOBUFSZ]; - data = (unsigned char *)mlnds->pdu_base_offset; + data = (unsigned char *)nds->pdu_base_offset; if (ref) data += ref->pdu_offset; else - data += mlnds->pdu_scan_offset; + data += nds->pdu_scan_offset; - mlndo_hexfmt(data, 16, 0, hexbuf, NDOBUFSZ); + ndo_hexfmt(data, 16, 0, hexbuf, NDOBUFSZ); - mlndo_printf(mlnds, ref, "ERROR=%d REF=%d OFFSET=%d SIZE=%d/%d", - mlnds->error, mlnds->error_ref, mlnds->pdu_scan_offset, - mlnds->pdu_size, mlnds->pdu_max_size); - mlndo_printf(mlnds, ref, " %s", hexbuf); + ndo_printf(nds, ref, "ERROR=%d REF=%d OFFSET=%d SIZE=%d/%d", + nds->error, nds->error_ref, nds->pdu_scan_offset, + nds->pdu_size, nds->pdu_max_size); + ndo_printf(nds, ref, " %s", hexbuf); } /* - * mlndo_reset + * ndo_reset * * Reset a stream: zap the outer_queue. We don't need to tamper * with the stream heap: it's handled externally to the stream. */ static int -mlndo_reset(struct mlndr_stream *mlnds) +ndo_reset(ndr_stream_t *nds) { - mlndo_printf(mlnds, 0, "reset"); + ndo_printf(nds, 0, "reset"); - mlnds->pdu_size = 0; - mlnds->pdu_scan_offset = 0; - mlnds->outer_queue_head = 0; - mlnds->outer_current = 0; - mlnds->outer_queue_tailp = &mlnds->outer_queue_head; + nds->pdu_size = 0; + nds->pdu_scan_offset = 0; + nds->outer_queue_head = 0; + nds->outer_current = 0; + nds->outer_queue_tailp = &nds->outer_queue_head; return (1); } /* - * mlndo_destruct + * ndo_destruct * * Destruct a stream: zap the outer_queue. * Note: heap management (creation/destruction) is external to the stream. */ static void -mlndo_destruct(struct mlndr_stream *mlnds) +ndo_destruct(ndr_stream_t *nds) { ndr_frag_t *frag; - mlndo_printf(mlnds, 0, "destruct"); + ndo_printf(nds, 0, "destruct"); + + if (nds == NULL) + return; - if (mlnds->pdu_base_addr != NULL) { - free(mlnds->pdu_base_addr); - mlnds->pdu_base_addr = NULL; - mlnds->pdu_base_offset = 0; + if (nds->pdu_base_addr != NULL) { + free(nds->pdu_base_addr); + nds->pdu_base_addr = NULL; + nds->pdu_base_offset = 0; } - while ((frag = mlnds->frags.head) != NULL) { - mlnds->frags.head = frag->next; + while ((frag = nds->frags.head) != NULL) { + nds->frags.head = frag->next; free(frag); } - bzero(&mlnds->frags, sizeof (ndr_fraglist_t)); + bzero(&nds->frags, sizeof (ndr_fraglist_t)); - mlnds->outer_queue_head = 0; - mlnds->outer_current = 0; - mlnds->outer_queue_tailp = &mlnds->outer_queue_head; + nds->outer_queue_head = 0; + nds->outer_current = 0; + nds->outer_queue_tailp = &nds->outer_queue_head; } /* * Printf style formatting for NDR operations. */ void -mlndo_printf(struct mlndr_stream *mlnds, struct ndr_reference *ref, - const char *fmt, ...) +ndo_printf(ndr_stream_t *nds, ndr_ref_t *ref, const char *fmt, ...) { va_list ap; char buf[NDOBUFSZ]; @@ -439,10 +431,10 @@ mlndo_printf(struct mlndr_stream *mlnds, struct ndr_reference *ref, (void) vsnprintf(buf, NDOBUFSZ, fmt, ap); va_end(ap); - if (mlnds) - mlndo_fmt(mlnds, ref, buf); + if (nds) + ndo_fmt(nds, ref, buf); else - mlndo_trace(buf); + ndo_trace(buf); } /* @@ -459,22 +451,22 @@ mlndo_printf(struct mlndr_stream *mlnds, struct ndr_reference *ref, * {05} Value */ void -mlndo_fmt(struct mlndr_stream *mlnds, struct ndr_reference *ref, char *note) +ndo_fmt(ndr_stream_t *nds, ndr_ref_t *ref, char *note) { - struct ndr_reference *p; - int indent; - char ref_name[NDOBUFSZ]; - char buf[NDOBUFSZ]; - int m_op_c = '?', dir_c = '?'; + ndr_ref_t *p; + int indent; + char ref_name[NDOBUFSZ]; + char buf[NDOBUFSZ]; + int m_op_c = '?', dir_c = '?'; - switch (mlnds->m_op) { + switch (nds->m_op) { case 0: m_op_c = '-'; break; case NDR_M_OP_MARSHALL: m_op_c = 'M'; break; case NDR_M_OP_UNMARSHALL: m_op_c = 'U'; break; default: m_op_c = '?'; break; } - switch (mlnds->dir) { + switch (nds->dir) { case 0: dir_c = '-'; break; case NDR_DIR_IN: dir_c = 'I'; break; case NDR_DIR_OUT: dir_c = 'O'; break; @@ -501,12 +493,12 @@ mlndo_fmt(struct mlndr_stream *mlnds, struct ndr_reference *ref, char *note) "....+....+....+....+....+....", 20 - indent, ref_name, note); - mlndo_trace(buf); + ndo_trace(buf); } /*ARGSUSED*/ void -mlndo_trace(const char *s) +ndo_trace(const char *s) { /* * Temporary fbt for dtrace until user space sdt enabled. @@ -522,7 +514,7 @@ mlndo_trace(const char *s) * be inserted before the closing brace. */ static void -mlndo_hexfmt(uint8_t *data, int size, int swap_bytes, char *buf, int len) +ndo_hexfmt(uint8_t *data, int size, int swap_bytes, char *buf, int len) { char *p = buf; int interp = 1; diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c index c6f889f5d7..cba8a45c42 100644 --- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c +++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Network Data Representation (NDR) is a compatible subset of the DCE RPC * and MSRPC NDR. NDR is used to move parameters consisting of @@ -39,7 +37,7 @@ #include <smbsrv/libsmb.h> #include <smbsrv/string.h> -#include <smbsrv/ndr.h> +#include <smbsrv/libmlrpc.h> #define NDR_STRING_MAX 256 @@ -48,7 +46,7 @@ #define NDR_IS_STRING(T) \ (((T)->type_flags & NDR_F_TYPEOP_MASK) == NDR_F_STRING) -extern struct ndr_typeinfo ndt_s_wchar; +extern ndr_typeinfo_t ndt_s_wchar; /* * The following synopsis describes the terms TOP-MOST, OUTER and INNER. @@ -128,24 +126,24 @@ extern struct ndr_typeinfo ndt_s_wchar; * * NDR_REFERENCE * - * The primary object for NDR is the struct ndr_reference. + * The primary object for NDR is the ndr_ref_t. * - * An ndr_reference indicates the local datum (i.e. native "C" data + * An ndr reference indicates the local datum (i.e. native "C" data * format), and the element within the Stub Data (contained within the - * RPC PDU (protocol data unit). An ndr_reference also indicates, + * RPC PDU (protocol data unit). An ndr reference also indicates, * largely as a debugging aid, something about the type of the * element/datum, and the enclosing construct for the element. The - * ndr_reference's are typically allocated on the stack as locals, - * and the chain of ndr_reference.enclosing references is in reverse + * ndr reference's are typically allocated on the stack as locals, + * and the chain of ndr-reference.enclosing references is in reverse * order of the call graph. * - * The ndr_reference.datum is a pointer to the local memory that - * contains/receives the value. The ndr_reference.pdu_offset indicates + * The ndr-reference.datum is a pointer to the local memory that + * contains/receives the value. The ndr-reference.pdu_offset indicates * where in the Stub Data the value is to be stored/retrieved. * - * The ndr_reference also contains various parameters to the NDR - * process, such as ndr_reference.size_is, which indicates the size - * of variable length data, or ndr_reference.switch_is, which + * The ndr-reference also contains various parameters to the NDR + * process, such as ndr-reference.size_is, which indicates the size + * of variable length data, or ndr-reference.switch_is, which * indicates the arm of a union to use. * * QUEUE OF OUTER REFERENCES @@ -158,13 +156,13 @@ extern struct ndr_typeinfo ndt_s_wchar; * Stub Data until we know the size of all its predecessors. * * This is managed using the queue of OUTER references. The queue is - * anchored in mlndr_stream.outer_queue_head. At any time, - * mlndr_stream.outer_queue_tailp indicates where to put the - * ndr_reference for the next encountered pointer. + * anchored in ndr_stream.outer_queue_head. At any time, + * ndr_stream.outer_queue_tailp indicates where to put the + * ndr-reference for the next encountered pointer. * * Refer to the example above as we illustrate the queue here. In these * illustrations, the queue entries are not the data structures themselves. - * Rather, they are ndr_reference entries which **refer** to the data + * Rather, they are ndr-reference entries which **refer** to the data * structures in both the PDU and local memory. * * During some point in the processing, the queue looks like this: @@ -187,9 +185,8 @@ extern struct ndr_typeinfo ndt_s_wchar; * outer_queue_head --> list#1 --> list#2 --> "foo" --0 * outer_queue_tailp ------------------------------& * - * Upon the completion of list#1, the processing continues by moving - * to mlndr_stream.outer_current->next, and the tail is set to this - * outer member: + * Upon the completion of list#1, the processing continues by moving to + * ndr_stream.outer_current->next, and the tail is set to this outer member: * * outer_current ------------------v * outer_queue_head --> list#1 --> list#2 --> "foo" --0 @@ -225,8 +222,8 @@ extern struct ndr_typeinfo ndt_s_wchar; * processed as an aid to debugging. */ -static struct ndr_reference *mlndr_enter_outer_queue(struct ndr_reference *); -extern int mlndr__ulong(struct ndr_reference *); +static ndr_ref_t *ndr_enter_outer_queue(ndr_ref_t *); +extern int ndr__ulong(ndr_ref_t *); /* * TOP-MOST ELEMENTS @@ -242,28 +239,26 @@ extern int mlndr__ulong(struct ndr_reference *); * top-most member, and commence the outer_queue processing. */ int -mlndo_process(struct mlndr_stream *mlnds, struct ndr_typeinfo *ti, - char *datum) +ndo_process(ndr_stream_t *nds, ndr_typeinfo_t *ti, char *datum) { - struct ndr_reference myref; + ndr_ref_t myref; bzero(&myref, sizeof (myref)); - myref.stream = mlnds; + myref.stream = nds; myref.datum = datum; myref.name = "PROCESS"; myref.ti = ti; - return (mlndr_topmost(&myref)); + return (ndr_topmost(&myref)); } int -mlndo_operation(struct mlndr_stream *mlnds, struct ndr_typeinfo *ti, - int opnum, char *datum) +ndo_operation(ndr_stream_t *nds, ndr_typeinfo_t *ti, int opnum, char *datum) { - struct ndr_reference myref; + ndr_ref_t myref; bzero(&myref, sizeof (myref)); - myref.stream = mlnds; + myref.stream = nds; myref.datum = datum; myref.name = "OPERATION"; myref.ti = ti; @@ -279,22 +274,22 @@ mlndo_operation(struct mlndr_stream *mlnds, struct ndr_typeinfo *ti, } int -mlndr_params(struct ndr_reference *params_ref) +ndr_params(ndr_ref_t *params_ref) { - struct ndr_typeinfo *ti = params_ref->ti; + ndr_typeinfo_t *ti = params_ref->ti; if (ti->type_flags == NDR_F_OPERATION) return (*ti->ndr_func) (params_ref); else - return (mlndr_topmost(params_ref)); + return (ndr_topmost(params_ref)); } int -mlndr_topmost(struct ndr_reference *top_ref) +ndr_topmost(ndr_ref_t *top_ref) { - struct mlndr_stream *mlnds; - struct ndr_typeinfo *ti; - struct ndr_reference *outer_ref = 0; + ndr_stream_t *nds; + ndr_typeinfo_t *ti; + ndr_ref_t *outer_ref = 0; int is_varlen; int is_string; int error; @@ -306,14 +301,14 @@ mlndr_topmost(struct ndr_reference *top_ref) assert(top_ref->stream); assert(top_ref->ti); - mlnds = top_ref->stream; + nds = top_ref->stream; ti = top_ref->ti; is_varlen = ti->pdu_size_variable_part; is_string = NDR_IS_STRING(ti); - assert(mlnds->outer_queue_tailp && !*mlnds->outer_queue_tailp); - assert(!mlnds->outer_current); + assert(nds->outer_queue_tailp && !*nds->outer_queue_tailp); + assert(!nds->outer_current); params = top_ref->inner_flags & NDR_F_PARAMS_MASK; @@ -358,14 +353,14 @@ mlndr_topmost(struct ndr_reference *top_ref) return (0); } - outer_ref = mlndr_enter_outer_queue(top_ref); + outer_ref = ndr_enter_outer_queue(top_ref); if (!outer_ref) return (0); /* error already set */ /* * Hand-craft the first OUTER construct and directly call - * mlndr_inner(). Then, run the outer_queue. We do this - * because mlndr_outer() wants to malloc() memory for + * ndr_inner(). Then, run the outer_queue. We do this + * because ndr_outer() wants to malloc() memory for * the construct, and we already have the memory. */ @@ -375,44 +370,43 @@ mlndr_topmost(struct ndr_reference *top_ref) outer_ref->datum = top_ref->datum; /* All outer constructs start on a mod4 (longword) boundary */ - if (!mlndr_outer_align(outer_ref)) + if (!ndr_outer_align(outer_ref)) return (0); /* error already set */ /* Regardless of what it is, this is where it starts */ - outer_ref->pdu_offset = mlnds->pdu_scan_offset; + outer_ref->pdu_offset = nds->pdu_scan_offset; - rc = mlndr_outer_grow(outer_ref, n_fixed); + rc = ndr_outer_grow(outer_ref, n_fixed); if (!rc) return (0); /* error already set */ outer_ref->pdu_end_offset = outer_ref->pdu_offset + n_fixed; /* set-up outer_current, as though run_outer_queue() was doing it */ - mlnds->outer_current = outer_ref; - mlnds->outer_queue_tailp = &mlnds->outer_current->next; - mlnds->pdu_scan_offset = outer_ref->pdu_end_offset; + nds->outer_current = outer_ref; + nds->outer_queue_tailp = &nds->outer_current->next; + nds->pdu_scan_offset = outer_ref->pdu_end_offset; /* do the topmost member */ - rc = mlndr_inner(outer_ref); + rc = ndr_inner(outer_ref); if (!rc) return (0); /* error already set */ - mlnds->pdu_scan_offset = outer_ref->pdu_end_offset; + nds->pdu_scan_offset = outer_ref->pdu_end_offset; /* advance, as though run_outer_queue() was doing it */ - mlnds->outer_current = mlnds->outer_current->next; - return (mlndr_run_outer_queue(mlnds)); + nds->outer_current = nds->outer_current->next; + return (ndr_run_outer_queue(nds)); } -static struct ndr_reference * -mlndr_enter_outer_queue(struct ndr_reference *arg_ref) +static ndr_ref_t * +ndr_enter_outer_queue(ndr_ref_t *arg_ref) { - struct mlndr_stream *mlnds = arg_ref->stream; - struct ndr_reference *outer_ref; + ndr_stream_t *nds = arg_ref->stream; + ndr_ref_t *outer_ref; /*LINTED E_BAD_PTR_CAST_ALIGN*/ - outer_ref = (struct ndr_reference *) - MLNDS_MALLOC(mlnds, sizeof (*outer_ref), arg_ref); + outer_ref = (ndr_ref_t *)NDS_MALLOC(nds, sizeof (*outer_ref), arg_ref); if (!outer_ref) { NDR_SET_ERROR(arg_ref, NDR_ERR_MALLOC_FAILED); return (0); @@ -423,28 +417,28 @@ mlndr_enter_outer_queue(struct ndr_reference *arg_ref) /* move advice in inner_flags to outer_flags */ outer_ref->outer_flags = arg_ref->inner_flags & NDR_F_PARAMS_MASK; outer_ref->inner_flags = 0; - outer_ref->enclosing = mlnds->outer_current; + outer_ref->enclosing = nds->outer_current; outer_ref->backptr = 0; outer_ref->datum = 0; - assert(mlnds->outer_queue_tailp); + assert(nds->outer_queue_tailp); - outer_ref->next = *mlnds->outer_queue_tailp; - *mlnds->outer_queue_tailp = outer_ref; - mlnds->outer_queue_tailp = &outer_ref->next; + outer_ref->next = *nds->outer_queue_tailp; + *nds->outer_queue_tailp = outer_ref; + nds->outer_queue_tailp = &outer_ref->next; return (outer_ref); } int -mlndr_run_outer_queue(struct mlndr_stream *mlnds) +ndr_run_outer_queue(ndr_stream_t *nds) { - while (mlnds->outer_current) { - mlnds->outer_queue_tailp = &mlnds->outer_current->next; + while (nds->outer_current) { + nds->outer_queue_tailp = &nds->outer_current->next; - if (!mlndr_outer(mlnds->outer_current)) + if (!ndr_outer(nds->outer_current)) return (0); - mlnds->outer_current = mlnds->outer_current->next; + nds->outer_current = nds->outer_current->next; } return (1); @@ -590,10 +584,10 @@ mlndr_run_outer_queue(struct mlndr_stream *mlnds) * implemented, we probably won't need the strings special case. */ int -mlndr_outer(struct ndr_reference *outer_ref) +ndr_outer(ndr_ref_t *outer_ref) { - struct mlndr_stream *mlnds = outer_ref->stream; - struct ndr_typeinfo *ti = outer_ref->ti; + ndr_stream_t *nds = outer_ref->stream; + ndr_typeinfo_t *ti = outer_ref->ti; int is_varlen = ti->pdu_size_variable_part; int is_union = NDR_IS_UNION(ti); int is_string = NDR_IS_STRING(ti); @@ -605,11 +599,11 @@ mlndr_outer(struct ndr_reference *outer_ref) NDR_TATTLE(outer_ref, "--OUTER--"); /* All outer constructs start on a mod4 (longword) boundary */ - if (!mlndr_outer_align(outer_ref)) + if (!ndr_outer_align(outer_ref)) return (0); /* error already set */ /* Regardless of what it is, this is where it starts */ - outer_ref->pdu_offset = mlnds->pdu_scan_offset; + outer_ref->pdu_offset = nds->pdu_scan_offset; if (is_union) { error = NDR_ERR_OUTER_UNION_ILLEGAL; @@ -620,11 +614,11 @@ mlndr_outer(struct ndr_reference *outer_ref) switch (params) { case NDR_F_NONE: if (is_string) - return (mlndr_outer_string(outer_ref)); + return (ndr_outer_string(outer_ref)); if (is_varlen) - return (mlndr_outer_conformant_construct(outer_ref)); + return (ndr_outer_conformant_construct(outer_ref)); - return (mlndr_outer_fixed(outer_ref)); + return (ndr_outer_fixed(outer_ref)); break; case NDR_F_SIZE_IS: @@ -635,9 +629,9 @@ mlndr_outer(struct ndr_reference *outer_ref) } if (params == NDR_F_SIZE_IS) - return (mlndr_outer_conformant_array(outer_ref)); + return (ndr_outer_conformant_array(outer_ref)); else - return (mlndr_outer_fixed_array(outer_ref)); + return (ndr_outer_fixed_array(outer_ref)); break; default: @@ -654,11 +648,11 @@ mlndr_outer(struct ndr_reference *outer_ref) } int -mlndr_outer_fixed(struct ndr_reference *outer_ref) +ndr_outer_fixed(ndr_ref_t *outer_ref) { - struct mlndr_stream *mlnds = outer_ref->stream; - struct ndr_typeinfo *ti = outer_ref->ti; - struct ndr_reference myref; + ndr_stream_t *nds = outer_ref->stream; + ndr_typeinfo_t *ti = outer_ref->ti; + ndr_ref_t myref; char *valp = NULL; int is_varlen = ti->pdu_size_variable_part; int is_union = NDR_IS_UNION(ti); @@ -692,11 +686,11 @@ mlndr_outer_fixed(struct ndr_reference *outer_ref) /* similar sum to determine how much local memory is required */ n_alloc = n_fixed + n_variable; - rc = mlndr_outer_grow(outer_ref, n_pdu_total); + rc = ndr_outer_grow(outer_ref, n_pdu_total); if (!rc) return (rc); /* error already set */ - switch (mlnds->m_op) { + switch (nds->m_op) { case NDR_M_OP_MARSHALL: valp = outer_ref->datum; assert(valp); @@ -706,7 +700,7 @@ mlndr_outer_fixed(struct ndr_reference *outer_ref) break; case NDR_M_OP_UNMARSHALL: - valp = MLNDS_MALLOC(mlnds, n_alloc, outer_ref); + valp = NDS_MALLOC(nds, n_alloc, outer_ref); if (!valp) { NDR_SET_ERROR(outer_ref, NDR_ERR_MALLOC_FAILED); return (0); @@ -722,7 +716,7 @@ mlndr_outer_fixed(struct ndr_reference *outer_ref) } bzero(&myref, sizeof (myref)); - myref.stream = mlnds; + myref.stream = nds; myref.enclosing = outer_ref; myref.ti = outer_ref->ti; myref.datum = outer_ref->datum; @@ -733,20 +727,20 @@ mlndr_outer_fixed(struct ndr_reference *outer_ref) myref.pdu_offset = outer_ref->pdu_offset; outer_ref->pdu_end_offset = outer_ref->pdu_offset + n_pdu_total; - rc = mlndr_inner(&myref); + rc = ndr_inner(&myref); if (!rc) return (rc); /* error already set */ - mlnds->pdu_scan_offset = outer_ref->pdu_end_offset; + nds->pdu_scan_offset = outer_ref->pdu_end_offset; return (1); } int -mlndr_outer_fixed_array(struct ndr_reference *outer_ref) +ndr_outer_fixed_array(ndr_ref_t *outer_ref) { - struct mlndr_stream *mlnds = outer_ref->stream; - struct ndr_typeinfo *ti = outer_ref->ti; - struct ndr_reference myref; + ndr_stream_t *nds = outer_ref->stream; + ndr_typeinfo_t *ti = outer_ref->ti; + ndr_ref_t myref; char *valp = NULL; int is_varlen = ti->pdu_size_variable_part; int is_union = NDR_IS_UNION(ti); @@ -780,11 +774,11 @@ mlndr_outer_fixed_array(struct ndr_reference *outer_ref) /* similar sum to determine how much local memory is required */ n_alloc = n_fixed + n_variable; - rc = mlndr_outer_grow(outer_ref, n_pdu_total); + rc = ndr_outer_grow(outer_ref, n_pdu_total); if (!rc) return (rc); /* error already set */ - switch (mlnds->m_op) { + switch (nds->m_op) { case NDR_M_OP_MARSHALL: valp = outer_ref->datum; assert(valp); @@ -794,7 +788,7 @@ mlndr_outer_fixed_array(struct ndr_reference *outer_ref) break; case NDR_M_OP_UNMARSHALL: - valp = MLNDS_MALLOC(mlnds, n_alloc, outer_ref); + valp = NDS_MALLOC(nds, n_alloc, outer_ref); if (!valp) { NDR_SET_ERROR(outer_ref, NDR_ERR_MALLOC_FAILED); return (0); @@ -810,7 +804,7 @@ mlndr_outer_fixed_array(struct ndr_reference *outer_ref) } bzero(&myref, sizeof (myref)); - myref.stream = mlnds; + myref.stream = nds; myref.enclosing = outer_ref; myref.ti = outer_ref->ti; myref.datum = outer_ref->datum; @@ -822,20 +816,20 @@ mlndr_outer_fixed_array(struct ndr_reference *outer_ref) myref.pdu_offset = outer_ref->pdu_offset; outer_ref->pdu_end_offset = outer_ref->pdu_offset + n_pdu_total; - rc = mlndr_inner(&myref); + rc = ndr_inner(&myref); if (!rc) return (rc); /* error already set */ - mlnds->pdu_scan_offset = outer_ref->pdu_end_offset; + nds->pdu_scan_offset = outer_ref->pdu_end_offset; return (1); } int -mlndr_outer_conformant_array(struct ndr_reference *outer_ref) +ndr_outer_conformant_array(ndr_ref_t *outer_ref) { - struct mlndr_stream *mlnds = outer_ref->stream; - struct ndr_typeinfo *ti = outer_ref->ti; - struct ndr_reference myref; + ndr_stream_t *nds = outer_ref->stream; + ndr_typeinfo_t *ti = outer_ref->ti; + ndr_ref_t myref; char *valp = NULL; int is_varlen = ti->pdu_size_variable_part; int is_union = NDR_IS_UNION(ti); @@ -870,14 +864,14 @@ mlndr_outer_conformant_array(struct ndr_reference *outer_ref) /* similar sum to determine how much local memory is required */ n_alloc = n_fixed + n_variable; - rc = mlndr_outer_grow(outer_ref, n_pdu_total); + rc = ndr_outer_grow(outer_ref, n_pdu_total); if (!rc) return (rc); /* error already set */ - switch (mlnds->m_op) { + switch (nds->m_op) { case NDR_M_OP_MARSHALL: size_is = outer_ref->size_is; - rc = mlndr_outer_poke_sizing(outer_ref, 0, &size_is); + rc = ndr_outer_poke_sizing(outer_ref, 0, &size_is); if (!rc) return (0); /* error already set */ @@ -889,7 +883,7 @@ mlndr_outer_conformant_array(struct ndr_reference *outer_ref) break; case NDR_M_OP_UNMARSHALL: - rc = mlndr_outer_peek_sizing(outer_ref, 0, &size_is); + rc = ndr_outer_peek_sizing(outer_ref, 0, &size_is); if (!rc) return (0); /* error already set */ @@ -900,7 +894,7 @@ mlndr_outer_conformant_array(struct ndr_reference *outer_ref) } if (size_is > 0) { - valp = MLNDS_MALLOC(mlnds, n_alloc, outer_ref); + valp = NDS_MALLOC(nds, n_alloc, outer_ref); if (!valp) { NDR_SET_ERROR(outer_ref, NDR_ERR_MALLOC_FAILED); return (0); @@ -923,7 +917,7 @@ mlndr_outer_conformant_array(struct ndr_reference *outer_ref) if (size_is > 0) { bzero(&myref, sizeof (myref)); - myref.stream = mlnds; + myref.stream = nds; myref.enclosing = outer_ref; myref.ti = outer_ref->ti; myref.datum = outer_ref->datum; @@ -937,21 +931,21 @@ mlndr_outer_conformant_array(struct ndr_reference *outer_ref) myref.pdu_offset = outer_ref->pdu_offset + 4; - rc = mlndr_inner(&myref); + rc = ndr_inner(&myref); if (!rc) return (rc); /* error already set */ } - mlnds->pdu_scan_offset = outer_ref->pdu_end_offset; + nds->pdu_scan_offset = outer_ref->pdu_end_offset; return (1); } int -mlndr_outer_conformant_construct(struct ndr_reference *outer_ref) +ndr_outer_conformant_construct(ndr_ref_t *outer_ref) { - struct mlndr_stream *mlnds = outer_ref->stream; - struct ndr_typeinfo *ti = outer_ref->ti; - struct ndr_reference myref; + ndr_stream_t *nds = outer_ref->stream; + ndr_typeinfo_t *ti = outer_ref->ti; + ndr_ref_t myref; char *valp = NULL; int is_varlen = ti->pdu_size_variable_part; int is_union = NDR_IS_UNION(ti); @@ -986,19 +980,19 @@ mlndr_outer_conformant_construct(struct ndr_reference *outer_ref) n_alloc = n_fixed + n_variable; /* For the moment, grow enough for the fixed-size part */ - rc = mlndr_outer_grow(outer_ref, n_pdu_total); + rc = ndr_outer_grow(outer_ref, n_pdu_total); if (!rc) return (rc); /* error already set */ - switch (mlnds->m_op) { + switch (nds->m_op) { case NDR_M_OP_MARSHALL: /* * We don't know the size yet. We have to wait for * it. Proceed with the fixed-size part, and await - * the call to mlndr_size_is(). + * the call to ndr_size_is(). */ size_is = 0; - rc = mlndr_outer_poke_sizing(outer_ref, 0, &size_is); + rc = ndr_outer_poke_sizing(outer_ref, 0, &size_is); if (!rc) return (0); /* error already set */ @@ -1014,9 +1008,9 @@ mlndr_outer_conformant_construct(struct ndr_reference *outer_ref) * We know the size of the variable part because * of the CONFORMANT header. We will verify * the header against the [size_is(X)] advice - * later when mlndr_size_is() is called. + * later when ndr_size_is() is called. */ - rc = mlndr_outer_peek_sizing(outer_ref, 0, &size_is); + rc = ndr_outer_peek_sizing(outer_ref, 0, &size_is); if (!rc) return (0); /* error already set */ @@ -1025,13 +1019,13 @@ mlndr_outer_conformant_construct(struct ndr_reference *outer_ref) n_pdu_total = n_hdr + n_fixed + n_variable; n_alloc = n_fixed + n_variable; - rc = mlndr_outer_grow(outer_ref, n_pdu_total); + rc = ndr_outer_grow(outer_ref, n_pdu_total); if (!rc) return (rc); /* error already set */ outer_ref->size_is = size_is; /* verified later */ - valp = MLNDS_MALLOC(mlnds, n_alloc, outer_ref); + valp = NDS_MALLOC(nds, n_alloc, outer_ref); if (!valp) { NDR_SET_ERROR(outer_ref, NDR_ERR_MALLOC_FAILED); return (0); @@ -1051,7 +1045,7 @@ mlndr_outer_conformant_construct(struct ndr_reference *outer_ref) outer_ref->inner_flags = NDR_F_NONE; /* indicate pending */ bzero(&myref, sizeof (myref)); - myref.stream = mlnds; + myref.stream = nds; myref.enclosing = outer_ref; myref.ti = outer_ref->ti; myref.datum = outer_ref->datum; @@ -1062,11 +1056,11 @@ mlndr_outer_conformant_construct(struct ndr_reference *outer_ref) myref.pdu_offset = outer_ref->pdu_offset + 4; - rc = mlndr_inner(&myref); + rc = ndr_inner(&myref); if (!rc) return (rc); /* error already set */ - mlnds->pdu_scan_offset = outer_ref->pdu_end_offset; + nds->pdu_scan_offset = outer_ref->pdu_end_offset; if (outer_ref->inner_flags != NDR_F_SIZE_IS) { NDR_SET_ERROR(&myref, NDR_ERR_SIZE_IS_MISMATCH_AFTER); @@ -1077,11 +1071,11 @@ mlndr_outer_conformant_construct(struct ndr_reference *outer_ref) } int -mlndr_size_is(struct ndr_reference *ref) +ndr_size_is(ndr_ref_t *ref) { - struct mlndr_stream *mlnds = ref->stream; - struct ndr_reference *outer_ref = mlnds->outer_current; - struct ndr_typeinfo *ti = outer_ref->ti; + ndr_stream_t *nds = ref->stream; + ndr_ref_t *outer_ref = nds->outer_current; + ndr_typeinfo_t *ti = outer_ref->ti; unsigned long size_is; int rc; unsigned n_hdr; @@ -1102,30 +1096,30 @@ mlndr_size_is(struct ndr_reference *ref) return (0); } - /* repeat metrics, see mlndr_conformant_construct() above */ + /* repeat metrics, see ndr_conformant_construct() above */ n_hdr = 4; n_fixed = ti->pdu_size_fixed_part; n_variable = size_is * ti->pdu_size_variable_part; n_pdu_total = n_hdr + n_fixed + n_variable; - rc = mlndr_outer_grow(outer_ref, n_pdu_total); + rc = ndr_outer_grow(outer_ref, n_pdu_total); if (!rc) return (rc); /* error already set */ - switch (mlnds->m_op) { + switch (nds->m_op) { case NDR_M_OP_MARSHALL: /* * We have to set the sizing header and extend * the size of the PDU (already done). */ - rc = mlndr_outer_poke_sizing(outer_ref, 0, &size_is); + rc = ndr_outer_poke_sizing(outer_ref, 0, &size_is); if (!rc) return (0); /* error already set */ break; case NDR_M_OP_UNMARSHALL: /* - * Allocation done during mlndr_conformant_construct(). + * Allocation done during ndr_conformant_construct(). * All we are doing here is verifying that the * intended size (ref->size_is) matches the sizing header. */ @@ -1146,11 +1140,11 @@ mlndr_size_is(struct ndr_reference *ref) } int -mlndr_outer_string(struct ndr_reference *outer_ref) +ndr_outer_string(ndr_ref_t *outer_ref) { - struct mlndr_stream *mlnds = outer_ref->stream; - struct ndr_typeinfo *ti = outer_ref->ti; - struct ndr_reference myref; + ndr_stream_t *nds = outer_ref->stream; + ndr_typeinfo_t *ti = outer_ref->ti; + ndr_ref_t myref; char *valp = NULL; unsigned is_varlen = ti->pdu_size_variable_part; int is_union = NDR_IS_UNION(ti); @@ -1179,10 +1173,10 @@ mlndr_outer_string(struct ndr_reference *outer_ref) /* fixed part -- exactly none of these */ n_fixed = 0; - if (!mlndr_outer_grow(outer_ref, n_hdr)) + if (!ndr_outer_grow(outer_ref, n_hdr)) return (0); /* error already set */ - switch (mlnds->m_op) { + switch (nds->m_op) { case NDR_M_OP_MARSHALL: valp = outer_ref->datum; assert(valp); @@ -1227,21 +1221,21 @@ mlndr_outer_string(struct ndr_reference *outer_ref) first_is = 0; - if (mlnds->flags & MLNDS_F_NOTERM) + if (nds->flags & NDS_F_NOTERM) length_is = size_is - 1; else length_is = size_is; - if (!mlndr_outer_poke_sizing(outer_ref, 0, &size_is) || - !mlndr_outer_poke_sizing(outer_ref, 4, &first_is) || - !mlndr_outer_poke_sizing(outer_ref, 8, &length_is)) + if (!ndr_outer_poke_sizing(outer_ref, 0, &size_is) || + !ndr_outer_poke_sizing(outer_ref, 4, &first_is) || + !ndr_outer_poke_sizing(outer_ref, 8, &length_is)) return (0); /* error already set */ break; case NDR_M_OP_UNMARSHALL: - if (!mlndr_outer_peek_sizing(outer_ref, 0, &size_is) || - !mlndr_outer_peek_sizing(outer_ref, 4, &first_is) || - !mlndr_outer_peek_sizing(outer_ref, 8, &length_is)) + if (!ndr_outer_peek_sizing(outer_ref, 0, &size_is) || + !ndr_outer_peek_sizing(outer_ref, 4, &first_is) || + !ndr_outer_peek_sizing(outer_ref, 8, &length_is)) return (0); /* error already set */ /* @@ -1276,7 +1270,7 @@ mlndr_outer_string(struct ndr_reference *outer_ref) n_alloc = (size_is + 1) * is_varlen; } - valp = MLNDS_MALLOC(mlnds, n_alloc, outer_ref); + valp = NDS_MALLOC(nds, n_alloc, outer_ref); if (!valp) { NDR_SET_ERROR(outer_ref, NDR_ERR_MALLOC_FAILED); return (0); @@ -1311,13 +1305,13 @@ mlndr_outer_string(struct ndr_reference *outer_ref) /* similar sum to determine how much local memory is required */ n_alloc = n_fixed + n_variable; - rc = mlndr_outer_grow(outer_ref, n_pdu_total); + rc = ndr_outer_grow(outer_ref, n_pdu_total); if (!rc) return (rc); /* error already set */ if (length_is > 0) { bzero(&myref, sizeof (myref)); - myref.stream = mlnds; + myref.stream = nds; myref.enclosing = outer_ref; myref.ti = outer_ref->ti; myref.datum = outer_ref->datum; @@ -1326,7 +1320,7 @@ mlndr_outer_string(struct ndr_reference *outer_ref) myref.inner_flags = NDR_F_NONE; /* - * Set up size_is and strlen_is for mlndr_s_wchar. + * Set up size_is and strlen_is for ndr_s_wchar. */ myref.size_is = size_is; myref.strlen_is = length_is; @@ -1338,45 +1332,45 @@ mlndr_outer_string(struct ndr_reference *outer_ref) * Don't try to decode empty strings. */ if ((size_is == 0) && (first_is == 0) && (length_is == 0)) { - mlnds->pdu_scan_offset = outer_ref->pdu_end_offset; + nds->pdu_scan_offset = outer_ref->pdu_end_offset; return (1); } if ((size_is != 0) && (length_is != 0)) { - rc = mlndr_inner(&myref); + rc = ndr_inner(&myref); if (!rc) return (rc); /* error already set */ } - mlnds->pdu_scan_offset = outer_ref->pdu_end_offset; + nds->pdu_scan_offset = outer_ref->pdu_end_offset; return (1); } int -mlndr_outer_peek_sizing(struct ndr_reference *outer_ref, unsigned offset, +ndr_outer_peek_sizing(ndr_ref_t *outer_ref, unsigned offset, unsigned long *sizing_p) { - struct mlndr_stream *mlnds = outer_ref->stream; - unsigned long pdu_offset; - int rc; + ndr_stream_t *nds = outer_ref->stream; + unsigned long pdu_offset; + int rc; pdu_offset = outer_ref->pdu_offset + offset; - if (pdu_offset < mlnds->outer_current->pdu_offset || - pdu_offset > mlnds->outer_current->pdu_end_offset || - pdu_offset+4 > mlnds->outer_current->pdu_end_offset) { + if (pdu_offset < nds->outer_current->pdu_offset || + pdu_offset > nds->outer_current->pdu_end_offset || + pdu_offset+4 > nds->outer_current->pdu_end_offset) { NDR_SET_ERROR(outer_ref, NDR_ERR_BOUNDS_CHECK); return (0); } - switch (mlnds->m_op) { + switch (nds->m_op) { case NDR_M_OP_MARSHALL: NDR_SET_ERROR(outer_ref, NDR_ERR_UNIMPLEMENTED); return (0); case NDR_M_OP_UNMARSHALL: - rc = MLNDS_GET_PDU(mlnds, pdu_offset, 4, (char *)sizing_p, - mlnds->swap, outer_ref); + rc = NDS_GET_PDU(nds, pdu_offset, 4, (char *)sizing_p, + nds->swap, outer_ref); break; default: @@ -1388,26 +1382,26 @@ mlndr_outer_peek_sizing(struct ndr_reference *outer_ref, unsigned offset, } int -mlndr_outer_poke_sizing(struct ndr_reference *outer_ref, unsigned offset, +ndr_outer_poke_sizing(ndr_ref_t *outer_ref, unsigned offset, unsigned long *sizing_p) { - struct mlndr_stream *mlnds = outer_ref->stream; - unsigned long pdu_offset; - int rc; + ndr_stream_t *nds = outer_ref->stream; + unsigned long pdu_offset; + int rc; pdu_offset = outer_ref->pdu_offset + offset; - if (pdu_offset < mlnds->outer_current->pdu_offset || - pdu_offset > mlnds->outer_current->pdu_end_offset || - pdu_offset+4 > mlnds->outer_current->pdu_end_offset) { + if (pdu_offset < nds->outer_current->pdu_offset || + pdu_offset > nds->outer_current->pdu_end_offset || + pdu_offset+4 > nds->outer_current->pdu_end_offset) { NDR_SET_ERROR(outer_ref, NDR_ERR_BOUNDS_CHECK); return (0); } - switch (mlnds->m_op) { + switch (nds->m_op) { case NDR_M_OP_MARSHALL: - rc = MLNDS_PUT_PDU(mlnds, pdu_offset, 4, (char *)sizing_p, - mlnds->swap, outer_ref); + rc = NDS_PUT_PDU(nds, pdu_offset, 4, (char *)sizing_p, + nds->swap, outer_ref); break; case NDR_M_OP_UNMARSHALL: @@ -1428,30 +1422,29 @@ mlndr_outer_poke_sizing(struct ndr_reference *outer_ref, unsigned offset, * packed alignment. Strings appear to be dword aligned. */ int -mlndr_outer_align(struct ndr_reference *outer_ref) +ndr_outer_align(ndr_ref_t *outer_ref) { - struct mlndr_stream *mlnds = outer_ref->stream; - int rc; - unsigned n_pad; - unsigned align; + ndr_stream_t *nds = outer_ref->stream; + int rc; + unsigned n_pad; + unsigned align; if (outer_ref->packed_alignment && outer_ref->ti != &ndt_s_wchar) { align = outer_ref->ti->alignment; - n_pad = ((align + 1) - mlnds->pdu_scan_offset) & align; + n_pad = ((align + 1) - nds->pdu_scan_offset) & align; } else { - n_pad = (4 - mlnds->pdu_scan_offset) & 3; + n_pad = NDR_ALIGN4(nds->pdu_scan_offset); } if (n_pad == 0) return (1); /* already aligned, often the case */ - if (!mlndr_outer_grow(outer_ref, n_pad)) + if (!ndr_outer_grow(outer_ref, n_pad)) return (0); /* error already set */ - switch (mlnds->m_op) { + switch (nds->m_op) { case NDR_M_OP_MARSHALL: - rc = MLNDS_PAD_PDU(mlnds, - mlnds->pdu_scan_offset, n_pad, outer_ref); + rc = NDS_PAD_PDU(nds, nds->pdu_scan_offset, n_pad, outer_ref); if (!rc) { NDR_SET_ERROR(outer_ref, NDR_ERR_PAD_FAILED); return (0); @@ -1466,28 +1459,28 @@ mlndr_outer_align(struct ndr_reference *outer_ref) return (0); } - mlnds->pdu_scan_offset += n_pad; + nds->pdu_scan_offset += n_pad; return (1); } int -mlndr_outer_grow(struct ndr_reference *outer_ref, unsigned n_total) +ndr_outer_grow(ndr_ref_t *outer_ref, unsigned n_total) { - struct mlndr_stream *mlnds = outer_ref->stream; - unsigned long pdu_want_size; - int rc, is_ok = 0; + ndr_stream_t *nds = outer_ref->stream; + unsigned long pdu_want_size; + int rc, is_ok = 0; - pdu_want_size = mlnds->pdu_scan_offset + n_total; + pdu_want_size = nds->pdu_scan_offset + n_total; - if (pdu_want_size <= mlnds->pdu_max_size) { + if (pdu_want_size <= nds->pdu_max_size) { is_ok = 1; } - switch (mlnds->m_op) { + switch (nds->m_op) { case NDR_M_OP_MARSHALL: if (is_ok) break; - rc = MLNDS_GROW_PDU(mlnds, pdu_want_size, outer_ref); + rc = NDS_GROW_PDU(nds, pdu_want_size, outer_ref); if (!rc) { NDR_SET_ERROR(outer_ref, NDR_ERR_GROW_FAILED); return (0); @@ -1505,8 +1498,8 @@ mlndr_outer_grow(struct ndr_reference *outer_ref, unsigned n_total) return (0); } - if (mlnds->pdu_size < pdu_want_size) - mlnds->pdu_size = pdu_want_size; + if (nds->pdu_size < pdu_want_size) + nds->pdu_size = pdu_want_size; outer_ref->pdu_end_offset = pdu_want_size; return (1); @@ -1518,7 +1511,7 @@ mlndr_outer_grow(struct ndr_reference *outer_ref, unsigned n_total) * The local datum (arg_ref->datum) already exists, there is no need to * malloc() it. The datum should point at a member of a structure. * - * For the most part, mlndr_inner() and its helpers are just a sanity + * For the most part, ndr_inner() and its helpers are just a sanity * check. The underlying ti->ndr_func() could be called immediately * for non-pointer elements. For the sake of robustness, we detect * run-time errors here. Most of the situations this protects against @@ -1527,9 +1520,9 @@ mlndr_outer_grow(struct ndr_reference *outer_ref, unsigned n_total) * place to work from for debugging. */ int -mlndr_inner(struct ndr_reference *arg_ref) +ndr_inner(ndr_ref_t *arg_ref) { - struct ndr_typeinfo *ti = arg_ref->ti; + ndr_typeinfo_t *ti = arg_ref->ti; int is_varlen = ti->pdu_size_variable_part; int is_union = NDR_IS_UNION(ti); int error = NDR_ERR_INNER_PARAMS_BAD; @@ -1559,11 +1552,11 @@ mlndr_inner(struct ndr_reference *arg_ref) break; } if (params & NDR_F_IS_POINTER) - return (mlndr_inner_pointer(arg_ref)); + return (ndr_inner_pointer(arg_ref)); else if (params & NDR_F_IS_REFERENCE) - return (mlndr_inner_reference(arg_ref)); + return (ndr_inner_reference(arg_ref)); else - return (mlndr_inner_array(arg_ref)); + return (ndr_inner_array(arg_ref)); break; case NDR_F_IS_POINTER: /* type is pointer to one something */ @@ -1571,7 +1564,7 @@ mlndr_inner(struct ndr_reference *arg_ref) error = NDR_ERR_ARRAY_UNION_ILLEGAL; break; } - return (mlndr_inner_pointer(arg_ref)); + return (ndr_inner_pointer(arg_ref)); break; case NDR_F_IS_REFERENCE: /* type is pointer to one something */ @@ -1579,7 +1572,7 @@ mlndr_inner(struct ndr_reference *arg_ref) error = NDR_ERR_ARRAY_UNION_ILLEGAL; break; } - return (mlndr_inner_reference(arg_ref)); + return (ndr_inner_reference(arg_ref)); break; case NDR_F_SWITCH_IS: @@ -1604,19 +1597,19 @@ mlndr_inner(struct ndr_reference *arg_ref) } int -mlndr_inner_pointer(struct ndr_reference *arg_ref) +ndr_inner_pointer(ndr_ref_t *arg_ref) { - struct mlndr_stream *mlnds = arg_ref->stream; + ndr_stream_t *nds = arg_ref->stream; /*LINTED E_BAD_PTR_CAST_ALIGN*/ - char **valpp = (char **)arg_ref->datum; - struct ndr_reference *outer_ref; + char **valpp = (char **)arg_ref->datum; + ndr_ref_t *outer_ref; - if (!mlndr__ulong(arg_ref)) + if (!ndr__ulong(arg_ref)) return (0); /* error */ if (!*valpp) return (1); /* NULL pointer */ - outer_ref = mlndr_enter_outer_queue(arg_ref); + outer_ref = ndr_enter_outer_queue(arg_ref); if (!outer_ref) return (0); /* error already set */ @@ -1632,7 +1625,7 @@ mlndr_inner_pointer(struct ndr_reference *arg_ref) outer_ref->backptr = valpp; - switch (mlnds->m_op) { + switch (nds->m_op) { case NDR_M_OP_MARSHALL: outer_ref->datum = *valpp; break; @@ -1652,14 +1645,14 @@ mlndr_inner_pointer(struct ndr_reference *arg_ref) } int -mlndr_inner_reference(struct ndr_reference *arg_ref) +ndr_inner_reference(ndr_ref_t *arg_ref) { - struct mlndr_stream *mlnds = arg_ref->stream; + ndr_stream_t *nds = arg_ref->stream; /*LINTED E_BAD_PTR_CAST_ALIGN*/ - char **valpp = (char **)arg_ref->datum; - struct ndr_reference *outer_ref; + char **valpp = (char **)arg_ref->datum; + ndr_ref_t *outer_ref; - outer_ref = mlndr_enter_outer_queue(arg_ref); + outer_ref = ndr_enter_outer_queue(arg_ref); if (!outer_ref) return (0); /* error already set */ @@ -1675,7 +1668,7 @@ mlndr_inner_reference(struct ndr_reference *arg_ref) outer_ref->backptr = valpp; - switch (mlnds->m_op) { + switch (nds->m_op) { case NDR_M_OP_MARSHALL: outer_ref->datum = *valpp; break; @@ -1695,10 +1688,10 @@ mlndr_inner_reference(struct ndr_reference *arg_ref) } int -mlndr_inner_array(struct ndr_reference *encl_ref) +ndr_inner_array(ndr_ref_t *encl_ref) { - struct ndr_typeinfo *ti = encl_ref->ti; - struct ndr_reference myref; + ndr_typeinfo_t *ti = encl_ref->ti; + ndr_ref_t myref; unsigned long pdu_offset = encl_ref->pdu_offset; unsigned long n_elem; unsigned long i; @@ -1706,7 +1699,7 @@ mlndr_inner_array(struct ndr_reference *encl_ref) if (encl_ref->inner_flags & NDR_F_SIZE_IS) { /* now is the time to check/set size */ - if (!mlndr_size_is(encl_ref)) + if (!ndr_size_is(encl_ref)) return (0); /* error already set */ n_elem = encl_ref->size_is; } else { @@ -1727,7 +1720,7 @@ mlndr_inner_array(struct ndr_reference *encl_ref) myref.pdu_offset = pdu_offset + i * ti->pdu_size_fixed_part; myref.datum = encl_ref->datum + i * ti->c_size_fixed_part; - if (!mlndr_inner(&myref)) + if (!ndr_inner(&myref)) return (0); } @@ -1739,47 +1732,43 @@ mlndr_inner_array(struct ndr_reference *encl_ref) * BASIC TYPES */ #define MAKE_BASIC_TYPE_BASE(TYPE, SIZE) \ - extern int mlndr_##TYPE(struct ndr_reference *encl_ref); \ - struct ndr_typeinfo ndt_##TYPE = { \ + extern int ndr_##TYPE(struct ndr_reference *encl_ref); \ + ndr_typeinfo_t ndt_##TYPE = { \ 1, /* NDR version */ \ (SIZE)-1, /* alignment */ \ NDR_F_NONE, /* flags */ \ - mlndr_##TYPE, /* ndr_func */ \ + ndr_##TYPE, /* ndr_func */ \ SIZE, /* pdu_size_fixed_part */ \ 0, /* pdu_size_variable_part */ \ SIZE, /* c_size_fixed_part */ \ 0, /* c_size_variable_part */ \ }; \ - int mlndr_##TYPE(struct ndr_reference *ref) { \ - return (mlndr_basic_integer(ref, SIZE)); \ + int ndr_##TYPE(struct ndr_reference *ref) { \ + return (ndr_basic_integer(ref, SIZE)); \ } #define MAKE_BASIC_TYPE_STRING(TYPE, SIZE) \ - extern int mlndr_s##TYPE(struct ndr_reference *encl_ref); \ - struct ndr_typeinfo ndt_s##TYPE = { \ + extern int ndr_s##TYPE(struct ndr_reference *encl_ref); \ + ndr_typeinfo_t ndt_s##TYPE = { \ 1, /* NDR version */ \ (SIZE)-1, /* alignment */ \ NDR_F_STRING, /* flags */ \ - mlndr_s##TYPE, /* ndr_func */ \ + ndr_s##TYPE, /* ndr_func */ \ 0, /* pdu_size_fixed_part */ \ SIZE, /* pdu_size_variable_part */ \ 0, /* c_size_fixed_part */ \ SIZE, /* c_size_variable_part */ \ }; \ - int mlndr_s##TYPE(struct ndr_reference *ref) { \ - return (mlndr_string_basic_integer(ref, &ndt_##TYPE)); \ + int ndr_s##TYPE(struct ndr_reference *ref) { \ + return (ndr_string_basic_integer(ref, &ndt_##TYPE)); \ } #define MAKE_BASIC_TYPE(TYPE, SIZE) \ MAKE_BASIC_TYPE_BASE(TYPE, SIZE) \ MAKE_BASIC_TYPE_STRING(TYPE, SIZE) -extern int -mlndr_basic_integer(struct ndr_reference *ref, unsigned size); - -extern int -mlndr_string_basic_integer(struct ndr_reference *encl_ref, - struct ndr_typeinfo *type_under); +int ndr_basic_integer(ndr_ref_t *, unsigned); +int ndr_string_basic_integer(ndr_ref_t *, ndr_typeinfo_t *); MAKE_BASIC_TYPE(_char, 1) @@ -1792,21 +1781,21 @@ MAKE_BASIC_TYPE(_ulong, 4) MAKE_BASIC_TYPE_BASE(_wchar, 2) int -mlndr_basic_integer(struct ndr_reference *ref, unsigned size) +ndr_basic_integer(ndr_ref_t *ref, unsigned size) { - struct mlndr_stream *mlnds = ref->stream; - char *valp = (char *)ref->datum; - int rc; + ndr_stream_t *nds = ref->stream; + char *valp = (char *)ref->datum; + int rc; - switch (mlnds->m_op) { + switch (nds->m_op) { case NDR_M_OP_MARSHALL: - rc = MLNDS_PUT_PDU(mlnds, ref->pdu_offset, size, - valp, mlnds->swap, ref); + rc = NDS_PUT_PDU(nds, ref->pdu_offset, size, + valp, nds->swap, ref); break; case NDR_M_OP_UNMARSHALL: - rc = MLNDS_GET_PDU(mlnds, ref->pdu_offset, size, - valp, mlnds->swap, ref); + rc = NDS_GET_PDU(nds, ref->pdu_offset, size, + valp, nds->swap, ref); break; default: @@ -1818,13 +1807,12 @@ mlndr_basic_integer(struct ndr_reference *ref, unsigned size) } int -mlndr_string_basic_integer(struct ndr_reference *encl_ref, - struct ndr_typeinfo *type_under) +ndr_string_basic_integer(ndr_ref_t *encl_ref, ndr_typeinfo_t *type_under) { unsigned long pdu_offset = encl_ref->pdu_offset; unsigned size = type_under->pdu_size_fixed_part; char *valp; - struct ndr_reference myref; + ndr_ref_t myref; unsigned long i; long sense = 0; char name[30]; @@ -1845,7 +1833,7 @@ mlndr_string_basic_integer(struct ndr_reference *encl_ref, valp = encl_ref->datum + i * size; myref.datum = valp; - if (!mlndr_inner(&myref)) + if (!ndr_inner(&myref)) return (0); switch (size) { @@ -1864,12 +1852,12 @@ mlndr_string_basic_integer(struct ndr_reference *encl_ref, } -extern int mlndr_s_wchar(struct ndr_reference *encl_ref); -struct ndr_typeinfo ndt_s_wchar = { +extern int ndr_s_wchar(ndr_ref_t *encl_ref); +ndr_typeinfo_t ndt_s_wchar = { 1, /* NDR version */ 2-1, /* alignment */ NDR_F_STRING, /* flags */ - mlndr_s_wchar, /* ndr_func */ + ndr_s_wchar, /* ndr_func */ 0, /* pdu_size_fixed_part */ 2, /* pdu_size_variable_part */ 0, /* c_size_fixed_part */ @@ -1889,23 +1877,23 @@ struct ndr_typeinfo ndt_s_wchar = { * null character. It now looks like NT does not always terminate * RPC Unicode strings and the terminating null is a side effect * of field alignment. So now we rely on the strlen_is (set up in - * mlndr_outer_string) of the enclosing reference. This may or may + * ndr_outer_string) of the enclosing reference. This may or may * not include the null but it doesn't matter, the algorithm will * get it right. */ int -mlndr_s_wchar(struct ndr_reference *encl_ref) +ndr_s_wchar(ndr_ref_t *encl_ref) { - struct mlndr_stream *mlnds = encl_ref->stream; + ndr_stream_t *nds = encl_ref->stream; unsigned short wide_char; char *valp; - struct ndr_reference myref; + ndr_ref_t myref; unsigned long i; char name[30]; int count; int char_count = 0; - if (mlnds->m_op == NDR_M_OP_UNMARSHALL) { + if (nds->m_op == NDR_M_OP_UNMARSHALL) { /* * To avoid problems with zero length strings * we can just null terminate here and be done. @@ -1932,7 +1920,7 @@ mlndr_s_wchar(struct ndr_reference *encl_ref) for (i = 0; i < NDR_STRING_MAX; i++) { (void) sprintf(name, "[%lu]", i); - if (mlnds->m_op == NDR_M_OP_MARSHALL) { + if (nds->m_op == NDR_M_OP_MARSHALL) { count = mts_mbtowc((mts_wchar_t *)&wide_char, valp, MTS_MB_CHAR_MAX); if (count < 0) { @@ -1951,10 +1939,10 @@ mlndr_s_wchar(struct ndr_reference *encl_ref) } } - if (!mlndr_inner(&myref)) + if (!ndr_inner(&myref)) return (0); - if (mlnds->m_op == NDR_M_OP_UNMARSHALL) { + if (nds->m_op == NDR_M_OP_UNMARSHALL) { count = mts_wctomb(valp, wide_char); if ((++char_count) == encl_ref->strlen_is) { @@ -1984,14 +1972,14 @@ mlndr_s_wchar(struct ndr_reference *encl_ref) * multibyte character is encountered. */ size_t -ndr_mbstowcs(struct mlndr_stream *mlnds, mts_wchar_t *wcs, const char *mbs, +ndr_mbstowcs(ndr_stream_t *nds, mts_wchar_t *wcs, const char *mbs, size_t nwchars) { mts_wchar_t *start = wcs; int nbytes; while (nwchars--) { - nbytes = ndr_mbtowc(mlnds, wcs, mbs, MTS_MB_CHAR_MAX); + nbytes = ndr_mbtowc(nds, wcs, mbs, MTS_MB_CHAR_MAX); if (nbytes < 0) { *wcs = 0; return ((size_t)-1); @@ -2016,8 +2004,8 @@ ndr_mbstowcs(struct mlndr_stream *mlnds, mts_wchar_t *wcs, const char *mbs, */ /*ARGSUSED*/ int -ndr_mbtowc(struct mlndr_stream *mlnds, mts_wchar_t *wcharp, - const char *mbchar, size_t nbytes) +ndr_mbtowc(ndr_stream_t *nds, mts_wchar_t *wcharp, const char *mbchar, + size_t nbytes) { int rc; @@ -2025,7 +2013,7 @@ ndr_mbtowc(struct mlndr_stream *mlnds, mts_wchar_t *wcharp, return (rc); #ifdef _BIG_ENDIAN - if (mlnds == NULL || NDR_MODE_MATCH(mlnds, NDR_MODE_RETURN_SEND)) + if (nds == NULL || NDR_MODE_MATCH(nds, NDR_MODE_RETURN_SEND)) *wcharp = BSWAP_16(*wcharp); #endif diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c index 76d414c1ca..7e15258c0d 100644 --- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c +++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c @@ -39,75 +39,65 @@ #include <smbsrv/libsmb.h> #include <smbsrv/libmlrpc.h> -#include <smbsrv/mlsvc.h> -#include <smbsrv/ndr.h> -#include <smbsrv/mlrpc.h> -#include <smbsrv/mlsvc_util.h> - - -#define SMB_CTXT_BUFSZ 65536 /* * Fragment size (5680: NT style). */ -#define MLRPC_FRAG_SZ 5680 -static unsigned long mlrpc_frag_size = MLRPC_FRAG_SZ; - -/* - * Service context table. - */ -#define CTXT_TABLE_ENTRIES 128 -static struct mlsvc_rpc_context context_table[CTXT_TABLE_ENTRIES]; -static mutex_t mlrpc_context_lock; - -static int ndr_s_transact(struct mlsvc_rpc_context *); -static struct mlsvc_rpc_context *ndr_s_lookup(int); -static void ndr_s_release(struct mlsvc_rpc_context *); -static struct mlsvc_rpc_context *ndr_s_allocate(int); -static void ndr_s_deallocate(struct mlsvc_rpc_context *); -static void ndr_s_rewind(struct mlsvc_rpc_context *); -static void ndr_s_flush(struct mlsvc_rpc_context *); - -static int mlrpc_s_process(struct mlrpc_xaction *); -static int mlrpc_s_bind(struct mlrpc_xaction *); -static int mlrpc_s_request(struct mlrpc_xaction *); -static void mlrpc_reply_prepare_hdr(struct mlrpc_xaction *); -static int mlrpc_s_alter_context(struct mlrpc_xaction *); -static void mlrpc_reply_fault(struct mlrpc_xaction *, unsigned long); -static int mlrpc_build_reply(struct mlrpc_xaction *); -static void mlrpc_build_frag(struct mlndr_stream *, uint8_t *, uint32_t); +#define NDR_FRAG_SZ 5680 + +#define NDR_PIPE_BUFSZ 65536 +#define NDR_PIPE_MAX 128 +static ndr_pipe_t ndr_pipe_table[NDR_PIPE_MAX]; +static mutex_t ndr_pipe_lock; + +static int ndr_pipe_transact(ndr_pipe_t *); +static ndr_pipe_t *ndr_pipe_lookup(int); +static void ndr_pipe_release(ndr_pipe_t *); +static ndr_pipe_t *ndr_pipe_allocate(int); +static void ndr_pipe_deallocate(ndr_pipe_t *); +static void ndr_pipe_rewind(ndr_pipe_t *); +static void ndr_pipe_flush(ndr_pipe_t *); + +static int ndr_svc_process(ndr_xa_t *); +static int ndr_svc_bind(ndr_xa_t *); +static int ndr_svc_request(ndr_xa_t *); +static void ndr_reply_prepare_hdr(ndr_xa_t *); +static int ndr_svc_alter_context(ndr_xa_t *); +static void ndr_reply_fault(ndr_xa_t *, unsigned long); +static int ndr_build_reply(ndr_xa_t *); +static void ndr_build_frag(ndr_stream_t *, uint8_t *, uint32_t); /* * Allocate and associate a service context with a fid. */ int -ndr_s_open(int fid, uint8_t *data, uint32_t datalen) +ndr_pipe_open(int fid, uint8_t *data, uint32_t datalen) { - struct mlsvc_rpc_context *svc; + ndr_pipe_t *np; - (void) mutex_lock(&mlrpc_context_lock); + (void) mutex_lock(&ndr_pipe_lock); - if ((svc = ndr_s_lookup(fid)) != NULL) { - ndr_s_release(svc); - (void) mutex_unlock(&mlrpc_context_lock); + if ((np = ndr_pipe_lookup(fid)) != NULL) { + ndr_pipe_release(np); + (void) mutex_unlock(&ndr_pipe_lock); return (EEXIST); } - if ((svc = ndr_s_allocate(fid)) == NULL) { - (void) mutex_unlock(&mlrpc_context_lock); + if ((np = ndr_pipe_allocate(fid)) == NULL) { + (void) mutex_unlock(&ndr_pipe_lock); return (ENOMEM); } - if (smb_opipe_context_decode(&svc->svc_ctx, data, datalen) == -1) { - ndr_s_release(svc); - (void) mutex_unlock(&mlrpc_context_lock); + if (smb_opipe_context_decode(&np->np_ctx, data, datalen) == -1) { + ndr_pipe_release(np); + (void) mutex_unlock(&ndr_pipe_lock); return (EINVAL); } - mlrpc_binding_pool_initialize(&svc->binding, svc->binding_pool, - CTXT_N_BINDING_POOL); + ndr_svc_binding_pool_init(&np->np_binding, np->np_binding_pool, + NDR_N_BINDING_POOL); - (void) mutex_unlock(&mlrpc_context_lock); + (void) mutex_unlock(&ndr_pipe_lock); return (0); } @@ -115,14 +105,14 @@ ndr_s_open(int fid, uint8_t *data, uint32_t datalen) * Release the context associated with a fid when an opipe is closed. */ int -ndr_s_close(int fid) +ndr_pipe_close(int fid) { - struct mlsvc_rpc_context *svc; + ndr_pipe_t *np; - (void) mutex_lock(&mlrpc_context_lock); + (void) mutex_lock(&ndr_pipe_lock); - if ((svc = ndr_s_lookup(fid)) == NULL) { - (void) mutex_unlock(&mlrpc_context_lock); + if ((np = ndr_pipe_lookup(fid)) == NULL) { + (void) mutex_unlock(&ndr_pipe_lock); return (ENOENT); } @@ -130,9 +120,9 @@ ndr_s_close(int fid) * Release twice: once for the lookup above * and again to close the fid. */ - ndr_s_release(svc); - ndr_s_release(svc); - (void) mutex_unlock(&mlrpc_context_lock); + ndr_pipe_release(np); + ndr_pipe_release(np); + (void) mutex_unlock(&ndr_pipe_lock); return (0); } @@ -141,25 +131,25 @@ ndr_s_close(int fid) * until the response is requested. */ int -ndr_s_write(int fid, uint8_t *buf, uint32_t len) +ndr_pipe_write(int fid, uint8_t *buf, uint32_t len) { - struct mlsvc_rpc_context *svc; + ndr_pipe_t *np; ssize_t nbytes; if (len == 0) return (0); - (void) mutex_lock(&mlrpc_context_lock); + (void) mutex_lock(&ndr_pipe_lock); - if ((svc = ndr_s_lookup(fid)) == NULL) { - (void) mutex_unlock(&mlrpc_context_lock); + if ((np = ndr_pipe_lookup(fid)) == NULL) { + (void) mutex_unlock(&ndr_pipe_lock); return (ENOENT); } - nbytes = ndr_uiomove((caddr_t)buf, len, UIO_READ, &svc->in_uio); + nbytes = ndr_uiomove((caddr_t)buf, len, UIO_READ, &np->np_uio); - ndr_s_release(svc); - (void) mutex_unlock(&mlrpc_context_lock); + ndr_pipe_release(np); + (void) mutex_unlock(&ndr_pipe_lock); return ((nbytes == len) ? 0 : EIO); } @@ -170,9 +160,9 @@ ndr_s_write(int fid, uint8_t *buf, uint32_t len) * the output stream. */ int -ndr_s_read(int fid, uint8_t *buf, uint32_t *len, uint32_t *resid) +ndr_pipe_read(int fid, uint8_t *buf, uint32_t *len, uint32_t *resid) { - struct mlsvc_rpc_context *svc; + ndr_pipe_t *np; ssize_t nbytes = *len; int rc; @@ -181,37 +171,37 @@ ndr_s_read(int fid, uint8_t *buf, uint32_t *len, uint32_t *resid) return (0); } - (void) mutex_lock(&mlrpc_context_lock); - if ((svc = ndr_s_lookup(fid)) == NULL) { - (void) mutex_unlock(&mlrpc_context_lock); + (void) mutex_lock(&ndr_pipe_lock); + if ((np = ndr_pipe_lookup(fid)) == NULL) { + (void) mutex_unlock(&ndr_pipe_lock); return (ENOENT); } - (void) mutex_unlock(&mlrpc_context_lock); - - if (svc->in_uio.uio_offset) { - if ((rc = ndr_s_transact(svc)) != 0) { - ndr_s_flush(svc); - (void) mutex_lock(&mlrpc_context_lock); - ndr_s_release(svc); - (void) mutex_unlock(&mlrpc_context_lock); + (void) mutex_unlock(&ndr_pipe_lock); + + if (np->np_uio.uio_offset) { + if ((rc = ndr_pipe_transact(np)) != 0) { + ndr_pipe_flush(np); + (void) mutex_lock(&ndr_pipe_lock); + ndr_pipe_release(np); + (void) mutex_unlock(&ndr_pipe_lock); return (rc); } } - *len = ndr_uiomove((caddr_t)buf, nbytes, UIO_WRITE, &svc->frags.uio); - *resid = svc->frags.uio.uio_resid; + *len = ndr_uiomove((caddr_t)buf, nbytes, UIO_WRITE, &np->np_frags.uio); + *resid = np->np_frags.uio.uio_resid; if (*resid == 0) { /* * Nothing left, cleanup the output stream. */ - ndr_s_flush(svc); + ndr_pipe_flush(np); } - (void) mutex_lock(&mlrpc_context_lock); - ndr_s_release(svc); - (void) mutex_unlock(&mlrpc_context_lock); + (void) mutex_lock(&ndr_pipe_lock); + ndr_pipe_release(np); + (void) mutex_unlock(&ndr_pipe_lock); return (0); } @@ -219,70 +209,70 @@ ndr_s_read(int fid, uint8_t *buf, uint32_t *len, uint32_t *resid) * Process a server-side RPC request. */ static int -ndr_s_transact(struct mlsvc_rpc_context *svc) +ndr_pipe_transact(ndr_pipe_t *np) { - ndr_xa_t *mxa; - struct mlndr_stream *recv_mlnds; - struct mlndr_stream *send_mlnds; - char *data; - int datalen; + ndr_xa_t *mxa; + ndr_stream_t *recv_nds; + ndr_stream_t *send_nds; + char *data; + int datalen; - data = svc->in_buf; - datalen = svc->in_uio.uio_offset; + data = np->np_buf; + datalen = np->np_uio.uio_offset; if ((mxa = (ndr_xa_t *)malloc(sizeof (ndr_xa_t))) == NULL) return (ENOMEM); - bzero(mxa, sizeof (struct mlrpc_xaction)); - mxa->fid = svc->fid; - mxa->context = svc; - mxa->binding_list = svc->binding; + bzero(mxa, sizeof (ndr_xa_t)); + mxa->fid = np->np_fid; + mxa->pipe = np; + mxa->binding_list = np->np_binding; - if ((mxa->heap = mlrpc_heap_create()) == NULL) { + if ((mxa->heap = ndr_heap_create()) == NULL) { free(mxa); return (ENOMEM); } - recv_mlnds = &mxa->recv_mlnds; - mlnds_initialize(recv_mlnds, datalen, NDR_MODE_CALL_RECV, mxa->heap); + recv_nds = &mxa->recv_nds; + nds_initialize(recv_nds, datalen, NDR_MODE_CALL_RECV, mxa->heap); /* * Copy the input data and reset the input stream. */ - bcopy(data, recv_mlnds->pdu_base_addr, datalen); - ndr_s_rewind(svc); + bcopy(data, recv_nds->pdu_base_addr, datalen); + ndr_pipe_rewind(np); - send_mlnds = &mxa->send_mlnds; - mlnds_initialize(send_mlnds, 0, NDR_MODE_RETURN_SEND, mxa->heap); + send_nds = &mxa->send_nds; + nds_initialize(send_nds, 0, NDR_MODE_RETURN_SEND, mxa->heap); - (void) mlrpc_s_process(mxa); + (void) ndr_svc_process(mxa); - mlnds_finalize(send_mlnds, &svc->frags); - mlnds_destruct(&mxa->recv_mlnds); - mlnds_destruct(&mxa->send_mlnds); - mlrpc_heap_destroy(mxa->heap); + nds_finalize(send_nds, &np->np_frags); + nds_destruct(&mxa->recv_nds); + nds_destruct(&mxa->send_nds); + ndr_heap_destroy(mxa->heap); free(mxa); return (0); } /* - * Must be called with mlrpc_context_lock held. + * Must be called with ndr_pipe_lock held. */ -static struct mlsvc_rpc_context * -ndr_s_lookup(int fid) +static ndr_pipe_t * +ndr_pipe_lookup(int fid) { - struct mlsvc_rpc_context *svc; + ndr_pipe_t *np; int i; - for (i = 0; i < CTXT_TABLE_ENTRIES; ++i) { - svc = &context_table[i]; + for (i = 0; i < NDR_PIPE_MAX; ++i) { + np = &ndr_pipe_table[i]; - if (svc->fid == fid) { - if (svc->refcnt == 0) + if (np->np_fid == fid) { + if (np->np_refcnt == 0) return (NULL); - svc->refcnt++; - return (svc); + np->np_refcnt++; + return (np); } } @@ -290,37 +280,37 @@ ndr_s_lookup(int fid) } /* - * Must be called with mlrpc_context_lock held. + * Must be called with ndr_pipe_lock held. */ static void -ndr_s_release(struct mlsvc_rpc_context *svc) +ndr_pipe_release(ndr_pipe_t *np) { - svc->refcnt--; - ndr_s_deallocate(svc); + np->np_refcnt--; + ndr_pipe_deallocate(np); } /* - * Must be called with mlrpc_context_lock held. + * Must be called with ndr_pipe_lock held. */ -static struct mlsvc_rpc_context * -ndr_s_allocate(int fid) +static ndr_pipe_t * +ndr_pipe_allocate(int fid) { - struct mlsvc_rpc_context *svc = NULL; + ndr_pipe_t *np = NULL; int i; - for (i = 0; i < CTXT_TABLE_ENTRIES; ++i) { - svc = &context_table[i]; + for (i = 0; i < NDR_PIPE_MAX; ++i) { + np = &ndr_pipe_table[i]; - if (svc->fid == 0) { - bzero(svc, sizeof (struct mlsvc_rpc_context)); + if (np->np_fid == 0) { + bzero(np, sizeof (ndr_pipe_t)); - if ((svc->in_buf = malloc(SMB_CTXT_BUFSZ)) == NULL) + if ((np->np_buf = malloc(NDR_PIPE_BUFSZ)) == NULL) return (NULL); - ndr_s_rewind(svc); - svc->fid = fid; - svc->refcnt = 1; - return (svc); + ndr_pipe_rewind(np); + np->np_fid = fid; + np->np_refcnt = 1; + return (np); } } @@ -328,25 +318,25 @@ ndr_s_allocate(int fid) } /* - * Must be called with mlrpc_context_lock held. + * Must be called with ndr_pipe_lock held. */ static void -ndr_s_deallocate(struct mlsvc_rpc_context *svc) +ndr_pipe_deallocate(ndr_pipe_t *np) { - if (svc->refcnt == 0) { + if (np->np_refcnt == 0) { /* * Ensure that there are no RPC service policy handles * (associated with this fid) left around. */ - ndr_hdclose(svc->fid); - - ndr_s_rewind(svc); - ndr_s_flush(svc); - free(svc->in_buf); - free(svc->svc_ctx.oc_domain); - free(svc->svc_ctx.oc_account); - free(svc->svc_ctx.oc_workstation); - bzero(svc, sizeof (struct mlsvc_rpc_context)); + ndr_hdclose(np->np_fid); + + ndr_pipe_rewind(np); + ndr_pipe_flush(np); + free(np->np_buf); + free(np->np_ctx.oc_domain); + free(np->np_ctx.oc_account); + free(np->np_ctx.oc_workstation); + bzero(np, sizeof (ndr_pipe_t)); } } @@ -354,32 +344,32 @@ ndr_s_deallocate(struct mlsvc_rpc_context *svc) * Rewind the input data stream, ready for the next write. */ static void -ndr_s_rewind(struct mlsvc_rpc_context *svc) +ndr_pipe_rewind(ndr_pipe_t *np) { - svc->in_uio.uio_iov = &svc->in_iov; - svc->in_uio.uio_iovcnt = 1; - svc->in_uio.uio_offset = 0; - svc->in_uio.uio_segflg = UIO_USERSPACE; - svc->in_uio.uio_resid = SMB_CTXT_BUFSZ; - svc->in_iov.iov_base = svc->in_buf; - svc->in_iov.iov_len = SMB_CTXT_BUFSZ; + np->np_uio.uio_iov = &np->np_iov; + np->np_uio.uio_iovcnt = 1; + np->np_uio.uio_offset = 0; + np->np_uio.uio_segflg = UIO_USERSPACE; + np->np_uio.uio_resid = NDR_PIPE_BUFSZ; + np->np_iov.iov_base = np->np_buf; + np->np_iov.iov_len = NDR_PIPE_BUFSZ; } /* * Flush the output data stream. */ static void -ndr_s_flush(struct mlsvc_rpc_context *svc) +ndr_pipe_flush(ndr_pipe_t *np) { ndr_frag_t *frag; - while ((frag = svc->frags.head) != NULL) { - svc->frags.head = frag->next; + while ((frag = np->np_frags.head) != NULL) { + np->np_frags.head = frag->next; free(frag); } - free(svc->frags.iov); - bzero(&svc->frags, sizeof (ndr_fraglist_t)); + free(np->np_frags.iov); + bzero(&np->np_frags, sizeof (ndr_fraglist_t)); } /* @@ -390,9 +380,9 @@ ndr_s_flush(struct mlsvc_rpc_context *svc) boolean_t ndr_is_admin(ndr_xa_t *xa) { - smb_opipe_context_t *svc = &xa->context->svc_ctx; + smb_opipe_context_t *ctx = &xa->pipe->np_ctx; - return (svc->oc_flags & SMB_ATF_ADMIN); + return (ctx->oc_flags & SMB_ATF_ADMIN); } /* @@ -404,18 +394,18 @@ ndr_is_admin(ndr_xa_t *xa) boolean_t ndr_is_poweruser(ndr_xa_t *xa) { - smb_opipe_context_t *svc = &xa->context->svc_ctx; + smb_opipe_context_t *ctx = &xa->pipe->np_ctx; - return ((svc->oc_flags & SMB_ATF_ADMIN) || - (svc->oc_flags & SMB_ATF_POWERUSER)); + return ((ctx->oc_flags & SMB_ATF_ADMIN) || + (ctx->oc_flags & SMB_ATF_POWERUSER)); } int32_t ndr_native_os(ndr_xa_t *xa) { - smb_opipe_context_t *svc = &xa->context->svc_ctx; + smb_opipe_context_t *ctx = &xa->pipe->np_ctx; - return (svc->oc_native_os); + return (ctx->oc_native_os); } /* @@ -423,38 +413,38 @@ ndr_native_os(ndr_xa_t *xa) * It is assumed that the PDU has already been received. */ static int -mlrpc_s_process(struct mlrpc_xaction *mxa) +ndr_svc_process(ndr_xa_t *mxa) { int rc; - rc = mlrpc_decode_pdu_hdr(mxa); - if (!MLRPC_DRC_IS_OK(rc)) + rc = ndr_decode_pdu_hdr(mxa); + if (!NDR_DRC_IS_OK(rc)) return (-1); - (void) mlrpc_reply_prepare_hdr(mxa); + (void) ndr_reply_prepare_hdr(mxa); switch (mxa->ptype) { - case MLRPC_PTYPE_BIND: - rc = mlrpc_s_bind(mxa); + case NDR_PTYPE_BIND: + rc = ndr_svc_bind(mxa); break; - case MLRPC_PTYPE_REQUEST: - rc = mlrpc_s_request(mxa); + case NDR_PTYPE_REQUEST: + rc = ndr_svc_request(mxa); break; - case MLRPC_PTYPE_ALTER_CONTEXT: - rc = mlrpc_s_alter_context(mxa); + case NDR_PTYPE_ALTER_CONTEXT: + rc = ndr_svc_alter_context(mxa); break; default: - rc = MLRPC_DRC_FAULT_RPCHDR_PTYPE_INVALID; + rc = NDR_DRC_FAULT_RPCHDR_PTYPE_INVALID; break; } - if (MLRPC_DRC_IS_FAULT(rc)) - mlrpc_reply_fault(mxa, rc); + if (NDR_DRC_IS_FAULT(rc)) + ndr_reply_fault(mxa, rc); - (void) mlrpc_build_reply(mxa); + (void) ndr_build_reply(mxa); return (rc); } @@ -463,23 +453,20 @@ mlrpc_s_process(struct mlrpc_xaction *mxa) * p_results[] not supported. */ static int -mlrpc_s_bind(struct mlrpc_xaction *mxa) +ndr_svc_bind(ndr_xa_t *mxa) { - mlrpc_p_cont_list_t *cont_list; - mlrpc_p_result_list_t *result_list; - mlrpc_p_result_t *result; + ndr_p_cont_list_t *cont_list; + ndr_p_result_list_t *result_list; + ndr_p_result_t *result; unsigned p_cont_id; - struct mlrpc_binding *mbind; + ndr_binding_t *mbind; ndr_uuid_t *as_uuid; ndr_uuid_t *ts_uuid; - char as_buf[64]; - char ts_buf[64]; int as_vers; int ts_vers; - struct mlndr_stream *send_mlnds; - struct mlrpc_service *msvc; + ndr_service_t *msvc; int rc; - mlrpc_port_any_t *sec_addr; + ndr_port_any_t *sec_addr; /* acquire targets */ cont_list = &mxa->recv_hdr.bind_hdr.p_context_elem; @@ -490,7 +477,6 @@ mlrpc_s_bind(struct mlrpc_xaction *mxa) * Set up temporary secondary address port. * We will correct this later (below). */ - send_mlnds = &mxa->send_mlnds; sec_addr = &mxa->send_hdr.bind_ack_hdr.sec_addr; sec_addr->length = 13; (void) strcpy((char *)sec_addr->port_spec, "\\PIPE\\ntsvcs"); @@ -498,35 +484,34 @@ mlrpc_s_bind(struct mlrpc_xaction *mxa) result_list->n_results = 1; result_list->reserved = 0; result_list->reserved2 = 0; - result->result = MLRPC_PCDR_ACCEPTANCE; + result->result = NDR_PCDR_ACCEPTANCE; result->reason = 0; bzero(&result->transfer_syntax, sizeof (result->transfer_syntax)); /* sanity check */ if (cont_list->n_context_elem != 1 || cont_list->p_cont_elem[0].n_transfer_syn != 1) { - mlndo_trace("mlrpc_s_bind: warning: multiple p_cont_elem"); + ndo_trace("ndr_svc_bind: warning: multiple p_cont_elem"); } p_cont_id = cont_list->p_cont_elem[0].p_cont_id; - if ((mbind = mlrpc_find_binding(mxa, p_cont_id)) != NULL) { + if ((mbind = ndr_svc_find_binding(mxa, p_cont_id)) != NULL) { /* - * Duplicate p_cont_id. - * Send a bind_ack with a better error. + * Duplicate presentation context id. */ - mlndo_trace("mlrpc_s_bind: duplicate binding"); - return (MLRPC_DRC_FAULT_BIND_PCONT_BUSY); + ndo_trace("ndr_svc_bind: duplicate binding"); + return (NDR_DRC_FAULT_BIND_PCONT_BUSY); } - if ((mbind = mlrpc_new_binding(mxa)) == NULL) { + if ((mbind = ndr_svc_new_binding(mxa)) == NULL) { /* * No free binding slot */ - result->result = MLRPC_PCDR_PROVIDER_REJECTION; - result->reason = MLRPC_PPR_LOCAL_LIMIT_EXCEEDED; - mlndo_trace("mlrpc_s_bind: no resources"); - return (MLRPC_DRC_OK); + result->result = NDR_PCDR_PROVIDER_REJECTION; + result->reason = NDR_PPR_LOCAL_LIMIT_EXCEEDED; + ndo_trace("ndr_svc_bind: no resources"); + return (NDR_DRC_OK); } as_uuid = &cont_list->p_cont_elem[0].abstract_syntax.if_uuid; @@ -535,18 +520,11 @@ mlrpc_s_bind(struct mlrpc_xaction *mxa) ts_uuid = &cont_list->p_cont_elem[0].transfer_syntaxes[0].if_uuid; ts_vers = cont_list->p_cont_elem[0].transfer_syntaxes[0].if_version; - msvc = mlrpc_find_service_by_uuids(as_uuid, as_vers, ts_uuid, ts_vers); - if (!msvc) { - mlrpc_uuid_to_str(as_uuid, as_buf); - mlrpc_uuid_to_str(ts_uuid, ts_buf); - - mlndo_printf(send_mlnds, 0, "mlrpc_s_bind: unknown service"); - mlndo_printf(send_mlnds, 0, "abs=%s v%d, xfer=%s v%d", - as_buf, as_vers, ts_buf, ts_vers); - - result->result = MLRPC_PCDR_PROVIDER_REJECTION; - result->reason = MLRPC_PPR_ABSTRACT_SYNTAX_NOT_SUPPORTED; - return (MLRPC_DRC_OK); + msvc = ndr_svc_lookup_uuid(as_uuid, as_vers, ts_uuid, ts_vers); + if (msvc == NULL) { + result->result = NDR_PCDR_PROVIDER_REJECTION; + result->reason = NDR_PPR_ABSTRACT_SYNTAX_NOT_SUPPORTED; + return (NDR_DRC_OK); } /* @@ -555,10 +533,10 @@ mlrpc_s_bind(struct mlrpc_xaction *mxa) sec_addr = &mxa->send_hdr.bind_ack_hdr.sec_addr; sec_addr->length = strlen(msvc->sec_addr_port) + 1; (void) strlcpy((char *)sec_addr->port_spec, msvc->sec_addr_port, - MLRPC_PORT_ANY_MAX_PORT_SPEC); + NDR_PORT_ANY_MAX_PORT_SPEC); mbind->p_cont_id = p_cont_id; - mbind->which_side = MLRPC_BIND_SIDE_SERVER; + mbind->which_side = NDR_BIND_SIDE_SERVER; /* mbind->context set by app */ mbind->service = msvc; mbind->instance_specific = 0; @@ -572,7 +550,7 @@ mlrpc_s_bind(struct mlrpc_xaction *mxa) * on the bind ack. */ rc = (msvc->bind_req)(mxa); - if (MLRPC_DRC_IS_FAULT(rc)) { + if (NDR_DRC_IS_FAULT(rc)) { mbind->service = 0; /* free binding slot */ mbind->which_side = 0; mbind->p_cont_id = 0; @@ -584,30 +562,30 @@ mlrpc_s_bind(struct mlrpc_xaction *mxa) result->transfer_syntax = cont_list->p_cont_elem[0].transfer_syntaxes[0]; - return (MLRPC_DRC_BINDING_MADE); + return (NDR_DRC_BINDING_MADE); } /* - * mlrpc_s_alter_context + * ndr_svc_alter_context * * The alter context request is used to request additional presentation * context for another interface and/or version. It is very similar to * a bind request. */ static int -mlrpc_s_alter_context(struct mlrpc_xaction *mxa) +ndr_svc_alter_context(ndr_xa_t *mxa) { - mlrpc_p_result_list_t *result_list; - mlrpc_p_result_t *result; - mlrpc_p_cont_list_t *cont_list; - struct mlrpc_binding *mbind; - struct mlrpc_service *msvc; + ndr_p_result_list_t *result_list; + ndr_p_result_t *result; + ndr_p_cont_list_t *cont_list; + ndr_binding_t *mbind; + ndr_service_t *msvc; unsigned p_cont_id; ndr_uuid_t *as_uuid; ndr_uuid_t *ts_uuid; int as_vers; int ts_vers; - mlrpc_port_any_t *sec_addr; + ndr_port_any_t *sec_addr; result_list = &mxa->send_hdr.alter_context_rsp_hdr.p_result_list; result_list->n_results = 1; @@ -615,20 +593,20 @@ mlrpc_s_alter_context(struct mlrpc_xaction *mxa) result_list->reserved2 = 0; result = &result_list->p_results[0]; - result->result = MLRPC_PCDR_ACCEPTANCE; + result->result = NDR_PCDR_ACCEPTANCE; result->reason = 0; bzero(&result->transfer_syntax, sizeof (result->transfer_syntax)); cont_list = &mxa->recv_hdr.alter_context_hdr.p_context_elem; p_cont_id = cont_list->p_cont_elem[0].p_cont_id; - if (mlrpc_find_binding(mxa, p_cont_id) != NULL) - return (MLRPC_DRC_FAULT_BIND_PCONT_BUSY); + if (ndr_svc_find_binding(mxa, p_cont_id) != NULL) + return (NDR_DRC_FAULT_BIND_PCONT_BUSY); - if ((mbind = mlrpc_new_binding(mxa)) == NULL) { - result->result = MLRPC_PCDR_PROVIDER_REJECTION; - result->reason = MLRPC_PPR_LOCAL_LIMIT_EXCEEDED; - return (MLRPC_DRC_OK); + if ((mbind = ndr_svc_new_binding(mxa)) == NULL) { + result->result = NDR_PCDR_PROVIDER_REJECTION; + result->reason = NDR_PPR_LOCAL_LIMIT_EXCEEDED; + return (NDR_DRC_OK); } as_uuid = &cont_list->p_cont_elem[0].abstract_syntax.if_uuid; @@ -637,15 +615,15 @@ mlrpc_s_alter_context(struct mlrpc_xaction *mxa) ts_uuid = &cont_list->p_cont_elem[0].transfer_syntaxes[0].if_uuid; ts_vers = cont_list->p_cont_elem[0].transfer_syntaxes[0].if_version; - msvc = mlrpc_find_service_by_uuids(as_uuid, as_vers, ts_uuid, ts_vers); - if (msvc == 0) { - result->result = MLRPC_PCDR_PROVIDER_REJECTION; - result->reason = MLRPC_PPR_ABSTRACT_SYNTAX_NOT_SUPPORTED; - return (MLRPC_DRC_OK); + msvc = ndr_svc_lookup_uuid(as_uuid, as_vers, ts_uuid, ts_vers); + if (msvc == NULL) { + result->result = NDR_PCDR_PROVIDER_REJECTION; + result->reason = NDR_PPR_ABSTRACT_SYNTAX_NOT_SUPPORTED; + return (NDR_DRC_OK); } mbind->p_cont_id = p_cont_id; - mbind->which_side = MLRPC_BIND_SIDE_SERVER; + mbind->which_side = NDR_BIND_SIDE_SERVER; /* mbind->context set by app */ mbind->service = msvc; mbind->instance_specific = 0; @@ -653,27 +631,27 @@ mlrpc_s_alter_context(struct mlrpc_xaction *mxa) sec_addr = &mxa->send_hdr.alter_context_rsp_hdr.sec_addr; sec_addr->length = 0; - bzero(sec_addr->port_spec, MLRPC_PORT_ANY_MAX_PORT_SPEC); + bzero(sec_addr->port_spec, NDR_PORT_ANY_MAX_PORT_SPEC); result->transfer_syntax = cont_list->p_cont_elem[0].transfer_syntaxes[0]; - return (MLRPC_DRC_BINDING_MADE); + return (NDR_DRC_BINDING_MADE); } static int -mlrpc_s_request(struct mlrpc_xaction *mxa) +ndr_svc_request(ndr_xa_t *mxa) { - struct mlrpc_binding *mbind; - struct mlrpc_service *msvc; - unsigned p_cont_id; - int rc; + ndr_binding_t *mbind; + ndr_service_t *msvc; + unsigned p_cont_id; + int rc; mxa->opnum = mxa->recv_hdr.request_hdr.opnum; p_cont_id = mxa->recv_hdr.request_hdr.p_cont_id; - if ((mbind = mlrpc_find_binding(mxa, p_cont_id)) == NULL) - return (MLRPC_DRC_FAULT_REQUEST_PCONT_INVALID); + if ((mbind = ndr_svc_find_binding(mxa, p_cont_id)) == NULL) + return (NDR_DRC_FAULT_REQUEST_PCONT_INVALID); mxa->binding = mbind; msvc = mbind->service; @@ -681,15 +659,15 @@ mlrpc_s_request(struct mlrpc_xaction *mxa) /* * Make room for the response hdr. */ - mxa->send_mlnds.pdu_scan_offset = MLRPC_RSP_HDR_SIZE; + mxa->send_nds.pdu_scan_offset = NDR_RSP_HDR_SIZE; if (msvc->call_stub) rc = (*msvc->call_stub)(mxa); else - rc = mlrpc_generic_call_stub(mxa); + rc = ndr_generic_call_stub(mxa); - if (MLRPC_DRC_IS_FAULT(rc)) { - mlndo_printf(0, 0, "%s[0x%02x]: 0x%04x", + if (NDR_DRC_IS_FAULT(rc)) { + ndo_printf(0, 0, "%s[0x%02x]: 0x%04x", msvc->name, mxa->opnum, rc); } @@ -697,45 +675,45 @@ mlrpc_s_request(struct mlrpc_xaction *mxa) } /* - * The transaction and the two mlnds streams use the same heap, which + * The transaction and the two nds streams use the same heap, which * should already exist at this point. The heap will also be available * to the stub. */ int -mlrpc_generic_call_stub(struct mlrpc_xaction *mxa) +ndr_generic_call_stub(ndr_xa_t *mxa) { - struct mlrpc_binding *mbind = mxa->binding; - struct mlrpc_service *msvc = mbind->service; - struct ndr_typeinfo *intf_ti = msvc->interface_ti; - struct mlrpc_stub_table *ste; + ndr_binding_t *mbind = mxa->binding; + ndr_service_t *msvc = mbind->service; + ndr_typeinfo_t *intf_ti = msvc->interface_ti; + ndr_stub_table_t *ste; int opnum = mxa->opnum; unsigned p_len = intf_ti->c_size_fixed_part; char *param; int rc; if (mxa->heap == NULL) { - mlndo_printf(0, 0, "%s[0x%02x]: no heap", msvc->name, opnum); - return (MLRPC_DRC_FAULT_OUT_OF_MEMORY); + ndo_printf(0, 0, "%s[0x%02x]: no heap", msvc->name, opnum); + return (NDR_DRC_FAULT_OUT_OF_MEMORY); } - if ((ste = mlrpc_find_stub_in_svc(msvc, opnum)) == NULL) { - mlndo_printf(0, 0, "%s[0x%02x]: invalid opnum", + if ((ste = ndr_svc_find_stub(msvc, opnum)) == NULL) { + ndo_printf(0, 0, "%s[0x%02x]: invalid opnum", msvc->name, opnum); - return (MLRPC_DRC_FAULT_REQUEST_OPNUM_INVALID); + return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); } - if ((param = mlrpc_heap_malloc(mxa->heap, p_len)) == NULL) - return (MLRPC_DRC_FAULT_OUT_OF_MEMORY); + if ((param = ndr_heap_malloc(mxa->heap, p_len)) == NULL) + return (NDR_DRC_FAULT_OUT_OF_MEMORY); bzero(param, p_len); - rc = mlrpc_decode_call(mxa, param); - if (!MLRPC_DRC_IS_OK(rc)) + rc = ndr_decode_call(mxa, param); + if (!NDR_DRC_IS_OK(rc)) return (rc); rc = (*ste->func)(param, mxa); - if (rc == MLRPC_DRC_OK) - rc = mlrpc_encode_return(mxa, param); + if (rc == NDR_DRC_OK) + rc = ndr_encode_return(mxa, param); return (rc); } @@ -746,29 +724,29 @@ mlrpc_generic_call_stub(struct mlrpc_xaction *mxa) * negotiation for use during subsequent RPC calls. */ static void -mlrpc_reply_prepare_hdr(struct mlrpc_xaction *mxa) +ndr_reply_prepare_hdr(ndr_xa_t *mxa) { ndr_common_header_t *rhdr = &mxa->recv_hdr.common_hdr; ndr_common_header_t *hdr = &mxa->send_hdr.common_hdr; hdr->rpc_vers = 5; hdr->rpc_vers_minor = 0; - hdr->pfc_flags = MLRPC_PFC_FIRST_FRAG + MLRPC_PFC_LAST_FRAG; + hdr->pfc_flags = NDR_PFC_FIRST_FRAG + NDR_PFC_LAST_FRAG; hdr->packed_drep = rhdr->packed_drep; hdr->frag_length = 0; hdr->auth_length = 0; hdr->call_id = rhdr->call_id; #ifdef _BIG_ENDIAN - hdr->packed_drep.intg_char_rep = MLRPC_REPLAB_CHAR_ASCII - | MLRPC_REPLAB_INTG_BIG_ENDIAN; + hdr->packed_drep.intg_char_rep = NDR_REPLAB_CHAR_ASCII + | NDR_REPLAB_INTG_BIG_ENDIAN; #else - hdr->packed_drep.intg_char_rep = MLRPC_REPLAB_CHAR_ASCII - | MLRPC_REPLAB_INTG_LITTLE_ENDIAN; + hdr->packed_drep.intg_char_rep = NDR_REPLAB_CHAR_ASCII + | NDR_REPLAB_INTG_LITTLE_ENDIAN; #endif switch (mxa->ptype) { - case MLRPC_PTYPE_BIND: - hdr->ptype = MLRPC_PTYPE_BIND_ACK; + case NDR_PTYPE_BIND: + hdr->ptype = NDR_PTYPE_BIND_ACK; mxa->send_hdr.bind_ack_hdr.max_xmit_frag = mxa->recv_hdr.bind_hdr.max_xmit_frag; mxa->send_hdr.bind_ack_hdr.max_recv_frag = @@ -783,16 +761,14 @@ mlrpc_reply_prepare_hdr(struct mlrpc_xaction *mxa) * Save the maximum fragment sizes * for use with subsequent requests. */ - mxa->context->max_xmit_frag = + mxa->pipe->np_max_xmit_frag = mxa->recv_hdr.bind_hdr.max_xmit_frag; - - mxa->context->max_recv_frag = + mxa->pipe->np_max_recv_frag = mxa->recv_hdr.bind_hdr.max_recv_frag; - break; - case MLRPC_PTYPE_REQUEST: - hdr->ptype = MLRPC_PTYPE_RESPONSE; + case NDR_PTYPE_REQUEST: + hdr->ptype = NDR_PTYPE_RESPONSE; /* mxa->send_hdr.response_hdr.alloc_hint */ mxa->send_hdr.response_hdr.p_cont_id = mxa->recv_hdr.request_hdr.p_cont_id; @@ -800,8 +776,8 @@ mlrpc_reply_prepare_hdr(struct mlrpc_xaction *mxa) mxa->send_hdr.response_hdr.reserved = 0; break; - case MLRPC_PTYPE_ALTER_CONTEXT: - hdr->ptype = MLRPC_PTYPE_ALTER_CONTEXT_RESP; + case NDR_PTYPE_ALTER_CONTEXT: + hdr->ptype = NDR_PTYPE_ALTER_CONTEXT_RESP; /* * The max_xmit_frag, max_recv_frag and assoc_group_id are * ignored by the client but it's useful to fill them in. @@ -824,55 +800,55 @@ mlrpc_reply_prepare_hdr(struct mlrpc_xaction *mxa) * was in the response header with the fault information. */ static void -mlrpc_reply_fault(struct mlrpc_xaction *mxa, unsigned long drc) +ndr_reply_fault(ndr_xa_t *mxa, unsigned long drc) { ndr_common_header_t *rhdr = &mxa->recv_hdr.common_hdr; ndr_common_header_t *hdr = &mxa->send_hdr.common_hdr; - struct mlndr_stream *mlnds = &mxa->send_mlnds; + ndr_stream_t *nds = &mxa->send_nds; unsigned long fault_status; - MLNDS_RESET(mlnds); + NDS_RESET(nds); hdr->rpc_vers = 5; hdr->rpc_vers_minor = 0; - hdr->pfc_flags = MLRPC_PFC_FIRST_FRAG + MLRPC_PFC_LAST_FRAG; + hdr->pfc_flags = NDR_PFC_FIRST_FRAG + NDR_PFC_LAST_FRAG; hdr->packed_drep = rhdr->packed_drep; hdr->frag_length = sizeof (mxa->send_hdr.fault_hdr); hdr->auth_length = 0; hdr->call_id = rhdr->call_id; #ifdef _BIG_ENDIAN - hdr->packed_drep.intg_char_rep = MLRPC_REPLAB_CHAR_ASCII - | MLRPC_REPLAB_INTG_BIG_ENDIAN; + hdr->packed_drep.intg_char_rep = NDR_REPLAB_CHAR_ASCII + | NDR_REPLAB_INTG_BIG_ENDIAN; #else - hdr->packed_drep.intg_char_rep = MLRPC_REPLAB_CHAR_ASCII - | MLRPC_REPLAB_INTG_LITTLE_ENDIAN; + hdr->packed_drep.intg_char_rep = NDR_REPLAB_CHAR_ASCII + | NDR_REPLAB_INTG_LITTLE_ENDIAN; #endif - switch (drc & MLRPC_DRC_MASK_SPECIFIER) { - case MLRPC_DRC_FAULT_OUT_OF_MEMORY: - case MLRPC_DRC_FAULT_ENCODE_TOO_BIG: - fault_status = MLRPC_FAULT_NCA_OUT_ARGS_TOO_BIG; + switch (drc & NDR_DRC_MASK_SPECIFIER) { + case NDR_DRC_FAULT_OUT_OF_MEMORY: + case NDR_DRC_FAULT_ENCODE_TOO_BIG: + fault_status = NDR_FAULT_NCA_OUT_ARGS_TOO_BIG; break; - case MLRPC_DRC_FAULT_REQUEST_PCONT_INVALID: - fault_status = MLRPC_FAULT_NCA_INVALID_PRES_CONTEXT_ID; + case NDR_DRC_FAULT_REQUEST_PCONT_INVALID: + fault_status = NDR_FAULT_NCA_INVALID_PRES_CONTEXT_ID; break; - case MLRPC_DRC_FAULT_REQUEST_OPNUM_INVALID: - fault_status = MLRPC_FAULT_NCA_OP_RNG_ERROR; + case NDR_DRC_FAULT_REQUEST_OPNUM_INVALID: + fault_status = NDR_FAULT_NCA_OP_RNG_ERROR; break; - case MLRPC_DRC_FAULT_DECODE_FAILED: - case MLRPC_DRC_FAULT_ENCODE_FAILED: - fault_status = MLRPC_FAULT_NCA_PROTO_ERROR; + case NDR_DRC_FAULT_DECODE_FAILED: + case NDR_DRC_FAULT_ENCODE_FAILED: + fault_status = NDR_FAULT_NCA_PROTO_ERROR; break; default: - fault_status = MLRPC_FAULT_NCA_UNSPEC_REJECT; + fault_status = NDR_FAULT_NCA_UNSPEC_REJECT; break; } - mxa->send_hdr.fault_hdr.common_hdr.ptype = MLRPC_PTYPE_FAULT; + mxa->send_hdr.fault_hdr.common_hdr.ptype = NDR_PTYPE_FAULT; mxa->send_hdr.fault_hdr.status = fault_status; mxa->send_hdr.response_hdr.alloc_hint = hdr->frag_length; } @@ -882,19 +858,19 @@ mlrpc_reply_fault(struct mlrpc_xaction *mxa, unsigned long drc) * non-standard. */ static int -mlrpc_build_reply(struct mlrpc_xaction *mxa) +ndr_build_reply(ndr_xa_t *mxa) { ndr_common_header_t *hdr = &mxa->send_hdr.common_hdr; - struct mlndr_stream *mlnds = &mxa->send_mlnds; + ndr_stream_t *nds = &mxa->send_nds; uint8_t *pdu_buf; unsigned long pdu_size; unsigned long frag_size; unsigned long pdu_data_size; unsigned long frag_data_size; - frag_size = mlrpc_frag_size; - pdu_size = mlnds->pdu_size; - pdu_buf = mlnds->pdu_base_addr; + frag_size = NDR_FRAG_SZ; + pdu_size = nds->pdu_size; + pdu_buf = nds->pdu_base_addr; if (pdu_size <= frag_size) { /* @@ -904,22 +880,22 @@ mlrpc_build_reply(struct mlrpc_xaction *mxa) * encoded. */ switch (hdr->ptype) { - case MLRPC_PTYPE_BIND_ACK: - hdr->frag_length = mlrpc_bind_ack_hdr_size(mxa); + case NDR_PTYPE_BIND_ACK: + hdr->frag_length = ndr_bind_ack_hdr_size(mxa); break; - case MLRPC_PTYPE_FAULT: + case NDR_PTYPE_FAULT: /* already setup */ break; - case MLRPC_PTYPE_RESPONSE: + case NDR_PTYPE_RESPONSE: hdr->frag_length = pdu_size; mxa->send_hdr.response_hdr.alloc_hint = hdr->frag_length; break; - case MLRPC_PTYPE_ALTER_CONTEXT_RESP: - hdr->frag_length = mlrpc_alter_context_rsp_hdr_size(); + case NDR_PTYPE_ALTER_CONTEXT_RESP: + hdr->frag_length = ndr_alter_context_rsp_hdr_size(); break; default: @@ -927,22 +903,22 @@ mlrpc_build_reply(struct mlrpc_xaction *mxa) break; } - mlnds->pdu_scan_offset = 0; - (void) mlrpc_encode_pdu_hdr(mxa); - pdu_size = mlnds->pdu_size; - mlrpc_build_frag(mlnds, pdu_buf, pdu_size); + nds->pdu_scan_offset = 0; + (void) ndr_encode_pdu_hdr(mxa); + pdu_size = nds->pdu_size; + ndr_build_frag(nds, pdu_buf, pdu_size); return (0); } /* * Multiple fragment response. */ - hdr->pfc_flags = MLRPC_PFC_FIRST_FRAG; + hdr->pfc_flags = NDR_PFC_FIRST_FRAG; hdr->frag_length = frag_size; - mxa->send_hdr.response_hdr.alloc_hint = pdu_size - MLRPC_RSP_HDR_SIZE; - mlnds->pdu_scan_offset = 0; - (void) mlrpc_encode_pdu_hdr(mxa); - mlrpc_build_frag(mlnds, pdu_buf, frag_size); + mxa->send_hdr.response_hdr.alloc_hint = pdu_size - NDR_RSP_HDR_SIZE; + nds->pdu_scan_offset = 0; + (void) ndr_encode_pdu_hdr(mxa); + ndr_build_frag(nds, pdu_buf, frag_size); /* * We need to update the 24-byte header in subsequent fragments. @@ -950,10 +926,10 @@ mlrpc_build_reply(struct mlrpc_xaction *mxa) * pdu_data_size: total data remaining to be handled * frag_size: total fragment size including header * frag_data_size: data in fragment - * (i.e. frag_size - MLRPC_RSP_HDR_SIZE) + * (i.e. frag_size - NDR_RSP_HDR_SIZE) */ - pdu_data_size = pdu_size - MLRPC_RSP_HDR_SIZE; - frag_data_size = frag_size - MLRPC_RSP_HDR_SIZE; + pdu_data_size = pdu_size - NDR_RSP_HDR_SIZE; + frag_data_size = frag_size - NDR_RSP_HDR_SIZE; while (pdu_data_size) { mxa->send_hdr.response_hdr.alloc_hint -= frag_data_size; @@ -962,20 +938,20 @@ mlrpc_build_reply(struct mlrpc_xaction *mxa) if (pdu_data_size <= frag_data_size) { frag_data_size = pdu_data_size; - frag_size = frag_data_size + MLRPC_RSP_HDR_SIZE; - hdr->pfc_flags = MLRPC_PFC_LAST_FRAG; + frag_size = frag_data_size + NDR_RSP_HDR_SIZE; + hdr->pfc_flags = NDR_PFC_LAST_FRAG; } else { hdr->pfc_flags = 0; } hdr->frag_length = frag_size; - mlnds->pdu_scan_offset = 0; - (void) mlrpc_encode_pdu_hdr(mxa); - bcopy(mlnds->pdu_base_addr, pdu_buf, MLRPC_RSP_HDR_SIZE); + nds->pdu_scan_offset = 0; + (void) ndr_encode_pdu_hdr(mxa); + bcopy(nds->pdu_base_addr, pdu_buf, NDR_RSP_HDR_SIZE); - mlrpc_build_frag(mlnds, pdu_buf, frag_size); + ndr_build_frag(nds, pdu_buf, frag_size); - if (hdr->pfc_flags & MLRPC_PFC_LAST_FRAG) + if (hdr->pfc_flags & NDR_PFC_LAST_FRAG) break; } @@ -983,14 +959,14 @@ mlrpc_build_reply(struct mlrpc_xaction *mxa) } /* - * mlrpc_build_frag + * ndr_build_frag * * Build an RPC PDU fragment from the specified buffer. * If malloc fails, the client will see a header/pdu inconsistency * and report an error. */ static void -mlrpc_build_frag(struct mlndr_stream *mlnds, uint8_t *buf, uint32_t len) +ndr_build_frag(ndr_stream_t *nds, uint8_t *buf, uint32_t len) { ndr_frag_t *frag; int size = sizeof (ndr_frag_t) + len; @@ -1003,13 +979,13 @@ mlrpc_build_frag(struct mlndr_stream *mlnds, uint8_t *buf, uint32_t len) frag->len = len; bcopy(buf, frag->buf, len); - if (mlnds->frags.head == NULL) { - mlnds->frags.head = frag; - mlnds->frags.tail = frag; - mlnds->frags.nfrag = 1; + if (nds->frags.head == NULL) { + nds->frags.head = frag; + nds->frags.tail = frag; + nds->frags.nfrag = 1; } else { - mlnds->frags.tail->next = frag; - mlnds->frags.tail = frag; - ++mlnds->frags.nfrag; + nds->frags.tail->next = frag; + nds->frags.tail = frag; + ++nds->frags.nfrag; } } diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_svc.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_svc.c index 8f034f66a8..febf45ab69 100644 --- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_svc.c +++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_svc.c @@ -23,9 +23,8 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - - +#include <uuid/uuid.h> +#include <ctype.h> #include <synch.h> #include <stdio.h> #include <unistd.h> @@ -34,9 +33,7 @@ #include <assert.h> #include <smbsrv/libsmb.h> -#include <smbsrv/ndr.h> -#include <smbsrv/mlrpc.h> -#include <smbsrv/smb_sid.h> +#include <smbsrv/libmlrpc.h> /* @@ -51,16 +48,82 @@ static mutex_t ndr_handle_lock; /* * Table of registered services. */ -#define NDL_MAX_SERVICES 32 -static mlrpc_service_t *mlrpc_services[NDL_MAX_SERVICES]; +#define NDR_MAX_SERVICES 32 +static ndr_service_t *ndr_services[NDR_MAX_SERVICES]; + +/* + * Register a service. + * + * Returns: + * 0 Success + * -1 Duplicate service + * -2 Duplicate name + * -3 Table overflow + */ +int +ndr_svc_register(ndr_service_t *svc) +{ + ndr_service_t *p; + int free_slot = -1; + int i; + + for (i = 0; i < NDR_MAX_SERVICES; i++) { + if ((p = ndr_services[i]) == NULL) { + if (free_slot < 0) + free_slot = i; + continue; + } + + if (p == svc) + return (-1); + + if (strcasecmp(p->name, svc->name) == 0) + return (-2); + } + + if (free_slot < 0) + return (-3); + ndr_services[free_slot] = svc; + return (0); +} + +void +ndr_svc_unregister(ndr_service_t *svc) +{ + int i; + + for (i = 0; i < NDR_MAX_SERVICES; i++) { + if (ndr_services[i] == svc) + ndr_services[i] = NULL; + } +} + +int +ndr_svc_list(char *buffer, int bufsize) +{ + ndr_service_t *svc; + smb_ctxbuf_t ctx; + int i; -struct mlrpc_stub_table * -mlrpc_find_stub_in_svc(mlrpc_service_t *msvc, int opnum) + (void) smb_ctxbuf_init(&ctx, (uint8_t *)buffer, bufsize); + + for (i = 0; i < NDR_MAX_SERVICES; i++) { + if ((svc = ndr_services[i]) != 0) { + (void) smb_ctxbuf_printf(&ctx, "%-16s %s\n", + svc->name, svc->desc); + } + } + + return (smb_ctxbuf_len(&ctx)); +} + +ndr_stub_table_t * +ndr_svc_find_stub(ndr_service_t *svc, int opnum) { - struct mlrpc_stub_table *ste; + ndr_stub_table_t *ste; - for (ste = msvc->stub_table; ste->func; ste++) { + for (ste = svc->stub_table; ste->func; ste++) { if (ste->opnum == opnum) return (ste); } @@ -68,178 +131,105 @@ mlrpc_find_stub_in_svc(mlrpc_service_t *msvc, int opnum) return (NULL); } -mlrpc_service_t * -mlrpc_find_service_by_name(const char *name) +ndr_service_t * +ndr_svc_lookup_name(const char *name) { - mlrpc_service_t *msvc; + ndr_service_t *svc; int i; - for (i = 0; i < NDL_MAX_SERVICES; i++) { - if ((msvc = mlrpc_services[i]) == NULL) + for (i = 0; i < NDR_MAX_SERVICES; i++) { + if ((svc = ndr_services[i]) == NULL) continue; - if (strcasecmp(name, msvc->name) != 0) + if (strcasecmp(name, svc->name) != 0) continue; - mlndo_printf(0, 0, "%s %s", msvc->name, msvc->desc); - return (msvc); + ndo_printf(0, 0, "%s %s", svc->name, svc->desc); + return (svc); } return (NULL); } -mlrpc_service_t * -mlrpc_find_service_by_uuids(ndr_uuid_t *as_uuid, int as_vers, +ndr_service_t * +ndr_svc_lookup_uuid(ndr_uuid_t *as_uuid, int as_vers, ndr_uuid_t *ts_uuid, int ts_vers) { - mlrpc_service_t *msvc; - char abstract_syntax[128]; - char transfer_syntax[128]; + ndr_service_t *svc; + char abstract_syntax[UUID_PRINTABLE_STRING_LENGTH]; + char transfer_syntax[UUID_PRINTABLE_STRING_LENGTH]; int i; if (as_uuid) - mlrpc_uuid_to_str(as_uuid, abstract_syntax); + ndr_uuid_unparse(as_uuid, abstract_syntax); if (ts_uuid) - mlrpc_uuid_to_str(ts_uuid, transfer_syntax); + ndr_uuid_unparse(ts_uuid, transfer_syntax); - for (i = 0; i < NDL_MAX_SERVICES; i++) { - if ((msvc = mlrpc_services[i]) == NULL) + for (i = 0; i < NDR_MAX_SERVICES; i++) { + if ((svc = ndr_services[i]) == NULL) continue; if (as_uuid) { - if (msvc->abstract_syntax_uuid == 0) + if (svc->abstract_syntax_uuid == 0) continue; - if (msvc->abstract_syntax_version != as_vers) + if (svc->abstract_syntax_version != as_vers) continue; if (strcasecmp(abstract_syntax, - msvc->abstract_syntax_uuid)) + svc->abstract_syntax_uuid)) continue; } if (ts_uuid) { - if (msvc->transfer_syntax_uuid == 0) + if (svc->transfer_syntax_uuid == 0) continue; - if (msvc->transfer_syntax_version != ts_vers) + if (svc->transfer_syntax_version != ts_vers) continue; if (strcasecmp(transfer_syntax, - msvc->transfer_syntax_uuid)) + svc->transfer_syntax_uuid)) continue; } - mlndo_printf(0, 0, "%s %s", msvc->name, msvc->desc); - return (msvc); + ndo_printf(0, 0, "%s %s", svc->name, svc->desc); + return (svc); } + ndo_printf(0, 0, "ndr_svc_lookup_uuid: unknown service"); + ndo_printf(0, 0, "abstract=%s v%d, transfer=%s v%d", + abstract_syntax, as_vers, transfer_syntax, ts_vers); return (NULL); } /* - * Register a service. - * - * Returns: - * 0 Success - * -1 Duplicate service - * -2 Duplicate name - * -3 Table overflow - */ -int -mlrpc_register_service(mlrpc_service_t *msvc) -{ - mlrpc_service_t *p; - int free_slot = -1; - int i; - - for (i = 0; i < NDL_MAX_SERVICES; i++) { - if ((p = mlrpc_services[i]) == NULL) { - if (free_slot < 0) - free_slot = i; - continue; - } - - if (p == msvc) - return (-1); - - if (strcasecmp(p->name, msvc->name) == 0) - return (-2); - } - - if (free_slot < 0) - return (-3); - - mlrpc_services[free_slot] = msvc; - return (0); -} - -void -mlrpc_unregister_service(mlrpc_service_t *msvc) -{ - int i; - - for (i = 0; i < NDL_MAX_SERVICES; i++) { - if (mlrpc_services[i] == msvc) - mlrpc_services[i] = NULL; - } -} - -int -mlrpc_list_services(char *buffer, int bufsize) -{ - mlrpc_service_t *msvc; - smb_ctxbuf_t ctx; - int i; - - (void) smb_ctxbuf_init(&ctx, (uint8_t *)buffer, bufsize); - - for (i = 0; i < NDL_MAX_SERVICES; i++) { - if ((msvc = mlrpc_services[i]) != 0) { - (void) smb_ctxbuf_printf(&ctx, "%-16s %s\n", - msvc->name, msvc->desc); - } - } - - return (smb_ctxbuf_len(&ctx)); -} - -/* * Allocate a handle for use with the server-side RPC functions. - * The handle contains the machine SID and an incrementing counter, - * which should make each handle unique. * * An arbitrary caller context can be associated with the handle * via data; it will not be dereferenced by the handle API. - * - * The uuid for the new handle is returned after it has been added - * to the global handle list. */ ndr_hdid_t * ndr_hdalloc(const ndr_xa_t *xa, const void *data) { - static ndr_hdid_t uuid; + static ndr_hdid_t id; ndr_handle_t *hd; - smb_sid_t *sid; + uuid_t uu; if ((hd = malloc(sizeof (ndr_handle_t))) == NULL) return (NULL); - if (uuid.data[1] == 0) { - if ((sid = nt_domain_local_sid()) == NULL) - return (NULL); - - uuid.data[0] = 0; - uuid.data[1] = 0; - uuid.data[2] = sid->sid_subauth[1]; - uuid.data[3] = sid->sid_subauth[2]; - uuid.data[4] = sid->sid_subauth[3]; + if (id.data2 == 0) { + uuid_generate_random(uu); + bcopy(uu, &id.data2, sizeof (uuid_t)); + id.data1 = 0; + id.data2 = 0; } - ++uuid.data[1]; + ++id.data2; - bcopy(&uuid, &hd->nh_id, sizeof (ndr_hdid_t)); + bcopy(&id, &hd->nh_id, sizeof (ndr_hdid_t)); hd->nh_fid = xa->fid; hd->nh_svc = xa->binding->service; hd->nh_data = (void *)data; @@ -258,7 +248,7 @@ ndr_hdalloc(const ndr_xa_t *xa, const void *data) void ndr_hdfree(const ndr_xa_t *xa, const ndr_hdid_t *id) { - mlrpc_service_t *svc = xa->binding->service; + ndr_service_t *svc = xa->binding->service; ndr_handle_t *hd; ndr_handle_t **pphd; @@ -292,7 +282,7 @@ ndr_hdfree(const ndr_xa_t *xa, const ndr_hdid_t *id) ndr_handle_t * ndr_hdlookup(const ndr_xa_t *xa, const ndr_hdid_t *id) { - mlrpc_service_t *svc = xa->binding->service; + ndr_service_t *svc = xa->binding->service; ndr_handle_t *hd; assert(id); @@ -341,10 +331,13 @@ ndr_hdclose(int fid) (void) mutex_unlock(&ndr_handle_lock); } +/* + * Convert a UUID to a string. + */ void -mlrpc_uuid_to_str(ndr_uuid_t *uuid, char *str) +ndr_uuid_unparse(ndr_uuid_t *uuid, char *out) { - (void) sprintf(str, "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x", + (void) sprintf(out, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", uuid->data1, uuid->data2, uuid->data3, uuid->data4[0], uuid->data4[1], uuid->data4[2], uuid->data4[3], @@ -352,53 +345,62 @@ mlrpc_uuid_to_str(ndr_uuid_t *uuid, char *str) uuid->data4[6], uuid->data4[7]); } +/* + * Convert a string to a UUID. + */ int -mlrpc_str_to_uuid(char *str, ndr_uuid_t *uuid) +ndr_uuid_parse(char *in, ndr_uuid_t *uuid) { - char *p = str; + char *p = in; char *q; char buf[4]; int i; + if (strlen(in) != UUID_PRINTABLE_STRING_LENGTH - 1) + return (-1); + uuid->data1 = strtoul(p, &p, 16); if (*p != '-') - return (0); + return (-1); p++; uuid->data2 = strtol(p, &p, 16); if (*p != '-') - return (0); + return (-1); p++; uuid->data3 = strtol(p, &p, 16); if (*p != '-') - return (0); + return (-1); p++; for (i = 0; i < 8; i++) { + if (*p == '-') + p++; + if (p[0] == 0 || p[1] == 0) - return (0); + return (-1); buf[0] = *p++; buf[1] = *p++; buf[2] = 0; uuid->data4[i] = strtol(buf, &q, 16); if (*q != 0) - return (0); + return (-1); } if (*p != 0) - return (0); + return (-1); - return (1); + return (0); } void -mlrpc_binding_pool_initialize(struct mlrpc_binding **headpp, - struct mlrpc_binding pool[], unsigned n_pool) +ndr_svc_binding_pool_init(ndr_binding_t **headpp, ndr_binding_t pool[], + int n_pool) { - struct mlrpc_binding *head = NULL; - int ix; + ndr_binding_t *head = NULL; + int ix; for (ix = n_pool - 1; ix >= 0; ix--) { pool[ix].next = head; @@ -411,14 +413,14 @@ mlrpc_binding_pool_initialize(struct mlrpc_binding **headpp, *headpp = head; } -struct mlrpc_binding * -mlrpc_find_binding(struct mlrpc_xaction *mxa, mlrpc_p_context_id_t p_cont_id) +ndr_binding_t * +ndr_svc_find_binding(ndr_xa_t *mxa, ndr_p_context_id_t p_cont_id) { - struct mlrpc_binding *mbind; + ndr_binding_t *mbind; for (mbind = mxa->binding_list; mbind; mbind = mbind->next) { if (mbind->service != NULL && - mbind->which_side == MLRPC_BIND_SIDE_SERVER && + mbind->which_side == NDR_BIND_SIDE_SERVER && mbind->p_cont_id == p_cont_id) break; } @@ -426,10 +428,10 @@ mlrpc_find_binding(struct mlrpc_xaction *mxa, mlrpc_p_context_id_t p_cont_id) return (mbind); } -struct mlrpc_binding * -mlrpc_new_binding(struct mlrpc_xaction *mxa) +ndr_binding_t * +ndr_svc_new_binding(ndr_xa_t *mxa) { - struct mlrpc_binding *mbind; + ndr_binding_t *mbind; for (mbind = mxa->binding_list; mbind; mbind = mbind->next) { if (mbind->service == NULL) diff --git a/usr/src/lib/smbsrv/libmlsvc/Makefile.com b/usr/src/lib/smbsrv/libmlsvc/Makefile.com index 13cc68c57c..6db89f995f 100644 --- a/usr/src/lib/smbsrv/libmlsvc/Makefile.com +++ b/usr/src/lib/smbsrv/libmlsvc/Makefile.com @@ -34,6 +34,7 @@ OBJS_COMMON = \ lsar_lookup.o \ lsar_open.o \ mlsvc_client.o \ + mlsvc_domain.o \ mlsvc_init.o \ mlsvc_logr.o \ mlsvc_lsa.o \ @@ -43,6 +44,7 @@ OBJS_COMMON = \ mlsvc_util.o \ mlsvc_winreg.o \ mlsvc_wkssvc.o \ + msgsvc_svc.o \ netdfs.o \ netr_auth.o \ netr_logon.o \ @@ -52,6 +54,7 @@ OBJS_COMMON = \ smb_autohome.o \ smb_logon.o \ smb_share.o \ + spoolss_svc.o \ srvsvc_client.o \ svcctl_scm.o \ svcctl_svc.o @@ -61,6 +64,7 @@ NDLLIST = \ dssetup \ eventlog \ lsarpc \ + msgsvc \ netdfs \ netlogon \ samrpc \ @@ -77,9 +81,11 @@ include ../../Makefile.lib INCS += -I$(SRC)/common/smbsrv LDLIBS += $(MACH_LDLIBS) -LDLIBS += -lmlrpc -lsmbrdr -lsmb -lsmbns -lshare -lnsl -lpkcs11 -lscf \ +LDLIBS += -lmlrpc -lsmbrdr -lsmb -lsmbns -lshare -lresolv -lnsl -lpkcs11 -lscf \ -luutil -lc +CPPFLAGS += $(INCS) -D_REENTRANT + SRCS= $(OBJS_COMMON:%.o=$(SRCDIR)/%.c) \ $(OBJS_SHARED:%.o=$(SRC)/common/smbsrv/%.c) diff --git a/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c b/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c index 0cd6504d66..b31f0ec1b8 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c @@ -29,74 +29,36 @@ #include <string.h> #include <strings.h> +#include <smbsrv/wintypes.h> #include <smbsrv/libsmb.h> #include <smbsrv/libsmbrdr.h> -#include <smbsrv/ndl/rpcpdu.ndl> #include <smbsrv/ndl/dssetup.ndl> -#include <smbsrv/mlsvc_util.h> - -/* - * Open the lsarpc pipe and bind to the dssetup service. - */ -static int -dssetup_open(mlsvc_handle_t *handle, mlrpc_heapref_t *heapref) -{ - smb_ntdomain_t *di; - int fid; - int rc; - - if ((di = smb_getdomaininfo(0)) == NULL) - return (-1); - - if (mlsvc_logon(di->server, di->domain, MLSVC_ANON_USER) != 0) - return (-1); - - fid = mlsvc_open_pipe(di->server, di->domain, MLSVC_ANON_USER, - "\\lsarpc"); - if (fid < 0) - return (-1); - - if ((rc = mlsvc_rpc_bind(handle, fid, "DSSETUP")) < 0) { - (void) mlsvc_close_pipe(fid); - return (rc); - } - - rc = mlsvc_rpc_init(heapref); - return (rc); -} - -/* - * Close the dssetup pipe and free the associated context. - * This function should only be called if the open was successful. - */ -static void -dssetup_close(mlsvc_handle_t *handle, mlrpc_heapref_t *heapref) -{ - mlsvc_rpc_free(handle->context, heapref); - (void) mlsvc_close_pipe(handle->context->fid); - free(handle->context); -} +#include <smbsrv/libmlsvc.h> int dssetup_get_domain_info(ds_primary_domain_info_t *ds_info) { dssetup_DsRoleGetPrimaryDomainInfo_t arg; struct dssetup_DsRolePrimaryDomInfo1 *info; + smb_domain_t di; mlsvc_handle_t handle; - mlrpc_heapref_t heap; int opnum; int rc; - if (dssetup_open(&handle, &heap) != 0) + if (!smb_domain_getinfo(&di)) + return (-1); + + if (ndr_rpc_bind(&handle, di.d_dc, di.d_nbdomain, + MLSVC_ANON_USER, "DSSETUP") != 0) return (-1); opnum = DSSETUP_OPNUM_DsRoleGetPrimaryDomainInfo; bzero(&arg, sizeof (dssetup_DsRoleGetPrimaryDomainInfo_t)); arg.level = DS_ROLE_BASIC_INFORMATION; - rc = mlsvc_rpc_call(handle.context, opnum, &arg, &heap); + rc = ndr_rpc_call(&handle, opnum, &arg); if ((rc != 0) || (arg.status != 0) || arg.info == NULL) { - dssetup_close(&handle, &heap); + ndr_rpc_unbind(&handle); return (-1); } @@ -105,7 +67,7 @@ dssetup_get_domain_info(ds_primary_domain_info_t *ds_info) if (info->nt_domain == NULL || info->dns_domain == NULL || info->forest == NULL) { - dssetup_close(&handle, &heap); + ndr_rpc_unbind(&handle); return (-1); } @@ -114,6 +76,6 @@ dssetup_get_domain_info(ds_primary_domain_info_t *ds_info) ds_info->dns_domain = (uint8_t *)strdup((char *)info->dns_domain); ds_info->forest = (uint8_t *)strdup((char *)info->forest); - dssetup_close(&handle, &heap); + ndr_rpc_unbind(&handle); return (0); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/dssetup_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/dssetup_svc.c index d9477a20db..2175553bfa 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/dssetup_svc.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/dssetup_svc.c @@ -35,7 +35,6 @@ #include <smbsrv/libsmb.h> #include <smbsrv/libmlrpc.h> #include <smbsrv/libmlsvc.h> -#include <smbsrv/mlsvc_util.h> #include <smbsrv/ndl/dssetup.ndl> #include <smbsrv/ntstatus.h> #include <smbsrv/smbinfo.h> @@ -48,19 +47,19 @@ static uint32_t dssetup_member_server(ds_primary_domain_info_t *, ndr_xa_t *); static uint32_t dssetup_standalone_server(ds_primary_domain_info_t *, ndr_xa_t *); -static mlrpc_stub_table_t dssetup_stub_table[] = { +static ndr_stub_table_t dssetup_stub_table[] = { { dssetup_DsRoleGetPrimaryDomainInfo, DSSETUP_OPNUM_DsRoleGetPrimaryDomainInfo }, {0} }; -static mlrpc_service_t dssetup_service = { +static ndr_service_t dssetup_service = { "DSSETUP", /* name */ "Active Directory Setup", /* desc */ "\\lsarpc", /* endpoint */ PIPE_LSASS, /* sec_addr_port */ - "3919286a-b10c-11d0-9ba800c04fd92ef5", 0, /* abstract */ - "8a885d04-1ceb-11c9-9fe808002b104860", 2, /* transfer */ + "3919286a-b10c-11d0-9ba8-00c04fd92ef5", 0, /* abstract */ + NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 0, /* no bind_instance_size */ 0, /* no bind_req() */ 0, /* no unbind_and_close() */ @@ -83,7 +82,7 @@ void dssetup_initialize(void) { dssetup_clear_domain_info(); - (void) mlrpc_register_service(&dssetup_service); + (void) ndr_svc_register(&dssetup_service); } void @@ -111,7 +110,7 @@ dssetup_DsRoleGetPrimaryDomainInfo(void *arg, ndr_xa_t *mxa) uint32_t status; int security_mode; - info = MLRPC_HEAP_MALLOC(mxa, sizeof (dssetup_GetPrimaryDomainInfo_t)); + info = NDR_MALLOC(mxa, sizeof (dssetup_GetPrimaryDomainInfo_t)); if (info == NULL) { status = NT_STATUS_NO_MEMORY; } else if (param->level != DS_ROLE_BASIC_INFORMATION) { @@ -136,7 +135,7 @@ dssetup_DsRoleGetPrimaryDomainInfo(void *arg, ndr_xa_t *mxa) param->status = NT_STATUS_SUCCESS; } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -169,11 +168,9 @@ dssetup_member_server(ds_primary_domain_info_t *info, ndr_xa_t *mxa) if (ds_info.flags & DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT) { info->flags = DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT; - info->nt_domain = MLRPC_HEAP_STRSAVE(mxa, - (char *)ds_info.nt_domain); - info->dns_domain = MLRPC_HEAP_STRSAVE(mxa, - (char *)ds_info.dns_domain); - info->forest = MLRPC_HEAP_STRSAVE(mxa, (char *)ds_info.forest); + info->nt_domain = NDR_STRDUP(mxa, (char *)ds_info.nt_domain); + info->dns_domain = NDR_STRDUP(mxa, (char *)ds_info.dns_domain); + info->forest = NDR_STRDUP(mxa, (char *)ds_info.forest); bcopy(&ds_info.domain_guid, &info->domain_guid, sizeof (ndr_uuid_t)); } else { @@ -190,9 +187,9 @@ dssetup_member_server(ds_primary_domain_info_t *info, ndr_xa_t *mxa) (void) utf8_strlwr(dns_domain); info->flags = 0; - info->nt_domain = MLRPC_HEAP_STRSAVE(mxa, nt_domain); - info->dns_domain = MLRPC_HEAP_STRSAVE(mxa, dns_domain); - info->forest = MLRPC_HEAP_STRSAVE(mxa, dns_domain); + info->nt_domain = NDR_STRDUP(mxa, nt_domain); + info->dns_domain = NDR_STRDUP(mxa, dns_domain); + info->forest = NDR_STRDUP(mxa, dns_domain); bzero(&info->domain_guid, sizeof (ndr_uuid_t)); } @@ -224,7 +221,7 @@ dssetup_standalone_server(ds_primary_domain_info_t *info, ndr_xa_t *mxa) if (smb_getdomainname(nt_domain, MAXHOSTNAMELEN) != 0) return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); - info->nt_domain = MLRPC_HEAP_STRSAVE(mxa, nt_domain); + info->nt_domain = NDR_STRDUP(mxa, nt_domain); if (info->nt_domain == NULL) return (NT_STATUS_NO_MEMORY); diff --git a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h index bf5f9fd2b9..7d5898c1fe 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h +++ b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h @@ -26,19 +26,89 @@ #ifndef _LIBMLSVC_H #define _LIBMLSVC_H +#include <uuid/uuid.h> +#include <sys/param.h> #include <sys/types.h> -#include <smbsrv/smb_sid.h> +#include <sys/uio.h> +#include <sys/ksynch.h> +#include <stdio.h> +#include <string.h> +#include <smbsrv/wintypes.h> #include <smbsrv/hash_table.h> #include <smbsrv/smb_token.h> #include <smbsrv/smb_privilege.h> #include <smbsrv/smb_share.h> -#include <smbsrv/libsmb.h> #include <smbsrv/smb_xdr.h> +#include <smbsrv/libsmb.h> +#include <smbsrv/libsmbrdr.h> +#include <smbsrv/libmlrpc.h> +#include <smbsrv/ndl/lsarpc.ndl> #ifdef __cplusplus extern "C" { #endif +typedef struct lsa_nt_domaininfo { + smb_sid_t *n_sid; + char n_domain[NETBIOS_NAME_SZ]; +} lsa_nt_domaininfo_t; + +typedef struct lsa_trusted_domainlist { + uint32_t t_num; + lsa_nt_domaininfo_t *t_domains; +} lsa_trusted_domainlist_t; + +typedef struct lsa_dns_domaininfo { + smb_sid_t *d_sid; + char d_nbdomain[NETBIOS_NAME_SZ]; + char d_fqdomain[MAXHOSTNAMELEN]; + char d_forest[MAXHOSTNAMELEN]; + mslsa_guid_t d_guid; +} lsa_dns_domaininfo_t; + +typedef enum lsa_info_type { + LSA_INFO_NONE, + LSA_INFO_PRIMARY_DOMAIN, + LSA_INFO_ACCOUNT_DOMAIN, + LSA_INFO_DNS_DOMAIN, + LSA_INFO_TRUSTED_DOMAINS +} lsa_info_type_t; + +typedef struct lsa_info { + lsa_info_type_t i_type; + union { + lsa_nt_domaininfo_t di_primary; + lsa_nt_domaininfo_t di_account; + lsa_dns_domaininfo_t di_dns; + lsa_trusted_domainlist_t di_trust; + } i_domain; +} lsa_info_t; + +extern DWORD lsa_query_primary_domain_info(char *, char *, lsa_info_t *); +extern DWORD lsa_query_account_domain_info(char *, char *, lsa_info_t *); +extern DWORD lsa_query_dns_domain_info(char *, char *, lsa_info_t *); +extern DWORD lsa_enum_trusted_domains(char *, char *, lsa_info_t *); +extern void lsa_free_info(lsa_info_t *); + +extern uint32_t mlsvc_lookup_name(char *, smb_sid_t **, uint16_t *); +extern uint32_t mlsvc_lookup_sid(smb_sid_t *, char **); + +/* + * SMB domain API to discover a domain controller and obtain domain + * information. + */ + +typedef struct smb_domain { + char d_dc[MAXHOSTNAMELEN]; + char d_nbdomain[NETBIOS_NAME_SZ]; + char d_fqdomain[MAXHOSTNAMELEN]; + char d_forest[MAXHOSTNAMELEN]; + char d_guid[UUID_PRINTABLE_STRING_LENGTH]; +} smb_domain_t; +extern boolean_t smb_locate_dc(char *, char *, smb_domain_t *); +extern boolean_t smb_domain_getinfo(smb_domain_t *); + + extern int mlsvc_get_door_fd(void); extern uint64_t mlsvc_get_num_users(void); extern int mlsvc_get_user_list(int, smb_dr_ulist_t *); @@ -46,14 +116,39 @@ extern void dssetup_clear_domain_info(void); extern int mlsvc_init(void); extern void mlsvc_set_door_fd(int); extern int mlsvc_set_share(int, char *, char *); -extern uint32_t mlsvc_lookup_name(char *, smb_sid_t **, uint16_t *); -extern uint32_t mlsvc_lookup_sid(smb_sid_t *, char **); extern DWORD mlsvc_netlogon(char *, char *); -extern DWORD lsa_query_primary_domain_info(void); -extern DWORD lsa_query_account_domain_info(void); -extern DWORD lsa_enum_trusted_domains(void); +extern DWORD mlsvc_join(smb_domain_t *, char *, char *); + + +/* + * The maximum number of domains (NT limit). + */ +#define MLSVC_DOMAIN_MAX 32 + +/* + * Status code returned from enumeration RPCs to indicate + * that the server has no more data. Normally returned at + * severity level ERROR_SEVERITY_WARNING. + */ +#define MLSVC_NO_MORE_DATA 0x1A + +#define MLSVC_ANON_USER "IPC$" + +char *mlsvc_ipc_name(int ipc_type, char *username); + +/* + * Passthrough negotiation and authentication interface. + * + * NT supports two forms of password: a Lanman (case-insensitive) + * password and an NT (case-sensitive) password. If either of the + * passwords is not available its pointer and length should be set + * to zero. The session key and vc number are required to validate + * the encrypted passwords. + */ -extern boolean_t smbd_locate_dc(char *, char *); +void mlsvc_nt_password_hash(char *result, char *password); +int mlsvc_encrypt_nt_password(char *password, char *key, int keylen, char *out, + int outmax); #define SMB_AUTOHOME_FILE "smbautohome" #define SMB_AUTOHOME_PATH "/etc" @@ -70,6 +165,50 @@ typedef struct smb_autohome { extern void smb_autohome_add(const char *); extern void smb_autohome_remove(const char *); +smb_userinfo_t *mlsvc_alloc_user_info(void); +void mlsvc_free_user_info(smb_userinfo_t *user_info); +void mlsvc_release_user_info(smb_userinfo_t *user_info); +void mlsvc_setadmin_user_info(smb_userinfo_t *user_info); +char *mlsvc_sid_name_use(unsigned int snu_id); +extern int mlsvc_is_local_domain(const char *); + +/* + * A local unique id (LUID) is an opaque id used by servers to identify + * local resources, such as privileges. A client will use lookup + * functions to translate the LUID to a more general, machine independent + * form; such as a string. + */ +typedef struct ms_luid { + uint32_t low_part; + uint32_t high_part; +} ms_luid_t; + +/* + * A client_t is created while binding a client connection to hold the + * context for calls made using that connection. + * + * Handles are RPC call specific and we use an inheritance mechanism to + * ensure that each handle has a pointer to the client_t. When the top + * level (bind) handle is released, we close the connection. + */ +typedef struct mlsvc_handle { + ndr_hdid_t handle; + ndr_client_t *clnt; + int remote_os; +} mlsvc_handle_t; + +int ndr_rpc_bind(mlsvc_handle_t *, char *, char *, char *, const char *); +void ndr_rpc_unbind(mlsvc_handle_t *); +int ndr_rpc_call(mlsvc_handle_t *, int, void *); +int ndr_rpc_server_os(mlsvc_handle_t *); +void *ndr_rpc_malloc(mlsvc_handle_t *, size_t); +ndr_heap_t *ndr_rpc_get_heap(mlsvc_handle_t *); +void ndr_rpc_release(mlsvc_handle_t *); +boolean_t ndr_is_null_handle(mlsvc_handle_t *); +boolean_t ndr_is_bind_handle(mlsvc_handle_t *); +void ndr_inherit_handle(mlsvc_handle_t *, mlsvc_handle_t *); +void ndr_rpc_status(mlsvc_handle_t *, int, uint32_t); + #ifdef __cplusplus } #endif diff --git a/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c b/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c index 87f64393e8..d0eafbc8eb 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * This module provides the high level interface to the LSA RPC functions. */ @@ -39,7 +37,7 @@ #include <smbsrv/libsmbns.h> #include <smbsrv/libmlsvc.h> #include <smbsrv/libsmbrdr.h> -#include <smbsrv/lsalib.h> +#include <lsalib.h> #include <smbsrv/ntstatus.h> #include <smbsrv/smbinfo.h> #include <smbsrv/smb_token.h> @@ -83,14 +81,14 @@ static int lsa_list_accounts(mlsvc_handle_t *); * first does a domain lookup and then a local lookup. */ uint32_t -lsa_lookup_name(char *server, char *account, uint16_t sid_type, +lsa_lookup_name(char *account, uint16_t sid_type, smb_userinfo_t *ainfo) { - nt_domain_t *dominfo; int lookup_mode; char *name; char *domain; uint32_t status = NT_STATUS_NONE_MAPPED; + smb_domain_t dinfo; (void) strsubst(account, '\\', '/'); name = strchr(account, '/'); @@ -113,15 +111,20 @@ lsa_lookup_name(char *server, char *account, uint16_t sid_type, return (lsa_lookup_name_local(domain, name, sid_type, ainfo)); case MLSVC_LOOKUP_DOMAIN: - return (lsa_lookup_name_domain(server, domain, name, ainfo)); + if (!smb_domain_getinfo(&dinfo)) + return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); + + return (lsa_lookup_name_domain(dinfo.d_dc, dinfo.d_nbdomain, + name, ainfo)); default: /* lookup the name in domain */ - dominfo = nt_domain_lookupbytype(NT_DOMAIN_PRIMARY); - if (dominfo == NULL) - return (NT_STATUS_INTERNAL_ERROR); - status = lsa_lookup_name_domain(server, dominfo->name, name, - ainfo); + if (!smb_domain_getinfo(&dinfo)) + return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); + + status = lsa_lookup_name_domain(dinfo.d_dc, dinfo.d_nbdomain, + name, ainfo); + if (status != NT_STATUS_NONE_MAPPED) return (status); @@ -157,20 +160,23 @@ lsa_lookup_sid(smb_sid_t *sid, smb_userinfo_t *ainfo) * should query the database to obtain a reference to the primary * domain information. * + * The requested information will be returned via 'info' argument. + * Caller must call lsa_free_info() when done. + * * Returns NT status codes. */ DWORD -lsa_query_primary_domain_info(void) +lsa_query_primary_domain_info(char *server, char *domain, lsa_info_t *info) { mlsvc_handle_t domain_handle; DWORD status; char *user = smbrdr_ipc_get_user(); - if ((lsar_open(NULL, NULL, user, &domain_handle)) != 0) + if ((lsar_open(server, domain, user, &domain_handle)) != 0) return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); status = lsar_query_info_policy(&domain_handle, - MSLSA_POLICY_PRIMARY_DOMAIN_INFO); + MSLSA_POLICY_PRIMARY_DOMAIN_INFO, info); (void) lsar_close(&domain_handle); return (status); @@ -185,20 +191,51 @@ lsa_query_primary_domain_info(void) * should query the database to obtain a reference to the account * domain information. * + * The requested information will be returned via 'info' argument. + * Caller must invoke lsa_free_info() to when done. + * * Returns NT status codes. */ DWORD -lsa_query_account_domain_info(void) +lsa_query_account_domain_info(char *server, char *domain, lsa_info_t *info) { mlsvc_handle_t domain_handle; DWORD status; char *user = smbrdr_ipc_get_user(); - if ((lsar_open(NULL, NULL, user, &domain_handle)) != 0) + if ((lsar_open(server, domain, user, &domain_handle)) != 0) return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); status = lsar_query_info_policy(&domain_handle, - MSLSA_POLICY_ACCOUNT_DOMAIN_INFO); + MSLSA_POLICY_ACCOUNT_DOMAIN_INFO, info); + + (void) lsar_close(&domain_handle); + return (status); +} + +/* + * lsa_query_dns_domain_info + * + * Obtains the DNS domain info from the specified server + * (domain controller). + * + * The requested information will be returned via 'info' argument. + * Caller must call lsa_free_info() when done. + * + * Returns NT status codes. + */ +DWORD +lsa_query_dns_domain_info(char *server, char *domain, lsa_info_t *info) +{ + mlsvc_handle_t domain_handle; + DWORD status; + char *user = smbrdr_ipc_get_user(); + + if ((lsar_open(server, domain, user, &domain_handle)) != 0) + return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); + + status = lsar_query_info_policy(&domain_handle, + MSLSA_POLICY_DNS_DOMAIN_INFO, info); (void) lsar_close(&domain_handle); return (status); @@ -212,22 +249,25 @@ lsa_query_account_domain_info(void) * lsar_enum_trusted_domains call. The caller should query the database * to obtain a reference to the trusted domain information. * + * The requested information will be returned via 'info' argument. + * Caller must call lsa_free_info() when done. + * * Returns NT status codes. */ DWORD -lsa_enum_trusted_domains(void) +lsa_enum_trusted_domains(char *server, char *domain, lsa_info_t *info) { mlsvc_handle_t domain_handle; DWORD enum_context; DWORD status; char *user = smbrdr_ipc_get_user(); - if ((lsar_open(NULL, NULL, user, &domain_handle)) != 0) + if ((lsar_open(server, domain, user, &domain_handle)) != 0) return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); enum_context = 0; - status = lsar_enum_trusted_domains(&domain_handle, &enum_context); + status = lsar_enum_trusted_domains(&domain_handle, &enum_context, info); if (status == MLSVC_NO_MORE_DATA) { /* * MLSVC_NO_MORE_DATA indicates that we @@ -241,6 +281,43 @@ lsa_enum_trusted_domains(void) } /* + * lsa_free_info + */ +void +lsa_free_info(lsa_info_t *info) +{ + lsa_trusted_domainlist_t *list; + int i; + + if (!info) + return; + + switch (info->i_type) { + case LSA_INFO_PRIMARY_DOMAIN: + smb_sid_free(info->i_domain.di_primary.n_sid); + break; + + case LSA_INFO_ACCOUNT_DOMAIN: + smb_sid_free(info->i_domain.di_account.n_sid); + break; + + case LSA_INFO_DNS_DOMAIN: + smb_sid_free(info->i_domain.di_dns.d_sid); + break; + + case LSA_INFO_TRUSTED_DOMAINS: + list = &info->i_domain.di_trust; + for (i = 0; i < list->t_num; i++) + smb_sid_free(list->t_domains[i].n_sid); + free(list->t_domains); + break; + + case LSA_INFO_NONE: + break; + } +} + +/* * lsa_lookup_name_builtin * * lookup builtin account table to see if account_name is @@ -395,15 +472,15 @@ lsa_test_lookup(char *name) smb_userinfo_t *user_info; smb_sid_t *sid; DWORD status; - smb_ntdomain_t *di; + smb_domain_t di; - if ((di = smb_getdomaininfo(0)) == 0) + if (!smb_domain_getinfo(&di)) return; user_info = mlsvc_alloc_user_info(); if (lsa_lookup_name_builtin(name, user_info) != 0) { - status = lsa_lookup_name_domain(di->server, di->domain, name, + status = lsa_lookup_name_domain(di.d_dc, di.d_nbdomain, name, user_info); if (status == 0) { @@ -433,14 +510,19 @@ lsa_test_lookup(char *name) */ /*ARGSUSED*/ int -lsa_lookup_privs(char *server, char *account_name, char *target_name, +lsa_lookup_privs(char *account_name, char *target_name, smb_userinfo_t *user_info) { mlsvc_handle_t domain_handle; int rc; char *user = smbrdr_ipc_get_user(); + smb_domain_t dinfo; - if ((lsar_open(NULL, NULL, user, &domain_handle)) != 0) + if (!smb_domain_getinfo(&dinfo)) + return (-1); + + if ((lsar_open(dinfo.d_dc, dinfo.d_nbdomain, user, + &domain_handle)) != 0) return (-1); rc = lsa_list_accounts(&domain_handle); @@ -489,19 +571,17 @@ lsa_list_privs(char *server, char *domain) * lsa_test * * LSA test routine: open and close the LSA interface. - * TBD: the parameters should be server and domain. * * On success 0 is returned. Otherwise a -ve error code. */ -/*ARGSUSED*/ int -lsa_test(char *server, char *account_name) +lsa_test(char *server, char *domain) { mlsvc_handle_t domain_handle; int rc; char *user = smbrdr_ipc_get_user(); - rc = lsar_open(NULL, NULL, user, &domain_handle); + rc = lsar_open(server, domain, user, &domain_handle); if (rc != 0) return (-1); @@ -731,8 +811,12 @@ lsa_lookup_sid_domain(smb_sid_t *sid, smb_userinfo_t *ainfo) mlsvc_handle_t domain_handle; char *user = smbrdr_ipc_get_user(); uint32_t status; + smb_domain_t dinfo; + + if (!smb_domain_getinfo(&dinfo)) + return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); - if (lsar_open(NULL, NULL, user, &domain_handle) != 0) + if (lsar_open(dinfo.d_dc, dinfo.d_nbdomain, user, &domain_handle) != 0) return (NT_STATUS_INVALID_PARAMETER); status = lsar_lookup_sids2(&domain_handle, diff --git a/usr/src/lib/smbsrv/libmlsvc/common/lsalib.h b/usr/src/lib/smbsrv/libmlsvc/common/lsalib.h new file mode 100644 index 0000000000..526ad35bec --- /dev/null +++ b/usr/src/lib/smbsrv/libmlsvc/common/lsalib.h @@ -0,0 +1,131 @@ +/* + * 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 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SMBSRV_LSALIB_H +#define _SMBSRV_LSALIB_H + +/* + * Prototypes for the LSA library and RPC client side library interface. + * There are two levels of interface defined here: lsa_xxx and lsar_xxx. + * The lsa_xxx functions provide a high level interface which make + * multiple RPC calls and do all the work necessary to obtain and return + * the requested information. The lsar_xxx functions provide a low level + * interface in which each function maps to a single underlying RPC. + */ + +#include <smbsrv/ndl/lsarpc.ndl> +#include <smbsrv/libmlsvc.h> +#include <smbsrv/smb_sid.h> + + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * lsalib.c + */ +extern uint32_t lsa_lookup_name(char *, uint16_t, smb_userinfo_t *); +extern uint32_t lsa_lookup_sid(smb_sid_t *, smb_userinfo_t *); +extern int lsa_lookup_privs(char *, char *, smb_userinfo_t *); +extern int lsa_test(char *, char *); + +/* + * lsar_open.c + */ +int lsar_open(char *server, + char *domain, + char *username, + mlsvc_handle_t *domain_handle); + +int lsar_open_policy2(char *server, + char *domain, + char *username, + mlsvc_handle_t *lsa_handle); + +int lsar_open_account(mlsvc_handle_t *lsa_handle, + struct mslsa_sid *sid, + mlsvc_handle_t *lsa_account_handle); + +int lsar_close(mlsvc_handle_t *lsa_handle); + + +/* + * lsar_lookup.c + */ +int lsar_query_security_desc(mlsvc_handle_t *lsa_handle); + +DWORD lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass, + lsa_info_t *); + +uint32_t lsar_lookup_names(mlsvc_handle_t *lsa_handle, + char *name, + smb_userinfo_t *user_info); + +uint32_t lsar_lookup_sids(mlsvc_handle_t *lsa_handle, + struct mslsa_sid *sid, + smb_userinfo_t *user_info); + +DWORD lsar_get_userid(char *server, char *name); + +int lsar_enum_accounts(mlsvc_handle_t *lsa_handle, + DWORD *enum_context, + struct mslsa_EnumAccountBuf *accounts); + +DWORD lsar_enum_trusted_domains(mlsvc_handle_t *lsa_handle, + DWORD *enum_context, lsa_info_t *); + +int lsar_enum_privs_account(mlsvc_handle_t *account_handle, + smb_userinfo_t *user_info); + +int lsar_lookup_priv_value(mlsvc_handle_t *lsa_handle, + char *name, + struct ms_luid *luid); + +int lsar_lookup_priv_name(mlsvc_handle_t *lsa_handle, + struct ms_luid *luid, + char *name, + int namelen); + +DWORD lsar_lookup_priv_display_name(mlsvc_handle_t *lsa_handle, + char *name, + char *display_name, + int display_len); + +uint32_t lsar_lookup_sids2(mlsvc_handle_t *lsa_handle, + struct mslsa_sid *sid, + smb_userinfo_t *user_info); + +uint32_t lsar_lookup_names2(mlsvc_handle_t *lsa_handle, + char *name, + smb_userinfo_t *user_info); + + +#ifdef __cplusplus +} +#endif + + +#endif /* _SMBSRV_LSALIB_H */ diff --git a/usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c b/usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c index 7bfacd27f1..33bc6c6311 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Local Security Authority RPC (LSARPC) library interface functions for * query, lookup and enumeration calls. @@ -40,9 +38,9 @@ #include <smbsrv/ntaccess.h> #include <smbsrv/ntstatus.h> #include <smbsrv/ntlocale.h> -#include <smbsrv/lsalib.h> #include <smbsrv/string.h> -#include <smbsrv/mlsvc.h> +#include <smbsrv/libmlsvc.h> +#include <lsalib.h> /* * The maximum number of bytes we are prepared to deal with in a @@ -59,6 +57,14 @@ typedef struct lookup_name_table { mslsa_string_t name[8]; } lookup_name_table_t; +static void lsar_set_nt_domaininfo(smb_sid_t *, char *, lsa_nt_domaininfo_t *); +static void lsar_set_primary_domaininfo(smb_sid_t *, char *, lsa_info_t *); +static void lsar_set_account_domaininfo(smb_sid_t *, char *, lsa_info_t *); +static void lsar_set_dns_domaininfo(smb_sid_t *, char *, char *, char *, + mslsa_guid_t *, lsa_info_t *); +static void lsar_set_trusted_domainlist(struct mslsa_EnumTrustedDomainBuf *, + lsa_info_t *); + /* * lsar_query_security_desc * @@ -68,23 +74,20 @@ int lsar_query_security_desc(mlsvc_handle_t *lsa_handle) { struct mslsa_QuerySecurityObject arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int rc; int opnum; - context = lsa_handle->context; opnum = LSARPC_OPNUM_QuerySecurityObject; bzero(&arg, sizeof (struct mslsa_QuerySecurityObject)); (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); - (void) mlsvc_rpc_init(&heap); - rc = mlsvc_rpc_call(context, opnum, &arg, &heap); - mlsvc_rpc_free(context, &heap); + rc = ndr_rpc_call(lsa_handle, opnum, &arg); + ndr_rpc_release(lsa_handle); return (rc); } + /* * lsar_query_info_policy * @@ -102,54 +105,63 @@ lsar_query_security_desc(mlsvc_handle_t *lsa_handle) * user_info will not have been updated. */ DWORD -lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass) +lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass, + lsa_info_t *info) { struct mslsa_QueryInfoPolicy arg; - struct mlsvc_rpc_context *context; struct mslsa_PrimaryDomainInfo *pd_info; struct mslsa_AccountDomainInfo *ad_info; - mlrpc_heapref_t heap; - nt_domain_t *nt_new_dp; + struct mslsa_DnsDomainInfo *dns_info; int opnum; DWORD status; - if (lsa_handle == 0) + + if (lsa_handle == NULL || info == NULL) return (NT_STATUS_INVALID_PARAMETER); - context = lsa_handle->context; opnum = LSARPC_OPNUM_QueryInfoPolicy; + bzero(info, sizeof (lsa_info_t)); bzero(&arg, sizeof (struct mslsa_QueryInfoPolicy)); (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); + arg.info_class = infoClass; - (void) mlsvc_rpc_init(&heap); - if (mlsvc_rpc_call(context, opnum, &arg, &heap) != 0) { + if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { status = NT_STATUS_INVALID_PARAMETER; } else if (arg.status != 0) { - mlsvc_rpc_report_status(opnum, arg.status); + ndr_rpc_status(lsa_handle, opnum, arg.status); status = NT_SC_VALUE(arg.status); } else { + switch (infoClass) { case MSLSA_POLICY_PRIMARY_DOMAIN_INFO: - pd_info = &arg.info->ru.pd_info; + pd_info = &arg.ru.pd_info; + + lsar_set_primary_domaininfo((smb_sid_t *)pd_info->sid, + (char *)pd_info->name.str, info); - nt_domain_flush(NT_DOMAIN_PRIMARY); - nt_new_dp = nt_domain_new(NT_DOMAIN_PRIMARY, - (char *)pd_info->name.str, - (smb_sid_t *)pd_info->sid); - (void) nt_domain_add(nt_new_dp); status = NT_STATUS_SUCCESS; break; case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO: - ad_info = &arg.info->ru.ad_info; + ad_info = &arg.ru.ad_info; + + lsar_set_account_domaininfo((smb_sid_t *)ad_info->sid, + (char *)ad_info->name.str, info); + + status = NT_STATUS_SUCCESS; + break; - nt_domain_flush(NT_DOMAIN_ACCOUNT); - nt_new_dp = nt_domain_new(NT_DOMAIN_ACCOUNT, - (char *)ad_info->name.str, - (smb_sid_t *)ad_info->sid); - (void) nt_domain_add(nt_new_dp); + case MSLSA_POLICY_DNS_DOMAIN_INFO: + dns_info = &arg.ru.dns_info; + + lsar_set_dns_domaininfo((smb_sid_t *)dns_info->sid, + (char *)dns_info->nb_domain.str, + (char *)dns_info->dns_domain.str, + (char *)dns_info->forest.str, + &dns_info->guid, + info); status = NT_STATUS_SUCCESS; break; @@ -159,7 +171,7 @@ lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass) } } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(lsa_handle); return (status); } @@ -179,8 +191,6 @@ uint32_t lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name, smb_userinfo_t *user_info) { - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; int index; uint32_t status; @@ -197,7 +207,6 @@ lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name, bzero(user_info, sizeof (smb_userinfo_t)); user_info->sid_name_use = SidTypeUnknown; - context = lsa_handle->context; opnum = LSARPC_OPNUM_LookupNames; bzero(&arg, sizeof (struct mslsa_LookupNames)); @@ -215,7 +224,7 @@ lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name, * Note: NT returns an error if the mapped_count is non-zero * when the RPC is called. */ - if (context->server_os == NATIVE_OS_WIN2000) { + if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) { /* * Windows 2000 doesn't like an LSA lookup for * DOMAIN\Administrator. @@ -238,11 +247,10 @@ lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name, name_table.name[0].allosize = length; name_table.name[0].str = (unsigned char *)name; - (void) mlsvc_rpc_init(&heap); - if (mlsvc_rpc_call(context, opnum, &arg, &heap) != 0) { + if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { status = NT_STATUS_INVALID_PARAMETER; } else if (arg.status != 0) { - mlsvc_rpc_report_status(opnum, arg.status); + ndr_rpc_status(lsa_handle, opnum, arg.status); status = NT_SC_VALUE(arg.status); } else if (arg.mapped_count == 0) { user_info->sid_name_use = SidTypeInvalid; @@ -251,7 +259,7 @@ lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name, rid_entry = &arg.translated_sids.rids[0]; user_info->sid_name_use = rid_entry->sid_name_use; user_info->rid = rid_entry->rid; - user_info->name = MEM_STRDUP("mlrpc", name); + user_info->name = MEM_STRDUP("ndr", name); if ((index = rid_entry->domain_index) == -1) { user_info->domain_sid = 0; @@ -261,7 +269,7 @@ lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name, &arg.domain_table->entries[index]; user_info->domain_sid = smb_sid_dup( (smb_sid_t *)domain_entry->domain_sid); - user_info->domain_name = MEM_STRDUP("mlrpc", + user_info->domain_name = MEM_STRDUP("ndr", (const char *) domain_entry->domain_name.str); user_info->user_sid = smb_sid_splice( @@ -270,7 +278,7 @@ lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name, status = NT_STATUS_SUCCESS; } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(lsa_handle); return (status); } @@ -291,8 +299,6 @@ lsar_lookup_sids(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid, struct mslsa_lup_sid_entry sid_entry; struct mslsa_name_entry *name_entry; struct mslsa_domain_entry *domain_entry; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; int index; uint32_t status; @@ -300,7 +306,6 @@ lsar_lookup_sids(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid, if (lsa_handle == NULL || sid == NULL || user_info == NULL) return (NT_STATUS_INVALID_PARAMETER); - context = lsa_handle->context; opnum = LSARPC_OPNUM_LookupSids; bzero(&arg, sizeof (struct mslsa_LookupSids)); @@ -311,14 +316,13 @@ lsar_lookup_sids(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid, arg.lup_sid_table.n_entry = 1; arg.lup_sid_table.entries = &sid_entry; - (void) mlsvc_rpc_init(&heap); - if (mlsvc_rpc_call(context, opnum, &arg, &heap) != 0) { + if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { status = NT_STATUS_INVALID_PARAMETER; } else if (arg.mapped_count == 0) { user_info->sid_name_use = SidTypeInvalid; status = NT_STATUS_NONE_MAPPED; } else if (arg.status != 0) { - mlsvc_rpc_report_status(opnum, arg.status); + ndr_rpc_status(lsa_handle, opnum, arg.status); status = NT_SC_VALUE(arg.status); } else { name_entry = &arg.name_table.entries[0]; @@ -331,7 +335,7 @@ lsar_lookup_sids(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid, user_info->rid = sid->SubAuthority[sid->SubAuthCount - 1]; - user_info->name = MEM_STRDUP("mlrpc", + user_info->name = MEM_STRDUP("ndr", (const char *)name_entry->name.str); } @@ -345,14 +349,14 @@ lsar_lookup_sids(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid, user_info->domain_sid = smb_sid_dup( (smb_sid_t *)domain_entry->domain_sid); - user_info->domain_name = MEM_STRDUP("mlrpc", + user_info->domain_name = MEM_STRDUP("ndr", (const char *) domain_entry->domain_name.str); } status = NT_STATUS_SUCCESS; } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(lsa_handle); return (status); } @@ -375,8 +379,6 @@ lsar_enum_accounts(mlsvc_handle_t *lsa_handle, DWORD *enum_context, { struct mslsa_EnumerateAccounts arg; struct mslsa_AccountInfo *info; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; int rc; DWORD n_entries; @@ -389,7 +391,6 @@ lsar_enum_accounts(mlsvc_handle_t *lsa_handle, DWORD *enum_context, accounts->entries_read = 0; accounts->info = 0; - context = lsa_handle->context; opnum = LSARPC_OPNUM_EnumerateAccounts; bzero(&arg, sizeof (struct mslsa_EnumerateAccounts)); @@ -397,15 +398,13 @@ lsar_enum_accounts(mlsvc_handle_t *lsa_handle, DWORD *enum_context, arg.enum_context = *enum_context; arg.max_length = MLSVC_MAX_RESPONSE_LEN; - (void) mlsvc_rpc_init(&heap); - rc = mlsvc_rpc_call(context, opnum, &arg, &heap); + rc = ndr_rpc_call(lsa_handle, opnum, &arg); if (rc == 0) { if (arg.status != 0) { if ((arg.status & 0x00FFFFFF) == MLSVC_NO_MORE_DATA) { *enum_context = arg.enum_context; } else { - mlsvc_rpc_report_status(opnum, - (DWORD)arg.status); + ndr_rpc_status(lsa_handle, opnum, arg.status); rc = -1; } } else if (arg.enum_buf->entries_read != 0) { @@ -413,7 +412,7 @@ lsar_enum_accounts(mlsvc_handle_t *lsa_handle, DWORD *enum_context, nbytes = n_entries * sizeof (struct mslsa_AccountInfo); if ((info = malloc(nbytes)) == NULL) { - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(lsa_handle); return (-1); } @@ -427,7 +426,7 @@ lsar_enum_accounts(mlsvc_handle_t *lsa_handle, DWORD *enum_context, } } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(lsa_handle); return (rc); } @@ -447,27 +446,25 @@ lsar_enum_accounts(mlsvc_handle_t *lsa_handle, DWORD *enum_context, * the trusted domains. */ DWORD -lsar_enum_trusted_domains(mlsvc_handle_t *lsa_handle, DWORD *enum_context) +lsar_enum_trusted_domains(mlsvc_handle_t *lsa_handle, DWORD *enum_context, + lsa_info_t *info) { struct mslsa_EnumTrustedDomain arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; - nt_domain_t *nt_new_dp; int opnum; DWORD status; - DWORD n_entries; - DWORD i; - context = lsa_handle->context; + if (info == NULL) + return (NT_STATUS_INVALID_PARAMETER); + opnum = LSARPC_OPNUM_EnumTrustedDomain; + bzero(info, sizeof (lsa_info_t)); bzero(&arg, sizeof (struct mslsa_EnumTrustedDomain)); (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); arg.enum_context = *enum_context; arg.max_length = MLSVC_MAX_RESPONSE_LEN; - (void) mlsvc_rpc_init(&heap); - if (mlsvc_rpc_call(context, opnum, &arg, &heap) != 0) { + if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { status = NT_STATUS_INVALID_PARAMETER; } else if (arg.status != 0) { *enum_context = arg.enum_context; @@ -478,28 +475,17 @@ lsar_enum_trusted_domains(mlsvc_handle_t *lsa_handle, DWORD *enum_context) * which is not an error. */ if (status != MLSVC_NO_MORE_DATA) - mlsvc_rpc_report_status(opnum, arg.status); + ndr_rpc_status(lsa_handle, opnum, arg.status); } else if (arg.enum_buf->entries_read == 0) { *enum_context = arg.enum_context; status = 0; } else { - nt_domain_flush(NT_DOMAIN_TRUSTED); - n_entries = arg.enum_buf->entries_read; - - for (i = 0; i < n_entries; ++i) { - nt_new_dp = nt_domain_new( - NT_DOMAIN_TRUSTED, - (char *)arg.enum_buf->info[i].name.str, - (smb_sid_t *)arg.enum_buf->info[i].sid); - - (void) nt_domain_add(nt_new_dp); - } - + lsar_set_trusted_domainlist(arg.enum_buf, info); *enum_context = arg.enum_context; status = 0; } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(lsa_handle); return (status); } @@ -514,25 +500,21 @@ lsar_enum_privs_account(mlsvc_handle_t *account_handle, smb_userinfo_t *user_info) { struct mslsa_EnumPrivsAccount arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; int rc; - context = account_handle->context; opnum = LSARPC_OPNUM_EnumPrivsAccount; bzero(&arg, sizeof (struct mslsa_EnumPrivsAccount)); (void) memcpy(&arg.account_handle, &account_handle->handle, sizeof (mslsa_handle_t)); - (void) mlsvc_rpc_init(&heap); - rc = mlsvc_rpc_call(context, opnum, &arg, &heap); + rc = ndr_rpc_call(account_handle, opnum, &arg); if ((rc == 0) && (arg.status != 0)) { - mlsvc_rpc_report_status(opnum, (DWORD)arg.status); + ndr_rpc_status(account_handle, opnum, arg.status); rc = -1; } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(account_handle); return (rc); } @@ -550,8 +532,6 @@ lsar_lookup_priv_value(mlsvc_handle_t *lsa_handle, char *name, struct ms_luid *luid) { struct mslsa_LookupPrivValue arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; int rc; size_t length; @@ -559,22 +539,20 @@ lsar_lookup_priv_value(mlsvc_handle_t *lsa_handle, char *name, if (lsa_handle == NULL || name == NULL || luid == NULL) return (-1); - context = lsa_handle->context; opnum = LSARPC_OPNUM_LookupPrivValue; bzero(&arg, sizeof (struct mslsa_LookupPrivValue)); (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); length = mts_wcequiv_strlen(name); - if (context->server_os == NATIVE_OS_WIN2000) + if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) length += sizeof (mts_wchar_t); arg.name.length = length; arg.name.allosize = length; arg.name.str = (unsigned char *)name; - (void) mlsvc_rpc_init(&heap); - rc = mlsvc_rpc_call(context, opnum, &arg, &heap); + rc = ndr_rpc_call(lsa_handle, opnum, &arg); if (rc == 0) { if (arg.status != 0) rc = -1; @@ -582,7 +560,7 @@ lsar_lookup_priv_value(mlsvc_handle_t *lsa_handle, char *name, (void) memcpy(luid, &arg.luid, sizeof (struct ms_luid)); } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(lsa_handle); return (rc); } @@ -599,23 +577,19 @@ lsar_lookup_priv_name(mlsvc_handle_t *lsa_handle, struct ms_luid *luid, char *name, int namelen) { struct mslsa_LookupPrivName arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; int rc; if (lsa_handle == NULL || luid == NULL || name == NULL) return (-1); - context = lsa_handle->context; opnum = LSARPC_OPNUM_LookupPrivName; bzero(&arg, sizeof (struct mslsa_LookupPrivName)); (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); (void) memcpy(&arg.luid, luid, sizeof (struct ms_luid)); - (void) mlsvc_rpc_init(&heap); - rc = mlsvc_rpc_call(context, opnum, &arg, &heap); + rc = ndr_rpc_call(lsa_handle, opnum, &arg); if (rc == 0) { if (arg.status != 0) rc = -1; @@ -624,7 +598,7 @@ lsar_lookup_priv_name(mlsvc_handle_t *lsa_handle, struct ms_luid *luid, namelen); } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(lsa_handle); return (rc); } @@ -646,8 +620,6 @@ lsar_lookup_priv_display_name(mlsvc_handle_t *lsa_handle, char *name, char *display_name, int display_len) { struct mslsa_LookupPrivDisplayName arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; size_t length; DWORD status; @@ -655,7 +627,6 @@ lsar_lookup_priv_display_name(mlsvc_handle_t *lsa_handle, char *name, if (lsa_handle == NULL || name == NULL || display_name == NULL) return (NT_STATUS_INVALID_PARAMETER); - context = lsa_handle->context; opnum = LSARPC_OPNUM_LookupPrivDisplayName; bzero(&arg, sizeof (struct mslsa_LookupPrivDisplayName)); @@ -669,9 +640,7 @@ lsar_lookup_priv_display_name(mlsvc_handle_t *lsa_handle, char *name, arg.client_language = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); arg.default_language = MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL); - (void) mlsvc_rpc_init(&heap); - - if (mlsvc_rpc_call(context, opnum, &arg, &heap) != 0) + if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) status = NT_STATUS_INVALID_PARAMETER; #if 0 else if (arg.status != 0) @@ -683,7 +652,7 @@ lsar_lookup_priv_display_name(mlsvc_handle_t *lsa_handle, char *name, status = NT_STATUS_SUCCESS; } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(lsa_handle); return (status); } @@ -698,8 +667,6 @@ lsar_lookup_sids2(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid, struct lsar_name_entry2 *name_entry; struct mslsa_lup_sid_entry sid_entry; struct mslsa_domain_entry *domain_entry; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; int index; DWORD status; @@ -707,10 +674,9 @@ lsar_lookup_sids2(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid, if (lsa_handle == NULL || sid == NULL || user_info == NULL) return (NT_STATUS_INVALID_PARAMETER); - context = lsa_handle->context; opnum = LSARPC_OPNUM_LookupSids2; - if (context->server_os != NATIVE_OS_WIN2000) + if (ndr_rpc_server_os(lsa_handle) != NATIVE_OS_WIN2000) return (NT_STATUS_REVISION_MISMATCH); bzero(&arg, sizeof (struct lsar_lookup_sids2)); @@ -722,15 +688,13 @@ lsar_lookup_sids2(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid, arg.lookup_level = MSLSA_LOOKUP_LEVEL_1; arg.requested_count = arg.lup_sid_table.n_entry; - (void) mlsvc_rpc_init(&heap); - - if (mlsvc_rpc_call(context, opnum, &arg, &heap) != 0) { + if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { status = NT_STATUS_INVALID_PARAMETER; } else if (arg.mapped_count == 0) { user_info->sid_name_use = SidTypeInvalid; status = NT_STATUS_NONE_MAPPED; } else if (arg.status != 0) { - mlsvc_rpc_report_status(opnum, arg.status); + ndr_rpc_status(lsa_handle, opnum, arg.status); status = NT_SC_VALUE(arg.status); } else { name_entry = &arg.name_table.entries[0]; @@ -743,7 +707,7 @@ lsar_lookup_sids2(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid, user_info->rid = sid->SubAuthority[sid->SubAuthCount - 1]; - user_info->name = MEM_STRDUP("mlrpc", + user_info->name = MEM_STRDUP("ndr", (char const *)name_entry->name.str); } @@ -757,13 +721,13 @@ lsar_lookup_sids2(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid, user_info->domain_sid = smb_sid_dup( (smb_sid_t *)domain_entry->domain_sid); - user_info->domain_name = MEM_STRDUP("mlrpc", + user_info->domain_name = MEM_STRDUP("ndr", (char const *)domain_entry->domain_name.str); } status = NT_STATUS_SUCCESS; } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(lsa_handle); return (status); } @@ -788,8 +752,6 @@ uint32_t lsar_lookup_names2(mlsvc_handle_t *lsa_handle, char *name, smb_userinfo_t *user_info) { - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; int index; struct lsar_LookupNames2 arg; @@ -805,10 +767,9 @@ lsar_lookup_names2(mlsvc_handle_t *lsa_handle, char *name, bzero(user_info, sizeof (smb_userinfo_t)); user_info->sid_name_use = SidTypeUnknown; - context = lsa_handle->context; opnum = LSARPC_OPNUM_LookupNames2; - if (context->server_os != NATIVE_OS_WIN2000) + if (ndr_rpc_server_os(lsa_handle) != NATIVE_OS_WIN2000) return (NT_STATUS_REVISION_MISMATCH); bzero(&arg, sizeof (struct lsar_LookupNames2)); @@ -824,12 +785,10 @@ lsar_lookup_names2(mlsvc_handle_t *lsa_handle, char *name, name_table.name[0].allosize = length; name_table.name[0].str = (unsigned char *)name; - (void) mlsvc_rpc_init(&heap); - - if (mlsvc_rpc_call(context, opnum, &arg, &heap) != 0) { + if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { status = NT_STATUS_INVALID_PARAMETER; } else if (arg.status != 0) { - mlsvc_rpc_report_status(opnum, arg.status); + ndr_rpc_status(lsa_handle, opnum, arg.status); status = NT_SC_VALUE(arg.status); } else if (arg.mapped_count == 0) { user_info->sid_name_use = SidTypeInvalid; @@ -838,7 +797,7 @@ lsar_lookup_names2(mlsvc_handle_t *lsa_handle, char *name, rid_entry = &arg.translated_sids.rids[0]; user_info->sid_name_use = rid_entry->sid_name_use; user_info->rid = rid_entry->rid; - user_info->name = MEM_STRDUP("mlrpc", name); + user_info->name = MEM_STRDUP("ndr", name); if ((index = rid_entry->domain_index) == -1) { user_info->domain_sid = 0; @@ -849,7 +808,7 @@ lsar_lookup_names2(mlsvc_handle_t *lsa_handle, char *name, user_info->domain_sid = smb_sid_dup( (smb_sid_t *)domain_entry->domain_sid); - user_info->domain_name = MEM_STRDUP("mlrpc", + user_info->domain_name = MEM_STRDUP("ndr", (char const *)domain_entry->domain_name.str); user_info->user_sid = smb_sid_splice( user_info->domain_sid, user_info->rid); @@ -857,24 +816,95 @@ lsar_lookup_names2(mlsvc_handle_t *lsa_handle, char *name, status = NT_STATUS_SUCCESS; } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(lsa_handle); return (status); } +static void +lsar_set_nt_domaininfo(smb_sid_t *sid, char *nb_domain, + lsa_nt_domaininfo_t *info) +{ + if (sid == NULL || nb_domain == NULL || info == NULL) + return; + + info->n_sid = smb_sid_dup(sid); + (void) strlcpy(info->n_domain, nb_domain, NETBIOS_NAME_SZ); +} + +static void +lsar_set_primary_domaininfo(smb_sid_t *sid, char *nb_domain, + lsa_info_t *info) +{ + lsa_nt_domaininfo_t *di; + + if (sid == NULL || nb_domain == NULL || info == NULL) + return; + + info->i_type = LSA_INFO_PRIMARY_DOMAIN; + di = &info->i_domain.di_primary; + lsar_set_nt_domaininfo(sid, nb_domain, di); +} + +static void +lsar_set_account_domaininfo(smb_sid_t *sid, char *nb_domain, + lsa_info_t *info) +{ + lsa_nt_domaininfo_t *di; + + if (sid == NULL || nb_domain == NULL || info == NULL) + return; + + info->i_type = LSA_INFO_ACCOUNT_DOMAIN; + di = &info->i_domain.di_account; + lsar_set_nt_domaininfo(sid, nb_domain, di); +} + +static void +lsar_set_dns_domaininfo(smb_sid_t *sid, char *nb_domain, char *fq_domain, + char *forest, mslsa_guid_t *guid, lsa_info_t *info) +{ + lsa_dns_domaininfo_t *di; + + if (sid == NULL || nb_domain == NULL || fq_domain == NULL || + forest == NULL) + return; + + if (guid == NULL || info == NULL) + return; + + info->i_type = LSA_INFO_DNS_DOMAIN; + di = &info->i_domain.di_dns; + di->d_sid = smb_sid_dup(sid); + (void) strlcpy(di->d_nbdomain, nb_domain, NETBIOS_NAME_SZ); + (void) strlcpy(di->d_fqdomain, fq_domain, MAXHOSTNAMELEN); + (void) strlcpy(di->d_forest, forest, MAXHOSTNAMELEN); + (void) bcopy(guid, &di->d_guid, sizeof (mslsa_guid_t)); +} -void -mlsvc_rpc_report_status(int opnum, DWORD status) +static void +lsar_set_trusted_domainlist(struct mslsa_EnumTrustedDomainBuf *enum_buf, + lsa_info_t *info) { - char *s = "unknown"; - - if (status == 0) - s = "success"; - else if (NT_SC_IS_ERROR(status)) - s = "error"; - else if (NT_SC_IS_WARNING(status)) - s = "warning"; - else if (NT_SC_IS_INFO(status)) - s = "info"; - - smb_tracef("mlrpc[0x%02x]: %s: %s (0x%08x)", - opnum, s, xlate_nt_status(status), status); + int i; + lsa_trusted_domainlist_t *list; + + if (info == NULL) + return; + + if (enum_buf == NULL || enum_buf->entries_read == 0) + return; + + info->i_type = LSA_INFO_TRUSTED_DOMAINS; + list = &info->i_domain.di_trust; + list->t_domains = malloc(enum_buf->entries_read * + sizeof (lsa_nt_domaininfo_t)); + if (list->t_domains == NULL) { + list->t_num = 0; + } else { + list->t_num = enum_buf->entries_read; + for (i = 0; i < list->t_num; i++) + lsar_set_nt_domaininfo( + (smb_sid_t *)enum_buf->info[i].sid, + (char *)enum_buf->info[i].name.str, + &list->t_domains[i]); + } } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/lsar_open.c b/usr/src/lib/smbsrv/libmlsvc/common/lsar_open.c index 10f77f49cf..94a7b57ae5 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/lsar_open.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/lsar_open.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Local Security Authority RPC (LSARPC) library interface functions for * open and close calls. @@ -35,19 +33,17 @@ #include <smbsrv/libsmb.h> #include <smbsrv/libsmbrdr.h> -#include <smbsrv/mlsvc.h> +#include <smbsrv/libmlsvc.h> #include <smbsrv/smbinfo.h> #include <smbsrv/ntaccess.h> #include <smbsrv/ntstatus.h> -#include <smbsrv/lsalib.h> +#include <lsalib.h> /* * lsar_open * * This is a wrapper round lsar_open_policy2 to ensure that we connect - * using the appropriate session and logon. We default to the resource - * domain information if the caller didn't supply a server name and a - * domain name. + * using the appropriate domain information. * * If username argument is NULL, an anonymous connection will be established. * Otherwise, an authenticated connection will be established. @@ -57,39 +53,15 @@ int lsar_open(char *server, char *domain, char *username, mlsvc_handle_t *domain_handle) { - smb_ntdomain_t *di; - int remote_os; - int remote_lm; - int rc; - - if (server == NULL || domain == NULL) { - if ((di = smb_getdomaininfo(0)) == NULL) - return (-1); - - server = di->server; - domain = di->domain; - } + if (server == NULL || domain == NULL) + return (-1); if (username == NULL) username = MLSVC_ANON_USER; - rc = mlsvc_logon(server, domain, username); - - if (rc != 0) - return (-1); - - rc = lsar_open_policy2(server, domain, username, domain_handle); - if (rc == 0) { - if (mlsvc_session_native_values(domain_handle->context->fid, - &remote_os, &remote_lm, 0) != 0) - remote_os = NATIVE_OS_UNKNOWN; - - domain_handle->context->server_os = remote_os; - } - return (rc); + return (lsar_open_policy2(server, domain, username, domain_handle)); } - /* * lsar_open_policy2 * @@ -106,48 +78,33 @@ int lsar_open(char *server, char *domain, char *username, * * Returns 0 on success. Otherwise non-zero to indicate a failure. */ -int lsar_open_policy2(char *server, char *domain, char *username, +int +lsar_open_policy2(char *server, char *domain, char *username, mlsvc_handle_t *lsa_handle) { struct mslsa_OpenPolicy2 arg; - mlrpc_heapref_t heap; - int rc; int opnum; - int fid; - int remote_os; - int remote_lm; int len; + int rc; - if (server == NULL || domain == NULL || - username == NULL || lsa_handle == NULL) - return (-1); - - fid = mlsvc_open_pipe(server, domain, username, "\\lsarpc"); - if (fid < 0) + rc = ndr_rpc_bind(lsa_handle, server, domain, username, "LSARPC"); + if (rc != 0) return (-1); - if ((rc = mlsvc_rpc_bind(lsa_handle, fid, "LSARPC")) < 0) { - (void) mlsvc_close_pipe(fid); - return (rc); - } - opnum = LSARPC_OPNUM_OpenPolicy2; bzero(&arg, sizeof (struct mslsa_OpenPolicy2)); len = strlen(server) + 4; - arg.servername = malloc(len); + arg.servername = ndr_rpc_malloc(lsa_handle, len); if (arg.servername == NULL) { - (void) mlsvc_close_pipe(fid); - free(lsa_handle->context); + ndr_rpc_unbind(lsa_handle); return (-1); } (void) snprintf((char *)arg.servername, len, "\\\\%s", server); arg.attributes.length = sizeof (struct mslsa_object_attributes); - (void) mlsvc_session_native_values(fid, &remote_os, &remote_lm, 0); - - if (remote_os == NATIVE_OS_NT5_0) { + if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_NT5_0) { arg.desiredAccess = MAXIMUM_ALLOWED; } else { arg.desiredAccess = GENERIC_EXECUTE @@ -156,28 +113,25 @@ int lsar_open_policy2(char *server, char *domain, char *username, | POLICY_LOOKUP_NAMES; } - (void) mlsvc_rpc_init(&heap); - rc = mlsvc_rpc_call(lsa_handle->context, opnum, &arg, &heap); - if (rc == 0) { - if (arg.status != 0) { - rc = -1; - } else { - (void) memcpy(&lsa_handle->handle, &arg.domain_handle, - sizeof (mslsa_handle_t)); - - if (mlsvc_is_null_handle(lsa_handle)) - rc = -1; - } + if ((rc = ndr_rpc_call(lsa_handle, opnum, &arg)) != 0) { + ndr_rpc_unbind(lsa_handle); + return (-1); } - mlsvc_rpc_free(lsa_handle->context, &heap); - free(arg.servername); + if (arg.status != 0) { + rc = -1; + } else { + (void) memcpy(&lsa_handle->handle, &arg.domain_handle, + sizeof (ndr_hdid_t)); - if (rc != 0) { - (void) mlsvc_close_pipe(fid); - free(lsa_handle->context); + if (ndr_is_null_handle(lsa_handle)) + rc = -1; } + ndr_rpc_release(lsa_handle); + + if (rc != 0) + ndr_rpc_unbind(lsa_handle); return (rc); } @@ -197,16 +151,12 @@ lsar_open_account(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid, mlsvc_handle_t *lsa_account_handle) { struct mslsa_OpenAccount arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; - int rc; int opnum; + int rc; - if (mlsvc_is_null_handle(lsa_handle) || - sid == NULL || lsa_account_handle == NULL) + if (ndr_is_null_handle(lsa_handle) || sid == NULL) return (-1); - context = lsa_handle->context; opnum = LSARPC_OPNUM_OpenAccount; bzero(&arg, sizeof (struct mslsa_OpenAccount)); @@ -220,23 +170,22 @@ lsar_open_account(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid, #endif | POLICY_VIEW_LOCAL_INFORMATION; - (void) mlsvc_rpc_init(&heap); - rc = mlsvc_rpc_call(context, opnum, &arg, &heap); - if (rc == 0) { - if (arg.status != 0) { - rc = -1; - } else { - lsa_account_handle->context = context; + if ((rc = ndr_rpc_call(lsa_handle, opnum, &arg)) != 0) + return (-1); + + if (arg.status != 0) { + rc = -1; + } else { + ndr_inherit_handle(lsa_account_handle, lsa_handle); - (void) memcpy(&lsa_account_handle->handle, - &arg.account_handle, sizeof (mslsa_handle_t)); + (void) memcpy(&lsa_account_handle->handle, + &arg.account_handle, sizeof (ndr_hdid_t)); - if (mlsvc_is_null_handle(lsa_account_handle)) - rc = -1; - } + if (ndr_is_null_handle(lsa_account_handle)) + rc = -1; } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(lsa_handle); return (rc); } @@ -247,8 +196,7 @@ lsar_open_account(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid, * must be a valid handle obtained via a call to lsar_open_policy2 or * lsar_open_account. On success the handle will be zeroed out to * ensure that it is not used again. If this is the top level handle - * (i.e. the one obtained via lsar_open_policy2) the pipe is closed - * and the context is freed. + * (i.e. the one obtained via lsar_open_policy2) the pipe is closed. * * Returns 0 on success. Otherwise non-zero to indicate a failure. */ @@ -256,26 +204,21 @@ int lsar_close(mlsvc_handle_t *lsa_handle) { struct mslsa_CloseHandle arg; - mlrpc_heapref_t heap; - int rc; int opnum; - if (mlsvc_is_null_handle(lsa_handle)) + if (ndr_is_null_handle(lsa_handle)) return (-1); opnum = LSARPC_OPNUM_CloseHandle; bzero(&arg, sizeof (struct mslsa_CloseHandle)); (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); - (void) mlsvc_rpc_init(&heap); - rc = mlsvc_rpc_call(lsa_handle->context, opnum, &arg, &heap); - mlsvc_rpc_free(lsa_handle->context, &heap); + (void) ndr_rpc_call(lsa_handle, opnum, &arg); + ndr_rpc_release(lsa_handle); - if (lsa_handle->context->handle == &lsa_handle->handle) { - (void) mlsvc_close_pipe(lsa_handle->context->fid); - free(lsa_handle->context); - } + if (ndr_is_bind_handle(lsa_handle)) + ndr_rpc_unbind(lsa_handle); bzero(lsa_handle, sizeof (mlsvc_handle_t)); - return (rc); + return (0); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers b/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers index a81c82c83c..58fba14273 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers +++ b/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers @@ -28,7 +28,9 @@ SUNWprivate { global: dssetup_clear_domain_info; lsa_enum_trusted_domains; + lsa_free_info; lsa_query_account_domain_info; + lsa_query_dns_domain_info; lsa_query_primary_domain_info; mlsvc_get_door_fd; mlsvc_get_num_users; @@ -42,6 +44,8 @@ SUNWprivate { mlsvc_set_share; smb_autohome_add; smb_autohome_remove; + smb_domain_getinfo; + smb_locate_dc; smb_logon; smb_shr_add; smb_shr_chkname; @@ -51,6 +55,7 @@ SUNWprivate { smb_shr_iterate; smb_shr_iterinit; smb_shr_list; + smb_shr_load; smb_shr_modify; smb_shr_remove; smb_shr_rename; diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h new file mode 100644 index 0000000000..efe8fa6544 --- /dev/null +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h @@ -0,0 +1,61 @@ +/* + * 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 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SMBSRV_MLSVC_H +#define _SMBSRV_MLSVC_H + +#include <smbsrv/ndl/netlogon.ndl> + +#ifdef __cplusplus +extern "C" { +#endif + +int smb_dclocator_init(void); +void dssetup_initialize(void); +void srvsvc_initialize(void); +void wkssvc_initialize(void); +void lsarpc_initialize(void); +void logr_initialize(void); +void netr_initialize(void); +void samr_initialize(void); +void svcctl_initialize(void); +void winreg_initialize(void); +int srvsvc_gettime(unsigned long *); +void msgsvcsend_initialize(void); +void spoolss_initialize(void); + +int netr_open(char *, char *, mlsvc_handle_t *); +int netr_close(mlsvc_handle_t *); +DWORD netlogon_auth(char *, mlsvc_handle_t *, DWORD); +int netr_setup_authenticator(netr_info_t *, struct netr_authenticator *, + struct netr_authenticator *); +DWORD netr_validate_chain(netr_info_t *, struct netr_authenticator *); + +#ifdef __cplusplus +} +#endif + + +#endif /* _SMBSRV_MLSVC_H */ diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c index 25acdec4f2..c851a7fc07 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c @@ -23,162 +23,291 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* - * Context functions to support the RPC interface library. + * Client NDR RPC interface. */ #include <sys/errno.h> #include <strings.h> - +#include <assert.h> #include <smbsrv/libsmb.h> #include <smbsrv/libsmbrdr.h> -#include <smbsrv/ndr.h> -#include <smbsrv/mlrpc.h> -#include <smbsrv/mlsvc_util.h> - -static int mlsvc_xa_init(struct mlrpc_client *, struct mlrpc_xaction *, - mlrpc_heap_t *); -static int mlsvc_xa_exchange(struct mlrpc_client *, struct mlrpc_xaction *); -static int mlsvc_xa_read(struct mlrpc_client *, struct mlrpc_xaction *); -static int mlsvc_xa_preserve(struct mlrpc_client *, struct mlrpc_xaction *, - mlrpc_heapref_t *); -static int mlsvc_xa_destruct(struct mlrpc_client *, struct mlrpc_xaction *); -static void mlsvc_xa_release(struct mlrpc_client *, mlrpc_heapref_t *heapref); +#include <smbsrv/libmlrpc.h> +#include <smbsrv/libmlsvc.h> + +static int ndr_xa_init(ndr_client_t *, ndr_xa_t *); +static int ndr_xa_exchange(ndr_client_t *, ndr_xa_t *); +static int ndr_xa_read(ndr_client_t *, ndr_xa_t *); +static void ndr_xa_preserve(ndr_client_t *, ndr_xa_t *); +static void ndr_xa_destruct(ndr_client_t *, ndr_xa_t *); +static void ndr_xa_release(ndr_client_t *); /* - * mlsvc_rpc_bind + * This call must be made to initialize an RPC client structure and bind + * to the remote service before any RPCs can be exchanged with that service. * - * This the entry point for all client RPC services. This call must be - * made to initialize an RPC context structure and bind to the remote - * service before any RPCs can be exchanged with that service. The - * descriptor is a wrapper that is used to associate an RPC handle with - * the context data for that specific instance of the interface. The - * handle is zeroed to ensure that it doesn't look like a valid handle. - * The context handle is assigned to point at the RPC handle so that we - * know when to free the context. As each handle is initialized it will - * include a pointer to this context but only when we close this initial - * RPC handle can the context be freed. + * The mlsvc_handle_t is a wrapper that is used to associate an RPC handle + * with the client context for an instance of the interface. The handle + * is zeroed to ensure that it doesn't look like a valid handle - + * handle content is provided by the remove service. * - * On success, return a pointer to the descriptor. Otherwise return a - * null pointer. + * The client points to this top-level handle so that we know when to + * unbind and teardown the connection. As each handle is initialized it + * will inherit a reference to the client context. */ int -mlsvc_rpc_bind(mlsvc_handle_t *desc, int fid, char *service) +ndr_rpc_bind(mlsvc_handle_t *handle, char *server, char *domain, + char *username, const char *service) { - struct mlsvc_rpc_context *context; - int rc; + ndr_client_t *clnt; + ndr_service_t *svc; + smbrdr_session_info_t si; + int fid; + int rc; + + if (handle == NULL || server == NULL || + domain == NULL || username == NULL) + return (-1); + + if ((svc = ndr_svc_lookup_name(service)) == NULL) + return (-1); + + if ((clnt = malloc(sizeof (ndr_client_t))) == NULL) + return (-1); + + fid = smbrdr_open_pipe(server, domain, username, svc->endpoint); + if (fid < 0) { + free(clnt); + return (-1); + } - bzero(&desc->handle, sizeof (ms_handle_t)); + bzero(clnt, sizeof (ndr_client_t)); + clnt->handle = &handle->handle; + clnt->fid = fid; - context = malloc(sizeof (struct mlsvc_rpc_context)); - if ((desc->context = context) == NULL) + ndr_svc_binding_pool_init(&clnt->binding_list, + clnt->binding_pool, NDR_N_BINDING_POOL); + + clnt->xa_init = ndr_xa_init; + clnt->xa_exchange = ndr_xa_exchange; + clnt->xa_read = ndr_xa_read; + clnt->xa_preserve = ndr_xa_preserve; + clnt->xa_destruct = ndr_xa_destruct; + clnt->xa_release = ndr_xa_release; + + (void) smbrdr_session_info(fid, &si); + bzero(&handle->handle, sizeof (ndr_hdid_t)); + handle->clnt = clnt; + handle->remote_os = si.si_server_os; + + if (ndr_rpc_get_heap(handle) == NULL) { + free(clnt); return (-1); + } - bzero(context, sizeof (struct mlsvc_rpc_context)); - context->cli.context = context; - - mlrpc_binding_pool_initialize(&context->cli.binding_list, - context->binding_pool, CTXT_N_BINDING_POOL); - - context->fid = fid; - context->handle = &desc->handle; - context->cli.xa_init = mlsvc_xa_init; - context->cli.xa_exchange = mlsvc_xa_exchange; - context->cli.xa_read = mlsvc_xa_read; - context->cli.xa_preserve = mlsvc_xa_preserve; - context->cli.xa_destruct = mlsvc_xa_destruct; - context->cli.xa_release = mlsvc_xa_release; - - rc = mlrpc_c_bind(&context->cli, service, &context->binding); - if (MLRPC_DRC_IS_FAULT(rc)) { - free(context); - desc->context = NULL; + rc = ndr_clnt_bind(clnt, service, &clnt->binding); + if (NDR_DRC_IS_FAULT(rc)) { + (void) smbrdr_close_pipe(fid); + ndr_heap_destroy(clnt->heap); + free(clnt); + handle->clnt = NULL; return (-1); } - return (rc); + return (0); } /* - * mlsvc_rpc_init + * Unbind and close the pipe to an RPC service. * - * This function must be called by client side applications before - * calling mlsvc_rpc_call to allocate a heap. The heap must be - * destroyed by either calling mlrpc_heap_destroy or mlsvc_rpc_free. - * Use mlrpc_heap_destroy if mlsvc_rpc_call has not yet been called. - * Otherwise use mlsvc_rpc_free. + * If the heap has been preserved we need to go through an xa release. + * The heap is preserved during an RPC call because that's where data + * returned from the server is stored. * - * Returns 0 on success. Otherwise returns -1 to indicate an error. + * Otherwise we destroy the heap directly. + */ +void +ndr_rpc_unbind(mlsvc_handle_t *handle) +{ + ndr_client_t *clnt = handle->clnt; + + if (clnt->heap_preserved) + ndr_clnt_free_heap(clnt); + else + ndr_heap_destroy(clnt->heap); + + (void) smbrdr_close_pipe(clnt->fid); + free(handle->clnt); + bzero(handle, sizeof (mlsvc_handle_t)); +} + +/* + * Call the RPC function identified by opnum. The remote service is + * identified by the handle, which should have been initialized by + * ndr_rpc_bind. + * + * If the RPC call is successful (returns 0), the caller must call + * ndr_rpc_release to release the heap. Otherwise, we release the + * heap here. */ int -mlsvc_rpc_init(mlrpc_heapref_t *heapref) +ndr_rpc_call(mlsvc_handle_t *handle, int opnum, void *params) { - bzero(heapref, sizeof (mlrpc_heapref_t)); + ndr_client_t *clnt = handle->clnt; + int rc; + + if (ndr_rpc_get_heap(handle) == NULL) + return (-1); - if ((heapref->heap = mlrpc_heap_create()) == NULL) + rc = ndr_clnt_call(clnt->binding, opnum, params); + + if (NDR_DRC_IS_FAULT(rc)) { + ndr_rpc_release(handle); return (-1); + } return (0); } /* - * mlsvc_rpc_call - * - * This function should be called by the client RPC interface functions - * to make an RPC call. The remote service is identified by the context - * handle, which should have been initialized with by mlsvc_rpc_bind. + * Returns the Native-OS of the RPC server. */ int -mlsvc_rpc_call(struct mlsvc_rpc_context *context, int opnum, void *params, - mlrpc_heapref_t *heapref) +ndr_rpc_server_os(mlsvc_handle_t *handle) { - return (mlrpc_c_call(context->binding, opnum, params, heapref)); + return (handle->remote_os); +} + +void * +ndr_rpc_malloc(mlsvc_handle_t *handle, size_t size) +{ + ndr_heap_t *heap; + + if ((heap = ndr_rpc_get_heap(handle)) == NULL) + return (NULL); + + return (ndr_heap_malloc(heap, size)); +} + +ndr_heap_t * +ndr_rpc_get_heap(mlsvc_handle_t *handle) +{ + ndr_client_t *clnt = handle->clnt; + + if (clnt->heap == NULL) + clnt->heap = ndr_heap_create(); + + return (clnt->heap); } /* - * mlsvc_rpc_free - * - * This function should be called by the client RPC interface functions - * to free the heap after an RPC call returns. + * Must be called by RPC clients to free the heap after a successful RPC + * call, i.e. ndr_rpc_call returned 0. The caller should take a copy + * of any data returned by the RPC prior to calling this function because + * returned data is in the heap. */ void -mlsvc_rpc_free(struct mlsvc_rpc_context *context, mlrpc_heapref_t *heapref) +ndr_rpc_release(mlsvc_handle_t *handle) { - mlrpc_c_free_heap(context->binding, heapref); + ndr_client_t *clnt = handle->clnt; + + if (clnt->heap_preserved) + ndr_clnt_free_heap(clnt); + else + ndr_heap_destroy(clnt->heap); + + clnt->heap = NULL; } /* - * The following functions provide the callback interface in the - * context handle. + * Returns true if the handle is null. + * Otherwise returns false. + */ +boolean_t +ndr_is_null_handle(mlsvc_handle_t *handle) +{ + static ndr_hdid_t zero_handle; + + if (handle == NULL || handle->clnt == NULL) + return (B_TRUE); + + if (!memcmp(&handle->handle, &zero_handle, sizeof (ndr_hdid_t))) + return (B_TRUE); + + return (B_FALSE); +} + +/* + * Returns true if the handle is the top level bind handle. + * Otherwise returns false. + */ +boolean_t +ndr_is_bind_handle(mlsvc_handle_t *handle) +{ + return (handle->clnt->handle == &handle->handle); +} + +/* + * Pass the client reference from parent to child. + */ +void +ndr_inherit_handle(mlsvc_handle_t *child, mlsvc_handle_t *parent) +{ + child->clnt = parent->clnt; + child->remote_os = parent->remote_os; +} + +void +ndr_rpc_status(mlsvc_handle_t *handle, int opnum, DWORD status) +{ + ndr_service_t *svc; + char *name = "NDR RPC"; + char *s = "unknown"; + + if (status == 0) + s = "success"; + else if (NT_SC_IS_ERROR(status)) + s = "error"; + else if (NT_SC_IS_WARNING(status)) + s = "warning"; + else if (NT_SC_IS_INFO(status)) + s = "info"; + + if (handle) { + svc = handle->clnt->binding->service; + name = svc->name; + } + + smb_tracef("%s[0x%02x]: %s: %s (0x%08x)", + name, opnum, s, xlate_nt_status(status), status); +} + +/* + * The following functions provide the client callback interface. + * If the caller hasn't provided a heap, create one here. */ -/*ARGSUSED*/ static int -mlsvc_xa_init(struct mlrpc_client *mcli, struct mlrpc_xaction *mxa, - mlrpc_heap_t *heap) +ndr_xa_init(ndr_client_t *clnt, ndr_xa_t *mxa) { - struct mlndr_stream *recv_mlnds = &mxa->recv_mlnds; - struct mlndr_stream *send_mlnds = &mxa->send_mlnds; - - /* - * If the caller hasn't provided a heap, create one here. - */ - if (heap == 0) { - if ((heap = mlrpc_heap_create()) == 0) + ndr_stream_t *recv_nds = &mxa->recv_nds; + ndr_stream_t *send_nds = &mxa->send_nds; + ndr_heap_t *heap = clnt->heap; + + if (heap == NULL) { + if ((heap = ndr_heap_create()) == NULL) return (-1); + + clnt->heap = heap; } mxa->heap = heap; - mlnds_initialize(send_mlnds, 0, NDR_MODE_CALL_SEND, heap); - mlnds_initialize(recv_mlnds, 16 * 1024, NDR_MODE_RETURN_RECV, heap); + nds_initialize(send_nds, 0, NDR_MODE_CALL_SEND, heap); + nds_initialize(recv_nds, 16 * 1024, NDR_MODE_RETURN_RECV, heap); return (0); } /* - * mlsvc_xa_exchange - * * This is the entry pointy for an RPC client call exchange with * a server, which will result in an smbrdr SmbTransact request. * @@ -186,28 +315,26 @@ mlsvc_xa_init(struct mlrpc_client *mcli, struct mlrpc_xaction *mxa, * we record as the PDU size, or a negative error code. */ static int -mlsvc_xa_exchange(struct mlrpc_client *mcli, struct mlrpc_xaction *mxa) +ndr_xa_exchange(ndr_client_t *clnt, ndr_xa_t *mxa) { - struct mlsvc_rpc_context *context = mcli->context; - struct mlndr_stream *recv_mlnds = &mxa->recv_mlnds; - struct mlndr_stream *send_mlnds = &mxa->send_mlnds; - int rc; + ndr_stream_t *recv_nds = &mxa->recv_nds; + ndr_stream_t *send_nds = &mxa->send_nds; + int nbytes; - rc = smbrdr_transact(context->fid, - (char *)send_mlnds->pdu_base_offset, send_mlnds->pdu_size, - (char *)recv_mlnds->pdu_base_offset, recv_mlnds->pdu_max_size); + nbytes = smbrdr_transact(clnt->fid, + (char *)send_nds->pdu_base_offset, send_nds->pdu_size, + (char *)recv_nds->pdu_base_offset, recv_nds->pdu_max_size); - if (rc < 0) - recv_mlnds->pdu_size = 0; - else - recv_mlnds->pdu_size = rc; + if (nbytes < 0) { + recv_nds->pdu_size = 0; + return (-1); + } - return (rc); + recv_nds->pdu_size = nbytes; + return (nbytes); } /* - * mlsvc_xa_read - * * This entry point will be invoked if the xa-exchange response contained * only the first fragment of a multi-fragment response. The RPC client * code will then make repeated xa-read requests to obtain the remaining @@ -218,91 +345,70 @@ mlsvc_xa_exchange(struct mlrpc_client *mcli, struct mlrpc_xaction *mxa) * code. */ static int -mlsvc_xa_read(struct mlrpc_client *mcli, struct mlrpc_xaction *mxa) +ndr_xa_read(ndr_client_t *clnt, ndr_xa_t *mxa) { - struct mlsvc_rpc_context *context = mcli->context; - struct mlndr_stream *mlnds = &mxa->recv_mlnds; + ndr_stream_t *nds = &mxa->recv_nds; int len; - int rc; + int nbytes; - if ((len = (mlnds->pdu_max_size - mlnds->pdu_size)) < 0) + if ((len = (nds->pdu_max_size - nds->pdu_size)) < 0) return (-1); - rc = smbrdr_readx(context->fid, - (char *)mlnds->pdu_base_offset + mlnds->pdu_size, len); + nbytes = smbrdr_readx(clnt->fid, + (char *)nds->pdu_base_offset + nds->pdu_size, len); - if (rc < 0) + if (nbytes < 0) return (-1); - mlnds->pdu_size += rc; + nds->pdu_size += nbytes; - if (mlnds->pdu_size > mlnds->pdu_max_size) { - mlnds->pdu_size = mlnds->pdu_max_size; + if (nds->pdu_size > nds->pdu_max_size) { + nds->pdu_size = nds->pdu_max_size; return (-1); } - return (rc); + return (nbytes); } /* - * mlsvc_xa_preserve - * - * This function is called to preserve the heap. We save a reference - * to the heap and set the mxa heap pointer to null so that the heap - * will not be discarded when mlsvc_xa_destruct is called. + * Preserve the heap so that the client application has access to data + * returned from the server after an RPC call. */ -/*ARGSUSED*/ -static int -mlsvc_xa_preserve(struct mlrpc_client *mcli, struct mlrpc_xaction *mxa, - mlrpc_heapref_t *heapref) +static void +ndr_xa_preserve(ndr_client_t *clnt, ndr_xa_t *mxa) { - heapref->state = MLRPC_HRST_PRESERVED; - heapref->heap = mxa->heap; - heapref->recv_pdu_buf = (char *)mxa->recv_mlnds.pdu_base_addr; - heapref->send_pdu_buf = (char *)mxa->send_mlnds.pdu_base_addr; + assert(clnt->heap == mxa->heap); + clnt->heap_preserved = B_TRUE; mxa->heap = NULL; - return (0); } /* - * mlsvc_xa_destruct - * - * This function is called to dispose of the heap. If the heap has - * been preserved via mlsvc_xa_preserve, the mxa heap pointer will - * be null and we assume that the heap will be released later via - * a call to mlsvc_xa_release. Otherwise we free the memory here. + * Dispose of the transaction streams. If the heap has not been + * preserved, we can destroy it here. */ -/*ARGSUSED*/ -static int -mlsvc_xa_destruct(struct mlrpc_client *mcli, struct mlrpc_xaction *mxa) +static void +ndr_xa_destruct(ndr_client_t *clnt, ndr_xa_t *mxa) { - if (mxa->heap) { - mlnds_destruct(&mxa->recv_mlnds); - mlnds_destruct(&mxa->send_mlnds); - mlrpc_heap_destroy(mxa->heap); - } + nds_destruct(&mxa->recv_nds); + nds_destruct(&mxa->send_nds); - return (0); + if (!clnt->heap_preserved) { + ndr_heap_destroy(mxa->heap); + mxa->heap = NULL; + clnt->heap = NULL; + } } /* - * mlsvc_xa_release - * - * This function is called, via some indirection, as a result of a - * call to mlsvc_rpc_free. This is where we free the heap memory - * that was preserved during an RPC call. + * Dispose of a preserved heap. */ -/*ARGSUSED*/ static void -mlsvc_xa_release(struct mlrpc_client *mcli, mlrpc_heapref_t *heapref) +ndr_xa_release(ndr_client_t *clnt) { - if (heapref == NULL) - return; - - if (heapref->state == MLRPC_HRST_PRESERVED) { - free(heapref->recv_pdu_buf); - free(heapref->send_pdu_buf); - mlrpc_heap_destroy(heapref->heap); + if (clnt->heap_preserved) { + ndr_heap_destroy(clnt->heap); + clnt->heap = NULL; + clnt->heap_preserved = B_FALSE; } } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c new file mode 100644 index 0000000000..c36d12e062 --- /dev/null +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c @@ -0,0 +1,594 @@ +/* + * 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 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <syslog.h> +#include <synch.h> +#include <pthread.h> +#include <unistd.h> +#include <string.h> +#include <strings.h> +#include <sys/errno.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <resolv.h> +#include <netdb.h> +#include <assert.h> + +#include <smbsrv/libsmb.h> +#include <smbsrv/libsmbrdr.h> +#include <smbsrv/libsmbns.h> +#include <smbsrv/libmlsvc.h> + +#include <smbsrv/smbinfo.h> +#include <smbsrv/ntstatus.h> +#include <lsalib.h> + +/* + * Domain cache states + */ +#define SMB_DCACHE_STATE_INVALID 0 +#define SMB_DCACHE_STATE_UPDATING 1 +#define SMB_DCACHE_STATE_VALID 2 + +typedef struct smb_domain_cache { + uint32_t c_state; + smb_domain_t c_cache; + mutex_t c_mtx; + cond_t c_cv; +} smb_domain_cache_t; + +static smb_domain_cache_t smb_dcache; + +/* functions to manipulate the domain cache */ +static void smb_dcache_init(void); +static void smb_dcache_updating(void); +static void smb_dcache_invalid(void); +static void smb_dcache_valid(smb_domain_t *); +static void smb_dcache_set(uint32_t, smb_domain_t *); + +/* + * DC Locator + */ +#define SMB_DCLOCATOR_TIMEOUT 45 +#define SMB_IS_FQDN(domain) (strchr(domain, '.') != NULL) + +typedef struct smb_dclocator { + char sdl_domain[SMB_PI_MAX_DOMAIN]; + char sdl_dc[MAXHOSTNAMELEN]; + boolean_t sdl_locate; + mutex_t sdl_mtx; + cond_t sdl_cv; + uint32_t sdl_status; +} smb_dclocator_t; + +static smb_dclocator_t smb_dclocator; +static pthread_t smb_dclocator_thr; + +static void *smb_dclocator_main(void *); +static boolean_t smb_dc_discovery(char *, char *, smb_domain_t *); +static boolean_t smb_match_domains(char *, char *, uint32_t); +static uint32_t smb_domain_query(char *, char *, smb_domain_t *); +static void smb_domain_update_tabent(int, lsa_nt_domaininfo_t *); +static void smb_domain_populate_table(char *, char *); +static boolean_t smb_domain_use_config(char *, smb_domain_t *); + +/* + * =================================================================== + * API to initialize DC locator thread, trigger DC discovery, and + * get the discovered DC and/or domain information. + * =================================================================== + */ + +/* + * smb_dclocator_init + * + * Initialization of the DC locator thread. + * Returns 0 on success, an error number if thread creation fails. + */ +int +smb_dclocator_init(void) +{ + pthread_attr_t tattr; + int rc; + + smb_dcache_init(); + (void) pthread_attr_init(&tattr); + (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); + rc = pthread_create(&smb_dclocator_thr, &tattr, + smb_dclocator_main, 0); + (void) pthread_attr_destroy(&tattr); + return (rc); +} + +/* + * smb_locate_dc + * + * This is the entry point for discovering a domain controller for the + * specified domain. + * + * The actual work of discovering a DC is handled by DC locator thread. + * All we do here is signal the request and wait for a DC or a timeout. + * + * Input parameters: + * domain - domain to be discovered (can either be NetBIOS or DNS domain) + * dc - preferred DC. If the preferred DC is set to empty string, it + * will attempt to discover any DC in the specified domain. + * + * Output parameter: + * dp - on success, dp will be filled with the discovered DC and domain + * information. + * Returns B_TRUE if the DC/domain info is available. + */ +boolean_t +smb_locate_dc(char *domain, char *dc, smb_domain_t *dp) +{ + int rc; + timestruc_t to; + smb_domain_t domain_info; + + if (domain == NULL || *domain == '\0') + return (B_FALSE); + + (void) mutex_lock(&smb_dclocator.sdl_mtx); + + if (!smb_dclocator.sdl_locate) { + smb_dclocator.sdl_locate = B_TRUE; + (void) strlcpy(smb_dclocator.sdl_domain, domain, + SMB_PI_MAX_DOMAIN); + (void) strlcpy(smb_dclocator.sdl_dc, dc, + MAXHOSTNAMELEN); + (void) cond_broadcast(&smb_dclocator.sdl_cv); + } + + while (smb_dclocator.sdl_locate) { + to.tv_sec = SMB_DCLOCATOR_TIMEOUT; + to.tv_nsec = 0; + rc = cond_reltimedwait(&smb_dclocator.sdl_cv, + &smb_dclocator.sdl_mtx, &to); + + if (rc == ETIME) + break; + } + + if (dp == NULL) + dp = &domain_info; + rc = smb_domain_getinfo(dp); + (void) mutex_unlock(&smb_dclocator.sdl_mtx); + + return (rc); +} + +/* + * smb_domain_getinfo + * + * If the DC discovery process is underway, this function will wait on + * a condition variable until the state of SMB domain cache sets to + * either VALID/INVALID. + * + * Returns a copy of the domain cache. + */ +boolean_t +smb_domain_getinfo(smb_domain_t *dp) +{ + timestruc_t to; + int err; + boolean_t rc; + + (void) mutex_lock(&smb_dcache.c_mtx); + to.tv_sec = SMB_DCLOCATOR_TIMEOUT; + to.tv_nsec = 0; + while (smb_dcache.c_state == SMB_DCACHE_STATE_UPDATING) { + err = cond_reltimedwait(&smb_dcache.c_cv, &smb_dcache.c_mtx, + &to); + if (err == ETIME) + break; + } + + if (smb_dcache.c_state == SMB_DCACHE_STATE_VALID) { + bcopy(&smb_dcache.c_cache, dp, sizeof (smb_domain_t)); + rc = B_TRUE; + } else { + bzero(dp, sizeof (smb_domain_t)); + rc = B_FALSE; + } + + (void) mutex_unlock(&smb_dcache.c_mtx); + return (rc); +} + + +/* + * ===================================================================== + * Private functions used by DC locator thread to manipulate the domain + * cache. + * ====================================================================== + */ + +static void +smb_dcache_init(void) +{ + (void) mutex_lock(&smb_dcache.c_mtx); + smb_dcache.c_state = SMB_DCACHE_STATE_INVALID; + bzero(&smb_dcache.c_cache, sizeof (smb_domain_t)); + (void) mutex_unlock(&smb_dcache.c_mtx); +} + +/* + * Set the cache state to UPDATING + */ +static void +smb_dcache_updating(void) +{ + smb_dcache_set(SMB_DCACHE_STATE_UPDATING, NULL); +} + +/* + * Set the cache state to INVALID + */ +static void +smb_dcache_invalid(void) +{ + smb_dcache_set(SMB_DCACHE_STATE_INVALID, NULL); +} + +/* + * Set the cache state to VALID and populate the cache + */ +static void +smb_dcache_valid(smb_domain_t *dp) +{ + smb_dcache_set(SMB_DCACHE_STATE_VALID, dp); +} + +/* + * This function will update both the state and the contents of the + * SMB domain cache. If one attempts to set the state to + * SMB_DCACHE_STATE_UPDATING, the domain cache will be updated based + * on 'dp' argument. Otherwise, 'dp' is ignored. + */ +static void +smb_dcache_set(uint32_t state, smb_domain_t *dp) +{ + (void) mutex_lock(&smb_dcache.c_mtx); + switch (state) { + case SMB_DCACHE_STATE_INVALID: + break; + + case SMB_DCACHE_STATE_UPDATING: + bzero(&smb_dcache.c_cache, sizeof (smb_domain_t)); + break; + + case SMB_DCACHE_STATE_VALID: + assert(dp); + bcopy(dp, &smb_dcache.c_cache, sizeof (smb_domain_t)); + break; + + default: + (void) mutex_unlock(&smb_dcache.c_mtx); + return; + + } + + smb_dcache.c_state = state; + (void) cond_broadcast(&smb_dcache.c_cv); + (void) mutex_unlock(&smb_dcache.c_mtx); +} + +/* + * ========================================================== + * DC discovery functions + * ========================================================== + */ + +/* + * smb_dclocator_main + * + * This is the DC discovery thread: it gets woken up whenever someone + * wants to locate a domain controller. + * + * The state of the SMB domain cache will be initialized to + * SMB_DCACHE_STATE_UPDATING when the discovery process starts and will be + * transitioned to SMB_DCACHE_STATE_VALID/INVALID depending on the outcome of + * the discovery. + * + * If the discovery process is underway, callers of smb_domain_getinfo() + * will wait on a condition variable until the state of SMB domain cache + * sets to either VALID/INVALID. + * + * Upon success, the SMB domain cache will be populated with the discovered DC + * and domain info. + */ +/*ARGSUSED*/ +static void * +smb_dclocator_main(void *arg) +{ + char domain[SMB_PI_MAX_DOMAIN]; + char sought_dc[MAXHOSTNAMELEN]; + smb_domain_t dinfo; + + for (;;) { + (void) mutex_lock(&smb_dclocator.sdl_mtx); + + while (!smb_dclocator.sdl_locate) + (void) cond_wait(&smb_dclocator.sdl_cv, + &smb_dclocator.sdl_mtx); + + (void) strlcpy(domain, smb_dclocator.sdl_domain, + SMB_PI_MAX_DOMAIN); + (void) strlcpy(sought_dc, smb_dclocator.sdl_dc, MAXHOSTNAMELEN); + (void) mutex_unlock(&smb_dclocator.sdl_mtx); + + smb_dcache_updating(); + if (smb_dc_discovery(domain, sought_dc, &dinfo)) + smb_dcache_valid(&dinfo); + else + smb_dcache_invalid(); + + (void) mutex_lock(&smb_dclocator.sdl_mtx); + smb_dclocator.sdl_locate = B_FALSE; + (void) cond_broadcast(&smb_dclocator.sdl_cv); + (void) mutex_unlock(&smb_dclocator.sdl_mtx); + } + + /*NOTREACHED*/ + return (NULL); +} + +/* + * smb_dc_discovery + * + * If FQDN is specified, DC discovery will be done via DNS query only. + * If NetBIOS name of a domain is specified, DC discovery thread will + * use netlogon protocol to locate a DC. Upon failure, it will + * try to resolve it via DNS, i.e. find out if it is the first label + * of a DNS domain name. If the corresponding DNS name is found, DC + * discovery will be done via DNS query. + * + * Once the domain controller is found, it then queries the DC for domain + * information. If the LSA queries fail, the domain information stored in + * SMF might be used to set the SMB domain cache if the the discovered domain + * is the same as the previously joined domain. + * + * If the fully-qualified domain name is derived from the DNS config + * file, the NetBIOS domain name specified by the user will be compared + * against the NetBIOS domain name obtained via LSA query. If there is + * a mismatch, the DC discovery will fail since the discovered DC is + * actually for another domain, whose first label of its FQDN somehow + * matches with the NetBIOS name of the domain we're interested in. + */ +static boolean_t +smb_dc_discovery(char *domain, char *server, smb_domain_t *dinfo) +{ + char derived_dnsdomain[MAXHOSTNAMELEN]; + boolean_t netlogon_ok = B_FALSE; + + *derived_dnsdomain = '\0'; + if (!SMB_IS_FQDN(domain)) { + if (smb_browser_netlogon(domain, dinfo->d_dc, MAXHOSTNAMELEN)) + netlogon_ok = B_TRUE; + else if (!smb_match_domains(domain, derived_dnsdomain, + MAXHOSTNAMELEN)) + return (B_FALSE); + } + + if (!netlogon_ok && !smb_ads_lookup_msdcs( + (SMB_IS_FQDN(domain) ? domain : derived_dnsdomain), server, + dinfo->d_dc, MAXHOSTNAMELEN)) + return (B_FALSE); + + if ((smb_domain_query(domain, dinfo->d_dc, dinfo) + != NT_STATUS_SUCCESS) && + (!smb_domain_use_config(domain, dinfo))) + return (B_FALSE); + + if (*derived_dnsdomain != '\0' && + utf8_strcasecmp(domain, dinfo->d_nbdomain)) + return (B_FALSE); + + /* + * Now that we get the fully-qualified DNS name of the + * domain via LSA query. Verifies ADS configuration + * if we previously locate a DC via NetBIOS. On success, + * ADS cache will be populated. + */ + if (netlogon_ok) { + if (smb_ads_lookup_msdcs(dinfo->d_fqdomain, server, + dinfo->d_dc, MAXHOSTNAMELEN) == 0) + return (B_FALSE); + } + + return (B_TRUE); +} + +/* + * Tries to find a matching DNS domain for the given NetBIOS domain + * name by checking the first label of system's configured DNS domains. + * If a match is found, it'll be returned in the passed buffer. + */ +static boolean_t +smb_match_domains(char *nb_domain, char *buf, uint32_t len) +{ + struct __res_state res_state; + int i; + char *entry, *p; + char first_label[MAXHOSTNAMELEN]; + boolean_t found; + + if (!nb_domain || !buf) + return (B_FALSE); + + *buf = '\0'; + bzero(&res_state, sizeof (struct __res_state)); + if (res_ninit(&res_state)) + return (B_FALSE); + + found = B_FALSE; + entry = res_state.defdname; + for (i = 0; entry != NULL; i++) { + (void) strlcpy(first_label, entry, MAXHOSTNAMELEN); + if ((p = strchr(first_label, '.')) != NULL) { + *p = '\0'; + if (strlen(first_label) > 15) + first_label[15] = '\0'; + } + + if (utf8_strcasecmp(nb_domain, first_label) == 0) { + found = B_TRUE; + (void) strlcpy(buf, entry, len); + break; + } + + entry = res_state.dnsrch[i]; + } + + + res_ndestroy(&res_state); + return (found); +} + +/* + * smb_domain_query + * + * If the the NetBIOS name of an AD domain doesn't match with the + * first label of its fully-qualified DNS name, it is not possible + * to derive one name format from another. + * The missing domain info can be obtained via LSA query, DNS domain info. + * + * domain - either NetBIOS or fully-qualified domain name + * + */ +static uint32_t +smb_domain_query(char *domain, char *server, smb_domain_t *dp) +{ + uint32_t rc; + lsa_info_t info; + + rc = lsa_query_dns_domain_info(server, domain, &info); + if (rc == NT_STATUS_SUCCESS) { + lsa_dns_domaininfo_t *dnsinfo = &info.i_domain.di_dns; + (void) strlcpy(dp->d_nbdomain, dnsinfo->d_nbdomain, + sizeof (dp->d_nbdomain)); + (void) strlcpy(dp->d_fqdomain, dnsinfo->d_fqdomain, + sizeof (dp->d_fqdomain)); + (void) strlcpy(dp->d_forest, dnsinfo->d_forest, + sizeof (dp->d_forest)); + ndr_uuid_unparse((ndr_uuid_t *)&dnsinfo->d_guid, dp->d_guid); + smb_sid_free(dnsinfo->d_sid); + } + + smb_domain_populate_table(domain, server); + return (rc); +} + +/* + * smb_domain_populate_table + * + * Populates the domain tablele with primary, account and trusted + * domain info. + * domain - either NetBIOS or fully-qualified domain name. + */ +static void +smb_domain_populate_table(char *domain, char *server) +{ + lsa_info_t info; + lsa_nt_domaininfo_t *nt_info; + int i; + + if (lsa_query_primary_domain_info(server, domain, &info) + == NT_STATUS_SUCCESS) { + nt_info = &info.i_domain.di_primary; + smb_domain_update_tabent(NT_DOMAIN_PRIMARY, nt_info); + lsa_free_info(&info); + } + + if (lsa_query_account_domain_info(server, domain, &info) + == NT_STATUS_SUCCESS) { + nt_info = &info.i_domain.di_account; + smb_domain_update_tabent(NT_DOMAIN_ACCOUNT, nt_info); + lsa_free_info(&info); + } + + if (lsa_enum_trusted_domains(server, domain, &info) + == NT_STATUS_SUCCESS) { + lsa_trusted_domainlist_t *list = &info.i_domain.di_trust; + for (i = 0; i < list->t_num; i++) { + nt_info = &list->t_domains[i]; + smb_domain_update_tabent(NT_DOMAIN_TRUSTED, nt_info); + } + + lsa_free_info(&info); + } + + +} + +static void +smb_domain_update_tabent(int domain_type, lsa_nt_domaininfo_t *info) +{ + nt_domain_t *entry; + nt_domain_flush(domain_type); + entry = nt_domain_new(domain_type, info->n_domain, info->n_sid); + (void) nt_domain_add(entry); +} + +/* + * smb_domain_use_config + * + * If the domain to be discovered matches the current domain (i.e the + * value of either domain or fqdn configuration), the output parameter + * 'dinfo' will be set to the information stored in SMF. + */ +static boolean_t +smb_domain_use_config(char *domain, smb_domain_t *dinfo) +{ + smb_domain_t orig; + boolean_t use; + + if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN) + return (B_FALSE); + + smb_config_getdomaininfo(orig.d_nbdomain, orig.d_fqdomain, + orig.d_forest, orig.d_guid); + + if (SMB_IS_FQDN(domain)) { + use = (utf8_strcasecmp(orig.d_fqdomain, domain) == 0); + } else { + use = (utf8_strcasecmp(orig.d_nbdomain, domain) == 0); + } + + if (use) { + (void) strlcpy(dinfo->d_nbdomain, orig.d_nbdomain, + sizeof (dinfo->d_nbdomain)); + (void) strlcpy(dinfo->d_fqdomain, orig.d_fqdomain, + sizeof (dinfo->d_fqdomain)); + (void) strlcpy(dinfo->d_forest, orig.d_forest, + sizeof (dinfo->d_forest)); + (void) bcopy(orig.d_guid, dinfo->d_guid, + sizeof (dinfo->d_guid)); + } + + return (use); +} diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c index 6420672e8f..995018ada2 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c @@ -35,17 +35,7 @@ #include <smbsrv/smb_common_door.h> #include <smbsrv/libsmb.h> #include <smbsrv/libmlsvc.h> - -void dssetup_initialize(void); -void srvsvc_initialize(void); -void wkssvc_initialize(void); -void lsarpc_initialize(void); -void logr_initialize(void); -void netr_initialize(void); -void samr_initialize(void); -void svcctl_initialize(void); -void winreg_initialize(void); -int srvsvc_gettime(unsigned long *); +#include <mlsvc.h> static void *mlsvc_keepalive(void *); @@ -61,7 +51,7 @@ static int mlsvc_door_fd = -1; static mutex_t mlsvc_fd_mutex; /* - * All mlrpc initialization is invoked from here. + * All NDR RPC service initialization is invoked from here. * Returns 0 upon success. Otherwise, returns -1. */ int @@ -70,6 +60,9 @@ mlsvc_init(void) pthread_attr_t tattr; int rc; + if ((rc = smb_dclocator_init()) != 0) + return (rc); + srvsvc_initialize(); wkssvc_initialize(); lsarpc_initialize(); @@ -79,6 +72,8 @@ mlsvc_init(void) svcctl_initialize(); winreg_initialize(); logr_initialize(); + msgsvcsend_initialize(); + spoolss_initialize(); (void) pthread_attr_init(&tattr); (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); @@ -93,17 +88,12 @@ static void * mlsvc_keepalive(void *arg) { unsigned long t; - nt_domain_t *domain; for (;;) { (void) sleep(MLSVC_KEEPALIVE_INTERVAL); - if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN) { - domain = nt_domain_lookupbytype(NT_DOMAIN_PRIMARY); - if (domain == NULL) - (void) lsa_query_primary_domain_info(); + if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN) (void) srvsvc_gettime(&t); - } } /*NOTREACHED*/ diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_logr.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_logr.c index 35c803af2e..6c187062b3 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_logr.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_logr.c @@ -33,9 +33,10 @@ #include <netdb.h> #include <smbsrv/libsmb.h> +#include <smbsrv/libmlrpc.h> #include <smbsrv/ntstatus.h> #include <smbsrv/nmpipes.h> -#include <smbsrv/mlsvc_util.h> +#include <smbsrv/libmlsvc.h> #include <smbsrv/ndl/eventlog.ndl> #define FWD +1 @@ -155,13 +156,13 @@ typedef struct log_info { #define LOGR_KEY "LogrOpen" -static int logr_s_EventLogClose(void *, struct mlrpc_xaction *); -static int logr_s_EventLogQueryCount(void *, struct mlrpc_xaction *); -static int logr_s_EventLogGetOldestRec(void *, struct mlrpc_xaction *); -static int logr_s_EventLogOpen(void *, struct mlrpc_xaction *); -static int logr_s_EventLogRead(void *, struct mlrpc_xaction *); +static int logr_s_EventLogClose(void *, ndr_xa_t *); +static int logr_s_EventLogQueryCount(void *, ndr_xa_t *); +static int logr_s_EventLogGetOldestRec(void *, ndr_xa_t *); +static int logr_s_EventLogOpen(void *, ndr_xa_t *); +static int logr_s_EventLogRead(void *, ndr_xa_t *); -static mlrpc_stub_table_t logr_stub_table[] = { +static ndr_stub_table_t logr_stub_table[] = { { logr_s_EventLogClose, LOGR_OPNUM_EventLogClose }, { logr_s_EventLogQueryCount, LOGR_OPNUM_EventLogQueryCount }, { logr_s_EventLogGetOldestRec, LOGR_OPNUM_EventLogGetOldestRec }, @@ -170,13 +171,13 @@ static mlrpc_stub_table_t logr_stub_table[] = { {0} }; -static mlrpc_service_t logr_service = { +static ndr_service_t logr_service = { "LOGR", /* name */ "Event Log Service", /* desc */ "\\eventlog", /* endpoint */ PIPE_NTSVCS, /* sec_addr_port */ - "82273fdc-e32a-18c3-3f78827929dc23ea", 0, /* abstract */ - "8a885d04-1ceb-11c9-9fe808002b104860", 2, /* transfer */ + "82273fdc-e32a-18c3-3f78-827929dc23ea", 0, /* abstract */ + NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 0, /* no bind_instance_size */ 0, /* no bind_req() */ 0, /* no unbind_and_close() */ @@ -222,7 +223,7 @@ logr_initialize(void) (void) mts_mbstowcs(wcs_srcname, logr_sysname, len); srcname_len = len * sizeof (mts_wchar_t); - (void) mlrpc_register_service(&logr_service); + (void) ndr_svc_register(&logr_service); } /* @@ -233,7 +234,7 @@ logr_initialize(void) * handle for the client. */ static int -logr_s_EventLogClose(void *arg, struct mlrpc_xaction *mxa) +logr_s_EventLogClose(void *arg, ndr_xa_t *mxa) { struct logr_EventLogClose *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -242,7 +243,7 @@ logr_s_EventLogClose(void *arg, struct mlrpc_xaction *mxa) if ((hd = ndr_hdlookup(mxa, id)) == NULL) { bzero(¶m->result_handle, sizeof (logr_handle_t)); param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } free(hd->nh_data); @@ -250,7 +251,7 @@ logr_s_EventLogClose(void *arg, struct mlrpc_xaction *mxa) bzero(¶m->result_handle, sizeof (logr_handle_t)); param->status = NT_STATUS_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -260,13 +261,13 @@ logr_s_EventLogClose(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -logr_s_EventLogOpen(void *arg, struct mlrpc_xaction *mxa) +logr_s_EventLogOpen(void *arg, ndr_xa_t *mxa) { struct logr_EventLogOpen *param = arg; bzero(¶m->handle, sizeof (logr_handle_t)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -289,7 +290,7 @@ logr_get_snapshot(void) * call. */ static int -logr_s_EventLogQueryCount(void *arg, struct mlrpc_xaction *mxa) +logr_s_EventLogQueryCount(void *arg, ndr_xa_t *mxa) { struct logr_EventLogQueryCount *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -298,18 +299,18 @@ logr_s_EventLogQueryCount(void *arg, struct mlrpc_xaction *mxa) if ((hd = ndr_hdlookup(mxa, id)) == NULL) { param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if ((data = logr_get_snapshot()) == NULL) { param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } hd->nh_data = data; param->rec_num = data->tot_recnum; param->status = NT_STATUS_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -318,7 +319,7 @@ logr_s_EventLogQueryCount(void *arg, struct mlrpc_xaction *mxa) * Return oldest record number in the snapshot as result of RPC call. */ static int -logr_s_EventLogGetOldestRec(void *arg, struct mlrpc_xaction *mxa) +logr_s_EventLogGetOldestRec(void *arg, ndr_xa_t *mxa) { struct logr_EventLogGetOldestRec *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -327,13 +328,13 @@ logr_s_EventLogGetOldestRec(void *arg, struct mlrpc_xaction *mxa) if ((hd = ndr_hdlookup(mxa, id)) == NULL) { param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } data = (read_data_t *)hd->nh_data; param->oldest_rec = data->log.ix - data->tot_recnum; param->status = NT_STATUS_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -424,7 +425,7 @@ set_logrec(log_entry_t *le, DWORD recno, logr_record_t *rec) * read log entries in chronological or reverse chronological order. */ static int -logr_s_EventLogRead(void *arg, struct mlrpc_xaction *mxa) +logr_s_EventLogRead(void *arg, ndr_xa_t *mxa) { struct logr_EventLogRead *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -438,14 +439,14 @@ logr_s_EventLogRead(void *arg, struct mlrpc_xaction *mxa) if ((hd = ndr_hdlookup(mxa, id)) == NULL) { param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } rdata = (read_data_t *)hd->nh_data; if (rdata == NULL) { if ((rdata = logr_get_snapshot()) == NULL) { param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } hd->nh_data = rdata; @@ -485,7 +486,7 @@ logr_s_EventLogRead(void *arg, struct mlrpc_xaction *mxa) param->sent_size = 0; param->unknown = 0; param->status = NT_SC_ERROR(NT_STATUS_END_OF_FILE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } buf = (param->read_flags & EVENTLOG_SEEK_READ) @@ -505,7 +506,7 @@ logr_s_EventLogRead(void *arg, struct mlrpc_xaction *mxa) param->sent_size = sizeof (logr_record_t) * ent_remain; param->unknown = 0; param->status = NT_STATUS_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c index 8446a760d8..4e546749e7 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c @@ -35,9 +35,8 @@ #include <smbsrv/libsmb.h> #include <smbsrv/libmlrpc.h> #include <smbsrv/libmlsvc.h> -#include <smbsrv/mlsvc_util.h> #include <smbsrv/ndl/lsarpc.ndl> -#include <smbsrv/lsalib.h> +#include <lsalib.h> #include <smbsrv/ntstatus.h> #include <smbsrv/nterror.h> #include <smbsrv/smbinfo.h> @@ -54,38 +53,36 @@ struct local_group_table { static int lsarpc_key_domain; static int lsarpc_key_account; -static int lsarpc_call_stub(struct mlrpc_xaction *mxa); - -static int lsarpc_s_CloseHandle(void *arg, struct mlrpc_xaction *); -static int lsarpc_s_QuerySecurityObject(void *arg, struct mlrpc_xaction *); -static int lsarpc_s_EnumAccounts(void *arg, struct mlrpc_xaction *); -static int lsarpc_s_EnumTrustedDomain(void *arg, struct mlrpc_xaction *); -static int lsarpc_s_OpenAccount(void *arg, struct mlrpc_xaction *); -static int lsarpc_s_EnumPrivsAccount(void *arg, struct mlrpc_xaction *); -static int lsarpc_s_LookupPrivValue(void *arg, struct mlrpc_xaction *); -static int lsarpc_s_LookupPrivName(void *arg, struct mlrpc_xaction *); -static int lsarpc_s_LookupPrivDisplayName(void *arg, struct mlrpc_xaction *); -static int lsarpc_s_CreateSecret(void *, struct mlrpc_xaction *); -static int lsarpc_s_OpenSecret(void *, struct mlrpc_xaction *); -static int lsarpc_s_QueryInfoPolicy(void *arg, struct mlrpc_xaction *); -static int lsarpc_s_OpenDomainHandle(void *arg, struct mlrpc_xaction *); -static int lsarpc_s_OpenDomainHandle(void *arg, struct mlrpc_xaction *); -static int lsarpc_s_LookupSids(void *arg, struct mlrpc_xaction *); -static int lsarpc_s_LookupNames(void *arg, struct mlrpc_xaction *); -static int lsarpc_s_GetConnectedUser(void *arg, struct mlrpc_xaction *); -static int lsarpc_s_LookupSids2(void *arg, struct mlrpc_xaction *); -static int lsarpc_s_LookupNames2(void *arg, struct mlrpc_xaction *); +static int lsarpc_call_stub(ndr_xa_t *mxa); + +static int lsarpc_s_CloseHandle(void *arg, ndr_xa_t *); +static int lsarpc_s_QuerySecurityObject(void *arg, ndr_xa_t *); +static int lsarpc_s_EnumAccounts(void *arg, ndr_xa_t *); +static int lsarpc_s_EnumTrustedDomain(void *arg, ndr_xa_t *); +static int lsarpc_s_OpenAccount(void *arg, ndr_xa_t *); +static int lsarpc_s_EnumPrivsAccount(void *arg, ndr_xa_t *); +static int lsarpc_s_LookupPrivValue(void *arg, ndr_xa_t *); +static int lsarpc_s_LookupPrivName(void *arg, ndr_xa_t *); +static int lsarpc_s_LookupPrivDisplayName(void *arg, ndr_xa_t *); +static int lsarpc_s_CreateSecret(void *, ndr_xa_t *); +static int lsarpc_s_OpenSecret(void *, ndr_xa_t *); +static int lsarpc_s_QueryInfoPolicy(void *arg, ndr_xa_t *); +static int lsarpc_s_OpenDomainHandle(void *arg, ndr_xa_t *); +static int lsarpc_s_OpenDomainHandle(void *arg, ndr_xa_t *); +static int lsarpc_s_LookupSids(void *arg, ndr_xa_t *); +static int lsarpc_s_LookupNames(void *arg, ndr_xa_t *); +static int lsarpc_s_GetConnectedUser(void *arg, ndr_xa_t *); +static int lsarpc_s_LookupSids2(void *arg, ndr_xa_t *); +static int lsarpc_s_LookupNames2(void *arg, ndr_xa_t *); static DWORD lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo *, - struct mlrpc_xaction *); + ndr_xa_t *); static DWORD lsarpc_s_AccountDomainInfo(struct mslsa_AccountDomainInfo *, - struct mlrpc_xaction *); -static int lsarpc_s_UpdateDomainTable(struct mlrpc_xaction *, + ndr_xa_t *); +static int lsarpc_s_UpdateDomainTable(ndr_xa_t *, smb_userinfo_t *, struct mslsa_domain_table *, DWORD *); -static int lsarpc_w2k_enable; - -static mlrpc_stub_table_t lsarpc_stub_table[] = { +static ndr_stub_table_t lsarpc_stub_table[] = { { lsarpc_s_CloseHandle, LSARPC_OPNUM_CloseHandle }, { lsarpc_s_QuerySecurityObject, LSARPC_OPNUM_QuerySecurityObject }, { lsarpc_s_EnumAccounts, LSARPC_OPNUM_EnumerateAccounts }, @@ -108,31 +105,13 @@ static mlrpc_stub_table_t lsarpc_stub_table[] = { {0} }; -static mlrpc_service_t lsarpc_service = { +static ndr_service_t lsarpc_service = { "LSARPC", /* name */ "Local Security Authority", /* desc */ "\\lsarpc", /* endpoint */ PIPE_LSASS, /* sec_addr_port */ - "12345778-1234-abcd-ef000123456789ab", 0, /* abstract */ - "8a885d04-1ceb-11c9-9fe808002b104860", 2, /* transfer */ - 0, /* no bind_instance_size */ - NULL, /* no bind_req() */ - NULL, /* no unbind_and_close() */ - lsarpc_call_stub, /* call_stub() */ - &TYPEINFO(lsarpc_interface), /* interface ti */ - lsarpc_stub_table /* stub_table */ -}; - -/* - * Windows 2000 interface. - */ -static mlrpc_service_t lsarpc_w2k_service = { - "LSARPC_W2K", /* name */ - "Local Security Authority", /* desc */ - "\\lsarpc", /* endpoint */ - PIPE_LSASS, /* sec_addr_port */ - "3919286a-b10c-11d0-9ba800c04fd92ef5", 0, /* abstract */ - "8a885d04-1ceb-11c9-9fe808002b104860", 2, /* transfer */ + "12345778-1234-abcd-ef00-0123456789ab", 0, /* abstract */ + NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 0, /* no bind_instance_size */ NULL, /* no bind_req() */ NULL, /* no unbind_and_close() */ @@ -151,22 +130,19 @@ static mlrpc_service_t lsarpc_w2k_service = { void lsarpc_initialize(void) { - (void) mlrpc_register_service(&lsarpc_service); - - if (lsarpc_w2k_enable) - (void) mlrpc_register_service(&lsarpc_w2k_service); + (void) ndr_svc_register(&lsarpc_service); } /* * Custom call_stub to set the stream string policy. */ static int -lsarpc_call_stub(struct mlrpc_xaction *mxa) +lsarpc_call_stub(ndr_xa_t *mxa) { - MLNDS_SETF(&mxa->send_mlnds, MLNDS_F_NOTERM); - MLNDS_SETF(&mxa->recv_mlnds, MLNDS_F_NOTERM); + NDS_SETF(&mxa->send_nds, NDS_F_NOTERM); + NDS_SETF(&mxa->recv_nds, NDS_F_NOTERM); - return (mlrpc_generic_call_stub(mxa)); + return (ndr_generic_call_stub(mxa)); } /* @@ -176,7 +152,7 @@ lsarpc_call_stub(struct mlrpc_xaction *mxa) * The client is looking for an LSA domain handle. */ static int -lsarpc_s_OpenDomainHandle(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_OpenDomainHandle(void *arg, ndr_xa_t *mxa) { struct mslsa_OpenPolicy2 *param = arg; ndr_hdid_t *id; @@ -189,7 +165,7 @@ lsarpc_s_OpenDomainHandle(void *arg, struct mlrpc_xaction *mxa) param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -197,11 +173,11 @@ lsarpc_s_OpenDomainHandle(void *arg, struct mlrpc_xaction *mxa) * * This is a request to close the LSA interface specified by the handle. * We don't track handles (yet), so just zero out the handle and return - * MLRPC_DRC_OK. Setting the handle to zero appears to be standard + * NDR_DRC_OK. Setting the handle to zero appears to be standard * behaviour and someone may rely on it, i.e. we do on the client side. */ static int -lsarpc_s_CloseHandle(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_CloseHandle(void *arg, ndr_xa_t *mxa) { struct mslsa_CloseHandle *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -210,7 +186,7 @@ lsarpc_s_CloseHandle(void *arg, struct mlrpc_xaction *mxa) bzero(¶m->result_handle, sizeof (param->result_handle)); param->status = NT_STATUS_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -218,14 +194,14 @@ lsarpc_s_CloseHandle(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -lsarpc_s_QuerySecurityObject(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_QuerySecurityObject(void *arg, ndr_xa_t *mxa) { struct mslsa_QuerySecurityObject *param = arg; bzero(param, sizeof (struct mslsa_QuerySecurityObject)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -244,23 +220,23 @@ lsarpc_s_QuerySecurityObject(void *arg, struct mlrpc_xaction *mxa) * The enum_context is used to support multiple */ static int -lsarpc_s_EnumAccounts(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_EnumAccounts(void *arg, ndr_xa_t *mxa) { struct mslsa_EnumerateAccounts *param = arg; struct mslsa_EnumAccountBuf *enum_buf; bzero(param, sizeof (struct mslsa_EnumerateAccounts)); - enum_buf = MLRPC_HEAP_NEW(mxa, struct mslsa_EnumAccountBuf); + enum_buf = NDR_NEW(mxa, struct mslsa_EnumAccountBuf); if (enum_buf == NULL) { param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(enum_buf, sizeof (struct mslsa_EnumAccountBuf)); param->enum_buf = enum_buf; param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } @@ -280,23 +256,23 @@ lsarpc_s_EnumAccounts(void *arg, struct mlrpc_xaction *mxa) * the marshalling rules require that references must not be null. */ static int -lsarpc_s_EnumTrustedDomain(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_EnumTrustedDomain(void *arg, ndr_xa_t *mxa) { struct mslsa_EnumTrustedDomain *param = arg; struct mslsa_EnumTrustedDomainBuf *enum_buf; bzero(param, sizeof (struct mslsa_EnumTrustedDomain)); - enum_buf = MLRPC_HEAP_NEW(mxa, struct mslsa_EnumTrustedDomainBuf); + enum_buf = NDR_NEW(mxa, struct mslsa_EnumTrustedDomainBuf); if (enum_buf == NULL) { param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(enum_buf, sizeof (struct mslsa_EnumTrustedDomainBuf)); param->enum_buf = enum_buf; param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } @@ -306,7 +282,7 @@ lsarpc_s_EnumTrustedDomain(void *arg, struct mlrpc_xaction *mxa) * This is a request to open an account handle. */ static int -lsarpc_s_OpenAccount(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_OpenAccount(void *arg, ndr_xa_t *mxa) { struct mslsa_OpenAccount *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -316,7 +292,7 @@ lsarpc_s_OpenAccount(void *arg, struct mlrpc_xaction *mxa) if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) { bzero(param, sizeof (struct mslsa_OpenAccount)); param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if ((id = ndr_hdalloc(mxa, &lsarpc_key_account)) != NULL) { @@ -327,7 +303,7 @@ lsarpc_s_OpenAccount(void *arg, struct mlrpc_xaction *mxa) param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } @@ -336,19 +312,19 @@ lsarpc_s_OpenAccount(void *arg, struct mlrpc_xaction *mxa) * * This is the server side function for handling requests for account * privileges. For now just set the status to not-supported status and - * return MLRPC_DRC_OK. Note that we still have to provide a valid + * return NDR_DRC_OK. Note that we still have to provide a valid * address for enum_buf because it's a reference and the marshalling * rules require that references must not be null. */ /*ARGSUSED*/ static int -lsarpc_s_EnumPrivsAccount(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_EnumPrivsAccount(void *arg, ndr_xa_t *mxa) { struct mslsa_EnumPrivsAccount *param = arg; bzero(param, sizeof (struct mslsa_EnumPrivsAccount)); param->status = NT_SC_ERROR(NT_STATUS_NOT_SUPPORTED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -359,7 +335,7 @@ lsarpc_s_EnumPrivsAccount(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -lsarpc_s_LookupPrivValue(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_LookupPrivValue(void *arg, ndr_xa_t *mxa) { struct mslsa_LookupPrivValue *param = arg; smb_privinfo_t *pi; @@ -367,13 +343,13 @@ lsarpc_s_LookupPrivValue(void *arg, struct mlrpc_xaction *mxa) if ((pi = smb_priv_getbyname((char *)param->name.str)) == NULL) { bzero(param, sizeof (struct mslsa_LookupPrivValue)); param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_PRIVILEGE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } param->luid.low_part = pi->id; param->luid.high_part = 0; param->status = NT_STATUS_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -383,7 +359,7 @@ lsarpc_s_LookupPrivValue(void *arg, struct mlrpc_xaction *mxa) * to the appropriate privilege name string. */ static int -lsarpc_s_LookupPrivName(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_LookupPrivName(void *arg, ndr_xa_t *mxa) { struct mslsa_LookupPrivName *param = arg; smb_privinfo_t *pi; @@ -392,25 +368,25 @@ lsarpc_s_LookupPrivName(void *arg, struct mlrpc_xaction *mxa) if ((pi = smb_priv_getbyvalue(param->luid.low_part)) == NULL) { bzero(param, sizeof (struct mslsa_LookupPrivName)); param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_PRIVILEGE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } - param->name = MLRPC_HEAP_NEW(mxa, mslsa_string_t); + param->name = NDR_NEW(mxa, mslsa_string_t); if (param->name == NULL) { bzero(param, sizeof (struct mslsa_LookupPrivName)); param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } - rc = mlsvc_string_save((ms_string_t *)param->name, pi->name, mxa); - if (rc == 0) { + rc = NDR_MSTRING(mxa, pi->name, (ndr_mstring_t *)param->name); + if (rc == -1) { bzero(param, sizeof (struct mslsa_LookupPrivName)); param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } param->status = NT_STATUS_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -418,10 +394,10 @@ lsarpc_s_LookupPrivName(void *arg, struct mlrpc_xaction *mxa) * * This is the server side function for handling requests for account * privileges. For now just set the status to not-supported status and - * return MLRPC_DRC_OK. + * return NDR_DRC_OK. */ static int -lsarpc_s_LookupPrivDisplayName(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_LookupPrivDisplayName(void *arg, ndr_xa_t *mxa) { struct mslsa_LookupPrivDisplayName *param = arg; smb_privinfo_t *pi; @@ -430,32 +406,31 @@ lsarpc_s_LookupPrivDisplayName(void *arg, struct mlrpc_xaction *mxa) if ((pi = smb_priv_getbyname((char *)param->name.str)) == NULL) { bzero(param, sizeof (struct mslsa_LookupPrivDisplayName)); param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_PRIVILEGE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } - param->display_name = MLRPC_HEAP_NEW(mxa, mslsa_string_t); + param->display_name = NDR_NEW(mxa, mslsa_string_t); if (param->display_name == NULL) { bzero(param, sizeof (struct mslsa_LookupPrivDisplayName)); param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } - rc = mlsvc_string_save((ms_string_t *)param->display_name, - pi->display_name, mxa); - - if (rc == 0) { + rc = NDR_MSTRING(mxa, pi->display_name, + (ndr_mstring_t *)param->display_name); + if (rc == -1) { bzero(param, sizeof (struct mslsa_LookupPrivDisplayName)); param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } param->language_ret = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); param->status = NT_STATUS_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } static int -lsarpc_s_CreateSecret(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_CreateSecret(void *arg, ndr_xa_t *mxa) { struct mslsa_CreateSecret *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -465,16 +440,16 @@ lsarpc_s_CreateSecret(void *arg, struct mlrpc_xaction *mxa) if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) { bzero(param, sizeof (struct mslsa_OpenAccount)); param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(¶m->secret_handle, sizeof (mslsa_handle_t)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } static int -lsarpc_s_OpenSecret(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_OpenSecret(void *arg, ndr_xa_t *mxa) { struct mslsa_OpenSecret *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -484,12 +459,12 @@ lsarpc_s_OpenSecret(void *arg, struct mlrpc_xaction *mxa) if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) { bzero(param, sizeof (struct mslsa_OpenAccount)); param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(¶m->secret_handle, sizeof (mslsa_handle_t)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -504,47 +479,46 @@ lsarpc_s_OpenSecret(void *arg, struct mlrpc_xaction *mxa) * user from the client that makes this call. */ static int -lsarpc_s_GetConnectedUser(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_GetConnectedUser(void *arg, ndr_xa_t *mxa) { struct mslsa_GetConnectedUser *param = arg; - smb_opipe_context_t *svc = &mxa->context->svc_ctx; + smb_opipe_context_t *ctx = &mxa->pipe->np_ctx; DWORD status = NT_STATUS_SUCCESS; + smb_domain_t di; int rc1; int rc2; - if (smb_getdomaininfo(0) == NULL) { + if (!smb_domain_getinfo(&di)) { bzero(param, sizeof (struct mslsa_GetConnectedUser)); status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } - param->owner = MLRPC_HEAP_NEW(mxa, struct mslsa_string_desc); - param->domain = MLRPC_HEAP_NEW(mxa, struct mslsa_DomainName); + param->owner = NDR_NEW(mxa, struct mslsa_string_desc); + param->domain = NDR_NEW(mxa, struct mslsa_DomainName); if (param->owner == NULL || param->domain == NULL) { status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } - param->domain->name = MLRPC_HEAP_NEW(mxa, struct mslsa_string_desc); + param->domain->name = NDR_NEW(mxa, struct mslsa_string_desc); if (param->domain->name == NULL) { status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } - rc1 = mlsvc_string_save((ms_string_t *)param->owner, - svc->oc_account, mxa); + rc1 = NDR_MSTRING(mxa, ctx->oc_account, (ndr_mstring_t *)param->owner); + rc2 = NDR_MSTRING(mxa, ctx->oc_domain, + (ndr_mstring_t *)param->domain->name); - rc2 = mlsvc_string_save((ms_string_t *)param->domain->name, - svc->oc_domain, mxa); - - if (rc1 == 0 || rc2 == 0) + if (rc1 == -1 || rc2 == -1) status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } @@ -558,65 +532,58 @@ lsarpc_s_GetConnectedUser(void *arg, struct mlrpc_xaction *mxa) * obtaining and building the response. */ static int -lsarpc_s_QueryInfoPolicy(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_QueryInfoPolicy(void *arg, ndr_xa_t *mxa) { struct mslsa_QueryInfoPolicy *param = arg; - struct mslsa_PolicyInfo *info; + union mslsa_PolicyInfoResUnion *ru = ¶m->ru; int security_mode; DWORD status; - info = (struct mslsa_PolicyInfo *)MLRPC_HEAP_MALLOC( - mxa, sizeof (struct mslsa_PolicyInfo)); - if (info == NULL) { - bzero(param, sizeof (struct mslsa_QueryInfoPolicy)); - param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); - return (MLRPC_DRC_OK); - } - - info->switch_value = param->info_class; + param->switch_value = param->info_class; switch (param->info_class) { case MSLSA_POLICY_AUDIT_EVENTS_INFO: - info->ru.audit_events.enabled = 0; - info->ru.audit_events.count = 1; - info->ru.audit_events.settings - = MLRPC_HEAP_MALLOC(mxa, sizeof (DWORD)); - bzero(info->ru.audit_events.settings, sizeof (DWORD)); + ru->audit_events.enabled = 0; + ru->audit_events.count = 1; + ru->audit_events.settings + = NDR_MALLOC(mxa, sizeof (DWORD)); + bzero(ru->audit_events.settings, sizeof (DWORD)); status = NT_STATUS_SUCCESS; break; case MSLSA_POLICY_PRIMARY_DOMAIN_INFO: - status = lsarpc_s_PrimaryDomainInfo(&info->ru.pd_info, mxa); + status = lsarpc_s_PrimaryDomainInfo(&ru->pd_info, mxa); break; case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO: - status = lsarpc_s_AccountDomainInfo(&info->ru.ad_info, mxa); + status = lsarpc_s_AccountDomainInfo(&ru->ad_info, mxa); break; case MSLSA_POLICY_SERVER_ROLE_INFO: security_mode = smb_config_get_secmode(); if (security_mode == SMB_SECMODE_DOMAIN) - info->ru.server_role.role = LSA_ROLE_MEMBER_SERVER; + ru->server_role.role = LSA_ROLE_MEMBER_SERVER; else - info->ru.server_role.role = LSA_ROLE_STANDALONE_SERVER; + ru->server_role.role = LSA_ROLE_STANDALONE_SERVER; - info->ru.server_role.pad = 0; + ru->server_role.pad = 0; status = NT_STATUS_SUCCESS; break; default: bzero(param, sizeof (struct mslsa_QueryInfoPolicy)); param->status = NT_SC_ERROR(NT_STATUS_INVALID_INFO_CLASS); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (status != NT_STATUS_SUCCESS) param->status = NT_SC_ERROR(status); else param->status = NT_STATUS_SUCCESS; - param->info = info; - return (MLRPC_DRC_OK); + param->address = (DWORD)(uintptr_t)ru; + + return (NDR_DRC_OK); } @@ -632,7 +599,7 @@ lsarpc_s_QueryInfoPolicy(void *arg, struct mlrpc_xaction *mxa) */ static DWORD lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo *info, - struct mlrpc_xaction *mxa) + ndr_xa_t *mxa) { char domain_name[MAXHOSTNAMELEN]; smb_sid_t *sid = NULL; @@ -654,11 +621,11 @@ lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo *info, if ((sid == NULL) || (rc != 0)) return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); - rc = mlsvc_string_save((ms_string_t *)&info->name, domain_name, mxa); - info->sid = (struct mslsa_sid *)mlsvc_sid_save(sid, mxa); + rc = NDR_MSTRING(mxa, domain_name, (ndr_mstring_t *)&info->name); + info->sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, sid); free(sid); - if ((rc == 0) || (info->sid == NULL)) + if ((rc == -1) || (info->sid == NULL)) return (NT_STATUS_NO_MEMORY); return (NT_STATUS_SUCCESS); @@ -677,7 +644,7 @@ lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo *info, */ static DWORD lsarpc_s_AccountDomainInfo(struct mslsa_AccountDomainInfo *info, - struct mlrpc_xaction *mxa) + ndr_xa_t *mxa) { char domain_name[NETBIOS_NAME_SZ]; smb_sid_t *domain_sid; @@ -691,10 +658,10 @@ lsarpc_s_AccountDomainInfo(struct mslsa_AccountDomainInfo *info, if ((domain_sid = nt_domain_local_sid()) == NULL) return (NT_STATUS_NO_MEMORY); - rc = mlsvc_string_save((ms_string_t *)&info->name, domain_name, mxa); - info->sid = (struct mslsa_sid *)mlsvc_sid_save(domain_sid, mxa); + rc = NDR_MSTRING(mxa, domain_name, (ndr_mstring_t *)&info->name); + info->sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, domain_sid); - if ((rc == 0) || (info->sid == NULL)) + if ((rc == -1) || (info->sid == NULL)) return (NT_STATUS_NO_MEMORY); return (NT_STATUS_SUCCESS); @@ -709,7 +676,7 @@ lsarpc_s_AccountDomainInfo(struct mslsa_AccountDomainInfo *info, * client and the DC. */ static int -lsarpc_s_LookupNames(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_LookupNames(void *arg, ndr_xa_t *mxa) { struct mslsa_LookupNames *param = arg; struct mslsa_rid_entry *rids; @@ -721,11 +688,11 @@ lsarpc_s_LookupNames(void *arg, struct mlrpc_xaction *mxa) int rc = 0; if (param->name_table->n_entry != 1) - return (MLRPC_DRC_FAULT_PARAM_0_UNIMPLEMENTED); + return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED); - rids = MLRPC_HEAP_NEW(mxa, struct mslsa_rid_entry); - domain_table = MLRPC_HEAP_NEW(mxa, struct mslsa_domain_table); - domain_entry = MLRPC_HEAP_NEW(mxa, struct mslsa_domain_entry); + rids = NDR_NEW(mxa, struct mslsa_rid_entry); + domain_table = NDR_NEW(mxa, struct mslsa_domain_table); + domain_entry = NDR_NEW(mxa, struct mslsa_domain_entry); user_info = mlsvc_alloc_user_info(); if (rids == NULL || domain_table == NULL || @@ -735,7 +702,7 @@ lsarpc_s_LookupNames(void *arg, struct mlrpc_xaction *mxa) } account = (char *)param->name_table->names->str; - status = lsa_lookup_name(NULL, account, SidTypeUnknown, user_info); + status = lsa_lookup_name(account, SidTypeUnknown, user_info); if (status != NT_STATUS_SUCCESS) goto name_lookup_failed; @@ -755,13 +722,12 @@ lsarpc_s_LookupNames(void *arg, struct mlrpc_xaction *mxa) domain_table->n_entry = 1; domain_table->max_n_entry = MLSVC_DOMAIN_MAX; - rc = mlsvc_string_save((ms_string_t *)&domain_entry->domain_name, - user_info->domain_name, mxa); - + rc = NDR_MSTRING(mxa, user_info->domain_name, + (ndr_mstring_t *)&domain_entry->domain_name); domain_entry->domain_sid = - (struct mslsa_sid *)mlsvc_sid_save(user_info->domain_sid, mxa); + (struct mslsa_sid *)NDR_SIDDUP(mxa, user_info->domain_sid); - if (rc == 0 || domain_entry->domain_sid == NULL) { + if (rc == -1 || domain_entry->domain_sid == NULL) { status = NT_STATUS_NO_MEMORY; goto name_lookup_failed; } @@ -771,13 +737,13 @@ lsarpc_s_LookupNames(void *arg, struct mlrpc_xaction *mxa) param->status = 0; mlsvc_free_user_info(user_info); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); name_lookup_failed: mlsvc_free_user_info(user_info); bzero(param, sizeof (struct mslsa_LookupNames)); param->status = NT_SC_ERROR(status); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -794,7 +760,7 @@ name_lookup_failed: * On success return 0. Otherwise return an RPC specific error code. */ static int -lsarpc_s_LookupSids(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_LookupSids(void *arg, ndr_xa_t *mxa) { struct mslsa_LookupSids *param = arg; struct mslsa_domain_table *domain_table; @@ -810,16 +776,16 @@ lsarpc_s_LookupSids(void *arg, struct mlrpc_xaction *mxa) user_info = mlsvc_alloc_user_info(); n_entry = param->lup_sid_table.n_entry; - names = MLRPC_HEAP_NEWN(mxa, struct mslsa_name_entry, n_entry); - domain_table = MLRPC_HEAP_NEW(mxa, struct mslsa_domain_table); - domain_entry = MLRPC_HEAP_NEWN(mxa, struct mslsa_domain_entry, + names = NDR_NEWN(mxa, struct mslsa_name_entry, n_entry); + domain_table = NDR_NEW(mxa, struct mslsa_domain_table); + domain_entry = NDR_NEWN(mxa, struct mslsa_domain_entry, MLSVC_DOMAIN_MAX); if (names == NULL || domain_table == NULL || domain_entry == NULL || user_info == NULL) { bzero(param, sizeof (struct mslsa_LookupSids)); param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } domain_table->entries = domain_entry; @@ -835,8 +801,8 @@ lsarpc_s_LookupSids(void *arg, struct mlrpc_xaction *mxa) if (result != NT_STATUS_SUCCESS) goto lookup_sid_failed; - if (!mlsvc_string_save((ms_string_t *)&name->name, - user_info->name, mxa)) { + if (NDR_MSTRING(mxa, user_info->name, + (ndr_mstring_t *)&name->name) == -1) { result = NT_STATUS_NO_MEMORY; goto lookup_sid_failed; } @@ -860,7 +826,7 @@ lsarpc_s_LookupSids(void *arg, struct mlrpc_xaction *mxa) param->status = 0; mlsvc_free_user_info(user_info); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); lookup_sid_failed: param->domain_table = 0; @@ -870,7 +836,7 @@ lookup_sid_failed: param->status = NT_SC_ERROR(result); mlsvc_free_user_info(user_info); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -883,13 +849,14 @@ lookup_sid_failed: * it is added. On success return 0; Otherwise -1 is returned. */ static int -lsarpc_s_UpdateDomainTable(struct mlrpc_xaction *mxa, +lsarpc_s_UpdateDomainTable(ndr_xa_t *mxa, smb_userinfo_t *user_info, struct mslsa_domain_table *domain_table, DWORD *domain_idx) { struct mslsa_domain_entry *dentry; DWORD n_entry; DWORD i; + int rc; if (user_info->sid_name_use == SidTypeUnknown || user_info->sid_name_use == SidTypeInvalid) { @@ -918,14 +885,12 @@ lsarpc_s_UpdateDomainTable(struct mlrpc_xaction *mxa, if (i == MLSVC_DOMAIN_MAX) return (-1); - if (!mlsvc_string_save((ms_string_t *)&dentry[i].domain_name, - user_info->domain_name, mxa)) - return (-1); - + rc = NDR_MSTRING(mxa, user_info->domain_name, + (ndr_mstring_t *)&dentry[i].domain_name); dentry[i].domain_sid = - (struct mslsa_sid *)mlsvc_sid_save(user_info->domain_sid, mxa); + (struct mslsa_sid *)NDR_SIDDUP(mxa, user_info->domain_sid); - if (dentry[i].domain_sid == NULL) + if (rc == -1 || dentry[i].domain_sid == NULL) return (-1); ++domain_table->n_entry; @@ -940,7 +905,7 @@ lsarpc_s_UpdateDomainTable(struct mlrpc_xaction *mxa, * is identical to lsarpc_s_LookupSids. */ static int -lsarpc_s_LookupSids2(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_LookupSids2(void *arg, ndr_xa_t *mxa) { struct lsar_lookup_sids2 *param = arg; struct lsar_name_entry2 *names; @@ -956,16 +921,16 @@ lsarpc_s_LookupSids2(void *arg, struct mlrpc_xaction *mxa) user_info = mlsvc_alloc_user_info(); n_entry = param->lup_sid_table.n_entry; - names = MLRPC_HEAP_NEWN(mxa, struct lsar_name_entry2, n_entry); - domain_table = MLRPC_HEAP_NEW(mxa, struct mslsa_domain_table); - domain_entry = MLRPC_HEAP_NEWN(mxa, struct mslsa_domain_entry, + names = NDR_NEWN(mxa, struct lsar_name_entry2, n_entry); + domain_table = NDR_NEW(mxa, struct mslsa_domain_table); + domain_entry = NDR_NEWN(mxa, struct mslsa_domain_entry, MLSVC_DOMAIN_MAX); if (names == NULL || domain_table == NULL || domain_entry == NULL || user_info == NULL) { bzero(param, sizeof (struct lsar_lookup_sids2)); param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } domain_table->entries = domain_entry; @@ -981,8 +946,8 @@ lsarpc_s_LookupSids2(void *arg, struct mlrpc_xaction *mxa) if (result != NT_STATUS_SUCCESS) goto lookup_sid_failed; - if (!mlsvc_string_save((ms_string_t *)&name->name, - user_info->name, mxa)) { + if (NDR_MSTRING(mxa, user_info->name, + (ndr_mstring_t *)&name->name) == -1) { result = NT_STATUS_NO_MEMORY; goto lookup_sid_failed; } @@ -1006,7 +971,7 @@ lsarpc_s_LookupSids2(void *arg, struct mlrpc_xaction *mxa) param->status = 0; mlsvc_free_user_info(user_info); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); lookup_sid_failed: param->domain_table = 0; @@ -1016,7 +981,7 @@ lookup_sid_failed: param->status = NT_SC_ERROR(result); mlsvc_free_user_info(user_info); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -1026,7 +991,7 @@ lookup_sid_failed: * is identical to lsarpc_s_LookupNames. */ static int -lsarpc_s_LookupNames2(void *arg, struct mlrpc_xaction *mxa) +lsarpc_s_LookupNames2(void *arg, ndr_xa_t *mxa) { struct lsar_LookupNames2 *param = arg; struct lsar_rid_entry2 *rids; @@ -1038,11 +1003,11 @@ lsarpc_s_LookupNames2(void *arg, struct mlrpc_xaction *mxa) int rc = 0; if (param->name_table->n_entry != 1) - return (MLRPC_DRC_FAULT_PARAM_0_UNIMPLEMENTED); + return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED); - rids = MLRPC_HEAP_NEW(mxa, struct lsar_rid_entry2); - domain_table = MLRPC_HEAP_NEW(mxa, struct mslsa_domain_table); - domain_entry = MLRPC_HEAP_NEW(mxa, struct mslsa_domain_entry); + rids = NDR_NEW(mxa, struct lsar_rid_entry2); + domain_table = NDR_NEW(mxa, struct mslsa_domain_table); + domain_entry = NDR_NEW(mxa, struct mslsa_domain_entry); user_info = mlsvc_alloc_user_info(); if (rids == 0 || domain_table == 0 || @@ -1052,7 +1017,7 @@ lsarpc_s_LookupNames2(void *arg, struct mlrpc_xaction *mxa) } account = (char *)param->name_table->names->str; - status = lsa_lookup_name(NULL, account, SidTypeUnknown, user_info); + status = lsa_lookup_name(account, SidTypeUnknown, user_info); if (status != NT_STATUS_SUCCESS) goto name_lookup2_failed; @@ -1073,13 +1038,13 @@ lsarpc_s_LookupNames2(void *arg, struct mlrpc_xaction *mxa) domain_table->n_entry = 1; domain_table->max_n_entry = MLSVC_DOMAIN_MAX; - rc = mlsvc_string_save((ms_string_t *)&domain_entry->domain_name, - user_info->domain_name, mxa); + rc = NDR_MSTRING(mxa, user_info->domain_name, + (ndr_mstring_t *)&domain_entry->domain_name); domain_entry->domain_sid = - (struct mslsa_sid *)mlsvc_sid_save(user_info->domain_sid, mxa); + (struct mslsa_sid *)NDR_SIDDUP(mxa, user_info->domain_sid); - if (rc == 0 || domain_entry->domain_sid == NULL) { + if (rc == -1 || domain_entry->domain_sid == NULL) { status = NT_STATUS_NO_MEMORY; goto name_lookup2_failed; } @@ -1089,11 +1054,61 @@ lsarpc_s_LookupNames2(void *arg, struct mlrpc_xaction *mxa) param->status = 0; mlsvc_free_user_info(user_info); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); name_lookup2_failed: mlsvc_free_user_info(user_info); bzero(param, sizeof (struct lsar_LookupNames2)); param->status = NT_SC_ERROR(status); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); +} + + +/* + * There is a bug in the way that ndrgen and the marshalling code handles + * unions so we need to fix some of the data offsets at runtime. The + * following macros and the fixup functions handle the corrections. + */ + +DECL_FIXUP_STRUCT(mslsa_PolicyInfoResUnion); +DECL_FIXUP_STRUCT(mslsa_PolicyInfoRes); +DECL_FIXUP_STRUCT(mslsa_QueryInfoPolicy); +void +fixup_mslsa_QueryInfoPolicy(struct mslsa_QueryInfoPolicy *val) +{ + unsigned short size1 = 0; + unsigned short size2 = 0; + unsigned short size3 = 0; + + switch (val->info_class) { + case MSLSA_POLICY_AUDIT_EVENTS_INFO: + size1 = sizeof (struct mslsa_AuditEventsInfo); + break; + + case MSLSA_POLICY_PRIMARY_DOMAIN_INFO: + size1 = sizeof (struct mslsa_PrimaryDomainInfo); + break; + + case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO: + size1 = sizeof (struct mslsa_AccountDomainInfo); + break; + + case MSLSA_POLICY_SERVER_ROLE_INFO: + size1 = sizeof (struct mslsa_ServerRoleInfo); + break; + + case MSLSA_POLICY_DNS_DOMAIN_INFO: + size1 = sizeof (struct mslsa_DnsDomainInfo); + break; + + default: + return; + }; + + size2 = size1 + (2 * sizeof (DWORD)); + size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD); + + FIXUP_PDU_SIZE(mslsa_PolicyInfoResUnion, size1); + FIXUP_PDU_SIZE(mslsa_PolicyInfoRes, size2); + FIXUP_PDU_SIZE(mslsa_QueryInfoPolicy, size3); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_netr.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_netr.c index 63db7ce317..5f1cfa7417 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_netr.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_netr.c @@ -32,20 +32,20 @@ #include <strings.h> #include <smbsrv/libsmb.h> -#include <smbsrv/mlsvc_util.h> +#include <smbsrv/libmlsvc.h> #include <smbsrv/ndl/netlogon.ndl> #include <smbsrv/ntstatus.h> #include <smbsrv/nterror.h> #include <smbsrv/nmpipes.h> #include <smbsrv/netrauth.h> -static int netr_s_ServerReqChallenge(void *, struct mlrpc_xaction *); -static int netr_s_ServerAuthenticate2(void *, struct mlrpc_xaction *); -static int netr_s_ServerPasswordSet(void *, struct mlrpc_xaction *); -static int netr_s_SamLogon(void *, struct mlrpc_xaction *); -static int netr_s_SamLogoff(void *, struct mlrpc_xaction *); +static int netr_s_ServerReqChallenge(void *, ndr_xa_t *); +static int netr_s_ServerAuthenticate2(void *, ndr_xa_t *); +static int netr_s_ServerPasswordSet(void *, ndr_xa_t *); +static int netr_s_SamLogon(void *, ndr_xa_t *); +static int netr_s_SamLogoff(void *, ndr_xa_t *); -static mlrpc_stub_table_t netr_stub_table[] = { +static ndr_stub_table_t netr_stub_table[] = { { netr_s_ServerReqChallenge, NETR_OPNUM_ServerReqChallenge }, { netr_s_ServerAuthenticate2, NETR_OPNUM_ServerAuthenticate2 }, { netr_s_ServerPasswordSet, NETR_OPNUM_ServerPasswordSet }, @@ -54,13 +54,13 @@ static mlrpc_stub_table_t netr_stub_table[] = { {0} }; -static mlrpc_service_t netr_service = { +static ndr_service_t netr_service = { "NETR", /* name */ "NetLogon", /* desc */ "\\netlogon", /* endpoint */ PIPE_LSASS, /* sec_addr_port */ - "12345678-1234-abcd-ef0001234567cffb", 1, /* abstract */ - "8a885d04-1ceb-11c9-9fe808002b104860", 2, /* transfer */ + "12345678-1234-abcd-ef00-01234567cffb", 1, /* abstract */ + NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 0, /* no bind_instance_size */ 0, /* no bind_req() */ 0, /* no unbind_and_close() */ @@ -79,7 +79,7 @@ static mlrpc_service_t netr_service = { void netr_initialize(void) { - (void) mlrpc_register_service(&netr_service); + (void) ndr_svc_register(&netr_service); } /* @@ -87,13 +87,13 @@ netr_initialize(void) */ /*ARGSUSED*/ static int -netr_s_ServerReqChallenge(void *arg, struct mlrpc_xaction *mxa) +netr_s_ServerReqChallenge(void *arg, ndr_xa_t *mxa) { struct netr_ServerReqChallenge *param = arg; bzero(param, sizeof (struct netr_ServerReqChallenge)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -101,13 +101,13 @@ netr_s_ServerReqChallenge(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -netr_s_ServerAuthenticate2(void *arg, struct mlrpc_xaction *mxa) +netr_s_ServerAuthenticate2(void *arg, ndr_xa_t *mxa) { struct netr_ServerAuthenticate2 *param = arg; bzero(param, sizeof (struct netr_ServerAuthenticate2)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -115,13 +115,13 @@ netr_s_ServerAuthenticate2(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -netr_s_ServerPasswordSet(void *arg, struct mlrpc_xaction *mxa) +netr_s_ServerPasswordSet(void *arg, ndr_xa_t *mxa) { struct netr_PasswordSet *param = arg; bzero(param, sizeof (struct netr_PasswordSet)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -129,13 +129,13 @@ netr_s_ServerPasswordSet(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -netr_s_SamLogon(void *arg, struct mlrpc_xaction *mxa) +netr_s_SamLogon(void *arg, ndr_xa_t *mxa) { struct netr_SamLogon *param = arg; bzero(param, sizeof (struct netr_SamLogon)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -143,13 +143,13 @@ netr_s_SamLogon(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -netr_s_SamLogoff(void *arg, struct mlrpc_xaction *mxa) +netr_s_SamLogoff(void *arg, ndr_xa_t *mxa) { struct netr_SamLogoff *param = arg; bzero(param, sizeof (struct netr_SamLogoff)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c index 1549b1f7e0..12040f3d21 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c @@ -37,14 +37,12 @@ #include <smbsrv/libsmb.h> #include <smbsrv/libmlrpc.h> #include <smbsrv/libmlsvc.h> - #include <smbsrv/ntstatus.h> #include <smbsrv/nterror.h> #include <smbsrv/smbinfo.h> #include <smbsrv/nmpipes.h> -#include <smbsrv/mlsvc_util.h> #include <smbsrv/ndl/samrpc.ndl> -#include <smbsrv/samlib.h> +#include <samlib.h> /* * The keys associated with the various handles dispensed by the SAMR @@ -101,19 +99,19 @@ static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, nt_domain_type_t, DWORD); static void samr_hdfree(ndr_xa_t *, ndr_hdid_t *); static ndr_handle_t *samr_hdlookup(ndr_xa_t *, ndr_hdid_t *, samr_key_t); -static int samr_call_stub(struct mlrpc_xaction *mxa); +static int samr_call_stub(ndr_xa_t *mxa); static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *, - struct mlrpc_xaction *); + ndr_xa_t *); -static mlrpc_stub_table_t samr_stub_table[]; +static ndr_stub_table_t samr_stub_table[]; -static mlrpc_service_t samr_service = { +static ndr_service_t samr_service = { "SAMR", /* name */ "Security Accounts Manager", /* desc */ "\\samr", /* endpoint */ PIPE_LSASS, /* sec_addr_port */ - "12345778-1234-abcd-ef000123456789ac", 1, /* abstract */ - "8a885d04-1ceb-11c9-9fe808002b104860", 2, /* transfer */ + "12345778-1234-abcd-ef00-0123456789ac", 1, /* abstract */ + NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 0, /* no bind_instance_size */ NULL, /* no bind_req() */ NULL, /* no unbind_and_close() */ @@ -132,19 +130,19 @@ static mlrpc_service_t samr_service = { void samr_initialize(void) { - (void) mlrpc_register_service(&samr_service); + (void) ndr_svc_register(&samr_service); } /* * Custom call_stub to set the stream string policy. */ static int -samr_call_stub(struct mlrpc_xaction *mxa) +samr_call_stub(ndr_xa_t *mxa) { - MLNDS_SETF(&mxa->send_mlnds, MLNDS_F_NOTERM); - MLNDS_SETF(&mxa->recv_mlnds, MLNDS_F_NOTERM); + NDS_SETF(&mxa->send_nds, NDS_F_NOTERM); + NDS_SETF(&mxa->recv_nds, NDS_F_NOTERM); - return (mlrpc_generic_call_stub(mxa)); + return (ndr_generic_call_stub(mxa)); } /* @@ -212,7 +210,7 @@ samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key) * Return a handle for use with subsequent SAM requests. */ static int -samr_s_ConnectAnon(void *arg, struct mlrpc_xaction *mxa) +samr_s_ConnectAnon(void *arg, ndr_xa_t *mxa) { struct samr_ConnectAnon *param = arg; ndr_hdid_t *id; @@ -226,7 +224,7 @@ samr_s_ConnectAnon(void *arg, struct mlrpc_xaction *mxa) param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -236,7 +234,7 @@ samr_s_ConnectAnon(void *arg, struct mlrpc_xaction *mxa) * Free the handle and zero out the result handle for the client. */ static int -samr_s_CloseHandle(void *arg, struct mlrpc_xaction *mxa) +samr_s_CloseHandle(void *arg, ndr_xa_t *mxa) { struct samr_CloseHandle *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -245,7 +243,7 @@ samr_s_CloseHandle(void *arg, struct mlrpc_xaction *mxa) bzero(¶m->result_handle, sizeof (samr_handle_t)); param->status = 0; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -257,7 +255,7 @@ samr_s_CloseHandle(void *arg, struct mlrpc_xaction *mxa) * rejected. */ static int -samr_s_LookupDomain(void *arg, struct mlrpc_xaction *mxa) +samr_s_LookupDomain(void *arg, ndr_xa_t *mxa) { struct samr_LookupDomain *param = arg; char resource_domain[SMB_PI_MAX_DOMAIN]; @@ -267,7 +265,7 @@ samr_s_LookupDomain(void *arg, struct mlrpc_xaction *mxa) if ((domain_name = (char *)param->domain_name.str) == NULL) { bzero(param, sizeof (struct samr_LookupDomain)); param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } (void) smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN); @@ -284,13 +282,13 @@ samr_s_LookupDomain(void *arg, struct mlrpc_xaction *mxa) } if (sid) { - param->sid = (struct samr_sid *)mlsvc_sid_save(sid, mxa); + param->sid = (struct samr_sid *)NDR_SIDDUP(mxa, sid); free(sid); if (param->sid == NULL) { bzero(param, sizeof (struct samr_LookupDomain)); param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } param->status = NT_STATUS_SUCCESS; @@ -299,7 +297,7 @@ samr_s_LookupDomain(void *arg, struct mlrpc_xaction *mxa) param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_DOMAIN); } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -310,7 +308,7 @@ samr_s_LookupDomain(void *arg, struct mlrpc_xaction *mxa) * work is done in samr_s_enum_local_domains. */ static int -samr_s_EnumLocalDomains(void *arg, struct mlrpc_xaction *mxa) +samr_s_EnumLocalDomains(void *arg, ndr_xa_t *mxa) { struct samr_EnumLocalDomain *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -330,7 +328,7 @@ samr_s_EnumLocalDomains(void *arg, struct mlrpc_xaction *mxa) param->status = NT_SC_ERROR(status); } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } @@ -347,28 +345,28 @@ samr_s_EnumLocalDomains(void *arg, struct mlrpc_xaction *mxa) */ static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *param, - struct mlrpc_xaction *mxa) + ndr_xa_t *mxa) { struct samr_LocalDomainInfo *info; struct samr_LocalDomainEntry *entry; char *hostname; - hostname = MLRPC_HEAP_MALLOC(mxa, NETBIOS_NAME_SZ); + hostname = NDR_MALLOC(mxa, NETBIOS_NAME_SZ); if (hostname == NULL) return (NT_STATUS_NO_MEMORY); if (smb_getnetbiosname(hostname, NETBIOS_NAME_SZ) != 0) return (NT_STATUS_NO_MEMORY); - entry = MLRPC_HEAP_NEWN(mxa, struct samr_LocalDomainEntry, 2); + entry = NDR_NEWN(mxa, struct samr_LocalDomainEntry, 2); if (entry == NULL) return (NT_STATUS_NO_MEMORY); bzero(entry, (sizeof (struct samr_LocalDomainEntry) * 2)); - (void) mlsvc_string_save((ms_string_t *)&entry[0].name, hostname, mxa); - (void) mlsvc_string_save((ms_string_t *)&entry[1].name, "Builtin", mxa); + (void) NDR_MSTRING(mxa, hostname, (ndr_mstring_t *)&entry[0].name); + (void) NDR_MSTRING(mxa, "Builtin", (ndr_mstring_t *)&entry[1].name); - info = MLRPC_HEAP_NEW(mxa, struct samr_LocalDomainInfo); + info = NDR_NEW(mxa, struct samr_LocalDomainInfo); if (info == NULL) return (NT_STATUS_NO_MEMORY); @@ -386,7 +384,7 @@ samr_s_enum_local_domains(struct samr_EnumLocalDomain *param, * We return a handle to be used to access objects within this domain. */ static int -samr_s_OpenDomain(void *arg, struct mlrpc_xaction *mxa) +samr_s_OpenDomain(void *arg, ndr_xa_t *mxa) { struct samr_OpenDomain *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -395,20 +393,20 @@ samr_s_OpenDomain(void *arg, struct mlrpc_xaction *mxa) if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) { bzero(¶m->domain_handle, sizeof (samr_handle_t)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if ((domain = nt_domain_lookup_sid((smb_sid_t *)param->sid)) == NULL) { bzero(¶m->domain_handle, sizeof (samr_handle_t)); param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if ((domain->type != NT_DOMAIN_BUILTIN) && (domain->type != NT_DOMAIN_LOCAL)) { bzero(¶m->domain_handle, sizeof (samr_handle_t)); param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } id = samr_hdalloc(mxa, SAMR_KEY_DOMAIN, domain->type, 0); @@ -420,7 +418,7 @@ samr_s_OpenDomain(void *arg, struct mlrpc_xaction *mxa) param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -434,7 +432,7 @@ samr_s_OpenDomain(void *arg, struct mlrpc_xaction *mxa) * We have no information on what the various information levels mean. */ static int -samr_s_QueryDomainInfo(void *arg, struct mlrpc_xaction *mxa) +samr_s_QueryDomainInfo(void *arg, ndr_xa_t *mxa) { struct samr_QueryDomainInfo *param = arg; struct samr_QueryDomainInfoRes *info; @@ -449,14 +447,14 @@ samr_s_QueryDomainInfo(void *arg, struct mlrpc_xaction *mxa) if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { bzero(param, sizeof (struct samr_QueryDomainInfo)); param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } - info = MLRPC_HEAP_NEW(mxa, struct samr_QueryDomainInfoRes); + info = NDR_NEW(mxa, struct samr_QueryDomainInfoRes); if (info == NULL) { bzero(param, sizeof (struct samr_QueryDomainInfo)); param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } info->switch_value = param->info_level; param->info = info; @@ -482,13 +480,13 @@ samr_s_QueryDomainInfo(void *arg, struct mlrpc_xaction *mxa) default: bzero(param, sizeof (struct samr_QueryDomainInfo)); param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (rc != 0) { bzero(param, sizeof (struct samr_QueryDomainInfo)); param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } switch (param->info_level) { @@ -510,14 +508,12 @@ samr_s_QueryDomainInfo(void *arg, struct mlrpc_xaction *mxa) info->ru.info2.unknown1 = 0x00000000; info->ru.info2.unknown2 = 0x80000000; - (void) mlsvc_string_save((ms_string_t *)&(info->ru.info2.s1), - "", mxa); - - (void) mlsvc_string_save( - (ms_string_t *)&(info->ru.info2.domain), domain, mxa); - - (void) mlsvc_string_save((ms_string_t *)&(info->ru.info2.s2), - "", mxa); + (void) NDR_MSTRING(mxa, "", + (ndr_mstring_t *)&(info->ru.info2.s1)); + (void) NDR_MSTRING(mxa, domain, + (ndr_mstring_t *)&(info->ru.info2.domain)); + (void) NDR_MSTRING(mxa, "", + (ndr_mstring_t *)&(info->ru.info2.s2)); info->ru.info2.sequence_num = 0x0000002B; info->ru.info2.unknown3 = 0x00000000; @@ -532,10 +528,10 @@ samr_s_QueryDomainInfo(void *arg, struct mlrpc_xaction *mxa) default: bzero(param, sizeof (struct samr_QueryDomainInfo)); - return (MLRPC_DRC_FAULT_REQUEST_OPNUM_INVALID); + return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); }; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -546,7 +542,7 @@ samr_s_QueryDomainInfo(void *arg, struct mlrpc_xaction *mxa) * support multiple name lookup but I can only get one working for now. */ static int -samr_s_LookupNames(void *arg, struct mlrpc_xaction *mxa) +samr_s_LookupNames(void *arg, ndr_xa_t *mxa) { struct samr_LookupNames *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -576,11 +572,11 @@ samr_s_LookupNames(void *arg, struct mlrpc_xaction *mxa) if (status != NT_STATUS_SUCCESS) { bzero(param, sizeof (struct samr_LookupNames)); param->status = NT_SC_ERROR(status); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } - param->rids.rid = MLRPC_HEAP_NEW(mxa, DWORD); - param->rid_types.rid_type = MLRPC_HEAP_NEW(mxa, DWORD); + param->rids.rid = NDR_NEW(mxa, DWORD); + param->rid_types.rid_type = NDR_NEW(mxa, DWORD); data = (samr_keydata_t *)hd->nh_data; @@ -594,7 +590,7 @@ samr_s_LookupNames(void *arg, struct mlrpc_xaction *mxa) param->rid_types.n_entry = 1; param->rid_types.rid_type[0] = wka->wka_type; param->status = NT_STATUS_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } break; @@ -607,7 +603,7 @@ samr_s_LookupNames(void *arg, struct mlrpc_xaction *mxa) param->rid_types.rid_type[0] = grp.sg_id.gs_type; param->status = NT_STATUS_SUCCESS; smb_lgrp_free(&grp); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (smb_pwd_getpasswd((const char *)param->name.str, @@ -620,7 +616,7 @@ samr_s_LookupNames(void *arg, struct mlrpc_xaction *mxa) param->rid_types.rid_type[0] = SidTypeUser; param->status = NT_STATUS_SUCCESS; free(sid); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } } break; @@ -628,13 +624,13 @@ samr_s_LookupNames(void *arg, struct mlrpc_xaction *mxa) default: bzero(param, sizeof (struct samr_LookupNames)); param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } param->rids.n_entry = 0; param->rid_types.n_entry = 0; param->status = NT_SC_ERROR(NT_STATUS_NONE_MAPPED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -646,7 +642,7 @@ samr_s_LookupNames(void *arg, struct mlrpc_xaction *mxa) * specified by the rid in the request. */ static int -samr_s_OpenUser(void *arg, struct mlrpc_xaction *mxa) +samr_s_OpenUser(void *arg, ndr_xa_t *mxa) { struct samr_OpenUser *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -656,7 +652,7 @@ samr_s_OpenUser(void *arg, struct mlrpc_xaction *mxa) if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { bzero(¶m->user_handle, sizeof (samr_handle_t)); param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } data = (samr_keydata_t *)hd->nh_data; @@ -675,7 +671,7 @@ samr_s_OpenUser(void *arg, struct mlrpc_xaction *mxa) param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -686,13 +682,13 @@ samr_s_OpenUser(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -samr_s_DeleteUser(void *arg, struct mlrpc_xaction *mxa) +samr_s_DeleteUser(void *arg, ndr_xa_t *mxa) { struct samr_DeleteUser *param = arg; bzero(param, sizeof (struct samr_DeleteUser)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -707,13 +703,13 @@ samr_s_DeleteUser(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -samr_s_QueryUserInfo(void *arg, struct mlrpc_xaction *mxa) +samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa) { struct samr_QueryUserInfo *param = arg; bzero(param, sizeof (struct samr_QueryUserInfo)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -724,7 +720,7 @@ samr_s_QueryUserInfo(void *arg, struct mlrpc_xaction *mxa) * rid in the discriminator field. Note that this is a local user. */ static int -samr_s_QueryUserGroups(void *arg, struct mlrpc_xaction *mxa) +samr_s_QueryUserGroups(void *arg, ndr_xa_t *mxa) { struct samr_QueryUserGroups *param = arg; struct samr_UserGroupInfo *info; @@ -770,7 +766,7 @@ samr_s_QueryUserGroups(void *arg, struct mlrpc_xaction *mxa) goto query_error; } - info = MLRPC_HEAP_NEW(mxa, struct samr_UserGroupInfo); + info = NDR_NEW(mxa, struct samr_UserGroupInfo); if (info == NULL) { status = NT_STATUS_NO_MEMORY; goto query_error; @@ -778,7 +774,7 @@ samr_s_QueryUserGroups(void *arg, struct mlrpc_xaction *mxa) bzero(info, sizeof (struct samr_UserGroupInfo)); size = 32 * 1024; - info->groups = MLRPC_HEAP_MALLOC(mxa, size); + info->groups = NDR_MALLOC(mxa, size); if (info->groups == NULL) { status = NT_STATUS_NO_MEMORY; goto query_error; @@ -807,13 +803,13 @@ samr_s_QueryUserGroups(void *arg, struct mlrpc_xaction *mxa) free(user_sid); param->info = info; param->status = NT_STATUS_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); query_error: free(user_sid); bzero(param, sizeof (struct samr_QueryUserGroups)); param->status = NT_SC_ERROR(status); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -828,7 +824,7 @@ query_error: * We return a handle to be used to access information about this group. */ static int -samr_s_OpenGroup(void *arg, struct mlrpc_xaction *mxa) +samr_s_OpenGroup(void *arg, ndr_xa_t *mxa) { struct samr_OpenGroup *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -838,7 +834,7 @@ samr_s_OpenGroup(void *arg, struct mlrpc_xaction *mxa) if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { bzero(¶m->group_handle, sizeof (samr_handle_t)); param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } data = (samr_keydata_t *)hd->nh_data; @@ -852,7 +848,7 @@ samr_s_OpenGroup(void *arg, struct mlrpc_xaction *mxa) param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -866,7 +862,7 @@ samr_s_OpenGroup(void *arg, struct mlrpc_xaction *mxa) * Return a handle for use with subsequent SAM requests. */ static int -samr_s_Connect(void *arg, struct mlrpc_xaction *mxa) +samr_s_Connect(void *arg, ndr_xa_t *mxa) { struct samr_Connect *param = arg; ndr_hdid_t *id; @@ -880,7 +876,7 @@ samr_s_Connect(void *arg, struct mlrpc_xaction *mxa) param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -890,13 +886,13 @@ samr_s_Connect(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -samr_s_GetUserPwInfo(void *arg, struct mlrpc_xaction *mxa) +samr_s_GetUserPwInfo(void *arg, ndr_xa_t *mxa) { struct samr_GetUserPwInfo *param = arg; bzero(param, sizeof (struct samr_GetUserPwInfo)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -904,13 +900,13 @@ samr_s_GetUserPwInfo(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -samr_s_CreateUser(void *arg, struct mlrpc_xaction *mxa) +samr_s_CreateUser(void *arg, ndr_xa_t *mxa) { struct samr_CreateUser *param = arg; bzero(¶m->user_handle, sizeof (samr_handle_t)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -918,13 +914,13 @@ samr_s_CreateUser(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -samr_s_ChangeUserPasswd(void *arg, struct mlrpc_xaction *mxa) +samr_s_ChangeUserPasswd(void *arg, ndr_xa_t *mxa) { struct samr_ChangeUserPasswd *param = arg; bzero(param, sizeof (struct samr_ChangeUserPasswd)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -932,13 +928,13 @@ samr_s_ChangeUserPasswd(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -samr_s_GetDomainPwInfo(void *arg, struct mlrpc_xaction *mxa) +samr_s_GetDomainPwInfo(void *arg, ndr_xa_t *mxa) { struct samr_GetDomainPwInfo *param = arg; bzero(param, sizeof (struct samr_GetDomainPwInfo)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -946,13 +942,13 @@ samr_s_GetDomainPwInfo(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -samr_s_SetUserInfo(void *arg, struct mlrpc_xaction *mxa) +samr_s_SetUserInfo(void *arg, ndr_xa_t *mxa) { struct samr_SetUserInfo *param = arg; bzero(param, sizeof (struct samr_SetUserInfo)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -966,7 +962,7 @@ samr_s_SetUserInfo(void *arg, struct mlrpc_xaction *mxa) * and returned size. The client doesn't seem to care. */ static int -samr_s_QueryDispInfo(void *arg, struct mlrpc_xaction *mxa) +samr_s_QueryDispInfo(void *arg, ndr_xa_t *mxa) { struct samr_QueryDispInfo *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; @@ -1010,7 +1006,7 @@ samr_s_QueryDispInfo(void *arg, struct mlrpc_xaction *mxa) ret_cnt = num_users - start_idx; if (ret_cnt > param->max_entries) ret_cnt = param->max_entries; - param->users.acct = MLRPC_HEAP_MALLOC(mxa, + param->users.acct = NDR_MALLOC(mxa, ret_cnt * sizeof (struct user_acct_info)); user = param->users.acct; if (user == NULL) { @@ -1034,16 +1030,16 @@ samr_s_QueryDispInfo(void *arg, struct mlrpc_xaction *mxa) user->ctrl = ACF_NORMUSER | ACF_PWDNOEXP; if (uinfo->su_ctrl & SMB_PWF_DISABLE) user->ctrl |= ACF_DISABLED; - if (mlsvc_string_save((ms_string_t *)&user->name, - uinfo->su_name, mxa) == 0) { + if (NDR_MSTRING(mxa, uinfo->su_name, + (ndr_mstring_t *)&user->name) == -1) { smb_pwd_iterclose(&pwi); status = NT_STATUS_NO_MEMORY; goto error; } - (void) mlsvc_string_save((ms_string_t *)&user->fullname, - uinfo->su_fullname, mxa); - (void) mlsvc_string_save((ms_string_t *)&user->desc, - uinfo->su_desc, mxa); + (void) NDR_MSTRING(mxa, uinfo->su_fullname, + (ndr_mstring_t *)&user->fullname); + (void) NDR_MSTRING(mxa, uinfo->su_desc, + (ndr_mstring_t *)&user->desc); user++; ret_cnt++; } @@ -1064,7 +1060,7 @@ samr_s_QueryDispInfo(void *arg, struct mlrpc_xaction *mxa) } param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); no_info: param->users.total_size = 0; @@ -1073,12 +1069,12 @@ no_info: param->users.count = 0; param->users.acct = NULL; param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); error: bzero(param, sizeof (struct samr_QueryDispInfo)); param->status = NT_SC_ERROR(status); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -1093,7 +1089,7 @@ error: * All information is hard-coded from packet captures. */ static int -samr_s_EnumDomainGroups(void *arg, struct mlrpc_xaction *mxa) +samr_s_EnumDomainGroups(void *arg, ndr_xa_t *mxa) { struct samr_EnumDomainGroups *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; @@ -1108,7 +1104,7 @@ samr_s_EnumDomainGroups(void *arg, struct mlrpc_xaction *mxa) param->count = 0; param->groups = 0; param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); #ifdef SAMR_SUPPORT_GROUPS if ((desc->discrim != SAMR_LOCAL_DOMAIN) || (param->start_idx != 0)) { @@ -1122,23 +1118,22 @@ samr_s_EnumDomainGroups(void *arg, struct mlrpc_xaction *mxa) param->returned_size = 64; param->switch_value = 3; param->count = 1; - param->groups = (struct group_disp_info *)MLRPC_HEAP_MALLOC( + param->groups = (struct group_disp_info *)NDR_MALLOC( mxa, sizeof (struct group_disp_info)); param->groups->count = 1; param->groups->acct[0].index = 1; param->groups->acct[0].rid = 513; param->groups->acct[0].ctrl = 0x7; - (void) mlsvc_string_save( - (ms_string_t *)¶m->groups->acct[0].name, "None", mxa); + (void) NDR_MSTRING(mxa, "None", + (ndr_mstring_t *)¶m->groups->acct[0].name); - (void) mlsvc_string_save( - (ms_string_t *)¶m->groups->acct[0].desc, - "Ordinary users", mxa); + (void) NDR_MSTRING(mxa, "Ordinary users", + (ndr_mstring_t *)¶m->groups->acct[0].desc); } param->status = NT_STATUS_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); #endif } @@ -1150,7 +1145,7 @@ samr_s_EnumDomainGroups(void *arg, struct mlrpc_xaction *mxa) * the passed domain handle. */ static int -samr_s_OpenAlias(void *arg, struct mlrpc_xaction *mxa) +samr_s_OpenAlias(void *arg, ndr_xa_t *mxa) { struct samr_OpenAlias *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; @@ -1180,7 +1175,7 @@ samr_s_OpenAlias(void *arg, struct mlrpc_xaction *mxa) if (id) { bcopy(id, ¶m->alias_handle, sizeof (samr_handle_t)); param->status = NT_STATUS_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } status = NT_STATUS_NO_MEMORY; @@ -1188,7 +1183,7 @@ samr_s_OpenAlias(void *arg, struct mlrpc_xaction *mxa) open_alias_err: bzero(¶m->alias_handle, sizeof (samr_handle_t)); param->status = NT_SC_ERROR(status); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -1202,7 +1197,7 @@ open_alias_err: */ /*ARGSUSED*/ static int -samr_s_CreateDomainAlias(void *arg, struct mlrpc_xaction *mxa) +samr_s_CreateDomainAlias(void *arg, ndr_xa_t *mxa) { struct samr_CreateDomainAlias *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; @@ -1210,12 +1205,12 @@ samr_s_CreateDomainAlias(void *arg, struct mlrpc_xaction *mxa) 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 (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(param, sizeof (struct samr_CreateDomainAlias)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); #ifdef SAMR_SUPPORT_ADD_ALIAS DWORD status = NT_STATUS_SUCCESS; @@ -1251,12 +1246,12 @@ samr_s_CreateDomainAlias(void *arg, struct mlrpc_xaction *mxa) bcopy(handle, ¶m->alias_handle, sizeof (samr_handle_t)); param->status = 0; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); create_alias_err: bzero(¶m->alias_handle, sizeof (samr_handle_t)); param->status = NT_SC_ERROR(status); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); #endif } @@ -1266,7 +1261,7 @@ create_alias_err: * Similar to NetLocalGroupSetInfo. */ static int -samr_s_SetAliasInfo(void *arg, struct mlrpc_xaction *mxa) +samr_s_SetAliasInfo(void *arg, ndr_xa_t *mxa) { struct samr_SetAliasInfo *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; @@ -1276,7 +1271,7 @@ samr_s_SetAliasInfo(void *arg, struct mlrpc_xaction *mxa) status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -1286,7 +1281,7 @@ samr_s_SetAliasInfo(void *arg, struct mlrpc_xaction *mxa) * by given handle. */ static int -samr_s_QueryAliasInfo(void *arg, struct mlrpc_xaction *mxa) +samr_s_QueryAliasInfo(void *arg, ndr_xa_t *mxa) { struct samr_QueryAliasInfo *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; @@ -1312,19 +1307,19 @@ samr_s_QueryAliasInfo(void *arg, struct mlrpc_xaction *mxa) switch (param->level) { case SAMR_QUERY_ALIAS_INFO_1: param->ru.info1.level = param->level; - (void) mlsvc_string_save( - (ms_string_t *)¶m->ru.info1.name, grp.sg_name, mxa); + (void) NDR_MSTRING(mxa, grp.sg_name, + (ndr_mstring_t *)¶m->ru.info1.name); - (void) mlsvc_string_save( - (ms_string_t *)¶m->ru.info1.desc, grp.sg_cmnt, mxa); + (void) NDR_MSTRING(mxa, grp.sg_cmnt, + (ndr_mstring_t *)¶m->ru.info1.desc); param->ru.info1.unknown = 1; break; case SAMR_QUERY_ALIAS_INFO_3: param->ru.info3.level = param->level; - (void) mlsvc_string_save( - (ms_string_t *)¶m->ru.info3.desc, grp.sg_cmnt, mxa); + (void) NDR_MSTRING(mxa, grp.sg_cmnt, + (ndr_mstring_t *)¶m->ru.info3.desc); break; default: @@ -1336,11 +1331,11 @@ samr_s_QueryAliasInfo(void *arg, struct mlrpc_xaction *mxa) smb_lgrp_free(&grp); param->address = (DWORD)(uintptr_t)¶m->ru; param->status = 0; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); query_alias_err: param->status = NT_SC_ERROR(status); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -1356,7 +1351,7 @@ query_alias_err: * The peice of code that removes a local group doesn't get compiled. */ static int -samr_s_DeleteDomainAlias(void *arg, struct mlrpc_xaction *mxa) +samr_s_DeleteDomainAlias(void *arg, ndr_xa_t *mxa) { struct samr_DeleteDomainAlias *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; @@ -1364,12 +1359,12 @@ samr_s_DeleteDomainAlias(void *arg, struct mlrpc_xaction *mxa) if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL) { bzero(param, sizeof (struct samr_DeleteDomainAlias)); param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(param, sizeof (struct samr_DeleteDomainAlias)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); #ifdef SAMR_SUPPORT_DEL_ALIAS nt_group_t *grp; @@ -1394,11 +1389,11 @@ samr_s_DeleteDomainAlias(void *arg, struct mlrpc_xaction *mxa) goto delete_alias_err; param->status = 0; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); delete_alias_err: param->status = NT_SC_ERROR(status); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); #endif } @@ -1408,7 +1403,7 @@ delete_alias_err: * This function sends back a list which contains all local groups' name. */ static int -samr_s_EnumDomainAliases(void *arg, struct mlrpc_xaction *mxa) +samr_s_EnumDomainAliases(void *arg, ndr_xa_t *mxa) { struct samr_EnumDomainAliases *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; @@ -1422,43 +1417,43 @@ samr_s_EnumDomainAliases(void *arg, struct mlrpc_xaction *mxa) if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { bzero(param, sizeof (struct samr_EnumDomainAliases)); param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } data = (samr_keydata_t *)hd->nh_data; (void) smb_lgrp_numbydomain((smb_gdomain_t)data->kd_type, &cnt); if (cnt <= param->resume_handle) { - param->aliases = (struct aliases_info *)MLRPC_HEAP_MALLOC(mxa, + param->aliases = (struct aliases_info *)NDR_MALLOC(mxa, sizeof (struct aliases_info)); if (param->aliases == NULL) { bzero(param, sizeof (struct samr_EnumDomainAliases)); param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(param->aliases, sizeof (struct aliases_info)); param->out_resume = 0; param->entries = 0; param->status = NT_STATUS_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } cnt -= param->resume_handle; - param->aliases = (struct aliases_info *)MLRPC_HEAP_MALLOC(mxa, + param->aliases = (struct aliases_info *)NDR_MALLOC(mxa, sizeof (struct aliases_info) + (cnt-1) * sizeof (struct name_rid)); if (param->aliases == NULL) { bzero(param, sizeof (struct samr_EnumDomainAliases)); param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) { bzero(param, sizeof (struct samr_EnumDomainAliases)); param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } skip = i = 0; @@ -1467,8 +1462,8 @@ samr_s_EnumDomainAliases(void *arg, struct mlrpc_xaction *mxa) if ((skip++ >= param->resume_handle) && (grp.sg_domain == data->kd_type) && (i++ < cnt)) { info->rid = grp.sg_rid; - (void) mlsvc_string_save((ms_string_t *)&info->name, - grp.sg_name, mxa); + (void) NDR_MSTRING(mxa, grp.sg_name, + (ndr_mstring_t *)&info->name); info++; } @@ -1482,7 +1477,7 @@ samr_s_EnumDomainAliases(void *arg, struct mlrpc_xaction *mxa) param->out_resume = i; param->entries = i; param->status = 0; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -1496,12 +1491,12 @@ samr_s_EnumDomainAliases(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -samr_s_Connect3(void *arg, struct mlrpc_xaction *mxa) +samr_s_Connect3(void *arg, ndr_xa_t *mxa) { struct samr_Connect3 *param = arg; bzero(param, sizeof (struct samr_Connect3)); - return (MLRPC_DRC_FAULT_REQUEST_OPNUM_INVALID); + return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); } @@ -1513,15 +1508,15 @@ samr_s_Connect3(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -samr_s_Connect4(void *arg, struct mlrpc_xaction *mxa) +samr_s_Connect4(void *arg, ndr_xa_t *mxa) { struct samr_Connect4 *param = arg; bzero(param, sizeof (struct samr_Connect4)); - return (MLRPC_DRC_FAULT_REQUEST_OPNUM_INVALID); + return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); } -static mlrpc_stub_table_t samr_stub_table[] = { +static ndr_stub_table_t samr_stub_table[] = { { samr_s_ConnectAnon, SAMR_OPNUM_ConnectAnon }, { samr_s_CloseHandle, SAMR_OPNUM_CloseHandle }, { samr_s_LookupDomain, SAMR_OPNUM_LookupDomain }, diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_srvsvc.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_srvsvc.c index 2b8ed20292..c3065af140 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_srvsvc.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_srvsvc.c @@ -55,8 +55,6 @@ #include <smbsrv/nmpipes.h> #include <smbsrv/cifs.h> #include <smbsrv/netrauth.h> -#include <smbsrv/mlsvc.h> -#include <smbsrv/mlsvc_util.h> #include <smbsrv/ndl/srvsvc.ndl> #include <smbsrv/smb_common_door.h> @@ -83,31 +81,31 @@ typedef struct srvsvc_enum { uint32_t se_n_read; } srvsvc_enum_t; -static DWORD srvsvc_NetFileEnum2(struct mlrpc_xaction *, +static DWORD srvsvc_NetFileEnum2(ndr_xa_t *, struct mslm_NetFileEnum *); -static DWORD srvsvc_NetFileEnum3(struct mlrpc_xaction *, +static DWORD srvsvc_NetFileEnum3(ndr_xa_t *, struct mslm_NetFileEnum *); static DWORD mlsvc_NetSessionEnumLevel0(struct mslm_infonres *, DWORD, - struct mlrpc_xaction *); + ndr_xa_t *); static DWORD mlsvc_NetSessionEnumLevel1(struct mslm_infonres *, DWORD, - struct mlrpc_xaction *); + ndr_xa_t *); -static DWORD mlsvc_NetShareEnumLevel0(struct mlrpc_xaction *, +static DWORD mlsvc_NetShareEnumLevel0(ndr_xa_t *, struct mslm_infonres *, srvsvc_enum_t *, int); -static DWORD mlsvc_NetShareEnumLevel1(struct mlrpc_xaction *, +static DWORD mlsvc_NetShareEnumLevel1(ndr_xa_t *, struct mslm_infonres *, srvsvc_enum_t *, int); -static DWORD mlsvc_NetShareEnumLevel2(struct mlrpc_xaction *, +static DWORD mlsvc_NetShareEnumLevel2(ndr_xa_t *, struct mslm_infonres *, srvsvc_enum_t *, int); -static DWORD mlsvc_NetShareEnumLevel501(struct mlrpc_xaction *, +static DWORD mlsvc_NetShareEnumLevel501(ndr_xa_t *, struct mslm_infonres *, srvsvc_enum_t *, int); -static DWORD mlsvc_NetShareEnumLevel502(struct mlrpc_xaction *, +static DWORD mlsvc_NetShareEnumLevel502(ndr_xa_t *, struct mslm_infonres *, srvsvc_enum_t *, int); -static DWORD mlsvc_NetShareEnumCommon(struct mlrpc_xaction *, +static DWORD mlsvc_NetShareEnumCommon(ndr_xa_t *, srvsvc_enum_t *, smb_share_t *, void *); -static boolean_t srvsvc_add_autohome(struct mlrpc_xaction *, srvsvc_enum_t *, +static boolean_t srvsvc_add_autohome(ndr_xa_t *, srvsvc_enum_t *, void *); -static char *srvsvc_share_mkpath(struct mlrpc_xaction *, char *); +static char *srvsvc_share_mkpath(ndr_xa_t *, char *); static uint32_t srvsvc_estimate_objcnt(uint32_t, uint32_t, uint32_t); @@ -116,15 +114,15 @@ static uint32_t srvsvc_sa_delete(char *); static char empty_string[1]; -static mlrpc_stub_table_t srvsvc_stub_table[]; +static ndr_stub_table_t srvsvc_stub_table[]; -static mlrpc_service_t srvsvc_service = { +static ndr_service_t srvsvc_service = { "SRVSVC", /* name */ "Server services", /* desc */ "\\srvsvc", /* endpoint */ PIPE_NTSVCS, /* sec_addr_port */ - "4b324fc8-1670-01d3-12785a47bf6ee188", 3, /* abstract */ - "8a885d04-1ceb-11c9-9fe808002b104860", 2, /* transfer */ + "4b324fc8-1670-01d3-1278-5a47bf6ee188", 3, /* abstract */ + NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 0, /* no bind_instance_size */ 0, /* no bind_req() */ 0, /* no unbind_and_close() */ @@ -143,7 +141,7 @@ static mlrpc_service_t srvsvc_service = { void srvsvc_initialize(void) { - (void) mlrpc_register_service(&srvsvc_service); + (void) ndr_svc_register(&srvsvc_service); } /* @@ -153,13 +151,13 @@ srvsvc_initialize(void) * Current level 0 and level 1 connection info are supported. * * Level 1 request is made by 'srvmgr' (Server Manager) - * utility of NT Server part of NT Domain to MLRPC server + * utility of NT Server part of NT Domain to RPC server * while double click of share info icon. These values - * are currectly virtual to MLRPC client and does't + * are currectly virtual to RPC client and does't * reflect the real state of server. */ static int -srvsvc_s_NetConnectEnum(void *arg, struct mlrpc_xaction *mxa) +srvsvc_s_NetConnectEnum(void *arg, ndr_xa_t *mxa) { struct mslm_NetConnectEnum *param = arg; struct mslm_NetConnectInfoBuf0 *ci0; @@ -169,7 +167,7 @@ srvsvc_s_NetConnectEnum(void *arg, struct mlrpc_xaction *mxa) status = ERROR_SUCCESS; switch (param->info.level) { case 0: - ci0 = MLRPC_HEAP_NEW(mxa, struct mslm_NetConnectInfoBuf0); + ci0 = NDR_NEW(mxa, struct mslm_NetConnectInfoBuf0); if (ci0 == 0) { status = ERROR_NOT_ENOUGH_MEMORY; break; @@ -177,7 +175,7 @@ srvsvc_s_NetConnectEnum(void *arg, struct mlrpc_xaction *mxa) ci0->coni0_id = 0x17; param->info.ru.info0 - = MLRPC_HEAP_NEW(mxa, struct mslm_NetConnectInfo0); + = NDR_NEW(mxa, struct mslm_NetConnectInfo0); if (param->info.ru.info0 == 0) { status = ERROR_NOT_ENOUGH_MEMORY; @@ -191,7 +189,7 @@ srvsvc_s_NetConnectEnum(void *arg, struct mlrpc_xaction *mxa) break; case 1: - ci1 = MLRPC_HEAP_NEW(mxa, struct mslm_NetConnectInfoBuf1); + ci1 = NDR_NEW(mxa, struct mslm_NetConnectInfoBuf1); if (ci1 == 0) { status = ERROR_NOT_ENOUGH_MEMORY; break; @@ -202,12 +200,12 @@ srvsvc_s_NetConnectEnum(void *arg, struct mlrpc_xaction *mxa) ci1->coni1_num_users = 1; ci1->coni1_time = 16; ci1->coni1_username = - (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, "Administrator"); + (unsigned char *)NDR_STRDUP(mxa, "Administrator"); ci1->coni1_netname = - (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, "IPC$"); + (unsigned char *)NDR_STRDUP(mxa, "IPC$"); - param->info.ru.info1 = MLRPC_HEAP_NEW(mxa, + param->info.ru.info1 = NDR_NEW(mxa, struct mslm_NetConnectInfo1); if (param->info.ru.info1 == 0) { @@ -230,7 +228,7 @@ srvsvc_s_NetConnectEnum(void *arg, struct mlrpc_xaction *mxa) bzero(param, sizeof (struct mslm_NetConnectEnum)); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -286,7 +284,7 @@ srvsvc_s_NetConnectEnum(void *arg, struct mlrpc_xaction *mxa) * NERR_BufTooSmall The supplied buffer is too small. */ static int -srvsvc_s_NetFileEnum(void *arg, struct mlrpc_xaction *mxa) +srvsvc_s_NetFileEnum(void *arg, ndr_xa_t *mxa) { struct mslm_NetFileEnum *param = arg; DWORD status; @@ -294,7 +292,7 @@ srvsvc_s_NetFileEnum(void *arg, struct mlrpc_xaction *mxa) if (!ndr_is_admin(mxa)) { bzero(param, sizeof (struct mslm_NetFileEnum)); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } switch (param->info.switch_value) { @@ -318,14 +316,14 @@ srvsvc_s_NetFileEnum(void *arg, struct mlrpc_xaction *mxa) if (status != ERROR_SUCCESS) { bzero(param, sizeof (struct mslm_NetFileEnum)); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (param->resume_handle) *param->resume_handle = 0; param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -335,11 +333,11 @@ srvsvc_s_NetFileEnum(void *arg, struct mlrpc_xaction *mxa) * fields have been set up. */ static DWORD -srvsvc_NetFileEnum2(struct mlrpc_xaction *mxa, struct mslm_NetFileEnum *param) +srvsvc_NetFileEnum2(ndr_xa_t *mxa, struct mslm_NetFileEnum *param) { struct mslm_NetFileInfoBuf2 *fi2; - fi2 = MLRPC_HEAP_NEW(mxa, struct mslm_NetFileInfoBuf2); + fi2 = NDR_NEW(mxa, struct mslm_NetFileInfoBuf2); if (fi2 == NULL) return (ERROR_NOT_ENOUGH_MEMORY); @@ -349,7 +347,7 @@ srvsvc_NetFileEnum2(struct mlrpc_xaction *mxa, struct mslm_NetFileEnum *param) */ fi2->fi2_id = 0xF5; - param->info.ru.info2 = MLRPC_HEAP_NEW(mxa, struct mslm_NetFileInfo2); + param->info.ru.info2 = NDR_NEW(mxa, struct mslm_NetFileInfo2); if (param->info.ru.info3 == NULL) return (ERROR_NOT_ENOUGH_MEMORY); @@ -366,11 +364,11 @@ srvsvc_NetFileEnum2(struct mlrpc_xaction *mxa, struct mslm_NetFileEnum *param) * fields have been set up. */ static DWORD -srvsvc_NetFileEnum3(struct mlrpc_xaction *mxa, struct mslm_NetFileEnum *param) +srvsvc_NetFileEnum3(ndr_xa_t *mxa, struct mslm_NetFileEnum *param) { struct mslm_NetFileInfoBuf3 *fi3; - fi3 = MLRPC_HEAP_NEW(mxa, struct mslm_NetFileInfoBuf3); + fi3 = NDR_NEW(mxa, struct mslm_NetFileInfoBuf3); if (fi3 == NULL) return (ERROR_NOT_ENOUGH_MEMORY); @@ -381,11 +379,11 @@ srvsvc_NetFileEnum3(struct mlrpc_xaction *mxa, struct mslm_NetFileEnum *param) fi3->fi3_permissions = 0x23; fi3->fi3_num_locks = 0; fi3->fi3_pathname = - (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, "\\PIPE\\srvsvc"); + (unsigned char *)NDR_STRDUP(mxa, "\\PIPE\\srvsvc"); fi3->fi3_username = - (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, "Administrator"); + (unsigned char *)NDR_STRDUP(mxa, "Administrator"); - param->info.ru.info3 = MLRPC_HEAP_NEW(mxa, struct mslm_NetFileInfo3); + param->info.ru.info3 = NDR_NEW(mxa, struct mslm_NetFileInfo3); if (param->info.ru.info3 == NULL) return (ERROR_NOT_ENOUGH_MEMORY); @@ -413,33 +411,29 @@ srvsvc_NetFileEnum3(struct mlrpc_xaction *mxa, struct mslm_NetFileEnum *param) * The NetFileClose2 MSDN page has the right error code. */ static int -srvsvc_s_NetFileClose(void *arg, struct mlrpc_xaction *mxa) +srvsvc_s_NetFileClose(void *arg, ndr_xa_t *mxa) { struct mslm_NetFileClose *param = arg; if (!ndr_is_admin(mxa)) { bzero(param, sizeof (struct mslm_NetFileClose)); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(param, sizeof (struct mslm_NetFileClose)); param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* * srvsvc_s_NetShareGetInfo * - * This call is made by Windows2000 to get share information. There are - * probably other information levels but these are the only ones I've - * seen so far. - * * Returns Win32 error codes. */ static int -srvsvc_s_NetShareGetInfo(void *arg, struct mlrpc_xaction *mxa) +srvsvc_s_NetShareGetInfo(void *arg, ndr_xa_t *mxa) { struct mlsm_NetShareGetInfo *param = arg; struct mslm_NetShareGetInfo0 *info0; @@ -447,7 +441,9 @@ srvsvc_s_NetShareGetInfo(void *arg, struct mlrpc_xaction *mxa) struct mslm_NetShareGetInfo2 *info2; struct mslm_NetShareGetInfo501 *info501; struct mslm_NetShareGetInfo502 *info502; + struct mslm_NetShareGetInfo1004 *info1004; struct mslm_NetShareGetInfo1005 *info1005; + struct mslm_NetShareGetInfo1006 *info1006; smb_share_t si; char shr_comment[SMB_SHARE_CMNT_MAX]; DWORD status; @@ -456,7 +452,7 @@ srvsvc_s_NetShareGetInfo(void *arg, struct mlrpc_xaction *mxa) if (status != NERR_Success) { bzero(param, sizeof (struct mlsm_NetShareGetInfo)); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (strlen(si.shr_cmnt)) @@ -468,14 +464,14 @@ srvsvc_s_NetShareGetInfo(void *arg, struct mlrpc_xaction *mxa) switch (param->level) { case 0: - info0 = MLRPC_HEAP_NEW(mxa, struct mslm_NetShareGetInfo0); + info0 = NDR_NEW(mxa, struct mslm_NetShareGetInfo0); if (info0 == NULL) { status = ERROR_NOT_ENOUGH_MEMORY; break; } info0->shi0_netname - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, si.shr_name); + = (unsigned char *)NDR_STRDUP(mxa, si.shr_name); if (info0->shi0_netname == NULL) { status = ERROR_NOT_ENOUGH_MEMORY; break; @@ -485,16 +481,16 @@ srvsvc_s_NetShareGetInfo(void *arg, struct mlrpc_xaction *mxa) break; case 1: - info1 = MLRPC_HEAP_NEW(mxa, struct mslm_NetShareGetInfo1); + info1 = NDR_NEW(mxa, struct mslm_NetShareGetInfo1); if (info1 == NULL) { status = ERROR_NOT_ENOUGH_MEMORY; break; } info1->shi1_netname = - (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, si.shr_name); + (unsigned char *)NDR_STRDUP(mxa, si.shr_name); info1->shi1_comment = - (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, shr_comment); + (unsigned char *)NDR_STRDUP(mxa, shr_comment); if (info1->shi1_netname == NULL || info1->shi1_comment == NULL) { status = ERROR_NOT_ENOUGH_MEMORY; @@ -506,16 +502,16 @@ srvsvc_s_NetShareGetInfo(void *arg, struct mlrpc_xaction *mxa) break; case 2: - info2 = MLRPC_HEAP_NEW(mxa, struct mslm_NetShareGetInfo2); + info2 = NDR_NEW(mxa, struct mslm_NetShareGetInfo2); if (info2 == NULL) { status = ERROR_NOT_ENOUGH_MEMORY; break; } info2->shi2_netname = - (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, si.shr_name); + (unsigned char *)NDR_STRDUP(mxa, si.shr_name); info2->shi2_comment = - (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, shr_comment); + (unsigned char *)NDR_STRDUP(mxa, shr_comment); if (info2->shi2_netname == NULL || info2->shi2_comment == NULL) { status = ERROR_NOT_ENOUGH_MEMORY; @@ -532,30 +528,73 @@ srvsvc_s_NetShareGetInfo(void *arg, struct mlrpc_xaction *mxa) param->result.ru.info2 = info2; break; + case 1004: + info1004 = NDR_NEW(mxa, struct mslm_NetShareGetInfo1004); + if (info1004 == NULL) { + status = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + info1004->shi1004_comment = + (unsigned char *)NDR_STRDUP(mxa, shr_comment); + if (info1004->shi1004_comment == NULL) + status = ERROR_NOT_ENOUGH_MEMORY; + break; + case 1005: - info1005 = MLRPC_HEAP_NEW(mxa, struct mslm_NetShareGetInfo1005); + info1005 = NDR_NEW(mxa, struct mslm_NetShareGetInfo1005); if (info1005 == NULL) { status = ERROR_NOT_ENOUGH_MEMORY; break; } + info1005->shi1005_flags = 0; + + switch (si.shr_flags & SMB_SHRF_CSC_MASK) { + case SMB_SHRF_CSC_DISABLED: + info1005->shi1005_flags |= CSC_CACHE_NONE; + break; + case SMB_SHRF_CSC_AUTO: + info1005->shi1005_flags |= CSC_CACHE_AUTO_REINT; + break; + case SMB_SHRF_CSC_VDO: + info1005->shi1005_flags |= CSC_CACHE_VDO; + break; + case SMB_SHRF_CSC_MANUAL: + default: + /* + * Default to CSC_CACHE_MANUAL_REINT. + */ + break; + } + param->result.ru.info1005 = info1005; break; + case 1006: + info1006 = NDR_NEW(mxa, struct mslm_NetShareGetInfo1006); + if (info1006 == NULL) { + status = ERROR_NOT_ENOUGH_MEMORY; + break; + } + info1006->shi1006_max_uses = SHI_USES_UNLIMITED; + param->result.ru.info1006 = info1006; + break; + case 501: /* * Level 501 provides level 1 information. */ - info501 = MLRPC_HEAP_NEW(mxa, struct mslm_NetShareGetInfo501); + info501 = NDR_NEW(mxa, struct mslm_NetShareGetInfo501); if (info501 == NULL) { status = ERROR_NOT_ENOUGH_MEMORY; break; } info501->shi501_netname = - (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, si.shr_name); + (unsigned char *)NDR_STRDUP(mxa, si.shr_name); info501->shi501_comment = - (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, shr_comment); + (unsigned char *)NDR_STRDUP(mxa, shr_comment); if (info501->shi501_netname == NULL || info501->shi501_comment == NULL) { status = ERROR_NOT_ENOUGH_MEMORY; @@ -573,16 +612,16 @@ srvsvc_s_NetShareGetInfo(void *arg, struct mlrpc_xaction *mxa) * security descriptor. We don't support security * descriptors on shares yet. */ - info502 = MLRPC_HEAP_NEW(mxa, struct mslm_NetShareGetInfo502); + info502 = NDR_NEW(mxa, struct mslm_NetShareGetInfo502); if (info502 == NULL) { status = ERROR_NOT_ENOUGH_MEMORY; break; } info502->shi502_netname = - (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, si.shr_name); + (unsigned char *)NDR_STRDUP(mxa, si.shr_name); info502->shi502_comment = - (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, shr_comment); + (unsigned char *)NDR_STRDUP(mxa, shr_comment); if (info502->shi502_netname == NULL || info502->shi502_comment == NULL) { status = ERROR_NOT_ENOUGH_MEMORY; @@ -612,7 +651,7 @@ srvsvc_s_NetShareGetInfo(void *arg, struct mlrpc_xaction *mxa) param->result.switch_value = param->level; param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } @@ -625,12 +664,12 @@ srvsvc_s_NetShareGetInfo(void *arg, struct mlrpc_xaction *mxa) * Returns Win32 error codes. */ static int -srvsvc_s_NetShareSetInfo(void *arg, struct mlrpc_xaction *mxa) +srvsvc_s_NetShareSetInfo(void *arg, ndr_xa_t *mxa) { struct mlsm_NetShareSetInfo *param = arg; (void) memset(param, 0, sizeof (struct mlsm_NetShareSetInfo)); - param->parm_err_ptr = (DWORD)(uintptr_t)MLRPC_HEAP_MALLOC(mxa, + param->parm_err_ptr = (DWORD)(uintptr_t)NDR_MALLOC(mxa, sizeof (DWORD)); param->parm_err = 0; @@ -639,7 +678,7 @@ srvsvc_s_NetShareSetInfo(void *arg, struct mlrpc_xaction *mxa) else param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -667,18 +706,18 @@ srvsvc_s_NetShareSetInfo(void *arg, struct mlrpc_xaction *mxa) * NERR_UserNotFound The user name could not be found. */ static int -srvsvc_s_NetSessionEnum(void *arg, struct mlrpc_xaction *mxa) +srvsvc_s_NetSessionEnum(void *arg, ndr_xa_t *mxa) { struct mslm_NetSessionEnum *param = arg; struct mslm_infonres *infonres; DWORD status; DWORD n_sessions; - infonres = MLRPC_HEAP_NEW(mxa, struct mslm_infonres); + infonres = NDR_NEW(mxa, struct mslm_infonres); if (infonres == 0) { bzero(param, sizeof (struct mslm_NetSessionEnum)); param->status = ERROR_NOT_ENOUGH_MEMORY; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } infonres->entriesread = 0; @@ -707,13 +746,13 @@ srvsvc_s_NetSessionEnum(void *arg, struct mlrpc_xaction *mxa) if (status != 0) { bzero(param, sizeof (struct mslm_NetSessionEnum)); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } param->resume_handle = 0; param->total_entries = infonres->entriesread; param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -724,7 +763,7 @@ srvsvc_s_NetSessionEnum(void *arg, struct mlrpc_xaction *mxa) /*ARGSUSED*/ static DWORD mlsvc_NetSessionEnumLevel0(struct mslm_infonres *infonres, DWORD n_sessions, - struct mlrpc_xaction *mxa) + ndr_xa_t *mxa) { struct mslm_SESSION_INFO_0 *info0; smb_dr_ulist_t *ulist; @@ -733,7 +772,7 @@ mlsvc_NetSessionEnumLevel0(struct mslm_infonres *infonres, DWORD n_sessions, char ipaddr_buf[INET_ADDRSTRLEN]; int i, offset, cnt, total; - info0 = MLRPC_HEAP_NEWN(mxa, struct mslm_SESSION_INFO_0, n_sessions); + info0 = NDR_NEWN(mxa, struct mslm_SESSION_INFO_0, n_sessions); if (info0 == 0) return (ERROR_NOT_ENOUGH_MEMORY); @@ -765,7 +804,7 @@ mlsvc_NetSessionEnumLevel0(struct mslm_infonres *infonres, DWORD n_sessions, workstation = ipaddr_buf; } - info0[total].sesi0_cname = MLRPC_HEAP_STRSAVE(mxa, + info0[total].sesi0_cname = NDR_STRDUP(mxa, workstation); if (info0[total].sesi0_cname == 0) { smb_dr_ulist_free(ulist); @@ -794,7 +833,7 @@ mlsvc_NetSessionEnumLevel0(struct mslm_infonres *infonres, DWORD n_sessions, /*ARGSUSED*/ static DWORD mlsvc_NetSessionEnumLevel1(struct mslm_infonres *infonres, DWORD n_sessions, - struct mlrpc_xaction *mxa) + ndr_xa_t *mxa) { struct mslm_SESSION_INFO_1 *info1; smb_dr_ulist_t *ulist; @@ -804,7 +843,7 @@ mlsvc_NetSessionEnumLevel1(struct mslm_infonres *infonres, DWORD n_sessions, char ipaddr_buf[INET_ADDRSTRLEN]; int i, offset, cnt, total; - info1 = MLRPC_HEAP_NEWN(mxa, struct mslm_SESSION_INFO_1, n_sessions); + info1 = NDR_NEWN(mxa, struct mslm_SESSION_INFO_1, n_sessions); if (info1 == 0) return (ERROR_NOT_ENOUGH_MEMORY); @@ -839,9 +878,9 @@ mlsvc_NetSessionEnumLevel1(struct mslm_infonres *infonres, DWORD n_sessions, if ((account = user->oc_account) == 0) account = "Unknown"; - info1[total].sesi1_cname = MLRPC_HEAP_STRSAVE(mxa, + info1[total].sesi1_cname = NDR_STRDUP(mxa, workstation); - info1[total].sesi1_uname = MLRPC_HEAP_STRSAVE(mxa, + info1[total].sesi1_uname = NDR_STRDUP(mxa, account); if (info1[total].sesi1_cname == 0 || @@ -888,17 +927,17 @@ mlsvc_NetSessionEnumLevel1(struct mslm_infonres *infonres, DWORD n_sessions, * computer name. */ static int -srvsvc_s_NetSessionDel(void *arg, struct mlrpc_xaction *mxa) +srvsvc_s_NetSessionDel(void *arg, ndr_xa_t *mxa) { struct mslm_NetSessionDel *param = arg; if (!ndr_is_poweruser(mxa)) { param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -916,7 +955,7 @@ srvsvc_s_NetSessionDel(void *arg, struct mlrpc_xaction *mxa) * */ static int -srvsvc_s_NetServerGetInfo(void *arg, struct mlrpc_xaction *mxa) +srvsvc_s_NetServerGetInfo(void *arg, ndr_xa_t *mxa) { struct mslm_NetServerGetInfo *param = arg; struct mslm_SERVER_INFO_100 *info100; @@ -938,14 +977,14 @@ netservergetinfo_no_memory: switch (param->level) { case 100: - info100 = MLRPC_HEAP_NEW(mxa, struct mslm_SERVER_INFO_100); + info100 = NDR_NEW(mxa, struct mslm_SERVER_INFO_100); if (info100 == 0) goto netservergetinfo_no_memory; bzero(info100, sizeof (struct mslm_SERVER_INFO_100)); info100->sv100_platform_id = SV_PLATFORM_ID_NT; info100->sv100_name - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, hostname); + = (unsigned char *)NDR_STRDUP(mxa, hostname); if (info100->sv100_name == 0) goto netservergetinfo_no_memory; @@ -954,7 +993,7 @@ netservergetinfo_no_memory: break; case 101: - info101 = MLRPC_HEAP_NEW(mxa, struct mslm_SERVER_INFO_101); + info101 = NDR_NEW(mxa, struct mslm_SERVER_INFO_101); if (info101 == 0) goto netservergetinfo_no_memory; @@ -964,10 +1003,10 @@ netservergetinfo_no_memory: info101->sv101_version_minor = 0; info101->sv101_type = SV_TYPE_SENT_BY_ME; info101->sv101_name - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, hostname); + = (unsigned char *)NDR_STRDUP(mxa, hostname); info101->sv101_comment - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, sys_comment); + = (unsigned char *)NDR_STRDUP(mxa, sys_comment); if (info101->sv101_name == 0 || info101->sv101_comment == 0) goto netservergetinfo_no_memory; @@ -976,7 +1015,7 @@ netservergetinfo_no_memory: break; case 102: - info102 = MLRPC_HEAP_NEW(mxa, struct mslm_SERVER_INFO_102); + info102 = NDR_NEW(mxa, struct mslm_SERVER_INFO_102); if (info102 == 0) goto netservergetinfo_no_memory; @@ -986,10 +1025,10 @@ netservergetinfo_no_memory: info102->sv102_version_minor = 0; info102->sv102_type = SV_TYPE_SENT_BY_ME; info102->sv102_name - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, hostname); + = (unsigned char *)NDR_STRDUP(mxa, hostname); info102->sv102_comment - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, sys_comment); + = (unsigned char *)NDR_STRDUP(mxa, sys_comment); /* * The following level 102 fields are defaulted to zero @@ -1013,12 +1052,12 @@ netservergetinfo_no_memory: bzero(¶m->result, sizeof (struct mslm_NetServerGetInfo_result)); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } param->result.level = param->level; param->status = (ERROR_SUCCESS); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -1050,7 +1089,7 @@ netservergetinfo_no_memory: * (0.0001) second. */ static int -srvsvc_s_NetRemoteTOD(void *arg, struct mlrpc_xaction *mxa) +srvsvc_s_NetRemoteTOD(void *arg, ndr_xa_t *mxa) { struct mslm_NetRemoteTOD *param = arg; struct mslm_TIME_OF_DAY_INFO *tod; @@ -1060,7 +1099,7 @@ srvsvc_s_NetRemoteTOD(void *arg, struct mlrpc_xaction *mxa) (void) gettimeofday(&time_val, 0); (void) gmtime_r(&time_val.tv_sec, &tm); - tod = MLRPC_HEAP_NEW(mxa, struct mslm_TIME_OF_DAY_INFO); + tod = NDR_NEW(mxa, struct mslm_TIME_OF_DAY_INFO); if (tod == NULL) { bzero(param, sizeof (struct mslm_NetRemoteTOD)); return (ERROR_NOT_ENOUGH_MEMORY); @@ -1082,7 +1121,7 @@ srvsvc_s_NetRemoteTOD(void *arg, struct mlrpc_xaction *mxa) param->bufptr = tod; param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -1099,7 +1138,7 @@ srvsvc_s_NetRemoteTOD(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -srvsvc_s_NetNameValidate(void *arg, struct mlrpc_xaction *mxa) +srvsvc_s_NetNameValidate(void *arg, ndr_xa_t *mxa) { struct mslm_NetNameValidate *param = arg; char *name; @@ -1107,7 +1146,7 @@ srvsvc_s_NetNameValidate(void *arg, struct mlrpc_xaction *mxa) if ((name = (char *)param->pathname) == NULL) { param->status = ERROR_INVALID_PARAMETER; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } len = strlen(name); @@ -1115,7 +1154,7 @@ srvsvc_s_NetNameValidate(void *arg, struct mlrpc_xaction *mxa) if ((param->flags == 0 && len > 81) || (param->flags == 0x80000000 && len > 13)) { param->status = ERROR_INVALID_NAME; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } switch (param->type) { @@ -1146,7 +1185,7 @@ srvsvc_s_NetNameValidate(void *arg, struct mlrpc_xaction *mxa) break; } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -1169,7 +1208,7 @@ srvsvc_s_NetNameValidate(void *arg, struct mlrpc_xaction *mxa) * Returns Win32 error codes. */ static int -srvsvc_s_NetShareAdd(void *arg, struct mlrpc_xaction *mxa) +srvsvc_s_NetShareAdd(void *arg, ndr_xa_t *mxa) { static DWORD parm_err = 0; DWORD parm_stat; @@ -1183,7 +1222,7 @@ srvsvc_s_NetShareAdd(void *arg, struct mlrpc_xaction *mxa) if (!ndr_is_poweruser(mxa)) { bzero(param, sizeof (struct mslm_NetShareAdd)); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } switch (param->level) { @@ -1198,19 +1237,19 @@ srvsvc_s_NetShareAdd(void *arg, struct mlrpc_xaction *mxa) default: bzero(param, sizeof (struct mslm_NetShareAdd)); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (info2->shi2_netname == 0 || info2->shi2_path == 0) { bzero(param, sizeof (struct mslm_NetShareAdd)); param->status = NERR_NetNameNotFound; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (smb_shr_is_restricted((char *)info2->shi2_netname)) { bzero(param, sizeof (struct mslm_NetShareAdd)); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (info2->shi2_remark == 0) @@ -1229,13 +1268,13 @@ srvsvc_s_NetShareAdd(void *arg, struct mlrpc_xaction *mxa) param->status = parm_stat; param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } param->status = srvsvc_sa_add((char *)info2->shi2_netname, realpath, (char *)info2->shi2_remark); param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -1273,18 +1312,18 @@ srvsvc_estimate_objcnt(uint32_t prefmaxlen, uint32_t n_obj, uint32_t obj_size) * Level 502: level 2 + security descriptor. */ static int -srvsvc_s_NetShareEnum(void *arg, struct mlrpc_xaction *mxa) +srvsvc_s_NetShareEnum(void *arg, ndr_xa_t *mxa) { struct mslm_NetShareEnum *param = arg; struct mslm_infonres *infonres; srvsvc_enum_t se; DWORD status; - infonres = MLRPC_HEAP_NEW(mxa, struct mslm_infonres); + infonres = NDR_NEW(mxa, struct mslm_infonres); if (infonres == NULL) { bzero(param, sizeof (struct mslm_NetShareEnum)); param->status = ERROR_NOT_ENOUGH_MEMORY; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } infonres->entriesread = 0; @@ -1336,14 +1375,14 @@ srvsvc_s_NetShareEnum(void *arg, struct mlrpc_xaction *mxa) if (status != 0) { bzero(param, sizeof (struct mslm_NetShareEnum)); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (se.se_n_enum == 0) { if (param->resume_handle) *param->resume_handle = 0; param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (param->resume_handle && @@ -1358,7 +1397,7 @@ srvsvc_s_NetShareEnum(void *arg, struct mlrpc_xaction *mxa) param->totalentries = se.se_n_total; param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -1379,18 +1418,18 @@ srvsvc_s_NetShareEnum(void *arg, struct mlrpc_xaction *mxa) * place to resume. The resume_handle is similar to the readdir cookie. */ static int -srvsvc_s_NetShareEnumSticky(void *arg, struct mlrpc_xaction *mxa) +srvsvc_s_NetShareEnumSticky(void *arg, ndr_xa_t *mxa) { struct mslm_NetShareEnum *param = arg; struct mslm_infonres *infonres; srvsvc_enum_t se; DWORD status; - infonres = MLRPC_HEAP_NEW(mxa, struct mslm_infonres); + infonres = NDR_NEW(mxa, struct mslm_infonres); if (infonres == NULL) { bzero(param, sizeof (struct mslm_NetShareEnum)); param->status = ERROR_NOT_ENOUGH_MEMORY; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } infonres->entriesread = 0; @@ -1438,14 +1477,14 @@ srvsvc_s_NetShareEnumSticky(void *arg, struct mlrpc_xaction *mxa) if (status != ERROR_SUCCESS) { bzero(param, sizeof (struct mslm_NetShareEnum)); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (se.se_n_enum == 0) { if (param->resume_handle) *param->resume_handle = 0; param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (param->resume_handle && @@ -1460,14 +1499,14 @@ srvsvc_s_NetShareEnumSticky(void *arg, struct mlrpc_xaction *mxa) param->totalentries = se.se_n_total; param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* * NetShareEnum Level 0 */ static DWORD -mlsvc_NetShareEnumLevel0(struct mlrpc_xaction *mxa, +mlsvc_NetShareEnumLevel0(ndr_xa_t *mxa, struct mslm_infonres *infonres, srvsvc_enum_t *se, int sticky) { struct mslm_SHARE_INFO_0 *info0; @@ -1480,7 +1519,7 @@ mlsvc_NetShareEnumLevel0(struct mlrpc_xaction *mxa, if (se->se_n_enum == 0) return (ERROR_SUCCESS); - info0 = MLRPC_HEAP_NEWN(mxa, struct mslm_SHARE_INFO_0, se->se_n_enum); + info0 = NDR_NEWN(mxa, struct mslm_SHARE_INFO_0, se->se_n_enum); if (info0 == NULL) return (ERROR_NOT_ENOUGH_MEMORY); @@ -1527,7 +1566,7 @@ mlsvc_NetShareEnumLevel0(struct mlrpc_xaction *mxa, * NetShareEnum Level 1 */ static DWORD -mlsvc_NetShareEnumLevel1(struct mlrpc_xaction *mxa, +mlsvc_NetShareEnumLevel1(ndr_xa_t *mxa, struct mslm_infonres *infonres, srvsvc_enum_t *se, int sticky) { struct mslm_SHARE_INFO_1 *info1; @@ -1540,7 +1579,7 @@ mlsvc_NetShareEnumLevel1(struct mlrpc_xaction *mxa, if (se->se_n_enum == 0) return (ERROR_SUCCESS); - info1 = MLRPC_HEAP_NEWN(mxa, struct mslm_SHARE_INFO_1, se->se_n_enum); + info1 = NDR_NEWN(mxa, struct mslm_SHARE_INFO_1, se->se_n_enum); if (info1 == NULL) return (ERROR_NOT_ENOUGH_MEMORY); @@ -1587,7 +1626,7 @@ mlsvc_NetShareEnumLevel1(struct mlrpc_xaction *mxa, * NetShareEnum Level 2 */ static DWORD -mlsvc_NetShareEnumLevel2(struct mlrpc_xaction *mxa, +mlsvc_NetShareEnumLevel2(ndr_xa_t *mxa, struct mslm_infonres *infonres, srvsvc_enum_t *se, int sticky) { struct mslm_SHARE_INFO_2 *info2; @@ -1600,7 +1639,7 @@ mlsvc_NetShareEnumLevel2(struct mlrpc_xaction *mxa, if (se->se_n_enum == 0) return (ERROR_SUCCESS); - info2 = MLRPC_HEAP_NEWN(mxa, struct mslm_SHARE_INFO_2, se->se_n_enum); + info2 = NDR_NEWN(mxa, struct mslm_SHARE_INFO_2, se->se_n_enum); if (info2 == 0) return (ERROR_NOT_ENOUGH_MEMORY); @@ -1647,7 +1686,7 @@ mlsvc_NetShareEnumLevel2(struct mlrpc_xaction *mxa, * NetShareEnum Level 501 */ static DWORD -mlsvc_NetShareEnumLevel501(struct mlrpc_xaction *mxa, +mlsvc_NetShareEnumLevel501(ndr_xa_t *mxa, struct mslm_infonres *infonres, srvsvc_enum_t *se, int sticky) { struct mslm_SHARE_INFO_501 *info501; @@ -1660,7 +1699,7 @@ mlsvc_NetShareEnumLevel501(struct mlrpc_xaction *mxa, if (se->se_n_enum == 0) return (ERROR_SUCCESS); - info501 = MLRPC_HEAP_NEWN(mxa, struct mslm_SHARE_INFO_501, + info501 = NDR_NEWN(mxa, struct mslm_SHARE_INFO_501, se->se_n_enum); if (info501 == NULL) return (ERROR_NOT_ENOUGH_MEMORY); @@ -1708,7 +1747,7 @@ mlsvc_NetShareEnumLevel501(struct mlrpc_xaction *mxa, * NetShareEnum Level 502 */ static DWORD -mlsvc_NetShareEnumLevel502(struct mlrpc_xaction *mxa, +mlsvc_NetShareEnumLevel502(ndr_xa_t *mxa, struct mslm_infonres *infonres, srvsvc_enum_t *se, int sticky) { struct mslm_SHARE_INFO_502 *info502; @@ -1721,7 +1760,7 @@ mlsvc_NetShareEnumLevel502(struct mlrpc_xaction *mxa, if (se->se_n_enum == 0) return (ERROR_SUCCESS); - info502 = MLRPC_HEAP_NEWN(mxa, struct mslm_SHARE_INFO_502, + info502 = NDR_NEWN(mxa, struct mslm_SHARE_INFO_502, se->se_n_enum); if (info502 == NULL) return (ERROR_NOT_ENOUGH_MEMORY); @@ -1781,7 +1820,7 @@ mlsvc_NetShareEnumLevel502(struct mlrpc_xaction *mxa, * ERROR_INVALID_LEVEL */ static DWORD -mlsvc_NetShareEnumCommon(struct mlrpc_xaction *mxa, srvsvc_enum_t *se, +mlsvc_NetShareEnumCommon(ndr_xa_t *mxa, srvsvc_enum_t *se, smb_share_t *si, void *infop) { struct mslm_SHARE_INFO_0 *info0; @@ -1801,7 +1840,7 @@ mlsvc_NetShareEnumCommon(struct mlrpc_xaction *mxa, srvsvc_enum_t *se, case 0: info0 = (struct mslm_SHARE_INFO_0 *)infop; info0[i].shi0_netname - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, si->shr_name); + = (unsigned char *)NDR_STRDUP(mxa, si->shr_name); if (info0[i].shi0_netname == NULL) return (ERROR_NOT_ENOUGH_MEMORY); @@ -1810,10 +1849,10 @@ mlsvc_NetShareEnumCommon(struct mlrpc_xaction *mxa, srvsvc_enum_t *se, case 1: info1 = (struct mslm_SHARE_INFO_1 *)infop; info1[i].shi1_netname - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, si->shr_name); + = (unsigned char *)NDR_STRDUP(mxa, si->shr_name); info1[i].shi1_remark - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, shr_comment); + = (unsigned char *)NDR_STRDUP(mxa, shr_comment); info1[i].shi1_type = si->shr_type; @@ -1824,10 +1863,10 @@ mlsvc_NetShareEnumCommon(struct mlrpc_xaction *mxa, srvsvc_enum_t *se, case 2: info2 = (struct mslm_SHARE_INFO_2 *)infop; info2[i].shi2_netname - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, si->shr_name); + = (unsigned char *)NDR_STRDUP(mxa, si->shr_name); info2[i].shi2_remark - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, shr_comment); + = (unsigned char *)NDR_STRDUP(mxa, shr_comment); info2[i].shi2_path = (unsigned char *)srvsvc_share_mkpath(mxa, si->shr_path); @@ -1837,7 +1876,7 @@ mlsvc_NetShareEnumCommon(struct mlrpc_xaction *mxa, srvsvc_enum_t *se, info2[i].shi2_max_uses = SHI_USES_UNLIMITED; info2[i].shi2_current_uses = 0; info2[i].shi2_passwd - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, empty_string); + = (unsigned char *)NDR_STRDUP(mxa, empty_string); if (!info2[i].shi2_netname || !info2[i].shi2_remark || !info2[i].shi2_passwd || !info2[i].shi2_path) @@ -1848,10 +1887,10 @@ mlsvc_NetShareEnumCommon(struct mlrpc_xaction *mxa, srvsvc_enum_t *se, case 501: info501 = (struct mslm_SHARE_INFO_501 *)infop; info501[i].shi501_netname - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, si->shr_name); + = (unsigned char *)NDR_STRDUP(mxa, si->shr_name); info501[i].shi501_remark - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, shr_comment); + = (unsigned char *)NDR_STRDUP(mxa, shr_comment); info501[i].shi501_type = si->shr_type; info501[i].shi501_flags = 0; @@ -1863,10 +1902,10 @@ mlsvc_NetShareEnumCommon(struct mlrpc_xaction *mxa, srvsvc_enum_t *se, case 502: info502 = (struct mslm_SHARE_INFO_502 *)infop; info502[i].shi502_netname - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, si->shr_name); + = (unsigned char *)NDR_STRDUP(mxa, si->shr_name); info502[i].shi502_remark - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, shr_comment); + = (unsigned char *)NDR_STRDUP(mxa, shr_comment); info502[i].shi502_path = (unsigned char *)srvsvc_share_mkpath(mxa, si->shr_path); @@ -1876,7 +1915,7 @@ mlsvc_NetShareEnumCommon(struct mlrpc_xaction *mxa, srvsvc_enum_t *se, info502[i].shi502_max_uses = SHI_USES_UNLIMITED; info502[i].shi502_current_uses = 0; info502[i].shi502_passwd - = (unsigned char *)MLRPC_HEAP_STRSAVE(mxa, empty_string); + = (unsigned char *)NDR_STRDUP(mxa, empty_string); info502[i].shi502_reserved = 0; info502[i].shi502_security_descriptor = 0; @@ -1900,10 +1939,10 @@ mlsvc_NetShareEnumCommon(struct mlrpc_xaction *mxa, srvsvc_enum_t *se, * share to avoid duplicates. */ static boolean_t -srvsvc_add_autohome(struct mlrpc_xaction *mxa, srvsvc_enum_t *se, void *infop) +srvsvc_add_autohome(ndr_xa_t *mxa, srvsvc_enum_t *se, void *infop) { - smb_opipe_context_t *svc = &mxa->context->svc_ctx; - char *username = svc->oc_account; + smb_opipe_context_t *ctx = &mxa->pipe->np_ctx; + char *username = ctx->oc_account; smb_share_t si; DWORD status; @@ -1936,7 +1975,7 @@ srvsvc_add_autohome(struct mlrpc_xaction *mxa, srvsvc_enum_t *se, void *infop) * could be a null pointer if the heap allocation fails. */ static char * -srvsvc_share_mkpath(struct mlrpc_xaction *mxa, char *path) +srvsvc_share_mkpath(ndr_xa_t *mxa, char *path) { char tmpbuf[MAXPATHLEN]; char *p; @@ -1951,7 +1990,7 @@ srvsvc_share_mkpath(struct mlrpc_xaction *mxa, char *path) (void) snprintf(tmpbuf, MAXPATHLEN, "%c:/%s", 'B', p); (void) strsubst(tmpbuf, '/', '\\'); - return (MLRPC_HEAP_STRSAVE(mxa, tmpbuf)); + return (NDR_STRDUP(mxa, tmpbuf)); } /* @@ -1967,18 +2006,18 @@ srvsvc_share_mkpath(struct mlrpc_xaction *mxa, char *path) * Returns Win32 error codes. */ static int -srvsvc_s_NetShareDel(void *arg, struct mlrpc_xaction *mxa) +srvsvc_s_NetShareDel(void *arg, ndr_xa_t *mxa) { struct mslm_NetShareDel *param = arg; if (!ndr_is_poweruser(mxa) || smb_shr_is_restricted((char *)param->netname)) { param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } param->status = srvsvc_sa_delete((char *)param->netname); - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -1987,17 +2026,17 @@ srvsvc_s_NetShareDel(void *arg, struct mlrpc_xaction *mxa) * Get security descriptor of the requested file/folder * * Right now, just returns ERROR_ACCESS_DENIED, because we cannot - * get the requested SD here in MLRPC code. + * get the requested SD here in RPC code. */ /*ARGSUSED*/ static int -srvsvc_s_NetGetFileSecurity(void *arg, struct mlrpc_xaction *mxa) +srvsvc_s_NetGetFileSecurity(void *arg, ndr_xa_t *mxa) { struct mslm_NetGetFileSecurity *param = arg; param->length = 0; param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -2006,16 +2045,16 @@ srvsvc_s_NetGetFileSecurity(void *arg, struct mlrpc_xaction *mxa) * Set the given security descriptor for the requested file/folder * * Right now, just returns ERROR_ACCESS_DENIED, because we cannot - * set the requested SD here in MLRPC code. + * set the requested SD here in RPC code. */ /*ARGSUSED*/ static int -srvsvc_s_NetSetFileSecurity(void *arg, struct mlrpc_xaction *mxa) +srvsvc_s_NetSetFileSecurity(void *arg, ndr_xa_t *mxa) { struct mslm_NetSetFileSecurity *param = arg; param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -2125,7 +2164,7 @@ srvsvc_sa_delete(char *sharename) return (status); } -static mlrpc_stub_table_t srvsvc_stub_table[] = { +static ndr_stub_table_t srvsvc_stub_table[] = { { srvsvc_s_NetConnectEnum, SRVSVC_OPNUM_NetConnectEnum }, { srvsvc_s_NetFileEnum, SRVSVC_OPNUM_NetFileEnum }, { srvsvc_s_NetFileClose, SRVSVC_OPNUM_NetFileClose }, diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c index 9954278ba2..184d2ecdd7 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c @@ -33,7 +33,6 @@ #include <unistd.h> #include <netdb.h> #include <stdlib.h> - #include <sys/time.h> #include <sys/systm.h> @@ -41,12 +40,10 @@ #include <smbsrv/libsmbrdr.h> #include <smbsrv/libsmbns.h> #include <smbsrv/libmlsvc.h> - #include <smbsrv/smbinfo.h> -#include <smbsrv/lsalib.h> -#include <smbsrv/samlib.h> -#include <smbsrv/mlsvc_util.h> -#include <smbsrv/mlsvc.h> +#include <lsalib.h> +#include <samlib.h> +#include <smbsrv/netrauth.h> /* Domain join support (using MS-RPC) */ static boolean_t mlsvc_ntjoin_support = B_FALSE; @@ -111,7 +108,7 @@ mlsvc_lookup_name(char *account, smb_sid_t **sid, uint16_t *sid_type) if ((ainfo = mlsvc_alloc_user_info()) == NULL) return (NT_STATUS_NO_MEMORY); - status = lsa_lookup_name(NULL, account, *sid_type, ainfo); + status = lsa_lookup_name(account, *sid_type, ainfo); if (status == NT_STATUS_SUCCESS) { *sid = ainfo->user_sid; ainfo->user_sid = NULL; @@ -261,74 +258,6 @@ mlsvc_setadmin_user_info(smb_userinfo_t *user_info) } } -/* - * mlsvc_string_save - * - * This is a convenience function to prepare strings for an RPC call. - * An ms_string_t is set up with the appropriate lengths and str is - * set up to point to a copy of the original string on the heap. The - * macro MLRPC_HEAP_STRSAVE is an alias for mlrpc_heap_strsave, which - * extends the heap and copies the string into the new area. - */ -int -mlsvc_string_save(ms_string_t *ms, char *str, struct mlrpc_xaction *mxa) -{ - if (str == NULL) - return (0); - - ms->length = mts_wcequiv_strlen(str); - ms->allosize = ms->length + sizeof (mts_wchar_t); - - if ((ms->str = MLRPC_HEAP_STRSAVE(mxa, str)) == NULL) - return (0); - - return (1); -} - -/* - * mlsvc_sid_save - * - * Expand the heap and copy the sid into the new area. - * Returns a pointer to the copy of the sid on the heap. - */ -smb_sid_t * -mlsvc_sid_save(smb_sid_t *sid, struct mlrpc_xaction *mxa) -{ - smb_sid_t *heap_sid; - unsigned size; - - if (sid == NULL) - return (NULL); - - size = smb_sid_len(sid); - - if ((heap_sid = (smb_sid_t *)MLRPC_HEAP_MALLOC(mxa, size)) == NULL) - return (0); - - bcopy(sid, heap_sid, size); - return (heap_sid); -} - -/* - * mlsvc_is_null_handle - * - * Check a handle against a null handle. Returns 1 if the handle is - * null. Otherwise returns 0. - */ -int -mlsvc_is_null_handle(mlsvc_handle_t *handle) -{ - static ms_handle_t zero_handle; - - if (handle == NULL || handle->context == NULL) - return (1); - - if (!memcmp(&handle->handle, &zero_handle, sizeof (ms_handle_t))) - return (1); - - return (0); -} - DWORD mlsvc_netlogon(char *server, char *domain) { @@ -352,58 +281,40 @@ mlsvc_netlogon(char *server, char *domain) * Returns NT status codes. */ DWORD -mlsvc_join(char *server, char *domain, char *plain_user, char *plain_text) +mlsvc_join(smb_domain_t *dinfo, char *user, char *plain_text) { smb_auth_info_t auth; - smb_ntdomain_t *di; int erc; DWORD status; - char machine_passwd[MLSVC_MACHINE_ACCT_PASSWD_MAX]; - char fqdn[MAXHOSTNAMELEN]; + char machine_passwd[NETR_MACHINE_ACCT_PASSWD_MAX]; machine_passwd[0] = '\0'; /* * Ensure that the domain name is uppercase. */ - (void) utf8_strupr(domain); - - /* - * There is no point continuing if the domain information is - * not available. Wait for up to 10 seconds and then give up. - */ - if ((di = smb_getdomaininfo(10)) == 0) { - status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - return (status); - } - - if (strcasecmp(domain, di->domain) != 0) { - status = NT_STATUS_INVALID_PARAMETER; - return (status); - } + (void) utf8_strupr(dinfo->d_nbdomain); - erc = mlsvc_logon(server, domain, plain_user); + erc = mlsvc_logon(dinfo->d_dc, dinfo->d_nbdomain, user); if (erc == AUTH_USER_GRANT) { if (mlsvc_ntjoin_support == B_FALSE) { - if (smb_resolve_fqdn(domain, fqdn, MAXHOSTNAMELEN) != 1) - return (NT_STATUS_INVALID_PARAMETER); - if (smb_ads_join(fqdn, plain_user, plain_text, + if (smb_ads_join(dinfo->d_fqdomain, user, plain_text, machine_passwd, sizeof (machine_passwd)) == SMB_ADJOIN_SUCCESS) status = NT_STATUS_SUCCESS; else status = NT_STATUS_UNSUCCESSFUL; } else { - if (mlsvc_user_getauth(server, plain_user, &auth) + if (mlsvc_user_getauth(dinfo->d_dc, user, &auth) != 0) { status = NT_STATUS_INVALID_PARAMETER; return (status); } - status = sam_create_trust_account(server, domain, - &auth); + status = sam_create_trust_account(dinfo->d_dc, + dinfo->d_nbdomain, &auth); if (status == NT_STATUS_SUCCESS) { (void) smb_getnetbiosname(machine_passwd, sizeof (machine_passwd)); @@ -412,12 +323,12 @@ mlsvc_join(char *server, char *domain, char *plain_user, char *plain_text) } if (status == NT_STATUS_SUCCESS) { - erc = smb_setdomainprops(NULL, server, + erc = smb_setdomainprops(NULL, dinfo->d_dc, machine_passwd); if (erc != 0) return (NT_STATUS_UNSUCCESSFUL); - status = mlsvc_netlogon(server, domain); + status = mlsvc_netlogon(dinfo->d_dc, dinfo->d_nbdomain); } } else { status = NT_STATUS_LOGON_FAILURE; diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_winreg.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_winreg.c index fc1281ba13..c7715da298 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_winreg.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_winreg.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Windows Registry RPC (WINREG) server-side interface. * @@ -41,7 +39,7 @@ #include <smbsrv/ntstatus.h> #include <smbsrv/nterror.h> #include <smbsrv/nmpipes.h> -#include <smbsrv/mlsvc_util.h> +#include <smbsrv/libmlsvc.h> #include <smbsrv/ndl/winreg.ndl> /* @@ -78,28 +76,28 @@ static winreg_keylist_t winreg_keylist; static boolean_t winreg_key_has_subkey(const char *); static char *winreg_lookup_value(const char *); -static int winreg_s_OpenHK(void *, struct mlrpc_xaction *); -static int winreg_s_OpenHKLM(void *, struct mlrpc_xaction *); -static int winreg_s_OpenHKUsers(void *, struct mlrpc_xaction *); -static int winreg_s_Close(void *, struct mlrpc_xaction *); -static int winreg_s_CreateKey(void *, struct mlrpc_xaction *); -static int winreg_s_DeleteKey(void *, struct mlrpc_xaction *); -static int winreg_s_DeleteValue(void *, struct mlrpc_xaction *); -static int winreg_s_EnumKey(void *, struct mlrpc_xaction *); -static int winreg_s_EnumValue(void *, struct mlrpc_xaction *); -static int winreg_s_FlushKey(void *, struct mlrpc_xaction *); -static int winreg_s_GetKeySec(void *, struct mlrpc_xaction *); -static int winreg_s_NotifyChange(void *, struct mlrpc_xaction *); -static int winreg_s_OpenKey(void *, struct mlrpc_xaction *); -static int winreg_s_QueryKey(void *, struct mlrpc_xaction *); -static int winreg_s_QueryValue(void *, struct mlrpc_xaction *); -static int winreg_s_SetKeySec(void *, struct mlrpc_xaction *); -static int winreg_s_CreateValue(void *, struct mlrpc_xaction *); -static int winreg_s_Shutdown(void *, struct mlrpc_xaction *); -static int winreg_s_AbortShutdown(void *, struct mlrpc_xaction *); -static int winreg_s_GetVersion(void *, struct mlrpc_xaction *); - -static mlrpc_stub_table_t winreg_stub_table[] = { +static int winreg_s_OpenHK(void *, ndr_xa_t *); +static int winreg_s_OpenHKLM(void *, ndr_xa_t *); +static int winreg_s_OpenHKUsers(void *, ndr_xa_t *); +static int winreg_s_Close(void *, ndr_xa_t *); +static int winreg_s_CreateKey(void *, ndr_xa_t *); +static int winreg_s_DeleteKey(void *, ndr_xa_t *); +static int winreg_s_DeleteValue(void *, ndr_xa_t *); +static int winreg_s_EnumKey(void *, ndr_xa_t *); +static int winreg_s_EnumValue(void *, ndr_xa_t *); +static int winreg_s_FlushKey(void *, ndr_xa_t *); +static int winreg_s_GetKeySec(void *, ndr_xa_t *); +static int winreg_s_NotifyChange(void *, ndr_xa_t *); +static int winreg_s_OpenKey(void *, ndr_xa_t *); +static int winreg_s_QueryKey(void *, ndr_xa_t *); +static int winreg_s_QueryValue(void *, ndr_xa_t *); +static int winreg_s_SetKeySec(void *, ndr_xa_t *); +static int winreg_s_CreateValue(void *, ndr_xa_t *); +static int winreg_s_Shutdown(void *, ndr_xa_t *); +static int winreg_s_AbortShutdown(void *, ndr_xa_t *); +static int winreg_s_GetVersion(void *, ndr_xa_t *); + +static ndr_stub_table_t winreg_stub_table[] = { { winreg_s_OpenHK, WINREG_OPNUM_OpenHKCR }, { winreg_s_OpenHK, WINREG_OPNUM_OpenHKCU }, { winreg_s_OpenHKLM, WINREG_OPNUM_OpenHKLM }, @@ -129,13 +127,13 @@ static mlrpc_stub_table_t winreg_stub_table[] = { {0} }; -static mlrpc_service_t winreg_service = { +static ndr_service_t winreg_service = { "Winreg", /* name */ "Windows Registry", /* desc */ "\\winreg", /* endpoint */ PIPE_WINREG, /* sec_addr_port */ - "338cd001-2244-31f1-aaaa900038001003", 1, /* abstract */ - "8a885d04-1ceb-11c9-9fe808002b104860", 2, /* transfer */ + "338cd001-2244-31f1-aaaa-900038001003", 1, /* abstract */ + NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 0, /* no bind_instance_size */ 0, /* no bind_req() */ 0, /* no unbind_and_close() */ @@ -182,7 +180,7 @@ winreg_initialize(void) sysname = name.sysname; (void) strlcpy(winreg_sysname, sysname, SYS_NMLN); - (void) mlrpc_register_service(&winreg_service); + (void) ndr_svc_register(&winreg_service); } /* @@ -191,7 +189,7 @@ winreg_initialize(void) * Stub. */ static int -winreg_s_OpenHK(void *arg, struct mlrpc_xaction *mxa) +winreg_s_OpenHK(void *arg, ndr_xa_t *mxa) { struct winreg_OpenHKCR *param = arg; ndr_hdid_t *id; @@ -204,7 +202,7 @@ winreg_s_OpenHK(void *arg, struct mlrpc_xaction *mxa) param->status = ERROR_SUCCESS; } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -218,7 +216,7 @@ winreg_s_OpenHK(void *arg, struct mlrpc_xaction *mxa) * ERROR_ACCESS_DENIED Unable to allocate a handle. */ static int -winreg_s_OpenHKLM(void *arg, struct mlrpc_xaction *mxa) +winreg_s_OpenHKLM(void *arg, ndr_xa_t *mxa) { struct winreg_OpenHKLM *param = arg; ndr_hdid_t *id; @@ -231,7 +229,7 @@ winreg_s_OpenHKLM(void *arg, struct mlrpc_xaction *mxa) param->status = ERROR_SUCCESS; } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -243,7 +241,7 @@ winreg_s_OpenHKLM(void *arg, struct mlrpc_xaction *mxa) * seems okay with regedt32. */ static int -winreg_s_OpenHKUsers(void *arg, struct mlrpc_xaction *mxa) +winreg_s_OpenHKUsers(void *arg, ndr_xa_t *mxa) { struct winreg_OpenHKUsers *param = arg; ndr_hdid_t *id; @@ -256,7 +254,7 @@ winreg_s_OpenHKUsers(void *arg, struct mlrpc_xaction *mxa) param->status = ERROR_SUCCESS; } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -264,11 +262,11 @@ winreg_s_OpenHKUsers(void *arg, struct mlrpc_xaction *mxa) * * This is a request to close the WINREG interface specified by the * handle. We don't track handles (yet), so just zero out the handle - * and return MLRPC_DRC_OK. Setting the handle to zero appears to be + * and return NDR_DRC_OK. Setting the handle to zero appears to be * standard behaviour. */ static int -winreg_s_Close(void *arg, struct mlrpc_xaction *mxa) +winreg_s_Close(void *arg, ndr_xa_t *mxa) { struct winreg_Close *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -277,14 +275,14 @@ winreg_s_Close(void *arg, struct mlrpc_xaction *mxa) bzero(¶m->result_handle, sizeof (winreg_handle_t)); param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* * winreg_s_CreateKey */ static int -winreg_s_CreateKey(void *arg, struct mlrpc_xaction *mxa) +winreg_s_CreateKey(void *arg, ndr_xa_t *mxa) { struct winreg_CreateKey *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -298,20 +296,20 @@ winreg_s_CreateKey(void *arg, struct mlrpc_xaction *mxa) if (!ndr_is_admin(mxa) || (subkey == NULL)) { bzero(param, sizeof (struct winreg_CreateKey)); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } hd = ndr_hdlookup(mxa, id); if (hd == NULL) { bzero(param, sizeof (struct winreg_CreateKey)); param->status = ERROR_INVALID_HANDLE; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } - if ((action = MLRPC_HEAP_NEW(mxa, DWORD)) == NULL) { + if ((action = NDR_NEW(mxa, DWORD)) == NULL) { bzero(param, sizeof (struct winreg_CreateKey)); param->status = ERROR_NOT_ENOUGH_MEMORY; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (list_is_empty(&winreg_keylist.kl_list)) @@ -328,7 +326,7 @@ winreg_s_CreateKey(void *arg, struct mlrpc_xaction *mxa) *action = WINREG_ACTION_EXISTING_KEY; param->action = action; param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL); @@ -342,7 +340,7 @@ new_key: if ((id == NULL) || (key == NULL)) { bzero(param, sizeof (struct winreg_CreateKey)); param->status = ERROR_NOT_ENOUGH_MEMORY; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bcopy(id, &key->sk_handle, sizeof (ndr_hdid_t)); @@ -355,14 +353,14 @@ new_key: *action = WINREG_ACTION_NEW_KEY; param->action = action; param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* * winreg_s_DeleteKey */ static int -winreg_s_DeleteKey(void *arg, struct mlrpc_xaction *mxa) +winreg_s_DeleteKey(void *arg, ndr_xa_t *mxa) { struct winreg_DeleteKey *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -373,14 +371,14 @@ winreg_s_DeleteKey(void *arg, struct mlrpc_xaction *mxa) if (!ndr_is_admin(mxa) || (subkey == NULL)) { param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if ((ndr_hdlookup(mxa, id) == NULL) || list_is_empty(&winreg_keylist.kl_list) || winreg_key_has_subkey(subkey)) { param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } key = list_head(&winreg_keylist.kl_list); @@ -396,12 +394,12 @@ winreg_s_DeleteKey(void *arg, struct mlrpc_xaction *mxa) ndr_hdfree(mxa, &key->sk_handle); free(key); param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } static boolean_t @@ -435,19 +433,19 @@ winreg_key_has_subkey(const char *subkey) */ /*ARGSUSED*/ static int -winreg_s_DeleteValue(void *arg, struct mlrpc_xaction *mxa) +winreg_s_DeleteValue(void *arg, ndr_xa_t *mxa) { struct winreg_DeleteValue *param = arg; param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* * winreg_s_EnumKey */ static int -winreg_s_EnumKey(void *arg, struct mlrpc_xaction *mxa) +winreg_s_EnumKey(void *arg, ndr_xa_t *mxa) { struct winreg_EnumKey *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -455,19 +453,19 @@ winreg_s_EnumKey(void *arg, struct mlrpc_xaction *mxa) if (ndr_hdlookup(mxa, id) == NULL) { bzero(param, sizeof (struct winreg_EnumKey)); param->status = ERROR_NO_MORE_ITEMS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(param, sizeof (struct winreg_EnumKey)); param->status = ERROR_NO_MORE_ITEMS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* * winreg_s_EnumValue */ static int -winreg_s_EnumValue(void *arg, struct mlrpc_xaction *mxa) +winreg_s_EnumValue(void *arg, ndr_xa_t *mxa) { struct winreg_EnumValue *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -475,12 +473,12 @@ winreg_s_EnumValue(void *arg, struct mlrpc_xaction *mxa) if (ndr_hdlookup(mxa, id) == NULL) { bzero(param, sizeof (struct winreg_EnumValue)); param->status = ERROR_NO_MORE_ITEMS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(param, sizeof (struct winreg_EnumValue)); param->status = ERROR_NO_MORE_ITEMS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -489,7 +487,7 @@ winreg_s_EnumValue(void *arg, struct mlrpc_xaction *mxa) * Flush the attributes associated with the specified open key to disk. */ static int -winreg_s_FlushKey(void *arg, struct mlrpc_xaction *mxa) +winreg_s_FlushKey(void *arg, ndr_xa_t *mxa) { struct winreg_FlushKey *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -499,7 +497,7 @@ winreg_s_FlushKey(void *arg, struct mlrpc_xaction *mxa) else param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -507,20 +505,20 @@ winreg_s_FlushKey(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -winreg_s_GetKeySec(void *arg, struct mlrpc_xaction *mxa) +winreg_s_GetKeySec(void *arg, ndr_xa_t *mxa) { struct winreg_GetKeySec *param = arg; bzero(param, sizeof (struct winreg_GetKeySec)); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* * winreg_s_NotifyChange */ static int -winreg_s_NotifyChange(void *arg, struct mlrpc_xaction *mxa) +winreg_s_NotifyChange(void *arg, ndr_xa_t *mxa) { struct winreg_NotifyChange *param = arg; @@ -529,7 +527,7 @@ winreg_s_NotifyChange(void *arg, struct mlrpc_xaction *mxa) else param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -543,7 +541,7 @@ winreg_s_NotifyChange(void *arg, struct mlrpc_xaction *mxa) * ERROR_FILE_NOT_FOUND No key or unable to allocate a handle. */ static int -winreg_s_OpenKey(void *arg, struct mlrpc_xaction *mxa) +winreg_s_OpenKey(void *arg, ndr_xa_t *mxa) { struct winreg_OpenKey *param = arg; char *subkey = (char *)param->name.str; @@ -553,7 +551,7 @@ winreg_s_OpenKey(void *arg, struct mlrpc_xaction *mxa) if (list_is_empty(&winreg_keylist.kl_list)) { bzero(¶m->result_handle, sizeof (winreg_handle_t)); param->status = ERROR_FILE_NOT_FOUND; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } key = list_head(&winreg_keylist.kl_list); @@ -570,13 +568,13 @@ winreg_s_OpenKey(void *arg, struct mlrpc_xaction *mxa) bcopy(id, ¶m->result_handle, sizeof (winreg_handle_t)); param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL); bzero(¶m->result_handle, sizeof (winreg_handle_t)); param->status = ERROR_FILE_NOT_FOUND; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -584,7 +582,7 @@ winreg_s_OpenKey(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -winreg_s_QueryKey(void *arg, struct mlrpc_xaction *mxa) +winreg_s_QueryKey(void *arg, ndr_xa_t *mxa) { static char nullstr[2] = { 0, 0 }; struct winreg_QueryKey *param = arg; @@ -595,7 +593,7 @@ winreg_s_QueryKey(void *arg, struct mlrpc_xaction *mxa) param->name.allosize = 0; param->name.str = (unsigned char *)nullstr; param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -609,7 +607,7 @@ winreg_s_QueryKey(void *arg, struct mlrpc_xaction *mxa) * ERROR_CANTREAD No such name or memory problem. */ static int -winreg_s_QueryValue(void *arg, struct mlrpc_xaction *mxa) +winreg_s_QueryValue(void *arg, ndr_xa_t *mxa) { struct winreg_QueryValue *param = arg; struct winreg_value *pv; @@ -622,26 +620,26 @@ winreg_s_QueryValue(void *arg, struct mlrpc_xaction *mxa) if (strcasecmp(name, "PrimaryModule") == 0) { param->status = ERROR_FILE_NOT_FOUND; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if ((value = winreg_lookup_value(name)) == NULL) { param->status = ERROR_CANTREAD; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } slen = mts_wcequiv_strlen(value) + sizeof (mts_wchar_t); msize = sizeof (struct winreg_value) + slen; - param->value = (struct winreg_value *)MLRPC_HEAP_MALLOC(mxa, msize); - param->type = MLRPC_HEAP_NEW(mxa, DWORD); - param->value_size = MLRPC_HEAP_NEW(mxa, DWORD); - param->value_size_total = MLRPC_HEAP_NEW(mxa, DWORD); + param->value = (struct winreg_value *)NDR_MALLOC(mxa, msize); + param->type = NDR_NEW(mxa, DWORD); + param->value_size = NDR_NEW(mxa, DWORD); + param->value_size_total = NDR_NEW(mxa, DWORD); if (param->value == NULL || param->type == NULL || param->value_size == NULL || param->value_size_total == NULL) { param->status = ERROR_CANTREAD; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(param->value, msize); @@ -656,7 +654,7 @@ winreg_s_QueryValue(void *arg, struct mlrpc_xaction *mxa) *param->value_size_total = slen; param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -705,12 +703,12 @@ winreg_lookup_value(const char *name) */ /*ARGSUSED*/ static int -winreg_s_SetKeySec(void *arg, struct mlrpc_xaction *mxa) +winreg_s_SetKeySec(void *arg, ndr_xa_t *mxa) { struct winreg_SetKeySec *param = arg; param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -718,12 +716,12 @@ winreg_s_SetKeySec(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -winreg_s_CreateValue(void *arg, struct mlrpc_xaction *mxa) +winreg_s_CreateValue(void *arg, ndr_xa_t *mxa) { struct winreg_CreateValue *param = arg; param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -733,12 +731,12 @@ winreg_s_CreateValue(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -winreg_s_Shutdown(void *arg, struct mlrpc_xaction *mxa) +winreg_s_Shutdown(void *arg, ndr_xa_t *mxa) { struct winreg_Shutdown *param = arg; param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -747,7 +745,7 @@ winreg_s_Shutdown(void *arg, struct mlrpc_xaction *mxa) * Abort a shutdown request. */ static int -winreg_s_AbortShutdown(void *arg, struct mlrpc_xaction *mxa) +winreg_s_AbortShutdown(void *arg, ndr_xa_t *mxa) { struct winreg_AbortShutdown *param = arg; @@ -756,7 +754,7 @@ winreg_s_AbortShutdown(void *arg, struct mlrpc_xaction *mxa) else param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -768,11 +766,11 @@ winreg_s_AbortShutdown(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -winreg_s_GetVersion(void *arg, struct mlrpc_xaction *mxa) +winreg_s_GetVersion(void *arg, ndr_xa_t *mxa) { struct winreg_GetVersion *param = arg; param->version = 5; param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_wkssvc.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_wkssvc.c index a0ebb7b2cb..6306ddf4f1 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_wkssvc.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_wkssvc.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <netdb.h> #include <sys/types.h> #include <string.h> @@ -35,25 +33,24 @@ #include <smbsrv/nmpipes.h> #include <smbsrv/nterror.h> #include <smbsrv/lmerr.h> -#include <smbsrv/mlsvc_util.h> #include <smbsrv/ndl/srvsvc.ndl> -static int wkssvc_s_NetWkstaGetInfo(void *, struct mlrpc_xaction *); -static int wkssvc_s_NetWkstaTransportEnum(void *, struct mlrpc_xaction *); +static int wkssvc_s_NetWkstaGetInfo(void *, ndr_xa_t *); +static int wkssvc_s_NetWkstaTransportEnum(void *, ndr_xa_t *); -static mlrpc_stub_table_t wkssvc_stub_table[] = { +static ndr_stub_table_t wkssvc_stub_table[] = { { wkssvc_s_NetWkstaGetInfo, WKSSVC_OPNUM_NetWkstaGetInfo }, { wkssvc_s_NetWkstaTransportEnum, WKSSVC_OPNUM_NetWkstaTransportEnum }, {0} }; -static mlrpc_service_t wkssvc_service = { +static ndr_service_t wkssvc_service = { "Workstation", /* name (WKSSVC or WKSTA) */ "Workstation services", /* desc */ "\\wkssvc", /* endpoint */ PIPE_NTSVCS, /* sec_addr_port */ - "6bffd098-a112-3610-983346c3f87e345a", 1, /* abstract */ - "8a885d04-1ceb-11c9-9fe808002b104860", 2, /* transfer */ + "6bffd098-a112-3610-9833-46c3f87e345a", 1, /* abstract */ + NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 0, /* no bind_instance_size */ 0, /* no bind_req() */ 0, /* no unbind_and_close() */ @@ -65,14 +62,14 @@ static mlrpc_service_t wkssvc_service = { void wkssvc_initialize(void) { - (void) mlrpc_register_service(&wkssvc_service); + (void) ndr_svc_register(&wkssvc_service); } /* * WKSSVC NetWkstaGetInfo */ static int -wkssvc_s_NetWkstaGetInfo(void *arg, struct mlrpc_xaction *mxa) +wkssvc_s_NetWkstaGetInfo(void *arg, ndr_xa_t *mxa) { struct mslm_NetWkstaGetInfo *param = arg; mslm_NetWkstaGetInfo_rb *rb; @@ -85,17 +82,17 @@ wkssvc_s_NetWkstaGetInfo(void *arg, struct mlrpc_xaction *mxa) (void) smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN); - rb = MLRPC_HEAP_NEW(mxa, mslm_NetWkstaGetInfo_rb); + rb = NDR_NEW(mxa, mslm_NetWkstaGetInfo_rb); if ((rc = smb_getnetbiosname(hostname, MAXHOSTNAMELEN)) == 0) { - name = MLRPC_HEAP_STRSAVE(mxa, hostname); - domain = MLRPC_HEAP_STRSAVE(mxa, resource_domain); + name = NDR_STRDUP(mxa, hostname); + domain = NDR_STRDUP(mxa, resource_domain); } if ((rc != 0) || (rb == NULL) || (name == NULL) || (domain == NULL)) { bzero(param, sizeof (struct mslm_NetWkstaGetInfo)); param->status = ERROR_NOT_ENOUGH_MEMORY; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } param->result.level = param->level; @@ -161,14 +158,14 @@ wkssvc_s_NetWkstaGetInfo(void *arg, struct mlrpc_xaction *mxa) param->status = status; } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* * WKSSVC NetWkstaTransportEnum */ static int -wkssvc_s_NetWkstaTransportEnum(void *arg, struct mlrpc_xaction *mxa) +wkssvc_s_NetWkstaTransportEnum(void *arg, ndr_xa_t *mxa) { struct mslm_NetWkstaTransportEnum *param = arg; struct mslm_NetWkstaTransportCtr0 *info0; @@ -176,8 +173,8 @@ wkssvc_s_NetWkstaTransportEnum(void *arg, struct mlrpc_xaction *mxa) switch (param->info.level) { case 0: - info0 = MLRPC_HEAP_NEW(mxa, struct mslm_NetWkstaTransportCtr0); - ti0 = MLRPC_HEAP_NEW(mxa, struct mslm_NetWkstaTransportInfo0); + info0 = NDR_NEW(mxa, struct mslm_NetWkstaTransportCtr0); + ti0 = NDR_NEW(mxa, struct mslm_NetWkstaTransportInfo0); if (info0 == NULL || ti0 == NULL) { bzero(param, sizeof (struct mslm_NetWkstaGetInfo)); @@ -207,5 +204,5 @@ wkssvc_s_NetWkstaTransportEnum(void *arg, struct mlrpc_xaction *mxa) param->status = ERROR_INVALID_LEVEL; } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/msgsvc_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/msgsvc_svc.c new file mode 100644 index 0000000000..e630322c1f --- /dev/null +++ b/usr/src/lib/smbsrv/libmlsvc/common/msgsvc_svc.c @@ -0,0 +1,87 @@ +/* + * 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 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Message Service + */ + +#include <syslog.h> +#include <stdlib.h> + +#include <smbsrv/libsmb.h> +#include <smbsrv/libmlrpc.h> +#include <smbsrv/libmlsvc.h> +#include <smbsrv/ndl/msgsvc.ndl> +#include <smbsrv/nterror.h> +#include <smbsrv/smbinfo.h> +#include <smbsrv/nmpipes.h> + +static int msgsvcsend_NetrSendMessage(void *, ndr_xa_t *); + +static ndr_stub_table_t msgsvcsend_stub_table[] = { + { msgsvcsend_NetrSendMessage, MSGSVCSEND_OPNUM_NetrSendMessage }, + {0} +}; + +static ndr_service_t msgsvcsend_service = { + "MSGSVC", /* name */ + "Message Service", /* desc */ + "\\msgsvc", /* endpoint */ + PIPE_NTSVCS, /* sec_addr_port */ + "5a7b91f8-ff00-11d0-a9b200c04fb6e6fc", 0, /* abstract */ + NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ + 0, /* no bind_instance_size */ + 0, /* no bind_req() */ + 0, /* no unbind_and_close() */ + 0, /* use generic_call_stub() */ + &TYPEINFO(msgsvcsend_interface), /* interface ti */ + msgsvcsend_stub_table /* stub_table */ +}; + +void +msgsvcsend_initialize(void) +{ + (void) ndr_svc_register(&msgsvcsend_service); +} + +static int +msgsvcsend_NetrSendMessage(void *arg, ndr_xa_t *mxa) +{ + msgsvcsend_NetrSendMessage_t *param = arg; + + if (!ndr_is_admin(mxa)) { + param->status = ERROR_ACCESS_DENIED; + return (NDR_DRC_OK); + } + + if (param->from == NULL || param->to == NULL || param->text == NULL) { + param->status = ERROR_INVALID_PARAMETER; + return (NDR_DRC_OK); + } + + syslog(LOG_INFO, "%s to %s: %s", param->from, param->to, param->text); + param->status = ERROR_SUCCESS; + return (NDR_DRC_OK); +} diff --git a/usr/src/lib/smbsrv/libmlsvc/common/netdfs.c b/usr/src/lib/smbsrv/libmlsvc/common/netdfs.c index aad7e1bbd0..f127ec42d6 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/netdfs.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/netdfs.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Net DFS server side RPC service. */ @@ -38,7 +36,7 @@ #include <smbsrv/lmdfs.h> #include <smbsrv/nmpipes.h> #include <smbsrv/nterror.h> -#include <smbsrv/mlrpc.h> +#include <smbsrv/libmlrpc.h> #include <smbsrv/ndl/netdfs.ndl> typedef struct { @@ -48,22 +46,22 @@ typedef struct { char *buf; } netdfs_unc_t; -static int netdfs_unc_parse(struct mlrpc_xaction *, const char *, +static int netdfs_unc_parse(ndr_xa_t *, const char *, netdfs_unc_t *); -static int netdfs_s_getver(void *, struct mlrpc_xaction *); -static int netdfs_s_add(void *, struct mlrpc_xaction *); -static int netdfs_s_remove(void *, struct mlrpc_xaction *); -static int netdfs_s_setinfo(void *, struct mlrpc_xaction *); -static int netdfs_s_getinfo(void *, struct mlrpc_xaction *); -static int netdfs_s_enum(void *, struct mlrpc_xaction *); -static int netdfs_s_move(void *, struct mlrpc_xaction *); -static int netdfs_s_rename(void *, struct mlrpc_xaction *); -static int netdfs_s_addstdroot(void *, struct mlrpc_xaction *); -static int netdfs_s_remstdroot(void *, struct mlrpc_xaction *); -static int netdfs_s_enumex(void *, struct mlrpc_xaction *); - -static mlrpc_stub_table_t netdfs_stub_table[] = { +static int netdfs_s_getver(void *, ndr_xa_t *); +static int netdfs_s_add(void *, ndr_xa_t *); +static int netdfs_s_remove(void *, ndr_xa_t *); +static int netdfs_s_setinfo(void *, ndr_xa_t *); +static int netdfs_s_getinfo(void *, ndr_xa_t *); +static int netdfs_s_enum(void *, ndr_xa_t *); +static int netdfs_s_move(void *, ndr_xa_t *); +static int netdfs_s_rename(void *, ndr_xa_t *); +static int netdfs_s_addstdroot(void *, ndr_xa_t *); +static int netdfs_s_remstdroot(void *, ndr_xa_t *); +static int netdfs_s_enumex(void *, ndr_xa_t *); + +static ndr_stub_table_t netdfs_stub_table[] = { { netdfs_s_getver, NETDFS_OPNUM_GETVER }, { netdfs_s_add, NETDFS_OPNUM_ADD }, { netdfs_s_remove, NETDFS_OPNUM_REMOVE }, @@ -78,7 +76,7 @@ static mlrpc_stub_table_t netdfs_stub_table[] = { {0} }; -static mlrpc_service_t netdfs_service = { +static ndr_service_t netdfs_service = { "NETDFS", /* name */ "DFS", /* desc */ "\\dfs", /* endpoint */ @@ -103,7 +101,7 @@ static mlrpc_service_t netdfs_service = { void netdfs_initialize(void) { - (void) mlrpc_register_service(&netdfs_service); + (void) ndr_svc_register(&netdfs_service); } /* @@ -115,12 +113,12 @@ netdfs_initialize(void) */ /*ARGSUSED*/ static int -netdfs_s_getver(void *arg, struct mlrpc_xaction *mxa) +netdfs_s_getver(void *arg, ndr_xa_t *mxa) { struct netdfs_getver *param = arg; param->version = DFS_MANAGER_VERSION_W2K3; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -128,7 +126,7 @@ netdfs_s_getver(void *arg, struct mlrpc_xaction *mxa) * dfs_path. */ static int -netdfs_s_add(void *arg, struct mlrpc_xaction *mxa) +netdfs_s_add(void *arg, ndr_xa_t *mxa) { struct netdfs_add *param = arg; netdfs_unc_t unc; @@ -138,7 +136,7 @@ netdfs_s_add(void *arg, struct mlrpc_xaction *mxa) param->share == NULL) { bzero(param, sizeof (struct netdfs_add)); param->status = ERROR_INVALID_PARAMETER; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (netdfs_unc_parse(mxa, (char *)param->dfs_path, &unc) != 0) { @@ -154,12 +152,12 @@ netdfs_s_add(void *arg, struct mlrpc_xaction *mxa) if (param->status != ERROR_SUCCESS) { bzero(param, sizeof (struct netdfs_add)); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(param, sizeof (struct netdfs_add)); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -170,7 +168,7 @@ netdfs_s_add(void *arg, struct mlrpc_xaction *mxa) * the volume from the DFS. */ static int -netdfs_s_remove(void *arg, struct mlrpc_xaction *mxa) +netdfs_s_remove(void *arg, ndr_xa_t *mxa) { struct netdfs_remove *param = arg; netdfs_unc_t unc; @@ -180,7 +178,7 @@ netdfs_s_remove(void *arg, struct mlrpc_xaction *mxa) param->share == NULL) { bzero(param, sizeof (struct netdfs_remove)); param->status = ERROR_INVALID_PARAMETER; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (netdfs_unc_parse(mxa, (char *)param->dfs_path, &unc) != 0) { @@ -196,12 +194,12 @@ netdfs_s_remove(void *arg, struct mlrpc_xaction *mxa) if (param->status != ERROR_SUCCESS) { bzero(param, sizeof (struct netdfs_remove)); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(param, sizeof (struct netdfs_remove)); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -213,7 +211,7 @@ netdfs_s_remove(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -netdfs_s_setinfo(void *arg, struct mlrpc_xaction *mxa) +netdfs_s_setinfo(void *arg, ndr_xa_t *mxa) { struct netdfs_setinfo *param = arg; netdfs_unc_t unc; @@ -222,7 +220,7 @@ netdfs_s_setinfo(void *arg, struct mlrpc_xaction *mxa) if (param->dfs_path == NULL) { bzero(param, sizeof (struct netdfs_setinfo)); param->status = ERROR_INVALID_PARAMETER; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (netdfs_unc_parse(mxa, (char *)param->dfs_path, &unc) != 0) { @@ -235,7 +233,7 @@ netdfs_s_setinfo(void *arg, struct mlrpc_xaction *mxa) if (param->status != ERROR_SUCCESS) { bzero(param, sizeof (struct netdfs_setinfo)); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } switch (param->info.level) { @@ -247,12 +245,12 @@ netdfs_s_setinfo(void *arg, struct mlrpc_xaction *mxa) default: bzero(param, sizeof (struct netdfs_setinfo)); param->status = ERROR_INVALID_LEVEL; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(param, sizeof (struct netdfs_setinfo)); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -265,7 +263,7 @@ netdfs_s_setinfo(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -netdfs_s_getinfo(void *arg, struct mlrpc_xaction *mxa) +netdfs_s_getinfo(void *arg, ndr_xa_t *mxa) { struct netdfs_getinfo *param = arg; netdfs_unc_t unc; @@ -274,7 +272,7 @@ netdfs_s_getinfo(void *arg, struct mlrpc_xaction *mxa) if (param->dfs_path == NULL) { bzero(param, sizeof (struct netdfs_getinfo)); param->status = ERROR_INVALID_PARAMETER; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (netdfs_unc_parse(mxa, (char *)param->dfs_path, &unc) != 0) { @@ -287,7 +285,7 @@ netdfs_s_getinfo(void *arg, struct mlrpc_xaction *mxa) if (param->status != ERROR_SUCCESS) { bzero(param, sizeof (struct netdfs_getinfo)); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } switch (param->level) { @@ -305,12 +303,12 @@ netdfs_s_getinfo(void *arg, struct mlrpc_xaction *mxa) default: bzero(param, sizeof (struct netdfs_getinfo)); param->status = ERROR_INVALID_LEVEL; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(param, sizeof (struct netdfs_getinfo)); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -322,7 +320,7 @@ netdfs_s_getinfo(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -netdfs_s_enum(void *arg, struct mlrpc_xaction *mxa) +netdfs_s_enum(void *arg, ndr_xa_t *mxa) { struct netdfs_enum *param = arg; @@ -335,12 +333,12 @@ netdfs_s_enum(void *arg, struct mlrpc_xaction *mxa) default: (void) bzero(param, sizeof (struct netdfs_enum)); param->status = ERROR_INVALID_LEVEL; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } (void) bzero(param, sizeof (struct netdfs_enum)); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -349,19 +347,19 @@ netdfs_s_enum(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -netdfs_s_move(void *arg, struct mlrpc_xaction *mxa) +netdfs_s_move(void *arg, ndr_xa_t *mxa) { struct netdfs_move *param = arg; if (param->dfs_path == NULL || param->new_path == NULL) { bzero(param, sizeof (struct netdfs_move)); param->status = ERROR_INVALID_PARAMETER; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(param, sizeof (struct netdfs_move)); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -369,19 +367,19 @@ netdfs_s_move(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -netdfs_s_rename(void *arg, struct mlrpc_xaction *mxa) +netdfs_s_rename(void *arg, ndr_xa_t *mxa) { struct netdfs_rename *param = arg; if (param->dfs_path == NULL || param->new_path == NULL) { bzero(param, sizeof (struct netdfs_rename)); param->status = ERROR_INVALID_PARAMETER; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(param, sizeof (struct netdfs_rename)); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -389,13 +387,13 @@ netdfs_s_rename(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -netdfs_s_addstdroot(void *arg, struct mlrpc_xaction *mxa) +netdfs_s_addstdroot(void *arg, ndr_xa_t *mxa) { struct netdfs_addstdroot *param = arg; bzero(param, sizeof (struct netdfs_addstdroot)); param->status = ERROR_INVALID_PARAMETER; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -403,13 +401,13 @@ netdfs_s_addstdroot(void *arg, struct mlrpc_xaction *mxa) */ /*ARGSUSED*/ static int -netdfs_s_remstdroot(void *arg, struct mlrpc_xaction *mxa) +netdfs_s_remstdroot(void *arg, ndr_xa_t *mxa) { struct netdfs_remstdroot *param = arg; bzero(param, sizeof (struct netdfs_remstdroot)); param->status = ERROR_INVALID_PARAMETER; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -420,7 +418,7 @@ netdfs_s_remstdroot(void *arg, struct mlrpc_xaction *mxa) * Valid levels are 1-3, 300. */ static int -netdfs_s_enumex(void *arg, struct mlrpc_xaction *mxa) +netdfs_s_enumex(void *arg, ndr_xa_t *mxa) { struct netdfs_enumex *param = arg; netdfs_unc_t unc; @@ -429,11 +427,11 @@ netdfs_s_enumex(void *arg, struct mlrpc_xaction *mxa) if (param->dfs_path == NULL) { bzero(param, sizeof (struct netdfs_enumex)); param->status = ERROR_INVALID_PARAMETER; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } if (param->resume_handle == NULL) - param->resume_handle = MLRPC_HEAP_NEW(mxa, DWORD); + param->resume_handle = NDR_NEW(mxa, DWORD); if (param->resume_handle) *(param->resume_handle) = 0; @@ -451,19 +449,19 @@ netdfs_s_enumex(void *arg, struct mlrpc_xaction *mxa) if (param->status != ERROR_SUCCESS) { bzero(param, sizeof (struct netdfs_enumex)); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } - param->info = MLRPC_HEAP_NEW(mxa, struct netdfs_enum_info); + param->info = NDR_NEW(mxa, struct netdfs_enum_info); if (param->info == NULL) { bzero(param, sizeof (struct netdfs_enumex)); param->status = ERROR_NOT_ENOUGH_MEMORY; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(param->info, sizeof (struct netdfs_enumex)); param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -473,14 +471,14 @@ netdfs_s_enumex(void *arg, struct mlrpc_xaction *mxa) * Returns 0 on success, otherwise -1 to indicate an error. */ static int -netdfs_unc_parse(struct mlrpc_xaction *mxa, const char *path, netdfs_unc_t *unc) +netdfs_unc_parse(ndr_xa_t *mxa, const char *path, netdfs_unc_t *unc) { char *p; if (path == NULL || unc == NULL) return (-1); - if ((unc->buf = MLRPC_HEAP_STRSAVE(mxa, (char *)path)) == NULL) + if ((unc->buf = NDR_STRDUP(mxa, (char *)path)) == NULL) return (-1); if ((p = strchr(unc->buf, '\n')) != NULL) diff --git a/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c b/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c index edd680f59e..2d6ab90578 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c @@ -42,11 +42,10 @@ #include <smbsrv/libsmb.h> #include <smbsrv/libsmbrdr.h> #include <smbsrv/libsmbns.h> -#include <smbsrv/mlsvc_util.h> +#include <smbsrv/libmlsvc.h> #include <smbsrv/ndl/netlogon.ndl> #include <smbsrv/ntstatus.h> #include <smbsrv/smbinfo.h> -#include <smbsrv/mlsvc.h> #include <smbsrv/netrauth.h> #define NETR_SESSKEY_ZEROBUF_SZ 4 @@ -127,28 +126,11 @@ netlogon_auth(char *server, mlsvc_handle_t *netr_handle, DWORD flags) int netr_open(char *server, char *domain, mlsvc_handle_t *netr_handle) { - int fid; - int remote_os = 0; - int remote_lm = 0; - int server_pdc; char *user = smbrdr_ipc_get_user(); - if (mlsvc_logon(server, domain, user) != 0) + if (ndr_rpc_bind(netr_handle, server, domain, user, "NETR") < 0) return (-1); - fid = mlsvc_open_pipe(server, domain, user, "\\NETLOGON"); - if (fid < 0) - return (-1); - - if (mlsvc_rpc_bind(netr_handle, fid, "NETR") < 0) { - (void) mlsvc_close_pipe(fid); - return (-1); - } - - (void) mlsvc_session_native_values(fid, &remote_os, &remote_lm, - &server_pdc); - netr_handle->context->server_os = remote_os; - netr_handle->context->server_pdc = server_pdc; return (0); } @@ -160,8 +142,7 @@ netr_open(char *server, char *domain, mlsvc_handle_t *netr_handle) int netr_close(mlsvc_handle_t *netr_handle) { - (void) mlsvc_close_pipe(netr_handle->context->fid); - free(netr_handle->context); + ndr_rpc_unbind(netr_handle); return (0); } @@ -172,9 +153,7 @@ static int netr_server_req_challenge(mlsvc_handle_t *netr_handle, netr_info_t *netr_info) { struct netr_ServerReqChallenge arg; - mlrpc_heapref_t heap; int opnum; - int rc; bzero(&arg, sizeof (struct netr_ServerReqChallenge)); opnum = NETR_OPNUM_ServerReqChallenge; @@ -185,21 +164,20 @@ netr_server_req_challenge(mlsvc_handle_t *netr_handle, netr_info_t *netr_info) (void) memcpy(&arg.client_challenge, &netr_info->client_challenge, sizeof (struct netr_credential)); - (void) mlsvc_rpc_init(&heap); - rc = mlsvc_rpc_call(netr_handle->context, opnum, &arg, &heap); - if (rc == 0) { - if (arg.status != 0) { - mlsvc_rpc_report_status(opnum, arg.status); - rc = -1; - } else { - (void) memcpy(&netr_info->server_challenge, - &arg.server_challenge, - sizeof (struct netr_credential)); - } + if (ndr_rpc_call(netr_handle, opnum, &arg) != 0) + return (-1); + + if (arg.status != 0) { + ndr_rpc_status(netr_handle, opnum, arg.status); + ndr_rpc_release(netr_handle); + return (-1); } - mlsvc_rpc_free(netr_handle->context, &heap); - return (rc); + (void) memcpy(&netr_info->server_challenge, &arg.server_challenge, + sizeof (struct netr_credential)); + + ndr_rpc_release(netr_handle); + return (0); } /* @@ -209,7 +187,6 @@ static int netr_server_authenticate2(mlsvc_handle_t *netr_handle, netr_info_t *netr_info) { struct netr_ServerAuthenticate2 arg; - mlrpc_heapref_t heap; int opnum; int rc; char account_name[NETBIOS_NAME_SZ * 2]; @@ -229,7 +206,7 @@ netr_server_authenticate2(mlsvc_handle_t *netr_handle, netr_info_t *netr_info) arg.hostname = (unsigned char *)netr_info->hostname; arg.negotiate_flags = NETR_NEGOTIATE_BASE_FLAGS; - if (netr_handle->context->server_os != NATIVE_OS_WINNT) { + if (ndr_rpc_server_os(netr_handle) != NATIVE_OS_WINNT) { arg.negotiate_flags |= NETR_NEGOTIATE_STRONGKEY_FLAG; if (netr_gen_skey128(netr_info) != SMBAUTH_SUCCESS) return (-1); @@ -253,21 +230,19 @@ netr_server_authenticate2(mlsvc_handle_t *netr_handle, netr_info_t *netr_info) (void) memcpy(&arg.client_credential, &netr_info->client_credential, sizeof (struct netr_credential)); - (void) mlsvc_rpc_init(&heap); - - rc = mlsvc_rpc_call(netr_handle->context, opnum, &arg, &heap); - if (rc == 0) { - if (arg.status != 0) { - mlsvc_rpc_report_status(opnum, arg.status); - rc = -1; - } else { - rc = memcmp(&netr_info->server_credential, - &arg.server_credential, - sizeof (struct netr_credential)); - } + if (ndr_rpc_call(netr_handle, opnum, &arg) != 0) + return (-1); + + if (arg.status != 0) { + ndr_rpc_status(netr_handle, opnum, arg.status); + ndr_rpc_release(netr_handle); + return (-1); } - mlsvc_rpc_free(netr_handle->context, &heap); + rc = memcmp(&netr_info->server_credential, &arg.server_credential, + sizeof (struct netr_credential)); + + ndr_rpc_release(netr_handle); return (rc); } @@ -502,9 +477,7 @@ int netr_server_password_set(mlsvc_handle_t *netr_handle, netr_info_t *netr_info) { struct netr_PasswordSet arg; - mlrpc_heapref_t heap; int opnum; - int rc; BYTE new_password[NETR_OWF_PASSWORD_SZ]; char account_name[NETBIOS_NAME_SZ * 2]; @@ -538,11 +511,12 @@ netr_server_password_set(mlsvc_handle_t *netr_handle, netr_info_t *netr_info) (void) memcpy(&arg.uas_new_password, &new_password, NETR_OWF_PASSWORD_SZ); - (void) mlsvc_rpc_init(&heap); - rc = mlsvc_rpc_call(netr_handle->context, opnum, &arg, &heap); - if ((rc != 0) || (arg.status != 0)) { - mlsvc_rpc_report_status(opnum, arg.status); - mlsvc_rpc_free(netr_handle->context, &heap); + if (ndr_rpc_call(netr_handle, opnum, &arg) != 0) + return (-1); + + if (arg.status != 0) { + ndr_rpc_status(netr_handle, opnum, arg.status); + ndr_rpc_release(netr_handle); return (-1); } @@ -564,7 +538,7 @@ netr_server_password_set(mlsvc_handle_t *netr_handle, netr_info_t *netr_info) NETR_OWF_PASSWORD_SZ); } - mlsvc_rpc_free(netr_handle->context, &heap); + ndr_rpc_release(netr_handle); return (0); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c index 3ca1e44a7c..6169714d69 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c @@ -34,34 +34,28 @@ #include <alloca.h> #include <unistd.h> #include <netdb.h> +#include <thread.h> #include <smbsrv/libsmb.h> #include <smbsrv/libsmbrdr.h> +#include <smbsrv/libmlrpc.h> +#include <smbsrv/libmlsvc.h> #include <smbsrv/ndl/netlogon.ndl> -#include <smbsrv/mlsvc_util.h> -#include <smbsrv/mlsvc.h> #include <smbsrv/netrauth.h> #include <smbsrv/ntstatus.h> #include <smbsrv/smbinfo.h> -#include <smbsrv/mlrpc.h> #include <smbsrv/smb_token.h> +#include <mlsvc.h> -extern int netr_open(char *server, char *domain, mlsvc_handle_t *netr_handle); -extern int netr_close(mlsvc_handle_t *netr_handle); -extern DWORD netlogon_auth(char *server, mlsvc_handle_t *netr_handle, - DWORD flags); -extern int netr_setup_authenticator(netr_info_t *, struct netr_authenticator *, - struct netr_authenticator *); -extern DWORD netr_validate_chain(netr_info_t *, struct netr_authenticator *); - +static DWORD netlogon_logon_private(netr_client_t *, smb_userinfo_t *); static DWORD netr_server_samlogon(mlsvc_handle_t *, netr_info_t *, char *, netr_client_t *, smb_userinfo_t *); static void netr_invalidate_chain(void); static void netr_interactive_samlogon(netr_info_t *, netr_client_t *, struct netr_logon_info1 *); -static void netr_network_samlogon(mlrpc_heap_t *, netr_info_t *, +static void netr_network_samlogon(ndr_heap_t *, netr_info_t *, netr_client_t *, struct netr_logon_info2 *); -static void netr_setup_identity(mlrpc_heap_t *, netr_client_t *, +static void netr_setup_identity(ndr_heap_t *, netr_client_t *, netr_logon_id_t *); /* @@ -69,6 +63,8 @@ static void netr_setup_identity(mlrpc_heap_t *, netr_client_t *, */ extern netr_info_t netr_global_info; +static mutex_t netlogon_logon_mutex; + /* * netlogon_logon * @@ -87,19 +83,32 @@ extern netr_info_t netr_global_info; DWORD netlogon_logon(netr_client_t *clnt, smb_userinfo_t *user_info) { + DWORD status; + + (void) mutex_lock(&netlogon_logon_mutex); + + status = netlogon_logon_private(clnt, user_info); + + (void) mutex_unlock(&netlogon_logon_mutex); + return (status); +} + +static DWORD +netlogon_logon_private(netr_client_t *clnt, smb_userinfo_t *user_info) +{ char resource_domain[SMB_PI_MAX_DOMAIN]; char server[NETBIOS_NAME_SZ * 2]; mlsvc_handle_t netr_handle; - smb_ntdomain_t *di; + smb_domain_t di; DWORD status; int retries = 0, server_changed = 0; (void) smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN); - if ((di = smb_getdomaininfo(0)) == NULL) + if (!smb_domain_getinfo(&di)) return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); - if ((mlsvc_echo(di->server)) < 0) { + if ((mlsvc_echo(di.d_dc)) < 0) { /* * We had a session to the DC but it's not responding. * So drop the credential chain. @@ -109,13 +118,13 @@ netlogon_logon(netr_client_t *clnt, smb_userinfo_t *user_info) } do { - status = netr_open(di->server, di->domain, &netr_handle); + status = netr_open(di.d_dc, di.d_nbdomain, &netr_handle); if (status != 0) return (status); - if (di->server && (*netr_global_info.server != '\0')) { + if (di.d_dc && (*netr_global_info.server != '\0')) { (void) snprintf(server, sizeof (server), - "\\\\%s", di->server); + "\\\\%s", di.d_dc); server_changed = strncasecmp(netr_global_info.server, server, strlen(server)); } @@ -123,7 +132,7 @@ netlogon_logon(netr_client_t *clnt, smb_userinfo_t *user_info) if (server_changed || (netr_global_info.flags & NETR_FLG_VALID) == 0 || !smb_match_netlogon_seqnum()) { - status = netlogon_auth(di->server, &netr_handle, + status = netlogon_auth(di.d_dc, &netr_handle, NETR_FLG_NULL); if (status != 0) { @@ -135,7 +144,7 @@ netlogon_logon(netr_client_t *clnt, smb_userinfo_t *user_info) } status = netr_server_samlogon(&netr_handle, - &netr_global_info, di->server, clnt, user_info); + &netr_global_info, di.d_dc, clnt, user_info); (void) netr_close(&netr_handle); } while (status == NT_STATUS_INSUFFICIENT_LOGON_INFO && retries++ < 3); @@ -269,32 +278,35 @@ netr_server_samlogon(mlsvc_handle_t *netr_handle, netr_info_t *netr_info, struct netr_logon_info1 info1; struct netr_logon_info2 info2; struct netr_validation_info3 *info3; - mlrpc_heapref_t heap; + ndr_heap_t *heap; int opnum; int rc, len; DWORD status; bzero(&arg, sizeof (struct netr_SamLogon)); opnum = NETR_OPNUM_SamLogon; - (void) mlsvc_rpc_init(&heap); /* * Should we get the server and hostname from netr_info? */ + len = strlen(server) + 4; - arg.servername = alloca(len); - (void) snprintf((char *)arg.servername, len, "\\\\%s", server); + arg.servername = ndr_rpc_malloc(netr_handle, len); + arg.hostname = ndr_rpc_malloc(netr_handle, NETBIOS_NAME_SZ); + if (arg.servername == NULL || arg.hostname == NULL) { + ndr_rpc_release(netr_handle); + return (NT_STATUS_INTERNAL_ERROR); + } - arg.hostname = alloca(NETBIOS_NAME_SZ); - rc = smb_getnetbiosname((char *)arg.hostname, NETBIOS_NAME_SZ); - if (rc != 0) { - mlrpc_heap_destroy(heap.heap); + (void) snprintf((char *)arg.servername, len, "\\\\%s", server); + if (smb_getnetbiosname((char *)arg.hostname, NETBIOS_NAME_SZ) != 0) { + ndr_rpc_release(netr_handle); return (NT_STATUS_INTERNAL_ERROR); } rc = netr_setup_authenticator(netr_info, &auth, &ret_auth); if (rc != SMBAUTH_SUCCESS) { - mlrpc_heap_destroy(heap.heap); + ndr_rpc_release(netr_handle); return (NT_STATUS_INTERNAL_ERROR); } @@ -304,25 +316,27 @@ netr_server_samlogon(mlsvc_handle_t *netr_handle, netr_info_t *netr_info, arg.logon_info.logon_level = clnt->logon_level; arg.logon_info.switch_value = clnt->logon_level; + heap = ndr_rpc_get_heap(netr_handle); + switch (clnt->logon_level) { case NETR_INTERACTIVE_LOGON: - netr_setup_identity(heap.heap, clnt, &info1.identity); + netr_setup_identity(heap, clnt, &info1.identity); netr_interactive_samlogon(netr_info, clnt, &info1); arg.logon_info.ru.info1 = &info1; break; case NETR_NETWORK_LOGON: - netr_setup_identity(heap.heap, clnt, &info2.identity); - netr_network_samlogon(heap.heap, netr_info, clnt, &info2); + netr_setup_identity(heap, clnt, &info2.identity); + netr_network_samlogon(heap, netr_info, clnt, &info2); arg.logon_info.ru.info2 = &info2; break; default: - mlrpc_heap_destroy(heap.heap); + ndr_rpc_release(netr_handle); return (NT_STATUS_INVALID_PARAMETER); } - rc = mlsvc_rpc_call(netr_handle->context, opnum, &arg, &heap); + rc = ndr_rpc_call(netr_handle, opnum, &arg); if (rc != 0) { bzero(netr_info, sizeof (netr_info_t)); status = NT_STATUS_INVALID_PARAMETER; @@ -340,7 +354,7 @@ netr_server_samlogon(mlsvc_handle_t *netr_handle, netr_info_t *netr_info, } else { status = netr_validate_chain(netr_info, arg.ret_auth); if (status == NT_STATUS_INSUFFICIENT_LOGON_INFO) { - mlsvc_rpc_free(netr_handle->context, &heap); + ndr_rpc_release(netr_handle); return (status); } @@ -348,7 +362,7 @@ netr_server_samlogon(mlsvc_handle_t *netr_handle, netr_info_t *netr_info, status = netr_setup_userinfo(info3, user_info, clnt, netr_info); } - mlsvc_rpc_free(netr_handle->context, &heap); + ndr_rpc_release(netr_handle); return (status); } @@ -392,7 +406,7 @@ netr_interactive_samlogon(netr_info_t *netr_info, netr_client_t *clnt, */ /*ARGSUSED*/ static void -netr_network_samlogon(mlrpc_heap_t *heap, netr_info_t *netr_info, +netr_network_samlogon(ndr_heap_t *heap, netr_info_t *netr_info, netr_client_t *clnt, struct netr_logon_info2 *info2) { uint32_t len; @@ -401,15 +415,15 @@ netr_network_samlogon(mlrpc_heap_t *heap, netr_info_t *netr_info, 8); if ((len = clnt->nt_password.nt_password_len) != 0) { - mlrpc_heap_mkvcb(heap, clnt->nt_password.nt_password_val, len, - (mlrpc_vcbuf_t *)&info2->nt_response); + ndr_heap_mkvcb(heap, clnt->nt_password.nt_password_val, len, + (ndr_vcbuf_t *)&info2->nt_response); } else { bzero(&info2->nt_response, sizeof (netr_vcbuf_t)); } if ((len = clnt->lm_password.lm_password_len) != 0) { - mlrpc_heap_mkvcb(heap, clnt->lm_password.lm_password_val, len, - (mlrpc_vcbuf_t *)&info2->lm_response); + ndr_heap_mkvcb(heap, clnt->lm_password.lm_password_val, len, + (ndr_vcbuf_t *)&info2->lm_response); } else { bzero(&info2->lm_response, sizeof (netr_vcbuf_t)); } @@ -541,10 +555,13 @@ netr_invalidate_chain(void) * Increment it before each use. */ static void -netr_setup_identity(mlrpc_heap_t *heap, netr_client_t *clnt, +netr_setup_identity(ndr_heap_t *heap, netr_client_t *clnt, netr_logon_id_t *identity) { - static DWORD logon_id; + static mutex_t logon_id_mutex; + static uint32_t logon_id; + + (void) mutex_lock(&logon_id_mutex); if (logon_id == 0) logon_id = 0xDCD0; @@ -552,21 +569,23 @@ netr_setup_identity(mlrpc_heap_t *heap, netr_client_t *clnt, ++logon_id; clnt->logon_id = logon_id; + (void) mutex_unlock(&logon_id_mutex); + identity->parameter_control = 0; identity->logon_id.LowPart = logon_id; identity->logon_id.HighPart = 0; - mlrpc_heap_mkvcs(heap, clnt->domain, - (mlrpc_vcstr_t *)&identity->domain_name); + ndr_heap_mkvcs(heap, clnt->domain, + (ndr_vcstr_t *)&identity->domain_name); - mlrpc_heap_mkvcs(heap, clnt->username, - (mlrpc_vcstr_t *)&identity->username); + ndr_heap_mkvcs(heap, clnt->username, + (ndr_vcstr_t *)&identity->username); /* * Some systems prefix the client workstation name with \\. * It doesn't seem to make any difference whether it's there * or not. */ - mlrpc_heap_mkvcs(heap, clnt->workstation, - (mlrpc_vcstr_t *)&identity->workstation); + ndr_heap_mkvcs(heap, clnt->workstation, + (ndr_vcstr_t *)&identity->workstation); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samlib.c b/usr/src/lib/smbsrv/libmlsvc/common/samlib.c index fc4898ba21..3d76c7eddc 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/samlib.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/samlib.c @@ -38,8 +38,8 @@ #include <smbsrv/ntstatus.h> #include <smbsrv/ntaccess.h> -#include <smbsrv/lsalib.h> -#include <smbsrv/samlib.h> +#include <lsalib.h> +#include <samlib.h> /* * Valid values for the OEM OWF password encryption. @@ -49,6 +49,9 @@ extern DWORD samr_set_user_info(mlsvc_handle_t *, smb_auth_info_t *); +static struct samr_sid *sam_get_domain_sid(mlsvc_handle_t *, char *, char *, + smb_userinfo_t *); + /* * sam_create_trust_account * @@ -132,36 +135,7 @@ sam_create_account(char *server, char *domain_name, char *account_name, return (status); } - if (samr_handle.context->server_os == NATIVE_OS_WIN2000) { - nt_domain_t *ntdp; - - if ((ntdp = nt_domain_lookup_name(domain_name)) == 0) { - (void) lsa_query_account_domain_info(); - if ((ntdp = nt_domain_lookup_name(domain_name)) == 0) { - (void) samr_close_handle(&samr_handle); - status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - smb_tracef("SamCreateAccount[%s\\%s]: %s", - domain_name, account_name, - xlate_nt_status(status)); - mlsvc_free_user_info(user_info); - return (status); - } - } - - sid = (struct samr_sid *)ntdp->sid; - } else { - if (samr_lookup_domain(&samr_handle, - domain_name, user_info) != 0) { - (void) samr_close_handle(&samr_handle); - smb_tracef("SamCreateAccount[%s]: lookup failed", - account_name); - - mlsvc_free_user_info(user_info); - return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); - } - - sid = (struct samr_sid *)user_info->domain_sid; - } + sid = sam_get_domain_sid(&samr_handle, server, domain_name, user_info); status = samr_open_domain(&samr_handle, SAM_DOMAIN_CREATE_ACCOUNT, sid, &domain_handle); @@ -191,6 +165,7 @@ sam_create_account(char *server, char *domain_name, char *account_name, (void) samr_close_handle(&samr_handle); mlsvc_free_user_info(user_info); + free(sid); return (status); } @@ -248,29 +223,7 @@ sam_delete_account(char *server, char *domain_name, char *account_name) return (NT_STATUS_OPEN_FAILED); } - if (samr_handle.context->server_os == NATIVE_OS_WIN2000) { - nt_domain_t *ntdp; - - if ((ntdp = nt_domain_lookup_name(domain_name)) == 0) { - (void) lsa_query_account_domain_info(); - if ((ntdp = nt_domain_lookup_name(domain_name)) == 0) { - - (void) samr_close_handle(&samr_handle); - return (NT_STATUS_NO_SUCH_DOMAIN); - } - } - - sid = (struct samr_sid *)ntdp->sid; - } else { - if (samr_lookup_domain( - &samr_handle, domain_name, user_info) != 0) { - (void) samr_close_handle(&samr_handle); - mlsvc_free_user_info(user_info); - return (NT_STATUS_NO_SUCH_DOMAIN); - } - - sid = (struct samr_sid *)user_info->domain_sid; - } + sid = sam_get_domain_sid(&samr_handle, server, domain_name, user_info); status = samr_open_domain(&samr_handle, SAM_LOOKUP_INFORMATION, sid, &domain_handle); @@ -296,6 +249,7 @@ sam_delete_account(char *server, char *domain_name, char *account_name) (void) samr_close_handle(&samr_handle); mlsvc_free_user_info(user_info); + free(sid); return (status); } @@ -331,28 +285,7 @@ sam_check_user(char *server, char *domain_name, char *account_name) return (NT_STATUS_OPEN_FAILED); } - if (samr_handle.context->server_os == NATIVE_OS_WIN2000) { - nt_domain_t *ntdp; - - if ((ntdp = nt_domain_lookup_name(domain_name)) == 0) { - (void) lsa_query_account_domain_info(); - if ((ntdp = nt_domain_lookup_name(domain_name)) == 0) { - (void) samr_close_handle(&samr_handle); - return (NT_STATUS_NO_SUCH_DOMAIN); - } - } - - sid = (struct samr_sid *)ntdp->sid; - } else { - if (samr_lookup_domain(&samr_handle, domain_name, user_info) - != 0) { - (void) samr_close_handle(&samr_handle); - mlsvc_free_user_info(user_info); - return (NT_STATUS_NO_SUCH_DOMAIN); - } - - sid = (struct samr_sid *)user_info->domain_sid; - } + sid = sam_get_domain_sid(&samr_handle, server, domain_name, user_info); status = samr_open_domain(&samr_handle, SAM_LOOKUP_INFORMATION, sid, &domain_handle); @@ -384,6 +317,7 @@ sam_check_user(char *server, char *domain_name, char *account_name) (void) samr_close_handle(&samr_handle); mlsvc_free_user_info(user_info); + free(sid); return (status); } @@ -479,7 +413,8 @@ sam_get_local_domains(char *server, char *domain_name) * * Generate an OEM password. */ -int sam_oem_password(oem_password_t *oem_password, unsigned char *new_password, +int +sam_oem_password(oem_password_t *oem_password, unsigned char *new_password, unsigned char *old_password) { mts_wchar_t *unicode_password; @@ -504,3 +439,34 @@ int sam_oem_password(oem_password_t *oem_password, unsigned char *new_password, return (0); } + +static struct samr_sid * +sam_get_domain_sid(mlsvc_handle_t *samr_handle, char *server, char *domain_name, + smb_userinfo_t *user_info) +{ + struct samr_sid *sid; + + if (ndr_rpc_server_os(samr_handle) == NATIVE_OS_WIN2000) { + nt_domain_t *ntdp; + lsa_info_t account_domain; + + if ((ntdp = nt_domain_lookup_name(domain_name)) == 0) { + if (lsa_query_account_domain_info(server, + domain_name, &account_domain) != NT_STATUS_SUCCESS) + return (NULL); + + sid = (struct samr_sid *) + account_domain.i_domain.di_account.n_sid; + } else { + sid = (struct samr_sid *)smb_sid_dup(ntdp->sid); + } + } else { + if (samr_lookup_domain(samr_handle, domain_name, user_info) + != 0) + return (NULL); + + sid = (struct samr_sid *)smb_sid_dup(user_info->domain_sid); + } + + return (sid); +} diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samlib.h b/usr/src/lib/smbsrv/libmlsvc/common/samlib.h new file mode 100644 index 0000000000..c719a53925 --- /dev/null +++ b/usr/src/lib/smbsrv/libmlsvc/common/samlib.h @@ -0,0 +1,173 @@ +/* + * 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 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SMBSRV_SAMLIB_H +#define _SMBSRV_SAMLIB_H + +/* + * Prototypes for the SAM library and RPC client side library interface. + * There are two levels of interface defined here: sam_xxx and samr_xxx. + * The sam_xxx functions provide a high level interface which make + * multiple RPC calls and do all the work necessary to obtain and return + * the requested information. The samr_xxx functions provide a low level + * interface in which each function maps to a single underlying RPC. + */ + +#include <smbsrv/ndl/samrpc.ndl> + + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Account Control Flags + * Use in SAMR Query Display Information RPC + */ +#define ACF_DISABLED 0x001 /* account disable */ +#define ACF_HOMEDIRREQ 0x002 /* home dir required */ +#define ACF_PWDNOTREQ 0x004 /* password not required */ +#define ACF_TEMPDUP 0x008 /* temp dup account */ +#define ACF_NORMUSER 0x010 /* normal user */ +#define ACF_MNS 0x020 /* MNS account */ +#define ACF_DOMTRUST 0x040 /* Domain trust acct */ +#define ACF_WSTRUST 0x080 /* WKST trust acct */ +#define ACF_SVRTRUST 0x100 /* Server trust acct */ +#define ACF_PWDNOEXP 0x200 /* password no expire */ +#define ACF_AUTOLOCK 0x400 /* acct auto lock */ + +/* + * samlib.c + */ +int sam_lookup_user_info(char *server, char *domain_name, char *username, + smb_userinfo_t *user_info); + +DWORD sam_create_trust_account(char *server, char *domain, + smb_auth_info_t *auth); + +DWORD sam_create_account(char *server, char *domain_name, char *account_name, + smb_auth_info_t *auth, DWORD account_flags); + +DWORD sam_remove_trust_account(char *server, char *domain); + +DWORD sam_delete_account(char *server, char *domain_name, char *account_name); + +DWORD sam_lookup_name(char *server, char *domain_name, char *account_name, + DWORD *rid_ret); + +DWORD sam_get_local_domains(char *server, char *domain_name); +DWORD sam_check_user(char *server, char *domain_name, char *account_name); + +/* + * samr_open.c + */ +int samr_open(char *server, char *domain, char *username, + DWORD access_mask, mlsvc_handle_t *samr_handle); + +int samr_connect(char *server, char *domain, char *username, + DWORD access_mask, mlsvc_handle_t *samr_handle); + +int samr_close_handle(mlsvc_handle_t *handle); + +DWORD samr_open_domain(mlsvc_handle_t *samr_handle, DWORD access_mask, + struct samr_sid *sid, mlsvc_handle_t *domain_handle); + +DWORD samr_open_user(mlsvc_handle_t *domain_handle, DWORD access_mask, + DWORD rid, mlsvc_handle_t *user_handle); + +DWORD samr_delete_user(mlsvc_handle_t *user_handle); + +int samr_open_group(mlsvc_handle_t *domain_handle, DWORD rid, + mlsvc_handle_t *group_handle); + +DWORD samr_create_user(mlsvc_handle_t *domain_handle, char *username, + DWORD account_flags, DWORD *rid, mlsvc_handle_t *user_handle); + +/* + * samr_lookup.c + */ +union samr_user_info { + struct info1 { + char *username; + char *fullname; + DWORD group_rid; + char *description; + char *unknown; + } info1; + + struct info6 { + char *username; + char *fullname; + } info6; + + struct info7 { + char *username; + } info7; + + struct info8 { + char *fullname; + } info8; + + struct info9 { + DWORD group_rid; + } info9; + + struct info16 { + DWORD unknown; + } info16; +}; + + +int samr_lookup_domain(mlsvc_handle_t *samr_handle, char *domain_name, + smb_userinfo_t *user_info); + +DWORD samr_enum_local_domains(mlsvc_handle_t *samr_handle); + +DWORD samr_lookup_domain_names(mlsvc_handle_t *domain_handle, char *name, + smb_userinfo_t *user_info); + +int samr_query_user_info(mlsvc_handle_t *user_handle, WORD switch_value, + union samr_user_info *user_info); + +int samr_query_user_groups(mlsvc_handle_t *user_handle, + smb_userinfo_t *user_info); + +DWORD samr_get_user_pwinfo(mlsvc_handle_t *user_handle); + +typedef struct oem_password { + BYTE data[512]; + DWORD length; +} oem_password_t; + + +int sam_oem_password(oem_password_t *oem_password, unsigned char *new_password, + unsigned char *old_password); + +#ifdef __cplusplus +} +#endif + + +#endif /* _SMBSRV_SAMLIB_H */ diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samr_lookup.c b/usr/src/lib/smbsrv/libmlsvc/common/samr_lookup.c index 6eaf0cee3d..c599826fab 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/samr_lookup.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/samr_lookup.c @@ -35,12 +35,11 @@ #include <unistd.h> #include <smbsrv/libsmb.h> - +#include <smbsrv/libmlsvc.h> #include <smbsrv/ntstatus.h> #include <smbsrv/smb_sid.h> -#include <smbsrv/samlib.h> -#include <smbsrv/mlrpc.h> -#include <smbsrv/mlsvc.h> +#include <samlib.h> +#include <smbsrv/libmlrpc.h> static int samr_setup_user_info(WORD, struct samr_QueryUserInfo *, union samr_user_info *); @@ -63,18 +62,15 @@ samr_lookup_domain(mlsvc_handle_t *samr_handle, char *domain_name, smb_userinfo_t *user_info) { struct samr_LookupDomain arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; int rc; size_t length; - if (mlsvc_is_null_handle(samr_handle) || + if (ndr_is_null_handle(samr_handle) || domain_name == NULL || user_info == NULL) { return (-1); } - context = samr_handle->context; opnum = SAMR_OPNUM_LookupDomain; bzero(&arg, sizeof (struct samr_LookupDomain)); @@ -82,22 +78,21 @@ samr_lookup_domain(mlsvc_handle_t *samr_handle, char *domain_name, sizeof (samr_handle_t)); length = mts_wcequiv_strlen(domain_name); - if (context->server_os == NATIVE_OS_WIN2000) + if (ndr_rpc_server_os(samr_handle) == NATIVE_OS_WIN2000) length += sizeof (mts_wchar_t); arg.domain_name.length = length; arg.domain_name.allosize = length; arg.domain_name.str = (unsigned char *)domain_name; - (void) mlsvc_rpc_init(&heap); - rc = mlsvc_rpc_call(context, opnum, &arg, &heap); + rc = ndr_rpc_call(samr_handle, opnum, &arg); if (rc == 0) { user_info->sid_name_use = SidTypeDomain; user_info->domain_sid = smb_sid_dup((smb_sid_t *)arg.sid); - user_info->domain_name = MEM_STRDUP("mlrpc", domain_name); + user_info->domain_name = MEM_STRDUP("ndr", domain_name); } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(samr_handle); return (rc); } @@ -112,15 +107,12 @@ DWORD samr_enum_local_domains(mlsvc_handle_t *samr_handle) { struct samr_EnumLocalDomain arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; DWORD status; - if (mlsvc_is_null_handle(samr_handle)) + if (ndr_is_null_handle(samr_handle)) return (NT_STATUS_INVALID_PARAMETER); - context = samr_handle->context; opnum = SAMR_OPNUM_EnumLocalDomains; bzero(&arg, sizeof (struct samr_EnumLocalDomain)); @@ -129,8 +121,7 @@ samr_enum_local_domains(mlsvc_handle_t *samr_handle) arg.enum_context = 0; arg.max_length = 0x00002000; /* Value used by NT */ - (void) mlsvc_rpc_init(&heap); - if (mlsvc_rpc_call(context, opnum, &arg, &heap) != 0) { + if (ndr_rpc_call(samr_handle, opnum, &arg) != 0) { status = NT_STATUS_INVALID_PARAMETER; } else { status = NT_SC_VALUE(arg.status); @@ -139,9 +130,10 @@ samr_enum_local_domains(mlsvc_handle_t *samr_handle) * Handle none-mapped status quietly. */ if (status != NT_STATUS_NONE_MAPPED) - mlsvc_rpc_report_status(opnum, arg.status); + ndr_rpc_status(samr_handle, opnum, arg.status); } + ndr_rpc_release(samr_handle); return (status); } @@ -159,18 +151,15 @@ samr_lookup_domain_names(mlsvc_handle_t *domain_handle, char *name, smb_userinfo_t *user_info) { struct samr_LookupNames arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; DWORD status; size_t length; - if (mlsvc_is_null_handle(domain_handle) || + if (ndr_is_null_handle(domain_handle) || name == NULL || user_info == NULL) { return (NT_STATUS_INVALID_PARAMETER); } - context = domain_handle->context; opnum = SAMR_OPNUM_LookupNames; bzero(&arg, sizeof (struct samr_LookupNames)); @@ -182,15 +171,14 @@ samr_lookup_domain_names(mlsvc_handle_t *domain_handle, char *name, arg.total = 1; length = mts_wcequiv_strlen(name); - if (context->server_os == NATIVE_OS_WIN2000) + if (ndr_rpc_server_os(domain_handle) == NATIVE_OS_WIN2000) length += sizeof (mts_wchar_t); arg.name.length = length; arg.name.allosize = length; arg.name.str = (unsigned char *)name; - (void) mlsvc_rpc_init(&heap); - if (mlsvc_rpc_call(context, opnum, &arg, &heap) != 0) { + if (ndr_rpc_call(domain_handle, opnum, &arg) != 0) { status = NT_STATUS_INVALID_PARAMETER; } else if (arg.status != 0) { status = NT_SC_VALUE(arg.status); @@ -199,15 +187,15 @@ samr_lookup_domain_names(mlsvc_handle_t *domain_handle, char *name, * Handle none-mapped status quietly. */ if (status != NT_STATUS_NONE_MAPPED) - mlsvc_rpc_report_status(opnum, arg.status); + ndr_rpc_status(domain_handle, opnum, arg.status); } else { - user_info->name = MEM_STRDUP("mlrpc", name); + user_info->name = MEM_STRDUP("ndr", name); user_info->sid_name_use = arg.rid_types.rid_type[0]; user_info->rid = arg.rids.rid[0]; status = 0; } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(domain_handle); return (status); } @@ -224,15 +212,12 @@ samr_query_user_info(mlsvc_handle_t *user_handle, WORD switch_value, union samr_user_info *user_info) { struct samr_QueryUserInfo arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; int rc; - if (mlsvc_is_null_handle(user_handle) || user_info == 0) + if (ndr_is_null_handle(user_handle) || user_info == 0) return (-1); - context = user_handle->context; opnum = SAMR_OPNUM_QueryUserInfo; bzero(&arg, sizeof (struct samr_QueryUserInfo)); @@ -240,21 +225,20 @@ samr_query_user_info(mlsvc_handle_t *user_handle, WORD switch_value, sizeof (samr_handle_t)); arg.switch_value = switch_value; - (void) mlsvc_rpc_init(&heap); - rc = mlsvc_rpc_call(context, opnum, &arg, &heap); - if (rc == 0) { - if (arg.status != 0) - rc = -1; - else - rc = samr_setup_user_info(switch_value, &arg, - user_info); + if (ndr_rpc_call(user_handle, opnum, &arg) != 0) { + ndr_rpc_release(user_handle); + return (-1); } - mlsvc_rpc_free(context, &heap); + if (arg.status != 0) + rc = -1; + else + rc = samr_setup_user_info(switch_value, &arg, user_info); + + ndr_rpc_release(user_handle); return (rc); } - /* * samr_setup_user_info * @@ -331,25 +315,20 @@ int samr_query_user_groups(mlsvc_handle_t *user_handle, smb_userinfo_t *user_info) { struct samr_QueryUserGroups arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; int rc; int nbytes; - if (mlsvc_is_null_handle(user_handle) || user_info == NULL) + if (ndr_is_null_handle(user_handle) || user_info == NULL) return (-1); - context = user_handle->context; opnum = SAMR_OPNUM_QueryUserGroups; bzero(&arg, sizeof (struct samr_QueryUserGroups)); (void) memcpy(&arg.user_handle, &user_handle->handle, sizeof (samr_handle_t)); - (void) mlsvc_rpc_init(&heap); - - rc = mlsvc_rpc_call(context, opnum, &arg, &heap); + rc = ndr_rpc_call(user_handle, opnum, &arg); if (rc == 0) { if (arg.info == 0) { rc = -1; @@ -368,11 +347,11 @@ samr_query_user_groups(mlsvc_handle_t *user_handle, smb_userinfo_t *user_info) } } } - mlsvc_rpc_free(context, &heap); + + ndr_rpc_release(user_handle); return (rc); } - /* * samr_get_user_pwinfo * @@ -387,35 +366,30 @@ DWORD samr_get_user_pwinfo(mlsvc_handle_t *user_handle) { struct samr_GetUserPwInfo arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; DWORD status; - if (mlsvc_is_null_handle(user_handle)) + if (ndr_is_null_handle(user_handle)) return (NT_STATUS_INVALID_PARAMETER); - context = user_handle->context; opnum = SAMR_OPNUM_GetUserPwInfo; bzero(&arg, sizeof (struct samr_GetUserPwInfo)); (void) memcpy(&arg.user_handle, &user_handle->handle, sizeof (samr_handle_t)); - (void) mlsvc_rpc_init(&heap); - if (mlsvc_rpc_call(context, opnum, &arg, &heap) != 0) { + if (ndr_rpc_call(user_handle, opnum, &arg) != 0) { status = NT_STATUS_INVALID_PARAMETER; } else if (arg.status != 0) { - mlsvc_rpc_report_status(opnum, arg.status); + ndr_rpc_status(user_handle, opnum, arg.status); status = NT_SC_VALUE(arg.status); } else { status = 0; } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(user_handle); return (status); } - /* * samr_set_user_info * @@ -428,17 +402,12 @@ DWORD samr_set_user_info(mlsvc_handle_t *user_handle, smb_auth_info_t *auth) { struct samr_SetUserInfo arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; DWORD status = 0; - if (mlsvc_is_null_handle(user_handle)) + if (ndr_is_null_handle(user_handle)) return (NT_STATUS_INVALID_PARAMETER); - (void) mlsvc_rpc_init(&heap); - - context = user_handle->context; opnum = SAMR_OPNUM_SetUserInfo; bzero(&arg, sizeof (struct samr_SetUserInfo)); (void) memcpy(&arg.user_handle, &user_handle->handle, @@ -453,14 +422,14 @@ samr_set_user_info(mlsvc_handle_t *user_handle, smb_auth_info_t *auth) if (samr_set_user_password(auth, arg.info.ru.info23.password) < 0) status = NT_STATUS_INTERNAL_ERROR; - if (mlsvc_rpc_call(context, opnum, &arg, &heap) != 0) { + if (ndr_rpc_call(user_handle, opnum, &arg) != 0) { status = NT_STATUS_INVALID_PARAMETER; } else if (arg.status != 0) { - mlsvc_rpc_report_status(opnum, arg.status); + ndr_rpc_status(user_handle, opnum, arg.status); status = NT_SC_VALUE(arg.status); } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(user_handle); return (status); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samr_open.c b/usr/src/lib/smbsrv/libmlsvc/common/samr_open.c index 85655ca168..3de1af7fa5 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/samr_open.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/samr_open.c @@ -42,12 +42,12 @@ #include <smbsrv/libsmb.h> #include <smbsrv/libsmbrdr.h> +#include <smbsrv/libmlrpc.h> +#include <smbsrv/libmlsvc.h> #include <smbsrv/smbinfo.h> #include <smbsrv/ntstatus.h> #include <smbsrv/ntaccess.h> -#include <smbsrv/samlib.h> -#include <smbsrv/mlrpc.h> -#include <smbsrv/mlsvc.h> +#include <samlib.h> /*LINTED E_STATIC_UNUSED*/ static DWORD samr_connect1(char *, char *, char *, DWORD, mlsvc_handle_t *); @@ -58,11 +58,9 @@ static DWORD samr_connect4(char *, char *, char *, DWORD, mlsvc_handle_t *); /* * 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. + * Wrapper round samr_connect to ensure that we connect using the server + * and domain. We default to the resource domain if the caller doesn't + * supply a server name and a domain name. * * If username argument is NULL, an anonymous connection will be established. * Otherwise, an authenticated connection will be established. @@ -73,32 +71,21 @@ int samr_open(char *server, char *domain, char *username, DWORD access_mask, mlsvc_handle_t *samr_handle) { - smb_ntdomain_t *di; - int remote_os; - int remote_lm; + smb_domain_t di; int rc; if (server == NULL || domain == NULL) { - if ((di = smb_getdomaininfo(0)) == NULL) + if (!smb_domain_getinfo(&di)) return (-1); - server = di->server; - domain = di->domain; + server = di.d_dc; + domain = di.d_nbdomain; } if (username == NULL) username = MLSVC_ANON_USER; - rc = mlsvc_logon(server, domain, username); - - if (rc != 0) - return (-1); rc = samr_connect(server, domain, username, access_mask, samr_handle); - if (rc == 0) { - (void) mlsvc_session_native_values(samr_handle->context->fid, - &remote_os, &remote_lm, 0); - samr_handle->context->server_os = remote_os; - } return (rc); } @@ -118,26 +105,11 @@ samr_connect(char *server, char *domain, char *username, DWORD access_mask, mlsvc_handle_t *samr_handle) { DWORD status; - int remote_os; - int remote_lm; - int fid; - int rc = 0; - - if (server == NULL || domain == NULL || - username == NULL || samr_handle == NULL) - return (-1); - - if ((fid = mlsvc_open_pipe(server, domain, username, "\\samr")) < 0) - return (-1); - if (mlsvc_rpc_bind(samr_handle, fid, "SAMR") < 0) { - (void) mlsvc_close_pipe(fid); + if (ndr_rpc_bind(samr_handle, server, domain, username, "SAMR") < 0) return (-1); - } - (void) mlsvc_session_native_values(fid, &remote_os, &remote_lm, 0); - - switch (remote_os) { + switch (ndr_rpc_server_os(samr_handle)) { case NATIVE_OS_NT5_1: status = samr_connect4(server, domain, username, access_mask, samr_handle); @@ -156,11 +128,11 @@ samr_connect(char *server, char *domain, char *username, DWORD access_mask, } if (status != NT_STATUS_SUCCESS) { - (void) mlsvc_close_pipe(fid); - free(samr_handle->context); - rc = -1; + ndr_rpc_unbind(samr_handle); + return (-1); } - return (rc); + + return (0); } /* @@ -178,7 +150,6 @@ samr_connect1(char *server, char *domain, char *username, DWORD access_mask, mlsvc_handle_t *samr_handle) { struct samr_ConnectAnon arg; - mlrpc_heapref_t heapref; int opnum; DWORD status; @@ -186,25 +157,23 @@ samr_connect1(char *server, char *domain, char *username, DWORD access_mask, opnum = SAMR_OPNUM_ConnectAnon; status = NT_STATUS_SUCCESS; - (void) mlsvc_rpc_init(&heapref); - arg.servername = (DWORD *)mlrpc_heap_malloc(heapref.heap, - sizeof (DWORD)); + arg.servername = ndr_rpc_malloc(samr_handle, sizeof (DWORD)); *(arg.servername) = 0x0001005c; arg.access_mask = access_mask; - if (mlsvc_rpc_call(samr_handle->context, opnum, &arg, &heapref) != 0) { + if (ndr_rpc_call(samr_handle, opnum, &arg) != 0) { status = NT_STATUS_UNSUCCESSFUL; } else if (arg.status != 0) { status = NT_SC_VALUE(arg.status); } else { (void) memcpy(&samr_handle->handle, &arg.handle, - sizeof (ms_handle_t)); + sizeof (ndr_hdid_t)); - if (mlsvc_is_null_handle(samr_handle)) + if (ndr_is_null_handle(samr_handle)) status = NT_STATUS_INVALID_HANDLE; } - mlsvc_rpc_free(samr_handle->context, &heapref); + ndr_rpc_release(samr_handle); return (status); } @@ -224,7 +193,6 @@ samr_connect2(char *server, char *domain, char *username, DWORD access_mask, mlsvc_handle_t *samr_handle) { struct samr_Connect arg; - mlrpc_heapref_t heapref; int opnum; DWORD status; int len; @@ -233,25 +201,24 @@ samr_connect2(char *server, char *domain, char *username, DWORD access_mask, opnum = SAMR_OPNUM_Connect; status = NT_STATUS_SUCCESS; - (void) mlsvc_rpc_init(&heapref); len = strlen(server) + 4; - arg.servername = mlrpc_heap_malloc(heapref.heap, len); + arg.servername = ndr_rpc_malloc(samr_handle, len); (void) snprintf((char *)arg.servername, len, "\\\\%s", server); arg.access_mask = access_mask; - if (mlsvc_rpc_call(samr_handle->context, opnum, &arg, &heapref) != 0) { + if (ndr_rpc_call(samr_handle, opnum, &arg) != 0) { status = NT_STATUS_UNSUCCESSFUL; } else if (arg.status != 0) { status = NT_SC_VALUE(arg.status); } else { (void) memcpy(&samr_handle->handle, &arg.handle, - sizeof (ms_handle_t)); + sizeof (ndr_hdid_t)); - if (mlsvc_is_null_handle(samr_handle)) + if (ndr_is_null_handle(samr_handle)) status = NT_STATUS_INVALID_HANDLE; } - mlsvc_rpc_free(samr_handle->context, &heapref); + ndr_rpc_release(samr_handle); return (status); } @@ -266,7 +233,6 @@ samr_connect3(char *server, char *domain, char *username, DWORD access_mask, mlsvc_handle_t *samr_handle) { struct samr_Connect3 arg; - mlrpc_heapref_t heapref; int opnum; DWORD status; int len; @@ -275,26 +241,25 @@ samr_connect3(char *server, char *domain, char *username, DWORD access_mask, opnum = SAMR_OPNUM_Connect3; status = NT_STATUS_SUCCESS; - (void) mlsvc_rpc_init(&heapref); len = strlen(server) + 4; - arg.servername = mlrpc_heap_malloc(heapref.heap, len); + arg.servername = ndr_rpc_malloc(samr_handle, len); (void) snprintf((char *)arg.servername, len, "\\\\%s", server); arg.unknown_02 = 0x00000002; arg.access_mask = access_mask; - if (mlsvc_rpc_call(samr_handle->context, opnum, &arg, &heapref) != 0) { + if (ndr_rpc_call(samr_handle, opnum, &arg) != 0) { status = NT_STATUS_UNSUCCESSFUL; } else if (arg.status != 0) { status = NT_SC_VALUE(arg.status); } else { (void) memcpy(&samr_handle->handle, &arg.handle, - sizeof (ms_handle_t)); + sizeof (ndr_hdid_t)); - if (mlsvc_is_null_handle(samr_handle)) + if (ndr_is_null_handle(samr_handle)) status = NT_STATUS_INVALID_HANDLE; } - mlsvc_rpc_free(samr_handle->context, &heapref); + ndr_rpc_release(samr_handle); return (status); } @@ -315,31 +280,26 @@ samr_connect4(char *server, char *domain, char *username, DWORD access_mask, mlsvc_handle_t *samr_handle) { struct samr_Connect4 arg; - mlrpc_heapref_t heapref; - char dns_name[MAXHOSTNAMELEN]; int len; int opnum; DWORD status; + smb_domain_t dinfo; bzero(&arg, sizeof (struct samr_Connect4)); opnum = SAMR_OPNUM_Connect; status = NT_STATUS_SUCCESS; - if (smb_resolve_fqdn(domain, dns_name, MAXHOSTNAMELEN) != 1) - return (NT_STATUS_UNSUCCESSFUL); + if (!smb_domain_getinfo(&dinfo)) + return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); - (void) mlsvc_rpc_init(&heapref); + len = strlen(server) + strlen(dinfo.d_fqdomain) + 4; + arg.servername = ndr_rpc_malloc(samr_handle, len); - if (strlen(dns_name) > 0) { - len = strlen(server) + strlen(dns_name) + 4; - arg.servername = mlrpc_heap_malloc(heapref.heap, len); + if (*dinfo.d_fqdomain != '\0') (void) snprintf((char *)arg.servername, len, "\\\\%s.%s", - server, dns_name); - } else { - len = strlen(server) + 4; - arg.servername = mlrpc_heap_malloc(heapref.heap, len); + server, dinfo.d_fqdomain); + else (void) snprintf((char *)arg.servername, len, "\\\\%s", server); - } arg.access_mask = SAM_ENUM_LOCAL_DOMAIN; arg.unknown2_00000001 = 0x00000001; @@ -347,21 +307,20 @@ samr_connect4(char *server, char *domain, char *username, DWORD access_mask, arg.unknown4_00000003 = 0x00000003; arg.unknown5_00000000 = 0x00000000; - if (mlsvc_rpc_call(samr_handle->context, opnum, &arg, &heapref) != 0) { + if (ndr_rpc_call(samr_handle, opnum, &arg) != 0) { status = NT_STATUS_UNSUCCESSFUL; } else if (arg.status != 0) { status = NT_SC_VALUE(arg.status); } else { (void) memcpy(&samr_handle->handle, &arg.handle, - sizeof (ms_handle_t)); + sizeof (ndr_hdid_t)); - if (mlsvc_is_null_handle(samr_handle)) + if (ndr_is_null_handle(samr_handle)) status = NT_STATUS_INVALID_HANDLE; } - mlsvc_rpc_free(samr_handle->context, &heapref); - + ndr_rpc_release(samr_handle); return (status); } @@ -370,38 +329,30 @@ samr_connect4(char *server, char *domain, char *username, DWORD access_mask, * 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. + * If the handle being closed is the top level connect handle, we unbind. + * Then we zero out the handle to invalidate it. */ int -samr_close_handle(mlsvc_handle_t *desc) +samr_close_handle(mlsvc_handle_t *samr_handle) { struct samr_CloseHandle arg; - mlrpc_heapref_t heap; int opnum; - int rc; - if (mlsvc_is_null_handle(desc)) + if (ndr_is_null_handle(samr_handle)) return (-1); opnum = SAMR_OPNUM_CloseHandle; bzero(&arg, sizeof (struct samr_CloseHandle)); - (void) memcpy(&arg.handle, &desc->handle, sizeof (ms_handle_t)); + (void) memcpy(&arg.handle, &samr_handle->handle, sizeof (ndr_hdid_t)); - (void) mlsvc_rpc_init(&heap); - rc = mlsvc_rpc_call(desc->context, opnum, &arg, &heap); - mlsvc_rpc_free(desc->context, &heap); + (void) ndr_rpc_call(samr_handle, opnum, &arg); + ndr_rpc_release(samr_handle); - if (desc->context->handle == &desc->handle) { - (void) mlsvc_close_pipe(desc->context->fid); - free(desc->context); - } + if (ndr_is_bind_handle(samr_handle)) + ndr_rpc_unbind(samr_handle); - bzero(desc, sizeof (mlsvc_handle_t)); - return (rc); + bzero(samr_handle, sizeof (mlsvc_handle_t)); + return (0); } /* @@ -416,42 +367,40 @@ samr_open_domain(mlsvc_handle_t *samr_handle, DWORD access_mask, struct samr_sid *sid, mlsvc_handle_t *domain_handle) { struct samr_OpenDomain arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; DWORD status; - if (mlsvc_is_null_handle(samr_handle) || - sid == 0 || domain_handle == 0) { + if (ndr_is_null_handle(samr_handle) || + sid == NULL || domain_handle == NULL) { return (NT_STATUS_INVALID_PARAMETER); } - context = samr_handle->context; opnum = SAMR_OPNUM_OpenDomain; bzero(&arg, sizeof (struct samr_OpenDomain)); - (void) memcpy(&arg.handle, &samr_handle->handle, sizeof (ms_handle_t)); + (void) memcpy(&arg.handle, &samr_handle->handle, sizeof (ndr_hdid_t)); arg.access_mask = access_mask; arg.sid = sid; - (void) mlsvc_rpc_init(&heap); - if (mlsvc_rpc_call(context, opnum, &arg, &heap) != 0) { + if (ndr_rpc_call(samr_handle, opnum, &arg) != 0) { status = NT_STATUS_UNSUCCESSFUL; } else if (arg.status != 0) { status = arg.status; } else { status = NT_STATUS_SUCCESS; + ndr_inherit_handle(domain_handle, samr_handle); + (void) memcpy(&domain_handle->handle, &arg.domain_handle, - sizeof (ms_handle_t)); - domain_handle->context = context; - if (mlsvc_is_null_handle(domain_handle)) + sizeof (ndr_hdid_t)); + + if (ndr_is_null_handle(domain_handle)) status = NT_STATUS_INVALID_HANDLE; } if (status != NT_STATUS_SUCCESS) - mlsvc_rpc_report_status(opnum, status); + ndr_rpc_status(samr_handle, opnum, status); - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(samr_handle); return (status); } @@ -469,39 +418,35 @@ samr_open_user(mlsvc_handle_t *domain_handle, DWORD access_mask, DWORD rid, mlsvc_handle_t *user_handle) { struct samr_OpenUser arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; - int opnum, rc; + int opnum; DWORD status = NT_STATUS_SUCCESS; - if (mlsvc_is_null_handle(domain_handle) || user_handle == NULL) + if (ndr_is_null_handle(domain_handle) || user_handle == NULL) return (NT_STATUS_INVALID_PARAMETER); - context = domain_handle->context; opnum = SAMR_OPNUM_OpenUser; bzero(&arg, sizeof (struct samr_OpenUser)); (void) memcpy(&arg.handle, &domain_handle->handle, - sizeof (ms_handle_t)); + sizeof (ndr_hdid_t)); arg.access_mask = access_mask; arg.rid = rid; - (void) mlsvc_rpc_init(&heap); - rc = mlsvc_rpc_call(context, opnum, &arg, &heap); - if (rc != 0) { + if (ndr_rpc_call(domain_handle, opnum, &arg) != 0) { status = NT_STATUS_UNSUCCESSFUL; } else if (arg.status != 0) { - mlsvc_rpc_report_status(opnum, arg.status); + ndr_rpc_status(domain_handle, opnum, arg.status); status = NT_SC_VALUE(arg.status); } else { + ndr_inherit_handle(user_handle, domain_handle); + (void) memcpy(&user_handle->handle, &arg.user_handle, - sizeof (ms_handle_t)); - user_handle->context = context; + sizeof (ndr_hdid_t)); - if (mlsvc_is_null_handle(user_handle)) + if (ndr_is_null_handle(user_handle)) status = NT_STATUS_INVALID_HANDLE; } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(domain_handle); return (status); } @@ -514,31 +459,27 @@ DWORD samr_delete_user(mlsvc_handle_t *user_handle) { struct samr_DeleteUser arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; DWORD status; - if (mlsvc_is_null_handle(user_handle)) + if (ndr_is_null_handle(user_handle)) return (NT_STATUS_INVALID_PARAMETER); - context = user_handle->context; opnum = SAMR_OPNUM_DeleteUser; bzero(&arg, sizeof (struct samr_DeleteUser)); (void) memcpy(&arg.user_handle, &user_handle->handle, - sizeof (ms_handle_t)); + sizeof (ndr_hdid_t)); - (void) mlsvc_rpc_init(&heap); - if (mlsvc_rpc_call(context, opnum, &arg, &heap) != 0) { + if (ndr_rpc_call(user_handle, opnum, &arg) != 0) { status = NT_STATUS_INVALID_PARAMETER; } else if (arg.status != 0) { - mlsvc_rpc_report_status(opnum, arg.status); + ndr_rpc_status(user_handle, opnum, arg.status); status = NT_SC_VALUE(arg.status); } else { status = 0; } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(user_handle); return (status); } @@ -558,39 +499,36 @@ samr_open_group( mlsvc_handle_t *group_handle) { struct samr_OpenGroup arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; int opnum; int rc; - if (mlsvc_is_null_handle(domain_handle) || group_handle == 0) + if (ndr_is_null_handle(domain_handle) || group_handle == NULL) return (-1); - context = domain_handle->context; opnum = SAMR_OPNUM_OpenGroup; bzero(&arg, sizeof (struct samr_OpenUser)); (void) memcpy(&arg.handle, &domain_handle->handle, - sizeof (ms_handle_t)); + sizeof (ndr_hdid_t)); arg.access_mask = SAM_LOOKUP_INFORMATION | SAM_ACCESS_USER_READ; arg.rid = rid; - (void) mlsvc_rpc_init(&heap); + if ((rc = ndr_rpc_call(domain_handle, opnum, &arg)) != 0) + return (-1); + + if (arg.status != 0) { + ndr_rpc_status(domain_handle, opnum, arg.status); + rc = -1; + } else { + ndr_inherit_handle(group_handle, domain_handle); - rc = mlsvc_rpc_call(context, opnum, &arg, &heap); - if (rc == 0) { - if (arg.status != 0) { - mlsvc_rpc_report_status(opnum, arg.status); + (void) memcpy(&group_handle->handle, &arg.group_handle, + sizeof (ndr_hdid_t)); + + if (ndr_is_null_handle(group_handle)) rc = -1; - } else { - (void) memcpy(&group_handle->handle, &arg.group_handle, - sizeof (ms_handle_t)); - group_handle->context = context; - if (mlsvc_is_null_handle(group_handle)) - rc = -1; - } } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(domain_handle); return (rc); } @@ -614,31 +552,29 @@ samr_create_user(mlsvc_handle_t *domain_handle, char *username, DWORD account_flags, DWORD *rid, mlsvc_handle_t *user_handle) { struct samr_CreateUser arg; - struct mlsvc_rpc_context *context; - mlrpc_heapref_t heap; + ndr_heap_t *heap; int opnum; int rc; DWORD status = 0; - if (mlsvc_is_null_handle(domain_handle) || + if (ndr_is_null_handle(domain_handle) || username == NULL || rid == NULL) { return (NT_STATUS_INVALID_PARAMETER); } - context = domain_handle->context; opnum = SAMR_OPNUM_CreateUser; bzero(&arg, sizeof (struct samr_CreateUser)); (void) memcpy(&arg.handle, &domain_handle->handle, - sizeof (ms_handle_t)); + sizeof (ndr_hdid_t)); - (void) mlsvc_rpc_init(&heap); - mlrpc_heap_mkvcs(heap.heap, username, (mlrpc_vcstr_t *)&arg.username); + heap = ndr_rpc_get_heap(domain_handle); + ndr_heap_mkvcs(heap, username, (ndr_vcstr_t *)&arg.username); arg.account_flags = account_flags; arg.unknown_e00500b0 = 0xE00500B0; - rc = mlsvc_rpc_call(context, opnum, &arg, &heap); + rc = ndr_rpc_call(domain_handle, opnum, &arg); if (rc != 0) { status = NT_STATUS_INVALID_PARAMETER; } else if (arg.status != 0) { @@ -649,17 +585,19 @@ samr_create_user(mlsvc_handle_t *domain_handle, char *username, xlate_nt_status(status)); } } else { + ndr_inherit_handle(user_handle, domain_handle); + (void) memcpy(&user_handle->handle, &arg.user_handle, - sizeof (ms_handle_t)); - user_handle->context = context; + sizeof (ndr_hdid_t)); + *rid = arg.rid; - if (mlsvc_is_null_handle(user_handle)) + if (ndr_is_null_handle(user_handle)) status = NT_STATUS_INVALID_HANDLE; else status = 0; } - mlsvc_rpc_free(context, &heap); + ndr_rpc_release(domain_handle); return (status); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c b/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c index fc46b92084..09698c0eab 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c @@ -39,7 +39,7 @@ #include <smbsrv/smbinfo.h> #include <smbsrv/smb_token.h> -#include <smbsrv/lsalib.h> +#include <lsalib.h> extern uint32_t netlogon_logon(netr_client_t *clnt, smb_userinfo_t *uinfo); static uint32_t smb_logon_domain(netr_client_t *clnt, smb_userinfo_t *uinfo); diff --git a/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c b/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c index 96bacf1082..c28a301a19 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c @@ -48,6 +48,8 @@ #define SMB_SHR_ERROR_THRESHOLD 3 +#define SMB_SHR_CSC_BUFSZ 64 + /* * Cache functions and vars */ @@ -106,7 +108,9 @@ static void smb_shr_cache_freent(HT_ITEM *); static void *smb_shr_sa_loadall(void *); static void smb_shr_sa_loadgrp(sa_group_t); static uint32_t smb_shr_sa_load(sa_share_t, sa_resource_t); +static uint32_t smb_shr_sa_loadbyname(char *); static uint32_t smb_shr_sa_get(sa_share_t, sa_resource_t, smb_share_t *); +static void smb_shr_sa_csc_option(const char *, smb_share_t *); /* * share publishing @@ -153,36 +157,24 @@ static void smb_shr_unpublish(const char *, const char *); /* * Utility/helper functions */ +static uint32_t smb_shr_lookup(char *, smb_share_t *); static uint32_t smb_shr_addipc(void); static void smb_shr_set_oemname(smb_share_t *); /* - * Starts the publisher thread and another thread which - * populates the share cache by share information stored - * by sharemgr + * Creates and initializes the cache and starts the publisher + * thread. */ int smb_shr_start(void) { - pthread_t load_thr; - pthread_attr_t tattr; - int rc; - - if ((rc = smb_shr_publisher_start()) != 0) - return (rc); - if (smb_shr_cache_create() != NERR_Success) return (ENOMEM); if (smb_shr_addipc() != NERR_Success) return (ENOMEM); - (void) pthread_attr_init(&tattr); - (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); - rc = pthread_create(&load_thr, &tattr, smb_shr_sa_loadall, 0); - (void) pthread_attr_destroy(&tattr); - - return (rc); + return (smb_shr_publisher_start()); } void @@ -193,6 +185,25 @@ smb_shr_stop(void) } /* + * Launches a thread to populate the share cache by share information + * stored in sharemgr + */ +int +smb_shr_load(void) +{ + pthread_t load_thr; + pthread_attr_t tattr; + int rc; + + (void) pthread_attr_init(&tattr); + (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); + rc = pthread_create(&load_thr, &tattr, smb_shr_sa_loadall, 0); + (void) pthread_attr_destroy(&tattr); + + return (rc); +} + +/* * Return the total number of shares */ int @@ -425,25 +436,23 @@ smb_shr_rename(char *from_name, char *to_name) /* * Load the information for the specified share into the supplied share * info structure. + * + * First looks up the cache to see if the specified share exists, if there + * is a miss then it looks up sharemgr. */ uint32_t smb_shr_get(char *sharename, smb_share_t *si) { - smb_share_t *cached_si; - uint32_t status = NERR_NetNameNotFound; + uint32_t status; if (sharename == NULL || *sharename == '\0') return (NERR_NetNameNotFound); - if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) { - cached_si = smb_shr_cache_findent(sharename); - if (cached_si != NULL) { - bcopy(cached_si, si, sizeof (smb_share_t)); - status = NERR_Success; - } + if ((status = smb_shr_lookup(sharename, si)) == NERR_Success) + return (status); - smb_shr_cache_unlock(); - } + if ((status = smb_shr_sa_loadbyname(sharename)) == NERR_Success) + status = smb_shr_lookup(sharename, si); return (status); } @@ -461,6 +470,7 @@ smb_shr_modify(smb_share_t *new_si) smb_share_t *si; boolean_t adc_changed = B_FALSE; char old_container[MAXPATHLEN]; + uint32_t cscopt; uint32_t access; assert(new_si != NULL); @@ -492,6 +502,10 @@ smb_shr_modify(smb_share_t *new_si) sizeof (si->shr_container)); } + cscopt = (new_si->shr_flags & SMB_SHRF_CSC_MASK); + si->shr_flags &= ~SMB_SHRF_CSC_MASK; + si->shr_flags |= cscopt; + access = (new_si->shr_flags & SMB_SHRF_ACC_ALL); si->shr_flags |= access; @@ -782,6 +796,32 @@ smb_shr_list(int offset, smb_shrlist_t *list) */ /* + * Looks up the given share in the cache and return + * the info in 'si' + */ +static uint32_t +smb_shr_lookup(char *sharename, smb_share_t *si) +{ + smb_share_t *cached_si; + uint32_t status = NERR_NetNameNotFound; + + if (sharename == NULL || *sharename == '\0') + return (NERR_NetNameNotFound); + + if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) { + cached_si = smb_shr_cache_findent(sharename); + if (cached_si != NULL) { + bcopy(cached_si, si, sizeof (smb_share_t)); + status = NERR_Success; + } + + smb_shr_cache_unlock(); + } + + return (status); +} + +/* * Add IPC$ to the cache upon startup. */ static uint32_t @@ -923,22 +963,11 @@ static uint32_t smb_shr_cache_lock(int mode) { (void) mutex_lock(&smb_shr_cache.sc_mtx); - switch (smb_shr_cache.sc_state) { - case SMB_SHR_CACHE_STATE_CREATED: - smb_shr_cache.sc_nops++; - break; - - case SMB_SHR_CACHE_STATE_DESTROYING: + if (smb_shr_cache.sc_state != SMB_SHR_CACHE_STATE_CREATED) { (void) mutex_unlock(&smb_shr_cache.sc_mtx); return (NERR_InternalError); - - case SMB_SHR_CACHE_STATE_NONE: - default: - assert(0); - (void) mutex_unlock(&smb_shr_cache.sc_mtx); - return (NERR_InternalError); - } + smb_shr_cache.sc_nops++; (void) mutex_unlock(&smb_shr_cache.sc_mtx); /* @@ -1172,12 +1201,28 @@ smb_shr_sa_loadgrp(sa_group_t group) /* * Load a share definition from sharemgr and add it to the cache. + * If the share is already in the cache then it doesn't do anything. + * + * This function does not report duplicate shares as error since + * a share might have been added by smb_shr_get() while load is + * in progress. */ static uint32_t smb_shr_sa_load(sa_share_t share, sa_resource_t resource) { smb_share_t si; + char *sharename; uint32_t status; + boolean_t loaded; + + if ((sharename = sa_get_resource_attr(resource, "name")) == NULL) + return (NERR_InternalError); + + loaded = smb_shr_exists(sharename); + sa_free_attr_string(sharename); + + if (loaded) + return (NERR_Success); if ((status = smb_shr_sa_get(share, resource, &si)) != NERR_Success) { syslog(LOG_DEBUG, "share: failed to load %s (%d)", @@ -1185,7 +1230,8 @@ smb_shr_sa_load(sa_share_t share, sa_resource_t resource) return (status); } - if ((status = smb_shr_add(&si)) != NERR_Success) { + status = smb_shr_add(&si); + if ((status != NERR_Success) && (status != NERR_DuplicateShare)) { syslog(LOG_DEBUG, "share: failed to cache %s (%d)", si.shr_name, status); return (status); @@ -1239,7 +1285,7 @@ smb_shr_sa_get(sa_share_t share, sa_resource_t resource, smb_share_t *si) if (opts == NULL) return (NERR_Success); - prop = (sa_property_t)sa_get_property(opts, SMB_SHROPT_AD_CONTAINER); + prop = (sa_property_t)sa_get_property(opts, SHOPT_AD_CONTAINER); if (prop != NULL) { if ((val = sa_get_property_attr(prop, "value")) != NULL) { (void) strlcpy(si->shr_container, val, @@ -1248,6 +1294,14 @@ smb_shr_sa_get(sa_share_t share, sa_resource_t resource, smb_share_t *si) } } + prop = (sa_property_t)sa_get_property(opts, SHOPT_CSC); + if (prop != NULL) { + if ((val = sa_get_property_attr(prop, "value")) != NULL) { + smb_shr_sa_csc_option(val, si); + free(val); + } + } + prop = (sa_property_t)sa_get_property(opts, SHOPT_NONE); if (prop != NULL) { if ((val = sa_get_property_attr(prop, "value")) != NULL) { @@ -1283,6 +1337,95 @@ smb_shr_sa_get(sa_share_t share, sa_resource_t resource, smb_share_t *si) } /* + * Map a client-side caching (CSC) option to the appropriate share + * flag. Only one option is allowed; an error will be logged if + * multiple options have been specified. We don't need to do anything + * about multiple values here because the SRVSVC will not recognize + * a value containing multiple flags and will return the default value. + * + * If the option value is not recognized, it will be ignored: invalid + * values will typically be caught and rejected by sharemgr. + */ +static void +smb_shr_sa_csc_option(const char *value, smb_share_t *si) +{ + struct { + char *value; + uint32_t flag; + } cscopt[] = { + { "disabled", SMB_SHRF_CSC_DISABLED }, + { "manual", SMB_SHRF_CSC_MANUAL }, + { "auto", SMB_SHRF_CSC_AUTO }, + { "vdo", SMB_SHRF_CSC_VDO } + }; + + char buf[SMB_SHR_CSC_BUFSZ]; + smb_ctxbuf_t ctx; + int i; + + for (i = 0; i < (sizeof (cscopt) / sizeof (cscopt[0])); ++i) { + if (strcasecmp(value, cscopt[i].value) == 0) { + si->shr_flags |= cscopt[i].flag; + break; + } + } + + switch (si->shr_flags & SMB_SHRF_CSC_MASK) { + case 0: + case SMB_SHRF_CSC_DISABLED: + case SMB_SHRF_CSC_MANUAL: + case SMB_SHRF_CSC_AUTO: + case SMB_SHRF_CSC_VDO: + break; + + default: + (void) smb_ctxbuf_init(&ctx, (uint8_t *)buf, SMB_SHR_CSC_BUFSZ); + + for (i = 0; i < (sizeof (cscopt) / sizeof (cscopt[0])); ++i) { + if (si->shr_flags & cscopt[i].flag) + (void) smb_ctxbuf_printf(&ctx, " %s", + cscopt[i].value); + } + + syslog(LOG_ERR, "csc option conflict:%s", buf); + break; + } +} + +/* + * looks up sharemgr for the given share (resource) and loads + * the definition into cache if lookup is successful + */ +static uint32_t +smb_shr_sa_loadbyname(char *sharename) +{ + sa_handle_t handle; + sa_share_t share; + sa_resource_t resource; + uint32_t status; + + if ((handle = sa_init(SA_INIT_SHARE_API)) == NULL) + return (NERR_InternalError); + + resource = sa_find_resource(handle, sharename); + if (resource == NULL) { + sa_fini(handle); + return (NERR_NetNameNotFound); + } + + share = sa_get_resource_parent(resource); + if (share == NULL) { + sa_fini(handle); + return (NERR_InternalError); + } + + status = smb_shr_sa_load(share, resource); + + sa_fini(handle); + return (status); +} + +/* * ============================================ * Share publishing functions * diff --git a/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c new file mode 100644 index 0000000000..60337c6407 --- /dev/null +++ b/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c @@ -0,0 +1,130 @@ +/* + * 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 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Printing and Spooling RPC service. + */ + +#include <stdlib.h> +#include <strings.h> +#include <smbsrv/libsmb.h> +#include <smbsrv/libmlrpc.h> +#include <smbsrv/libmlsvc.h> +#include <smbsrv/ndl/spoolss.ndl> +#include <smbsrv/nterror.h> +#include <smbsrv/smbinfo.h> +#include <smbsrv/nmpipes.h> + +int spoolss_s_OpenPrinter(void *, ndr_xa_t *); +int spoolss_s_stub(void *, ndr_xa_t *); + +static ndr_stub_table_t spoolss_stub_table[] = { + { spoolss_s_OpenPrinter, SPOOLSS_OPNUM_OpenPrinter }, + { spoolss_s_stub, SPOOLSS_OPNUM_GetJob }, + { spoolss_s_stub, SPOOLSS_OPNUM_DeletePrinter }, + { spoolss_s_stub, SPOOLSS_OPNUM_GetPrinterDriver }, + { spoolss_s_stub, SPOOLSS_OPNUM_DeletePrinterDriver }, + { spoolss_s_stub, SPOOLSS_OPNUM_AddPrintProcessor }, + { spoolss_s_stub, SPOOLSS_OPNUM_GetPrintProcessorDirectory }, + { spoolss_s_stub, SPOOLSS_OPNUM_AbortPrinter }, + { spoolss_s_stub, SPOOLSS_OPNUM_ReadPrinter }, + { spoolss_s_stub, SPOOLSS_OPNUM_WaitForPrinterChange }, + { spoolss_s_stub, SPOOLSS_OPNUM_AddForm }, + { spoolss_s_stub, SPOOLSS_OPNUM_DeleteForm }, + { spoolss_s_stub, SPOOLSS_OPNUM_GetForm }, + { spoolss_s_stub, SPOOLSS_OPNUM_SetForm }, + { spoolss_s_stub, SPOOLSS_OPNUM_EnumMonitors }, + { spoolss_s_stub, SPOOLSS_OPNUM_AddPort }, + { spoolss_s_stub, SPOOLSS_OPNUM_ConfigurePort }, + { spoolss_s_stub, SPOOLSS_OPNUM_DeletePort }, + { spoolss_s_stub, SPOOLSS_OPNUM_CreatePrinterIc }, + { spoolss_s_stub, SPOOLSS_OPNUM_PlayDescriptionPrinterIc }, + { spoolss_s_stub, SPOOLSS_OPNUM_DeletePrinterIc }, + { spoolss_s_stub, SPOOLSS_OPNUM_AddPrinterConnection }, + { spoolss_s_stub, SPOOLSS_OPNUM_DeletePrinterConnection }, + { spoolss_s_stub, SPOOLSS_OPNUM_PrinterMessageBox }, + { spoolss_s_stub, SPOOLSS_OPNUM_AddMonitor }, + { spoolss_s_stub, SPOOLSS_OPNUM_DeleteMonitor }, + { spoolss_s_stub, SPOOLSS_OPNUM_DeletePrintProcessor }, + { spoolss_s_stub, SPOOLSS_OPNUM_AddPrintProvider }, + { spoolss_s_stub, SPOOLSS_OPNUM_DeletePrintProvider }, + { spoolss_s_stub, SPOOLSS_OPNUM_ResetPrinter }, + { spoolss_s_stub, SPOOLSS_OPNUM_FindFirstChangeNotify }, + { spoolss_s_stub, SPOOLSS_OPNUM_FindNextChangeNotify }, + { spoolss_s_stub, SPOOLSS_OPNUM_RouterFindFirstNotify }, + { spoolss_s_stub, SPOOLSS_OPNUM_ReplyOpenPrinter }, + { spoolss_s_stub, SPOOLSS_OPNUM_RouterReplyPrinter }, + { spoolss_s_stub, SPOOLSS_OPNUM_ReplyClosePrinter }, + { spoolss_s_stub, SPOOLSS_OPNUM_AddPortEx }, + { spoolss_s_stub, SPOOLSS_OPNUM_RemoteFindFirstChangeNotify }, + { spoolss_s_stub, SPOOLSS_OPNUM_SpoolerInitialize }, + { spoolss_s_stub, SPOOLSS_OPNUM_ResetPrinterEx }, + { spoolss_s_stub, SPOOLSS_OPNUM_RouterRefreshChangeNotify }, + { spoolss_s_OpenPrinter, SPOOLSS_OPNUM_OpenPrinter2 }, + {0} +}; + +static ndr_service_t spoolss_service = { + "SPOOLSS", /* name */ + "Print Spool Service", /* desc */ + "\\spoolss", /* endpoint */ + PIPE_SPOOLSS, /* sec_addr_port */ + "12345678-1234-abcd-ef000123456789ab", 1, /* abstract */ + NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ + 0, /* no bind_instance_size */ + 0, /* no bind_req() */ + 0, /* no unbind_and_close() */ + 0, /* use generic_call_stub() */ + &TYPEINFO(spoolss_interface), /* interface ti */ + spoolss_stub_table /* stub_table */ +}; + +void +spoolss_initialize(void) +{ + (void) ndr_svc_register(&spoolss_service); +} + +int +spoolss_s_OpenPrinter(void *arg, ndr_xa_t *mxa) +{ + struct spoolss_OpenPrinter *param = arg; + + bzero(param, sizeof (struct spoolss_OpenPrinter)); + + if (mxa == NULL) + param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); + else + param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); + + return (NDR_DRC_OK); +} + +/*ARGSUSED*/ +int +spoolss_s_stub(void *arg, ndr_xa_t *mxa) +{ + return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED); +} diff --git a/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_client.c b/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_client.c index 916ede52df..a90bb2a50c 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_client.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_client.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)srvsvc_client.c 1.3 08/07/16 SMI" - /* * Server Service (srvsvc) client side RPC library interface. The * srvsvc interface allows a client to query a server for information @@ -42,10 +40,10 @@ #include <smbsrv/libsmb.h> #include <smbsrv/libsmbrdr.h> +#include <smbsrv/libmlsvc.h> #include <smbsrv/smbinfo.h> #include <smbsrv/ntstatus.h> #include <smbsrv/ndl/srvsvc.ndl> -#include <smbsrv/mlsvc_util.h> /* * Information level for NetShareGetInfo. @@ -55,61 +53,40 @@ DWORD srvsvc_info_level = 1; static int srvsvc_net_remote_tod(char *, char *, struct timeval *, struct tm *); /* - * Ensure that an appropriate session and logon exists for the srvsvc - * client calls. Open and bind the RPC interface. + * Bind to the the SRVSVC. * * 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. */ static int -srvsvc_open(char *server, char *domain, char *username, - mlsvc_handle_t *handle, mlrpc_heapref_t *heapref) +srvsvc_open(char *server, char *domain, char *username, mlsvc_handle_t *handle) { - smb_ntdomain_t *di; - int fid; - int rc; + smb_domain_t di; if (server == NULL || domain == NULL) { - if ((di = smb_getdomaininfo(0)) == NULL) + if (!smb_domain_getinfo(&di)) return (-1); - server = di->server; - domain = di->domain; + server = di.d_dc; + domain = di.d_nbdomain; } if (username == NULL) username = MLSVC_ANON_USER; - rc = mlsvc_logon(server, domain, username); - - if (rc != 0) - return (-1); - - fid = mlsvc_open_pipe(server, domain, username, "\\srvsvc"); - if (fid < 0) + if (ndr_rpc_bind(handle, server, domain, username, "SRVSVC") < 0) return (-1); - if ((rc = mlsvc_rpc_bind(handle, fid, "SRVSVC")) < 0) { - (void) mlsvc_close_pipe(fid); - return (rc); - } - - rc = mlsvc_rpc_init(heapref); - return (rc); + return (0); } /* - * Close the srvsvc pipe and free the associated context. This function - * should only be called if the open was successful. + * Unbind the SRVSVC connection. */ -void -srvsvc_close(mlsvc_handle_t *handle, mlrpc_heapref_t *heapref) +static void +srvsvc_close(mlsvc_handle_t *handle) { - mlsvc_rpc_free(handle->context, heapref); - (void) mlsvc_close_pipe(handle->context->fid); - free(handle->context); + ndr_rpc_unbind(handle); } /* @@ -122,7 +99,6 @@ srvsvc_net_share_get_info(char *server, char *domain, char *netname) { struct mlsm_NetShareGetInfo arg; mlsvc_handle_t handle; - mlrpc_heapref_t heap; int rc; int opnum; struct mslm_NetShareGetInfo0 *info0; @@ -137,17 +113,16 @@ srvsvc_net_share_get_info(char *server, char *domain, char *netname) if (srvsvc_info_level == 2) user = smbrdr_ipc_get_user(); - rc = srvsvc_open(server, domain, user, &handle, &heap); - if (rc != 0) + if (srvsvc_open(server, domain, user, &handle) != 0) return (-1); opnum = SRVSVC_OPNUM_NetShareGetInfo; bzero(&arg, sizeof (struct mlsm_NetShareGetInfo)); len = strlen(server) + 4; - arg.servername = mlrpc_heap_malloc(heap.heap, len); + arg.servername = ndr_rpc_malloc(&handle, len); if (arg.servername == NULL) { - srvsvc_close(&handle, &heap); + srvsvc_close(&handle); return (-1); } @@ -155,9 +130,9 @@ srvsvc_net_share_get_info(char *server, char *domain, char *netname) arg.netname = (LPTSTR)netname; arg.level = srvsvc_info_level; /* share information level */ - rc = mlsvc_rpc_call(handle.context, opnum, &arg, &heap); + rc = ndr_rpc_call(&handle, opnum, &arg); if ((rc != 0) || (arg.status != 0)) { - srvsvc_close(&handle, &heap); + srvsvc_close(&handle); return (-1); } @@ -202,7 +177,7 @@ srvsvc_net_share_get_info(char *server, char *domain, char *netname) break; } - srvsvc_close(&handle, &heap); + srvsvc_close(&handle); return (0); } @@ -215,7 +190,6 @@ srvsvc_net_session_enum(char *server, char *domain, char *netname) { struct mslm_NetSessionEnum arg; mlsvc_handle_t handle; - mlrpc_heapref_t heap; int rc; int opnum; struct mslm_infonres infonres; @@ -226,7 +200,7 @@ srvsvc_net_session_enum(char *server, char *domain, char *netname) if (netname == NULL) return (-1); - rc = srvsvc_open(server, domain, user, &handle, &heap); + rc = srvsvc_open(server, domain, user, &handle); if (rc != 0) return (-1); @@ -234,9 +208,9 @@ srvsvc_net_session_enum(char *server, char *domain, char *netname) bzero(&arg, sizeof (struct mslm_NetSessionEnum)); len = strlen(server) + 4; - arg.servername = mlrpc_heap_malloc(heap.heap, len); + arg.servername = ndr_rpc_malloc(&handle, len); if (arg.servername == NULL) { - srvsvc_close(&handle, &heap); + srvsvc_close(&handle); return (-1); } @@ -249,9 +223,9 @@ srvsvc_net_session_enum(char *server, char *domain, char *netname) arg.resume_handle = 0; arg.pref_max_len = 0xFFFFFFFF; - rc = mlsvc_rpc_call(handle.context, opnum, &arg, &heap); + rc = ndr_rpc_call(&handle, opnum, &arg); if ((rc != 0) || (arg.status != 0)) { - srvsvc_close(&handle, &heap); + srvsvc_close(&handle); return (-1); } @@ -266,7 +240,7 @@ srvsvc_net_session_enum(char *server, char *domain, char *netname) smb_tracef("srvsvc sesi1_itime=%u", nsi1->sesi1_itime); smb_tracef("srvsvc sesi1_uflags=%u", nsi1->sesi1_uflags); - srvsvc_close(&handle, &heap); + srvsvc_close(&handle); return (0); } @@ -280,7 +254,6 @@ srvsvc_net_connect_enum(char *server, char *domain, char *netname, int level) { struct mslm_NetConnectEnum arg; mlsvc_handle_t handle; - mlrpc_heapref_t heap; int rc; int opnum; struct mslm_NetConnectInfo1 info1; @@ -292,7 +265,7 @@ srvsvc_net_connect_enum(char *server, char *domain, char *netname, int level) if (netname == NULL) return (-1); - rc = srvsvc_open(server, domain, user, &handle, &heap); + rc = srvsvc_open(server, domain, user, &handle); if (rc != 0) return (-1); @@ -300,9 +273,9 @@ srvsvc_net_connect_enum(char *server, char *domain, char *netname, int level) bzero(&arg, sizeof (struct mslm_NetConnectEnum)); len = strlen(server) + 4; - arg.servername = mlrpc_heap_malloc(heap.heap, len); + arg.servername = ndr_rpc_malloc(&handle, len); if (arg.servername == NULL) { - srvsvc_close(&handle, &heap); + srvsvc_close(&handle); return (-1); } @@ -325,16 +298,16 @@ srvsvc_net_connect_enum(char *server, char *domain, char *netname, int level) info1.ci1 = 0; break; default: - srvsvc_close(&handle, &heap); + srvsvc_close(&handle); return (-1); } arg.resume_handle = 0; arg.pref_max_len = 0xFFFFFFFF; - rc = mlsvc_rpc_call(handle.context, opnum, &arg, &heap); + rc = ndr_rpc_call(&handle, opnum, &arg); if ((rc != 0) || (arg.status != 0)) { - srvsvc_close(&handle, &heap); + srvsvc_close(&handle); return (-1); } @@ -370,7 +343,7 @@ srvsvc_net_connect_enum(char *server, char *domain, char *netname, int level) break; } - srvsvc_close(&handle, &heap); + srvsvc_close(&handle); return (0); } @@ -380,15 +353,15 @@ srvsvc_net_connect_enum(char *server, char *domain, char *netname, int level) void srvsvc_timesync(void) { - smb_ntdomain_t *di; + smb_domain_t di; struct timeval tv; struct tm tm; time_t tsecs; - if ((di = smb_getdomaininfo(0)) == NULL) + if (!smb_domain_getinfo(&di)) return; - if (srvsvc_net_remote_tod(di->server, di->domain, &tv, &tm) != 0) + if (srvsvc_net_remote_tod(di.d_dc, di.d_nbdomain, &tv, &tm) != 0) return; if (settimeofday(&tv, 0)) @@ -405,14 +378,14 @@ srvsvc_timesync(void) int srvsvc_gettime(unsigned long *t) { - smb_ntdomain_t *di; + smb_domain_t di; struct timeval tv; struct tm tm; - if ((di = smb_getdomaininfo(0)) == NULL) + if (!smb_domain_getinfo(&di)) return (-1); - if (srvsvc_net_remote_tod(di->server, di->domain, &tv, &tm) != 0) + if (srvsvc_net_remote_tod(di.d_dc, di.d_nbdomain, &tv, &tm) != 0) return (-1); *t = tv.tv_sec; @@ -455,13 +428,12 @@ srvsvc_net_remote_tod(char *server, char *domain, struct timeval *tv, struct mslm_NetRemoteTOD arg; struct mslm_TIME_OF_DAY_INFO *tod; mlsvc_handle_t handle; - mlrpc_heapref_t heap; int rc; int opnum; int len; char *user = smbrdr_ipc_get_user(); - rc = srvsvc_open(server, domain, user, &handle, &heap); + rc = srvsvc_open(server, domain, user, &handle); if (rc != 0) return (-1); @@ -469,17 +441,17 @@ srvsvc_net_remote_tod(char *server, char *domain, struct timeval *tv, bzero(&arg, sizeof (struct mslm_NetRemoteTOD)); len = strlen(server) + 4; - arg.servername = mlrpc_heap_malloc(heap.heap, len); + arg.servername = ndr_rpc_malloc(&handle, len); if (arg.servername == NULL) { - srvsvc_close(&handle, &heap); + srvsvc_close(&handle); return (-1); } (void) snprintf((char *)arg.servername, len, "\\\\%s", server); - rc = mlsvc_rpc_call(handle.context, opnum, &arg, &heap); + rc = ndr_rpc_call(&handle, opnum, &arg); if ((rc != 0) || (arg.status != 0)) { - srvsvc_close(&handle, &heap); + srvsvc_close(&handle); return (-1); } @@ -510,20 +482,20 @@ srvsvc_net_remote_tod(char *server, char *domain, struct timeval *tv, smb_tracef("NetRemoteTOD from %s: %s", server, timebuf); } - srvsvc_close(&handle, &heap); + srvsvc_close(&handle); return (0); } void srvsvc_net_test(char *server, char *domain, char *netname) { - smb_ntdomain_t *di; + smb_domain_t di; (void) smb_tracef("%s %s %s", server, domain, netname); - if ((di = smb_getdomaininfo(0)) != NULL) { - server = di->server; - domain = di->domain; + if (smb_domain_getinfo(&di)) { + server = di.d_dc; + domain = di.d_nbdomain; } (void) srvsvc_net_share_get_info(server, domain, netname); diff --git a/usr/src/lib/smbsrv/libmlsvc/common/svcctl_scm.h b/usr/src/lib/smbsrv/libmlsvc/common/svcctl_scm.h index dc5c84a974..4e7bf8658c 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/svcctl_scm.h +++ b/usr/src/lib/smbsrv/libmlsvc/common/svcctl_scm.h @@ -28,8 +28,9 @@ #include <libuutil.h> #include <smbsrv/libsmb.h> +#include <smbsrv/libmlrpc.h> +#include <smbsrv/libmlsvc.h> #include <smbsrv/nterror.h> -#include <smbsrv/mlrpc.h> #include <smbsrv/winsvc.h> #include <smbsrv/ndl/svcctl.ndl> diff --git a/usr/src/lib/smbsrv/libmlsvc/common/svcctl_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/svcctl_svc.c index f4a05e4b97..3af38cf938 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/svcctl_svc.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/svcctl_svc.c @@ -31,13 +31,11 @@ * SVCCTL access is restricted to administrators: members of the * Domain Admins or Administrators groups. */ + #include <stdio.h> #include <strings.h> - #include <smbsrv/ntstatus.h> #include <smbsrv/nmpipes.h> -#include <smbsrv/mlsvc_util.h> - #include "svcctl_scm.h" #define SVCCTL_OPENSVC_OP_UNIMPLEMENTED(S) \ @@ -47,17 +45,17 @@ ((S) & SERVICE_STOP) || \ ((S) & SERVICE_ENUMERATE_DEPENDENTS) -static int svcctl_s_Close(void *, struct mlrpc_xaction *); -static int svcctl_s_OpenManager(void *, struct mlrpc_xaction *); -static int svcctl_s_OpenService(void *, struct mlrpc_xaction *); -static int svcctl_s_QueryServiceStatus(void *, struct mlrpc_xaction *); -static int svcctl_s_QueryServiceConfig(void *, struct mlrpc_xaction *); -static int svcctl_s_EnumServicesStatus(void *, struct mlrpc_xaction *); -static int svcctl_s_GetServiceDisplayNameW(void *, struct mlrpc_xaction *); -static int svcctl_s_GetServiceKeyNameW(void *, struct mlrpc_xaction *); -static int svcctl_s_QueryServiceConfig2W(void *, struct mlrpc_xaction *); - -static mlrpc_stub_table_t svcctl_stub_table[] = { +static int svcctl_s_Close(void *, ndr_xa_t *); +static int svcctl_s_OpenManager(void *, ndr_xa_t *); +static int svcctl_s_OpenService(void *, ndr_xa_t *); +static int svcctl_s_QueryServiceStatus(void *, ndr_xa_t *); +static int svcctl_s_QueryServiceConfig(void *, ndr_xa_t *); +static int svcctl_s_EnumServicesStatus(void *, ndr_xa_t *); +static int svcctl_s_GetServiceDisplayNameW(void *, ndr_xa_t *); +static int svcctl_s_GetServiceKeyNameW(void *, ndr_xa_t *); +static int svcctl_s_QueryServiceConfig2W(void *, ndr_xa_t *); + +static ndr_stub_table_t svcctl_stub_table[] = { { svcctl_s_Close, SVCCTL_OPNUM_Close }, { svcctl_s_OpenManager, SVCCTL_OPNUM_OpenManager }, { svcctl_s_OpenService, SVCCTL_OPNUM_OpenService }, @@ -71,13 +69,13 @@ static mlrpc_stub_table_t svcctl_stub_table[] = { {0} }; -static mlrpc_service_t svcctl_service = { +static ndr_service_t svcctl_service = { "SVCCTL", /* name */ "Service Control Services", /* desc */ "\\svcctl", /* endpoint */ PIPE_NTSVCS, /* sec_addr_port */ - "367abb81-9844-35f1-ad3298f038001003", 2, /* abstract */ - "8a885d04-1ceb-11c9-9fe808002b104860", 2, /* transfer */ + "367abb81-9844-35f1-ad32-98f038001003", 2, /* abstract */ + NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 0, /* no bind_instance_size */ 0, /* no bind_req() */ 0, /* no unbind_and_close() */ @@ -96,7 +94,7 @@ static mlrpc_service_t svcctl_service = { void svcctl_initialize(void) { - (void) mlrpc_register_service(&svcctl_service); + (void) ndr_svc_register(&svcctl_service); } /* @@ -286,7 +284,7 @@ svcctl_svc_hdalloc(ndr_xa_t *mxa, ndr_hdid_t *mgr_id, char *svc_name) * ERROR_INVALID_HANDLE */ static int -svcctl_s_Close(void *arg, struct mlrpc_xaction *mxa) +svcctl_s_Close(void *arg, ndr_xa_t *mxa) { struct svcctl_Close *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; @@ -295,7 +293,7 @@ svcctl_s_Close(void *arg, struct mlrpc_xaction *mxa) bzero(¶m->result_handle, sizeof (svcctl_handle_t)); param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -312,7 +310,7 @@ svcctl_s_Close(void *arg, struct mlrpc_xaction *mxa) * On success, returns a handle for use with subsequent svcctl requests. */ static int -svcctl_s_OpenManager(void *arg, struct mlrpc_xaction *mxa) +svcctl_s_OpenManager(void *arg, ndr_xa_t *mxa) { struct svcctl_OpenManager *param = arg; ndr_hdid_t *id = NULL; @@ -323,7 +321,7 @@ svcctl_s_OpenManager(void *arg, struct mlrpc_xaction *mxa) if ((rc == 0) || (param->desired_access & SC_MANAGER_LOCK) != 0) { bzero(¶m->handle, sizeof (svcctl_handle_t)); param->status = ERROR_ACCESS_DENIED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } id = svcctl_mgr_hdalloc(mxa); @@ -335,7 +333,7 @@ svcctl_s_OpenManager(void *arg, struct mlrpc_xaction *mxa) param->status = ERROR_ACCESS_DENIED; } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -350,7 +348,7 @@ svcctl_s_OpenManager(void *arg, struct mlrpc_xaction *mxa) * ERROR_CALL_NOT_IMPLEMENTED */ static int -svcctl_s_OpenService(void *arg, struct mlrpc_xaction *mxa) +svcctl_s_OpenService(void *arg, ndr_xa_t *mxa) { struct svcctl_OpenService *param = arg; ndr_hdid_t *mgrid = (ndr_hdid_t *)¶m->manager_handle; @@ -368,14 +366,14 @@ svcctl_s_OpenService(void *arg, struct mlrpc_xaction *mxa) if (unimplemented_operations) { bzero(¶m->service_handle, sizeof (svcctl_handle_t)); param->status = ERROR_CALL_NOT_IMPLEMENTED; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } hd = svcctl_hdlookup(mxa, mgrid, SVCCTL_MANAGER_CONTEXT); if (hd == NULL) { bzero(¶m->service_handle, sizeof (svcctl_handle_t)); param->status = ERROR_INVALID_HANDLE; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; @@ -383,7 +381,7 @@ svcctl_s_OpenService(void *arg, struct mlrpc_xaction *mxa) if (status != ERROR_SUCCESS) { bzero(¶m->service_handle, sizeof (svcctl_handle_t)); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } id = svcctl_svc_hdalloc(mxa, mgrid, svc_name); @@ -395,7 +393,7 @@ svcctl_s_OpenService(void *arg, struct mlrpc_xaction *mxa) param->status = ERROR_ACCESS_DENIED; } - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -406,7 +404,7 @@ svcctl_s_OpenService(void *arg, struct mlrpc_xaction *mxa) * ERROR_INVALID_HANDLE */ static int -svcctl_s_QueryServiceStatus(void *arg, struct mlrpc_xaction *mxa) +svcctl_s_QueryServiceStatus(void *arg, ndr_xa_t *mxa) { struct svcctl_QueryServiceStatus *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; @@ -419,7 +417,7 @@ svcctl_s_QueryServiceStatus(void *arg, struct mlrpc_xaction *mxa) if (hd == NULL) { bzero(param, sizeof (struct svcctl_QueryServiceStatus)); param->status = ERROR_INVALID_HANDLE; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc; @@ -427,14 +425,14 @@ svcctl_s_QueryServiceStatus(void *arg, struct mlrpc_xaction *mxa) if (mgr_ctx == NULL) { bzero(param, sizeof (struct svcctl_QueryServiceConfig)); param->status = ERROR_INVALID_HANDLE; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname); if (svc == NULL || svc->sn_state == NULL) { bzero(param, sizeof (struct svcctl_QueryServiceConfig)); param->status = ERROR_SERVICE_DOES_NOT_EXIST; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } param->service_status.service_type = SERVICE_WIN32_SHARE_PROCESS; @@ -446,7 +444,7 @@ svcctl_s_QueryServiceStatus(void *arg, struct mlrpc_xaction *mxa) param->service_status.wait_hint = 0; param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -462,7 +460,7 @@ svcctl_s_QueryServiceStatus(void *arg, struct mlrpc_xaction *mxa) * ERROR_NOT_ENOUGH_MEMORY */ static int -svcctl_s_EnumServicesStatus(void *arg, struct mlrpc_xaction *mxa) +svcctl_s_EnumServicesStatus(void *arg, ndr_xa_t *mxa) { struct svcctl_EnumServicesStatus *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->manager_handle; @@ -473,24 +471,26 @@ svcctl_s_EnumServicesStatus(void *arg, struct mlrpc_xaction *mxa) hd = svcctl_hdlookup(mxa, id, SVCCTL_MANAGER_CONTEXT); if (hd == NULL) { bzero(param, sizeof (struct svcctl_EnumServicesStatus)); - param->services = MLRPC_HEAP_STRSAVE(mxa, ""); + param->services = NDR_STRDUP(mxa, ""); param->status = ERROR_INVALID_HANDLE; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; if (svcctl_scm_refresh(mgr_ctx) != 0) { bzero(param, sizeof (struct svcctl_EnumServicesStatus)); + param->services = NDR_STRDUP(mxa, ""); param->status = ERROR_INVALID_DATA; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } input_bufsize = param->buf_size; - param->services = MLRPC_HEAP_MALLOC(mxa, input_bufsize); + param->services = NDR_MALLOC(mxa, input_bufsize); if (param->services == NULL) { bzero(param, sizeof (struct svcctl_EnumServicesStatus)); + param->services = NDR_STRDUP(mxa, ""); param->status = ERROR_NOT_ENOUGH_MEMORY; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(param->services, input_bufsize); @@ -499,7 +499,7 @@ svcctl_s_EnumServicesStatus(void *arg, struct mlrpc_xaction *mxa) param->svc_num = 0; param->resume_handle = 0; param->status = ERROR_MORE_DATA; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } svcctl_scm_enum_services(mgr_ctx, param->services); @@ -509,7 +509,7 @@ svcctl_s_EnumServicesStatus(void *arg, struct mlrpc_xaction *mxa) param->svc_num = mgr_ctx->mc_scf_numsvcs; param->resume_handle = 0; param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -520,7 +520,7 @@ svcctl_s_EnumServicesStatus(void *arg, struct mlrpc_xaction *mxa) * ERROR_INVALID_HANDLE */ static int -svcctl_s_QueryServiceConfig(void *arg, struct mlrpc_xaction *mxa) +svcctl_s_QueryServiceConfig(void *arg, ndr_xa_t *mxa) { struct svcctl_QueryServiceConfig *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; @@ -535,7 +535,7 @@ svcctl_s_QueryServiceConfig(void *arg, struct mlrpc_xaction *mxa) if (hd == NULL) { bzero(param, sizeof (struct svcctl_QueryServiceConfig)); param->status = ERROR_INVALID_HANDLE; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc; @@ -543,26 +543,26 @@ svcctl_s_QueryServiceConfig(void *arg, struct mlrpc_xaction *mxa) if (mgr_ctx == NULL) { bzero(param, sizeof (struct svcctl_QueryServiceConfig)); param->status = ERROR_INVALID_HANDLE; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname); if (svc == NULL || svc->sn_fmri == NULL) { bzero(param, sizeof (struct svcctl_QueryServiceConfig)); param->status = ERROR_SERVICE_DOES_NOT_EXIST; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } cfg = ¶m->service_cfg; cfg->service_type = SERVICE_WIN32_SHARE_PROCESS; cfg->start_type = SERVICE_AUTO_START; cfg->error_control = SERVICE_AUTO_START; - cfg->binary_pathname = MLRPC_HEAP_STRSAVE(mxa, ""); - cfg->loadorder_group = MLRPC_HEAP_STRSAVE(mxa, ""); + cfg->binary_pathname = NDR_STRDUP(mxa, ""); + cfg->loadorder_group = NDR_STRDUP(mxa, ""); cfg->tag_id = 0; - cfg->dependencies = MLRPC_HEAP_STRSAVE(mxa, ""); - cfg->service_startname = MLRPC_HEAP_STRSAVE(mxa, ""); - cfg->display_name = MLRPC_HEAP_STRSAVE(mxa, svc->sn_fmri); + cfg->dependencies = NDR_STRDUP(mxa, ""); + cfg->service_startname = NDR_STRDUP(mxa, ""); + cfg->display_name = NDR_STRDUP(mxa, svc->sn_fmri); bytes_needed = sizeof (svc_config_t); bytes_needed += SVCCTL_WNSTRLEN((const char *)cfg->binary_pathname); @@ -575,12 +575,12 @@ svcctl_s_QueryServiceConfig(void *arg, struct mlrpc_xaction *mxa) bzero(param, sizeof (struct svcctl_QueryServiceConfig)); param->cfg_bytes = bytes_needed; param->status = ERROR_MORE_DATA; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } param->cfg_bytes = bytes_needed; param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -592,7 +592,7 @@ svcctl_s_QueryServiceConfig(void *arg, struct mlrpc_xaction *mxa) * ERROR_SERVICE_DOES_NOT_EXIST */ static int -svcctl_s_GetServiceDisplayNameW(void *arg, struct mlrpc_xaction *mxa) +svcctl_s_GetServiceDisplayNameW(void *arg, ndr_xa_t *mxa) { struct svcctl_GetServiceDisplayNameW *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->manager_handle; @@ -603,31 +603,31 @@ svcctl_s_GetServiceDisplayNameW(void *arg, struct mlrpc_xaction *mxa) hd = svcctl_hdlookup(mxa, id, SVCCTL_MANAGER_CONTEXT); if (hd == NULL) { bzero(param, sizeof (struct svcctl_GetServiceDisplayNameW)); - param->display_name = MLRPC_HEAP_STRSAVE(mxa, ""); + param->display_name = NDR_STRDUP(mxa, ""); param->status = ERROR_INVALID_HANDLE; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; svc = svcctl_scm_find_service(mgr_ctx, (char *)param->service_name); if (svc == NULL || svc->sn_fmri == NULL) { bzero(param, sizeof (struct svcctl_GetServiceDisplayNameW)); - param->display_name = MLRPC_HEAP_STRSAVE(mxa, ""); + param->display_name = NDR_STRDUP(mxa, ""); param->status = ERROR_SERVICE_DOES_NOT_EXIST; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } - param->display_name = MLRPC_HEAP_STRSAVE(mxa, svc->sn_fmri); + param->display_name = NDR_STRDUP(mxa, svc->sn_fmri); if (param->display_name == NULL) { bzero(param, sizeof (struct svcctl_GetServiceDisplayNameW)); - param->display_name = MLRPC_HEAP_STRSAVE(mxa, ""); + param->display_name = NDR_STRDUP(mxa, ""); param->status = ERROR_NOT_ENOUGH_MEMORY; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } param->buf_size = strlen(svc->sn_fmri); param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -639,7 +639,7 @@ svcctl_s_GetServiceDisplayNameW(void *arg, struct mlrpc_xaction *mxa) * ERROR_SERVICE_DOES_NOT_EXIST */ static int -svcctl_s_GetServiceKeyNameW(void *arg, struct mlrpc_xaction *mxa) +svcctl_s_GetServiceKeyNameW(void *arg, ndr_xa_t *mxa) { struct svcctl_GetServiceKeyNameW *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->manager_handle; @@ -650,31 +650,31 @@ svcctl_s_GetServiceKeyNameW(void *arg, struct mlrpc_xaction *mxa) hd = svcctl_hdlookup(mxa, id, SVCCTL_MANAGER_CONTEXT); if (hd == NULL) { bzero(param, sizeof (struct svcctl_GetServiceKeyNameW)); - param->key_name = MLRPC_HEAP_STRSAVE(mxa, ""); + param->key_name = NDR_STRDUP(mxa, ""); param->status = ERROR_INVALID_HANDLE; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; svc = svcctl_scm_find_service(mgr_ctx, (char *)param->service_name); if (svc == NULL || svc->sn_name == NULL) { bzero(param, sizeof (struct svcctl_GetServiceKeyNameW)); - param->key_name = MLRPC_HEAP_STRSAVE(mxa, ""); + param->key_name = NDR_STRDUP(mxa, ""); param->status = ERROR_SERVICE_DOES_NOT_EXIST; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } - param->key_name = MLRPC_HEAP_STRSAVE(mxa, svc->sn_name); + param->key_name = NDR_STRDUP(mxa, svc->sn_name); if (param->key_name == NULL) { bzero(param, sizeof (struct svcctl_GetServiceKeyNameW)); - param->key_name = MLRPC_HEAP_STRSAVE(mxa, ""); + param->key_name = NDR_STRDUP(mxa, ""); param->status = ERROR_NOT_ENOUGH_MEMORY; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } param->buf_size = strlen(svc->sn_name); param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } /* @@ -687,7 +687,7 @@ svcctl_s_GetServiceKeyNameW(void *arg, struct mlrpc_xaction *mxa) * ERROR_NOT_ENOUGH_MEMORY */ static int -svcctl_s_QueryServiceConfig2W(void *arg, struct mlrpc_xaction *mxa) +svcctl_s_QueryServiceConfig2W(void *arg, ndr_xa_t *mxa) { struct svcctl_QueryServiceConfig2W *param = arg; ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; @@ -705,17 +705,18 @@ svcctl_s_QueryServiceConfig2W(void *arg, struct mlrpc_xaction *mxa) hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); if (hd == NULL) { bzero(param, sizeof (struct svcctl_QueryServiceConfig2W)); - param->buffer = MLRPC_HEAP_STRSAVE(mxa, ""); + param->buffer = NDR_STRDUP(mxa, ""); param->status = ERROR_INVALID_HANDLE; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } input_bufsize = param->buf_size; - param->buffer = MLRPC_HEAP_MALLOC(mxa, input_bufsize); + param->buffer = NDR_MALLOC(mxa, input_bufsize); if (param->buffer == NULL) { bzero(param, sizeof (struct svcctl_QueryServiceConfig2W)); + param->buffer = NDR_STRDUP(mxa, ""); param->status = ERROR_NOT_ENOUGH_MEMORY; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } bzero(param->buffer, input_bufsize); @@ -741,7 +742,7 @@ svcctl_s_QueryServiceConfig2W(void *arg, struct mlrpc_xaction *mxa) if (input_bufsize <= bytes_needed) { param->bytes_needed = bytes_needed; param->status = ERROR_MORE_DATA; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } offset = sizeof (svc_description_t); @@ -771,11 +772,11 @@ svcctl_s_QueryServiceConfig2W(void *arg, struct mlrpc_xaction *mxa) if (status != ERROR_SUCCESS) { bzero(param, sizeof (struct svcctl_QueryServiceConfig2W)); - param->buffer = MLRPC_HEAP_STRSAVE(mxa, ""); + param->buffer = NDR_STRDUP(mxa, ""); param->status = status; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } param->status = ERROR_SUCCESS; - return (MLRPC_DRC_OK); + return (NDR_DRC_OK); } diff --git a/usr/src/lib/smbsrv/libsmb/Makefile.com b/usr/src/lib/smbsrv/libsmb/Makefile.com index 6804c1bafc..04182f247c 100644 --- a/usr/src/lib/smbsrv/libsmb/Makefile.com +++ b/usr/src/lib/smbsrv/libsmb/Makefile.com @@ -64,7 +64,6 @@ OBJS_COMMON = \ smb_privilege.o \ smb_scfutil.o \ smb_util.o \ - smb_wins.o \ smb_wksids.o OBJECTS= $(OBJS_COMMON) $(OBJS_SHARED) @@ -75,7 +74,8 @@ include ../../Makefile.lib INCS += -I$(SRC)/common/smbsrv LDLIBS += $(MACH_LDLIBS) -LDLIBS += -lscf -lmd -lnsl -lpkcs11 -lc -lsocket -lresolv -lidmap -lavl +LDLIBS += -lscf -lmd -lnsl -lpkcs11 -lsocket -lresolv +LDLIBS += -lidmap -lavl -lc CPPFLAGS += $(INCS) -D_REENTRANT SRCS= $(OBJS_COMMON:%.o=$(SRCDIR)/%.c) \ diff --git a/usr/src/lib/smbsrv/libsmb/common/libsmb.h b/usr/src/lib/smbsrv/libsmb/common/libsmb.h index 8fa749281f..801e71ce3a 100644 --- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h +++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h @@ -35,7 +35,6 @@ extern "C" { #include <arpa/inet.h> #include <net/if.h> #include <netdb.h> - #include <stdlib.h> #include <libscf.h> #include <libshare.h> @@ -62,6 +61,8 @@ extern "C" { #define SMB_CCACHE_FILE "ccache" #define SMB_CCACHE_PATH SMB_VARRUN_DIR "/" SMB_CCACHE_FILE + + /* Max value length of all SMB properties */ #define MAX_VALUE_BUFLEN 512 @@ -104,6 +105,9 @@ typedef enum { SMB_CI_DOMAIN_SID, SMB_CI_DOMAIN_MEMB, SMB_CI_DOMAIN_NAME, + SMB_CI_DOMAIN_FQDN, + SMB_CI_DOMAIN_FOREST, + SMB_CI_DOMAIN_GUID, SMB_CI_DOMAIN_SRV, SMB_CI_WINS_SRV1, @@ -111,7 +115,6 @@ typedef enum { SMB_CI_WINS_EXCL, SMB_CI_SRVSVC_SHRSET_ENABLE, - SMB_CI_MLRPC_KALIVE, SMB_CI_MAX_WORKERS, SMB_CI_MAX_CONNECTIONS, @@ -158,6 +161,7 @@ extern int smb_smf_get_opaque_property(smb_scfhandle_t *, char *, void *, size_t); extern int smb_smf_create_service_pgroup(smb_scfhandle_t *, char *); extern int smb_smf_restart_service(void); +extern int smb_smf_maintenance_mode(void); /* Configuration management functions */ extern int smb_config_get(smb_cfg_id_t, char *, int); @@ -180,6 +184,7 @@ extern int smb_config_set_secmode(int); extern int smb_config_set_idmap_domain(char *); extern int smb_config_refresh_idmap(void); + extern void smb_load_kconfig(smb_kmod_cfg_t *kcfg); extern uint32_t smb_crc_gen(uint8_t *, size_t); @@ -208,30 +213,11 @@ extern bool_t xdr_smb_dr_joininfo_t(XDR *, smb_joininfo_t *); extern int nt_domain_init(char *, uint32_t); -/* Following set of functions, manipulate WINS server configuration */ -extern int smb_wins_allow_list(char *config_list, char *allow_list); -extern int smb_wins_exclude_list(char *config_list, char *exclude_list); -extern boolean_t smb_wins_is_excluded(in_addr_t ipaddr, - ipaddr_t *exclude_list, int nexclude); -extern void smb_wins_build_list(char *buf, uint32_t iplist[], int max_naddr); -extern int smb_wins_iplist(char *list, uint32_t iplist[], int max_naddr); - -/* - * Information on a particular domain: the domain name, the - * name of a controller (PDC or BDC) and it's ip address. - */ -typedef struct smb_ntdomain { - char domain[SMB_PI_MAX_DOMAIN]; - char server[SMB_PI_MAX_DOMAIN]; - uint32_t ipaddr; -} smb_ntdomain_t; - -/* SMB domain information management functions */ -extern smb_ntdomain_t *smb_getdomaininfo(uint32_t); -extern void smb_setdomaininfo(char *, char *, uint32_t); -extern void smb_logdomaininfo(smb_ntdomain_t *); -extern uint32_t smb_get_dcinfo(smb_ntdomain_t *); -extern bool_t xdr_smb_dr_domain_t(XDR *, smb_ntdomain_t *); +extern void smb_config_getdomaininfo(char *domain, char *fqdn, char *forest, + char *guid); +extern void smb_config_setdomaininfo(char *domain, char *fqdn, char *forest, + char *guid); +extern uint32_t smb_get_dcinfo(char *, uint32_t, uint32_t *); /* * buffer context structure. This is used to keep track of the buffer @@ -261,17 +247,19 @@ extern int smb_idmap_restart(void); extern void hexdump(unsigned char *, int); extern size_t bintohex(const char *, size_t, char *, size_t); extern size_t hextobin(const char *, size_t, char *, size_t); -extern char *trim_whitespace(char *buf); +extern char *strstrip(char *, const char *); +extern char *strtrim(char *, const char *); +extern char *trim_whitespace(char *); extern void randomize(char *, unsigned); extern void rand_hash(unsigned char *, size_t, unsigned char *, size_t); -extern int smb_resolve_netbiosname(char *, char *, size_t); -extern int smb_resolve_fqdn(char *, char *, size_t); extern int smb_getdomainname(char *, size_t); extern int smb_getfqdomainname(char *, size_t); extern int smb_gethostname(char *, size_t, int); extern int smb_getfqhostname(char *, size_t); extern int smb_getnetbiosname(char *, size_t); +extern struct hostent *smb_gethostbyname(const char *, int *); +extern struct hostent *smb_gethostbyaddr(const char *, int, int, int *); #define SMB_SAMACCT_MAXLEN (NETBIOS_NAME_SZ + 1) extern int smb_getsamaccount(char *, size_t); diff --git a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers index ff3ba1eaa9..a545fd6af5 100644 --- a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers +++ b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers @@ -99,6 +99,7 @@ SUNWprivate { smb_config_get_localsid; smb_config_get_secmode; smb_config_getbool; + smb_config_getdomaininfo; smb_config_getname; smb_config_getnum; smb_config_getstr; @@ -109,6 +110,7 @@ SUNWprivate { smb_config_set_idmap_domain; smb_config_set_secmode; smb_config_setbool; + smb_config_setdomaininfo; smb_config_setnum; smb_config_setstr; smb_crc_gen; @@ -159,11 +161,12 @@ SUNWprivate { smb_dr_ulist_free; smb_get_dcinfo; smb_get_nameservers; - smb_getdomaininfo; smb_getdomainname; smb_getdomainsid; smb_getfqdomainname; smb_getfqhostname; + smb_gethostbyaddr; + smb_gethostbyname; smb_gethostname; smb_getnetbiosname; smb_getsamaccount; @@ -262,9 +265,6 @@ SUNWprivate { smb_pwd_num = AUXILIARY libsmb_pwd.so; smb_pwd_setcntl = AUXILIARY libsmb_pwd.so; smb_pwd_setpasswd = AUXILIARY libsmb_pwd.so; - smb_resolve_fqdn; - smb_resolve_netbiosname; - smb_setdomaininfo; smb_setdomainprops; smb_sid_cmp; smb_sid_dup; @@ -279,31 +279,14 @@ SUNWprivate { smb_sid_split; smb_sid_tostr; smb_sid_type2str; - smb_smf_create_service_pgroup; - smb_smf_end_transaction; - smb_smf_get_boolean_property; - smb_smf_get_integer_property; - smb_smf_get_opaque_property; - smb_smf_get_string_property; + smb_smf_maintenance_mode; smb_smf_restart_service; - smb_smf_scf_fini; - smb_smf_scf_init; - smb_smf_set_boolean_property; - smb_smf_set_integer_property; - smb_smf_set_opaque_property; - smb_smf_set_string_property; - smb_smf_start_transaction; smb_token_mkselfrel; smb_token_query_privilege; smb_tonetbiosname; smb_trace; smb_tracef; smb_update_netlogon_seqnum; - smb_wins_allow_list; - smb_wins_build_list; - smb_wins_exclude_list; - smb_wins_iplist; - smb_wins_is_excluded; smb_wka_fini; smb_wka_init; smb_wka_is_wellknown; @@ -315,7 +298,9 @@ SUNWprivate { smbnative_os_value; smbnative_pdc_value; strcanon; + strstrip; strsubst; + strtrim; trim_whitespace; unicodestooems; utf8_isstrascii; @@ -326,7 +311,6 @@ SUNWprivate { utf8_strncasecmp; utf8_strupr; xdr_smb_dr_bytes_t; - xdr_smb_dr_domain_t; xdr_smb_dr_joininfo_t; xdr_smb_dr_string_t; xdr_smb_dr_ulist_t; diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_api_door_calls.c b/usr/src/lib/smbsrv/libsmb/common/smb_api_door_calls.c index bbbea0b455..1e3215544f 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_api_door_calls.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_api_door_calls.c @@ -249,13 +249,19 @@ smb_join(smb_joininfo_t *jdi) * domain information. */ uint32_t -smb_get_dcinfo(smb_ntdomain_t *dc_info) +smb_get_dcinfo(char *namebuf, uint32_t namebuflen, uint32_t *ipaddr) { door_arg_t arg; char *buf; size_t len; int opcode = SMB_DR_GET_DCINFO; - int fd, rc = NT_STATUS_SUCCESS; + int fd; + char *srvname = NULL; + struct hostent *h; + int error_num; + + assert((namebuf != NULL) && (namebuflen != 0)); + *namebuf = '\0'; if ((fd = open(SMB_DR_SVC_NAME, O_RDONLY)) < 0) return (NT_STATUS_INTERNAL_ERROR); @@ -270,15 +276,23 @@ smb_get_dcinfo(smb_ntdomain_t *dc_info) if (smb_dr_clnt_call(fd, &arg) == 0) { buf = arg.rbuf + SMB_DR_DATA_OFFSET; len = arg.rsize - SMB_DR_DATA_OFFSET; - rc = smb_dr_decode_common(buf, len, xdr_smb_dr_domain_t, - dc_info); - if (rc != 0) - rc = NT_STATUS_INTERNAL_ERROR; + srvname = smb_dr_decode_string(buf, len); } smb_dr_clnt_cleanup(&arg); (void) close(fd); - return (rc); + + if (srvname) { + (void) strlcpy(namebuf, srvname, namebuflen); + if ((h = smb_gethostbyname(srvname, &error_num)) == NULL) { + *ipaddr = 0; + } else { + (void) memcpy(ipaddr, h->h_addr, h->h_length); + freehostent(h); + } + xdr_free(xdr_string, (char *)&srvname); + } + return (NT_STATUS_SUCCESS); } bool_t @@ -301,17 +315,3 @@ xdr_smb_dr_joininfo_t(XDR *xdrs, smb_joininfo_t *objp) return (TRUE); } - -bool_t -xdr_smb_dr_domain_t(XDR *xdrs, smb_ntdomain_t *objp) -{ - if (!xdr_vector(xdrs, (char *)objp->domain, SMB_PI_MAX_DOMAIN, - sizeof (char), (xdrproc_t)xdr_char)) - return (FALSE); - if (!xdr_vector(xdrs, (char *)objp->server, SMB_PI_MAX_DOMAIN, - sizeof (char), (xdrproc_t)xdr_char)) - return (FALSE); - if (!xdr_uint32_t(xdrs, &objp->ipaddr)) - return (FALSE); - return (TRUE); -} diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c b/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c index 5b9b0df61c..41ae235675 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c @@ -41,6 +41,7 @@ #include <sys/types.h> #include <libscf.h> #include <assert.h> +#include <uuid/uuid.h> #include <smbsrv/libsmb.h> typedef struct smb_cfg_param { @@ -82,6 +83,9 @@ static smb_cfg_param_t smb_cfg_table[] = {SMB_CI_DOMAIN_SID, "domain_sid", SCF_TYPE_ASTRING, 0}, {SMB_CI_DOMAIN_MEMB, "domain_member", SCF_TYPE_BOOLEAN, 0}, {SMB_CI_DOMAIN_NAME, "domain_name", SCF_TYPE_ASTRING, 0}, + {SMB_CI_DOMAIN_FQDN, "fqdn", SCF_TYPE_ASTRING, 0}, + {SMB_CI_DOMAIN_FOREST, "forest", SCF_TYPE_ASTRING, 0}, + {SMB_CI_DOMAIN_GUID, "domain_guid", SCF_TYPE_ASTRING, 0}, {SMB_CI_DOMAIN_SRV, "pdc", SCF_TYPE_ASTRING, 0}, /* WINS configuration */ @@ -92,8 +96,6 @@ static smb_cfg_param_t smb_cfg_table[] = /* RPC services configuration */ {SMB_CI_SRVSVC_SHRSET_ENABLE, "srvsvc_sharesetinfo_enable", SCF_TYPE_BOOLEAN, 0}, - {SMB_CI_MLRPC_KALIVE, "mlrpc_keep_alive_interval", - SCF_TYPE_INTEGER, 0}, /* Kmod specific configuration */ {SMB_CI_MAX_WORKERS, "max_workers", SCF_TYPE_INTEGER, 0}, @@ -756,3 +758,22 @@ smb_config_getent(smb_cfg_id_t id) assert(0); return (NULL); } + +void +smb_config_getdomaininfo(char *domain, char *fqdn, char *forest, char *guid) +{ + (void) smb_config_getstr(SMB_CI_DOMAIN_NAME, domain, NETBIOS_NAME_SZ); + (void) smb_config_getstr(SMB_CI_DOMAIN_FQDN, fqdn, MAXHOSTNAMELEN); + (void) smb_config_getstr(SMB_CI_DOMAIN_FOREST, forest, MAXHOSTNAMELEN); + (void) smb_config_getstr(SMB_CI_DOMAIN_GUID, guid, + UUID_PRINTABLE_STRING_LENGTH); +} + +void +smb_config_setdomaininfo(char *domain, char *fqdn, char *forest, char *guid) +{ + (void) smb_config_setstr(SMB_CI_DOMAIN_NAME, domain); + (void) smb_config_setstr(SMB_CI_DOMAIN_FQDN, fqdn); + (void) smb_config_setstr(SMB_CI_DOMAIN_FOREST, forest); + (void) smb_config_setstr(SMB_CI_DOMAIN_GUID, guid); +} diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c b/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c index 15df430d59..39c5e7746e 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c @@ -24,9 +24,20 @@ */ #include <strings.h> +#include <synch.h> #include <smbsrv/libsmb.h> -static idmap_handle_t *idmap_clnt_hdl = NULL; +#define SMB_IDMAP_STATE_INIT 1 +#define SMB_IDMAP_STATE_FINI 2 + +typedef struct smb_idmap_handle { + idmap_handle_t *sih_handle; + int sih_state; + rwlock_t sih_rwl; +} smb_idmap_handle_t; + +static smb_idmap_handle_t smb_idmaph; + static int smb_idmap_batch_binsid(smb_idmap_batch_t *sib); /* @@ -40,16 +51,22 @@ smb_idmap_start(void) { idmap_stat stat; - if (idmap_clnt_hdl) + (void) rw_wrlock(&smb_idmaph.sih_rwl); + if (smb_idmaph.sih_state == SMB_IDMAP_STATE_INIT) { + (void) rw_unlock(&smb_idmaph.sih_rwl); return (0); + } - stat = idmap_init(&idmap_clnt_hdl); + stat = idmap_init(&smb_idmaph.sih_handle); if (stat < 0) { + (void) rw_unlock(&smb_idmaph.sih_rwl); syslog(LOG_ERR, "smb_idmap_start: idmap_init failed (%s)", idmap_stat2string(NULL, stat)); return (-1); } + smb_idmaph.sih_state = SMB_IDMAP_STATE_INIT; + (void) rw_unlock(&smb_idmaph.sih_rwl); return (0); } @@ -62,10 +79,12 @@ smb_idmap_start(void) void smb_idmap_stop(void) { - if (idmap_clnt_hdl) { - (void) idmap_fini(idmap_clnt_hdl); - idmap_clnt_hdl = NULL; + (void) rw_wrlock(&smb_idmaph.sih_rwl); + if (smb_idmaph.sih_state == SMB_IDMAP_STATE_INIT) { + (void) idmap_fini(smb_idmaph.sih_handle); + smb_idmaph.sih_state = SMB_IDMAP_STATE_FINI; } + (void) rw_unlock(&smb_idmaph.sih_rwl); } /* @@ -77,13 +96,26 @@ smb_idmap_stop(void) int smb_idmap_restart(void) { - smb_idmap_stop(); - if (smb_idmap_start() != 0) { - syslog(LOG_ERR, "smb_idmap_restart: smb_idmap_start failed"); + idmap_stat stat; + int rc = 0; + + (void) rw_wrlock(&smb_idmaph.sih_rwl); + if (smb_idmaph.sih_state == SMB_IDMAP_STATE_FINI) { + (void) rw_unlock(&smb_idmaph.sih_rwl); return (-1); } - return (0); + (void) idmap_fini(smb_idmaph.sih_handle); + + stat = idmap_init(&smb_idmaph.sih_handle); + if (stat < 0) { + syslog(LOG_ERR, "smb_idmap_restart: idmap_init failed (%s)", + idmap_stat2string(NULL, stat)); + rc = -1; + } + + (void) rw_unlock(&smb_idmaph.sih_rwl); + return (rc); } /* @@ -173,8 +205,16 @@ smb_idmap_batch_create(smb_idmap_batch_t *sib, uint16_t nmap, int flags) if (!sib) return (IDMAP_ERR_ARG); + (void) rw_rdlock(&smb_idmaph.sih_rwl); + if (smb_idmaph.sih_state != SMB_IDMAP_STATE_INIT) { + (void) rw_unlock(&smb_idmaph.sih_rwl); + return (IDMAP_ERR_OTHER); + } + bzero(sib, sizeof (smb_idmap_batch_t)); - stat = idmap_get_create(idmap_clnt_hdl, &sib->sib_idmaph); + stat = idmap_get_create(smb_idmaph.sih_handle, &sib->sib_idmaph); + (void) rw_unlock(&smb_idmaph.sih_rwl); + if (stat != IDMAP_SUCCESS) return (stat); diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_info.c b/usr/src/lib/smbsrv/libsmb/common/smb_info.c index 82c1b82126..d8065f838f 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_info.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_info.c @@ -23,6 +23,7 @@ * Use is subject to license terms. */ +#include <assert.h> #include <sys/types.h> #include <stdarg.h> #include <unistd.h> @@ -39,92 +40,13 @@ #include <arpa/nameser.h> #include <resolv.h> #include <sys/sockio.h> +#include <sys/socket.h> #include <smbsrv/smbinfo.h> #include <smbsrv/netbios.h> #include <smbsrv/libsmb.h> -static smb_ntdomain_t smbpdc_cache; -static mutex_t smbpdc_mtx; -static cond_t smbpdc_cv; static mutex_t seqnum_mtx; -extern int getdomainname(char *, int); - -/* - * smb_getdomaininfo - * - * Returns a pointer to the cached domain data. The caller can specify - * whether or not he is prepared to wait if the cache is not yet valid - * and for how long. The specified timeout is in seconds. - */ -smb_ntdomain_t * -smb_getdomaininfo(uint32_t timeout) -{ - timestruc_t to; - int err; - - if (timeout != 0) { - (void) mutex_lock(&smbpdc_mtx); - while (smbpdc_cache.ipaddr == 0) { - to.tv_sec = timeout; - to.tv_nsec = 0; - err = cond_reltimedwait(&smbpdc_cv, &smbpdc_mtx, &to); - if (err == ETIME) - break; - } - (void) mutex_unlock(&smbpdc_mtx); - } - - if (smbpdc_cache.ipaddr != 0) - return (&smbpdc_cache); - else - return (0); -} - -void -smb_logdomaininfo(smb_ntdomain_t *di) -{ - char ipstr[16]; - - (void) inet_ntop(AF_INET, (const void *)&di->ipaddr, ipstr, - sizeof (ipstr)); - syslog(LOG_DEBUG, "smbd: %s (%s:%s)", di->domain, di->server, ipstr); -} - -/* - * smb_setdomaininfo - * - * Set the information for the specified domain. If the information is - * non-null, the notification event is raised to wakeup any threads - * blocking on the cache. - */ -void -smb_setdomaininfo(char *domain, char *server, uint32_t ipaddr) -{ - char *p; - - (void) mutex_lock(&smbpdc_mtx); - bzero(&smbpdc_cache, sizeof (smb_ntdomain_t)); - if (domain && server && ipaddr) { - (void) strlcpy(smbpdc_cache.domain, domain, SMB_PI_MAX_DOMAIN); - (void) strlcpy(smbpdc_cache.server, server, SMB_PI_MAX_DOMAIN); - - /* - * Remove DNS domain name extension - * to avoid confusing NetBIOS. - */ - if ((p = strchr(smbpdc_cache.domain, '.')) != 0) - *p = '\0'; - - if ((p = strchr(smbpdc_cache.server, '.')) != 0) - *p = '\0'; - - smbpdc_cache.ipaddr = ipaddr; - (void) cond_broadcast(&smbpdc_cv); - } - (void) mutex_unlock(&smbpdc_mtx); -} - void smb_load_kconfig(smb_kmod_cfg_t *kcfg) { @@ -259,35 +181,6 @@ smb_getfqhostname(char *buf, size_t buflen) } /* - * smb_resolve_netbiosname - * - * Convert the fully-qualified domain name (i.e. fqdn) to a NETBIOS name. - * Upon success, the NETBIOS name will be returned via buf parameter. - * Returns 0 upon success. Otherwise, returns -1. - */ -int -smb_resolve_netbiosname(char *fqdn, char *buf, size_t buflen) -{ - char *p; - - if (!buf) - return (-1); - - *buf = '\0'; - if (!fqdn) - return (-1); - - (void) strlcpy(buf, fqdn, buflen); - if ((p = strchr(buf, '.')) != NULL) - *p = 0; - - if (strlen(buf) >= NETBIOS_NAME_SZ) - buf[NETBIOS_NAME_SZ - 1] = '\0'; - - return (0); -} - -/* * smb_getdomainname * * Returns NETBIOS name of the domain if the system is in domain @@ -297,20 +190,17 @@ smb_resolve_netbiosname(char *fqdn, char *buf, size_t buflen) int smb_getdomainname(char *buf, size_t buflen) { - char domain[MAXHOSTNAMELEN]; int rc; if (buf == NULL || buflen == 0) return (-1); *buf = '\0'; - rc = smb_config_getstr(SMB_CI_DOMAIN_NAME, domain, - sizeof (domain)); + rc = smb_config_getstr(SMB_CI_DOMAIN_NAME, buf, buflen); - if ((rc != SMBD_SMF_OK) || (*domain == '\0')) + if ((rc != SMBD_SMF_OK) || (*buf == '\0')) return (-1); - (void) smb_resolve_netbiosname(domain, buf, buflen); return (0); } @@ -346,105 +236,42 @@ smb_getdomainsid(void) } /* - * smb_resolve_fqdn - * - * Converts the NETBIOS name of the domain (i.e. nbt_domain) to a fully - * qualified domain name. The domain from either the domain field or - * search list field of the /etc/resolv.conf will be returned via the - * buf parameter if the first label of the domain matches the given - * NETBIOS name. - * - * Returns -1 upon error. If a match is found, returns 1. Otherwise, - * returns 0. - */ -int -smb_resolve_fqdn(char *nbt_domain, char *buf, size_t buflen) -{ - struct __res_state res_state; - int i, found = 0; - char *p; - int dlen; - - if (!buf) - return (-1); - - *buf = '\0'; - if (!nbt_domain) - return (-1); - - bzero(&res_state, sizeof (struct __res_state)); - if (res_ninit(&res_state)) - return (-1); - - if (*nbt_domain == '\0') { - if (*res_state.defdname == '\0') { - res_ndestroy(&res_state); - return (0); - } - - (void) strlcpy(buf, res_state.defdname, buflen); - res_ndestroy(&res_state); - return (1); - } - - dlen = strlen(nbt_domain); - if (!strncasecmp(nbt_domain, res_state.defdname, dlen)) { - (void) strlcpy(buf, res_state.defdname, buflen); - res_ndestroy(&res_state); - return (1); - } - - for (i = 0; (p = res_state.dnsrch[i]) != NULL; i++) { - if (!strncasecmp(nbt_domain, p, dlen)) { - (void) strlcpy(buf, p, buflen); - found = 1; - break; - } - - } - - res_ndestroy(&res_state); - return (found); -} - -/* * smb_getfqdomainname * - * If the domain_name property value is FQDN, it will be returned. - * In domain mode, the domain from either the domain field or - * search list field of the /etc/resolv.conf will be returned via the - * buf parameter if the first label of the domain matches the - * domain_name property. In workgroup mode, it returns the local - * domain. + * In the system is in domain mode, the dns_domain property value + * is returned. Otherwise, it returns the local domain obtained via + * resolver. * * Returns 0 upon success. Otherwise, returns -1. */ int smb_getfqdomainname(char *buf, size_t buflen) { - char domain[MAXHOSTNAMELEN]; - int rc = 0; + struct __res_state res_state; + int rc; if (buf == NULL || buflen == 0) return (-1); *buf = '\0'; if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN) { - rc = smb_config_getstr(SMB_CI_DOMAIN_NAME, domain, - sizeof (domain)); + rc = smb_config_getstr(SMB_CI_DOMAIN_FQDN, buf, buflen); - if ((rc != SMBD_SMF_OK) || (*domain == '\0')) + if ((rc != SMBD_SMF_OK) || (*buf == '\0')) + return (-1); + } else { + bzero(&res_state, sizeof (struct __res_state)); + if (res_ninit(&res_state)) return (-1); - if (strchr(domain, '.') == NULL) { - if (smb_resolve_fqdn(domain, buf, buflen) != 1) - rc = -1; - } else { - (void) strlcpy(buf, domain, buflen); + if (*res_state.defdname == '\0') { + res_ndestroy(&res_state); + return (-1); } - } else { - if (smb_resolve_fqdn("", buf, buflen) != 1) - rc = -1; + + (void) strlcpy(buf, res_state.defdname, buflen); + res_ndestroy(&res_state); + rc = 0; } return (rc); @@ -646,3 +473,47 @@ smb_get_nameservers(struct in_addr *ips, int sz) res_ndestroy(&res_state); return (i); } + +/* + * smb_gethostbyname + * + * Looks up a host by the given name. The host entry can come + * from any of the sources for hosts specified in the + * /etc/nsswitch.conf and the NetBIOS cache. + * + * XXX Invokes nbt_name_resolve API once the NBTD is integrated + * to look in the NetBIOS cache if getipnodebyname fails. + * + * Caller should invoke freehostent to free the returned hostent. + */ +struct hostent * +smb_gethostbyname(const char *name, int *err_num) +{ + struct hostent *h; + + h = getipnodebyname(name, AF_INET, 0, err_num); + + return (h); +} + +/* + * smb_gethostbyaddr + * + * Looks up a host by the given IP address. The host entry can come + * from any of the sources for hosts specified in the + * /etc/nsswitch.conf and the NetBIOS cache. + * + * XXX Invokes nbt API to resolve name by IP once the NBTD is integrated + * to look in the NetBIOS cache if getipnodebyaddr fails. + * + * Caller should invoke freehostent to free the returned hostent. + */ +struct hostent * +smb_gethostbyaddr(const char *addr, int len, int type, int *err_num) +{ + struct hostent *h; + + h = getipnodebyaddr(addr, len, type, err_num); + + return (h); +} diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_nic.c b/usr/src/lib/smbsrv/libsmb/common/smb_nic.c index 20bd1afba9..82ea440ced 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_nic.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_nic.c @@ -80,6 +80,7 @@ #define NULL_MSGCHK(msg) ((msg) ? (msg) : "NULL") #define SMB_NIC_MAXIFS 256 +#define SMB_NIC_MAXEXCLLIST_LEN 512 typedef struct smb_hostifs { list_node_t if_lnd; @@ -124,6 +125,8 @@ static int smb_nic_dbdelhost(const char *); static int smb_nic_dbsetinfo(sqlite *); static int smb_nic_getinfo(char *, smb_nic_t *); +static boolean_t smb_nic_nbt_exclude(const smb_nic_t *, const char **, int); +static int smb_nic_nbt_get_exclude_list(char *, char **, int); /* This is the list we will monitor */ static smb_niclist_t smb_niclist; @@ -391,9 +394,9 @@ smb_nic_list_create(void) smb_hostifs_t *iflist; smb_nic_t *nc; char *ifname; - char excludestr[MAX_EXCLUDE_LIST_LEN]; - ipaddr_t exclude[SMB_PI_MAX_NETWORKS]; - int nexclude; + char excludestr[SMB_NIC_MAXEXCLLIST_LEN]; + char *exclude[SMB_PI_MAX_NETWORKS]; + int nexclude = 0; int i; if (smb_nic_hlist_create(&hlist) < 0) @@ -409,9 +412,12 @@ smb_nic_list_create(void) return (-1); } - (void) smb_config_getstr(SMB_CI_WINS_EXCL, excludestr, - sizeof (excludestr)); - nexclude = smb_wins_iplist(excludestr, exclude, SMB_PI_MAX_NETWORKS); + *excludestr = '\0'; + (void) smb_config_getstr(SMB_CI_WINS_EXCL, + excludestr, sizeof (excludestr)); + + nexclude = smb_nic_nbt_get_exclude_list(excludestr, + exclude, SMB_PI_MAX_NETWORKS); nc = smb_niclist.nl_nics; iflist = list_head(&hlist.h_list); @@ -432,8 +438,8 @@ smb_nic_list_create(void) if (strchr(ifname, ':')) nc->nic_smbflags |= SMB_NICF_ALIAS; - if (smb_wins_is_excluded(nc->nic_ip, - (ipaddr_t *)exclude, nexclude)) + if (smb_nic_nbt_exclude(nc, + (const char **)exclude, nexclude)) nc->nic_smbflags |= SMB_NICF_NBEXCL; smb_niclist.nl_cnt++; @@ -1073,3 +1079,66 @@ smb_nic_dbsetinfo(sqlite *db) return (rc); } + +/* + * smb_nic_nbt_get_exclude_list + * + * Construct an array containing list of i/f names on which NetBIOS traffic is + * to be disabled, from a string containing a list of comma separated i/f names. + * + * Returns the number of i/f on which NetBIOS traffic is to be disabled. + */ +static int +smb_nic_nbt_get_exclude_list(char *excludestr, char **iflist, int max_nifs) +{ + int n = 0; + char *entry; + + bzero(iflist, SMB_PI_MAX_NETWORKS * sizeof (char *)); + + (void) trim_whitespace(excludestr); + (void) strcanon(excludestr, ","); + + if (*excludestr == '\0') + return (0); + + while (((iflist[n] = strsep(&excludestr, ",")) != NULL) && + (n < max_nifs)) { + entry = iflist[n]; + if (*entry == '\0') + continue; + n++; + } + + return (n); +} + +/* + * smb_nic_nbt_exclude + * + * Check to see if the given interface name should send NetBIOS traffic or not. + * + * Returns TRUE if NetBIOS traffic is disabled on an interface name. + * Returns FALSE otherwise. + */ +static boolean_t +smb_nic_nbt_exclude(const smb_nic_t *nc, const char **exclude_list, + int nexclude) +{ + char buf[INET6_ADDRSTRLEN]; + const char *ifname = nc->nic_ifname; + int i; + + if (inet_ntop(AF_INET, &nc->nic_ip, buf, INET6_ADDRSTRLEN) == NULL) + buf[0] = '\0'; + + for (i = 0; i < nexclude; i++) { + if (strcmp(ifname, exclude_list[i]) == 0) + return (B_TRUE); + + if ((buf[0] != '\0') && (strcmp(buf, exclude_list[i]) == 0)) + return (B_TRUE); + } + + return (B_FALSE); +} diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c b/usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c index da1dbf8bc9..94071ee488 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c @@ -564,9 +564,16 @@ smb_smf_get_opaque_property(smb_scfhandle_t *handle, char *propname, } /* - * smb_smf_restart_service() - * - * Restarts SMB SMF service. + * Put the smb service into maintenance mode. + */ +int +smb_smf_maintenance_mode(void) +{ + return (smf_maintain_instance(SMBD_DEFAULT_INSTANCE_FMRI, 0)); +} + +/* + * Restart the smb service. */ int smb_smf_restart_service(void) diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_util.c b/usr/src/lib/smbsrv/libsmb/common/smb_util.c index 0ef2a302c4..d6eabf294b 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_util.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_util.c @@ -194,6 +194,69 @@ hextobin(const char *hexbuf, size_t hexlen, } /* + * Trim leading and trailing characters in the set defined by class + * from a buffer containing a null-terminated string. + * For example, if the input buffer contained "ABtext23" and class + * contains "ABC123", the buffer will contain "text" on return. + * + * This function modifies the contents of buf in place and returns + * a pointer to buf. + */ +char * +strtrim(char *buf, const char *class) +{ + char *p = buf; + char *q = buf; + + if (buf == NULL) + return (NULL); + + p += strspn(p, class); + + if (p != buf) { + while ((*q = *p++) != '\0') + ++q; + } + + while (q != buf) { + --q; + if (strspn(q, class) == 0) + return (buf); + *q = '\0'; + } + + return (buf); +} + +/* + * Strip the characters in the set defined by class from a buffer + * containing a null-terminated string. + * For example, if the input buffer contained "XYA 1textZ string3" + * and class contains "123XYZ", the buffer will contain "A text string" + * on return. + * + * This function modifies the contents of buf in place and returns + * a pointer to buf. + */ +char * +strstrip(char *buf, const char *class) +{ + char *p = buf; + char *q = buf; + + if (buf == NULL) + return (NULL); + + while (*p) { + p += strspn(p, class); + *q++ = *p++; + } + + *q = '\0'; + return (buf); +} + +/* * trim_whitespace * * Trim leading and trailing whitespace chars (as defined by isspace) diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_wins.c b/usr/src/lib/smbsrv/libsmb/common/smb_wins.c deleted file mode 100644 index eb3a5216f4..0000000000 --- a/usr/src/lib/smbsrv/libsmb/common/smb_wins.c +++ /dev/null @@ -1,209 +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 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * SMB WINS support functions - */ - -#include <strings.h> -#include <stdlib.h> - -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <smbsrv/smbinfo.h> - -#include <smbsrv/libsmb.h> - -/* - * smb_wins_iplist - * - * Get a string containing a list of comma separated IP addresses - * and return an array containing numeric equivalent for string IPs. - * - * Returns the number of parsed IPs. - * Return -1 if list is badly formatted. - * This routine need fix for IPv6 - */ -int -smb_wins_iplist(char *list, uint32_t iplist[], int max_naddr) -{ - char *ip, *ctx; - char *tmp; - int n = 0; - - if ((list == NULL) || (*list == '\0')) - return (0); - - if ((tmp = strdup(list)) == NULL) - return (0); - - ip = strtok_r(tmp, ",", &ctx); - while (ip && (n < max_naddr)) { - ip = trim_whitespace(ip); - if (*ip != 0) { - if (inet_pton(AF_INET, ip, &iplist[n]) == 1) { - n++; - } else { - return (-1); - } - } - ip = strtok_r(0, ",", &ctx); - } - - free(tmp); - return (n); -} - -/* - * smb_wins_is_excluded - * - * Check to see if the given IP addr shouldn't be registered in WINS. - * - * Returns 1 if it's excluded, 0 if it's not. - */ -boolean_t -smb_wins_is_excluded(in_addr_t ipaddr, ipaddr_t *exclude_list, int nexclude) -{ - int i; - - if (nexclude == 0) - return (B_FALSE); - - for (i = 0; i < nexclude; i++) - if (ipaddr == exclude_list[i]) { - return (B_TRUE); - } - - return (B_FALSE); -} - -/* - * Build a CSV list of ips to be excluded. - * This function needs fix for IPv6 - */ -void -smb_wins_build_list(char *buf, uint32_t iplist[], int max_naddr) -{ - char ipstr[16]; - int i; - - if (!buf) - return; - - buf[0] = '\0'; - for (i = 0; i < max_naddr; i++) { - /* XXX these will be removed */ - /*LINTED*/ - if (iplist[i] == -1) - continue; - - if (inet_ntop(AF_INET, (const void *)(&iplist[i]), ipstr, - sizeof (ipstr)) == 0) - continue; - (void) strcat(buf, ipstr); - (void) strcat(buf, ","); - } - buf[strlen(buf)-1] = '\0'; -} - -/* - * This function build the new WINS exclude list from - * configured list + new additions to exclude list - * It also assumes that the buffers are of enough space. - */ -int -smb_wins_exclude_list(char *config_list, char *exclude_list) -{ - int ccnt, ecnt, already_there; - int i, j; - uint32_t ncur_list[SMB_PI_MAX_NETWORKS]; - uint32_t ecur_list[SMB_PI_MAX_NETWORKS]; - - ccnt = smb_wins_iplist(config_list, ncur_list, SMB_PI_MAX_NETWORKS); - if (ccnt < 0) - return (-1); - - ecnt = smb_wins_iplist(exclude_list, ecur_list, SMB_PI_MAX_NETWORKS); - if (ecnt < 0) - return (-1); - - if ((ccnt + ecnt) > SMB_PI_MAX_NETWORKS) - return (-1); - - for (i = 0; i < ecnt; i++) { - already_there = 0; - for (j = 0; j < ccnt; j++) { - if (ncur_list[j] == ecur_list[i]) { - already_there = 1; - } - } - if (already_there) - continue; - - ncur_list[ccnt++] = ecur_list[i]; - } - - smb_wins_build_list(config_list, ncur_list, ccnt); - return (0); -} - -/* - * This function build the new WINS allow list from - * configured list - new allowed list - * It also assumes that the buffers are of enough space. - */ -int -smb_wins_allow_list(char *config_list, char *allow_list) -{ - int ccnt, acnt; - int i, j; - uint32_t ncur_list[SMB_PI_MAX_NETWORKS]; - uint32_t acur_list[SMB_PI_MAX_NETWORKS]; - - ccnt = smb_wins_iplist(config_list, ncur_list, SMB_PI_MAX_NETWORKS); - if (ccnt < 0) - return (-1); - - acnt = smb_wins_iplist(allow_list, acur_list, SMB_PI_MAX_NETWORKS); - if (acnt < 0) - return (0); - - for (i = 0; i < acnt; i++) { - for (j = 0; j < ccnt; j++) { - if (ncur_list[j] == (in_addr_t)(-1)) - continue; - if (ncur_list[j] == acur_list[i]) { - ncur_list[j] = (in_addr_t)(-1); - } - } - } - smb_wins_build_list(config_list, ncur_list, ccnt); - return (0); -} diff --git a/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h b/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h index 50d6275a1d..0eb8411f92 100644 --- a/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h +++ b/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h @@ -69,6 +69,7 @@ typedef enum smb_adjoin_status { SMB_ADJOIN_ERR_WRITE_KEYTAB, SMB_ADJOIN_ERR_IDMAP_SET_DOMAIN, SMB_ADJOIN_ERR_IDMAP_REFRESH, + SMB_ADJOIN_ERR_COMMIT_KEYTAB, SMB_ADJOIN_NUM_STATUS } smb_adjoin_status_t; @@ -88,13 +89,14 @@ extern int smb_ads_add_share(smb_ads_handle_t *, const char *, const char *, const char *); extern smb_adjoin_status_t smb_ads_join(char *, char *, char *, char *, int); extern char *smb_adjoin_report_err(smb_adjoin_status_t); -extern int smb_ads_domain_change_cleanup(char *); +extern boolean_t smb_ads_lookup_msdcs(char *, char *, char *, uint32_t); /* DYNDNS functions */ -extern void dns_msgid_init(void); +extern int dyndns_start(void); +extern void dyndns_stop(void); extern int dyndns_update(char *); -extern int dyndns_update_core(char *); -extern int dyndns_clear_rev_zone(char *); +extern void dyndns_update_zones(void); +extern void dyndns_clear_zones(void); /* Kerberos initialization function */ extern int smb_kinit(char *, char *); @@ -102,14 +104,13 @@ extern int smb_ccache_init(char *, char *); extern void smb_ccache_remove(char *); /* NETBIOS Functions */ -extern int smb_msdcs_lookup_ads(char *, char *); extern int smb_netbios_start(void); extern void smb_netbios_shutdown(void); extern void smb_netbios_name_reconfig(void); /* Browser Functions */ extern void smb_browser_reconfig(void); -extern void smb_browser_netlogon(char *); +extern boolean_t smb_browser_netlogon(char *, char *, uint32_t); #ifdef __cplusplus diff --git a/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers b/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers index 0f0bbebd23..2112aa6979 100644 --- a/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers +++ b/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers @@ -25,17 +25,18 @@ SUNWprivate { global: - dns_msgid_init; - dyndns_clear_rev_zone; + dyndns_clear_zones; + dyndns_start; + dyndns_stop; dyndns_update; - dyndns_update_core; + dyndns_update_zones; smb_adjoin_report_err; smb_ads_add_share; smb_ads_build_unc_name; smb_ads_close; - smb_ads_domain_change_cleanup; smb_ads_init; smb_ads_join; + smb_ads_lookup_msdcs; smb_ads_lookup_share; smb_ads_open; smb_ads_publish_share; @@ -46,7 +47,6 @@ SUNWprivate { smb_ccache_init; smb_ccache_remove; smb_kinit; - smb_msdcs_lookup_ads; smb_netbios_name_reconfig; smb_netbios_start; smb_netbios_shutdown; diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c index 89deba0712..834ea5b041 100644 --- a/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c +++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c @@ -2320,57 +2320,6 @@ smb_ads_gen_machine_passwd(char *machine_passwd, int bufsz) } /* - * smb_ads_domain_change_cleanup - * - * If we're attempting to join the system to a new domain, the keys for - * the host principal regarding the old domain should be removed from - * Kerberos keytab. Also, the smb_ads_cached_host_info cache should be cleared. - * - * newdom is fully-qualified domain name. It can be set to empty string - * if user attempts to switch to workgroup mode. - */ -int -smb_ads_domain_change_cleanup(char *newdom) -{ - char origdom[MAXHOSTNAMELEN]; - krb5_context ctx = NULL; - krb5_principal krb5princs[SMBKRB5_SPN_IDX_MAX]; - int rc; - - if (smb_getfqdomainname(origdom, MAXHOSTNAMELEN)) { - if (smb_getdomainname(origdom, MAXHOSTNAMELEN) == 0) - if (strncasecmp(origdom, newdom, strlen(origdom))) - smb_ads_free_cached_host(); - - return (0); - } - - if (utf8_strcasecmp(origdom, newdom) == 0) - return (0); - - smb_ads_free_cached_host(); - - if (smb_krb5_ctx_init(&ctx) != 0) - return (-1); - - if (smb_krb5_get_principals(origdom, ctx, krb5princs) != 0) { - smb_krb5_ctx_fini(ctx); - return (-1); - - } - - rc = smb_krb5_remove_keytab_entries(ctx, krb5princs, - SMBNS_KRB5_KEYTAB); - - smb_krb5_free_principals(ctx, krb5princs, SMBKRB5_SPN_IDX_MAX); - smb_krb5_ctx_fini(ctx); - - return (rc); -} - - - -/* * smb_ads_join * * Besides the NT-4 style domain join (using MS-RPC), CIFS server also @@ -2409,6 +2358,7 @@ smb_ads_join(char *domain, char *user, char *usr_passwd, char *machine_passwd, int dclevel, num; smb_ads_qstat_t qstat; char dn[SMB_ADS_DN_MAX]; + char *tmpfile; /* * Call library functions that can be used to get @@ -2512,24 +2462,16 @@ smb_ads_join(char *domain, char *user, char *usr_passwd, char *machine_passwd, encptr = pre_w2k8enctypes; } - if (smb_krb5_update_keytab_entries(ctx, krb5princs, SMBNS_KRB5_KEYTAB, + tmpfile = mktemp(SMBNS_KRB5_KEYTAB_TMP); + if (tmpfile == NULL) + tmpfile = SMBNS_KRB5_KEYTAB_TMP; + + if (smb_krb5_add_keytab_entries(ctx, krb5princs, tmpfile, kvno, machine_passwd, encptr, num) != 0) { rc = SMB_ADJOIN_ERR_WRITE_KEYTAB; goto adjoin_cleanup; } - /* Set IDMAP config */ - if (smb_config_set_idmap_domain(ah->domain) != 0) { - rc = SMB_ADJOIN_ERR_IDMAP_SET_DOMAIN; - goto adjoin_cleanup; - } - - /* Refresh IDMAP service */ - if (smb_config_refresh_idmap() != 0) { - rc = SMB_ADJOIN_ERR_IDMAP_REFRESH; - goto adjoin_cleanup; - } - delete = B_FALSE; adjoin_cleanup: if (new_acct && delete) @@ -2542,6 +2484,26 @@ adjoin_cleanup: smb_krb5_ctx_fini(ctx); } + /* commit keytab file */ + if (rc == SMB_ADJOIN_SUCCESS) { + if (rename(tmpfile, SMBNS_KRB5_KEYTAB) != 0) { + (void) unlink(tmpfile); + rc = SMB_ADJOIN_ERR_COMMIT_KEYTAB; + } else { + /* Set IDMAP config */ + if (smb_config_set_idmap_domain(ah->domain) != 0) { + rc = SMB_ADJOIN_ERR_IDMAP_SET_DOMAIN; + } else { + + /* Refresh IDMAP service */ + if (smb_config_refresh_idmap() != 0) + rc = SMB_ADJOIN_ERR_IDMAP_REFRESH; + } + } + } else { + (void) unlink(tmpfile); + } + smb_ads_close(ah); smb_ccache_remove(SMB_CCACHE_PATH); return (rc); @@ -2756,3 +2718,44 @@ smb_ads_select_dc(smb_ads_host_list_t *hlist) return (NULL); } + +/* + * smb_ads_lookup_msdcs + * + * If server argument is set, try to locate the specified DC. + * If it is set to empty string, locate any DCs in the specified domain. + * Returns the discovered DC via buf. + * + * fqdn - fully-qualified domain name + * server - fully-qualifed hostname of a DC + * buf - the hostname of the discovered DC + */ +boolean_t +smb_ads_lookup_msdcs(char *fqdn, char *server, char *buf, uint32_t buflen) +{ + smb_ads_host_info_t *hinfo = NULL; + char *p; + struct in_addr addr; + char *sought_host; + + if (!fqdn || !buf) + return (B_FALSE); + + *buf = '\0'; + sought_host = (*server == 0 ? NULL : server); + if ((hinfo = smb_ads_find_host(fqdn, sought_host)) == NULL) + return (B_FALSE); + + addr.s_addr = hinfo->ip_addr; + syslog(LOG_DEBUG, "msdcsLookupADS: %s [%s]", hinfo->name, + inet_ntoa(addr)); + + (void) strlcpy(buf, hinfo->name, buflen); + /* + * Remove the domain extension + */ + if ((p = strchr(buf, '.')) != 0) + *p = '\0'; + + return (B_TRUE); +} diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c index 8a1da0cc4e..ce7555f225 100644 --- a/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c +++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c @@ -23,8 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - +#include <errno.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> @@ -46,6 +45,14 @@ #include <smbns_browser.h> #include <smbns_netbios.h> +/* + * ntdomain_info + * Temporary. It should be removed once NBTD is integrated. + */ +smb_ntdomain_t ntdomain_info; +mutex_t ntdomain_mtx; +cond_t ntdomain_cv; + #define SMB_SERVER_SIGNATURE 0xaa550415 typedef struct smb_hostinfo { @@ -75,6 +82,9 @@ static void smb_browser_infoinit(void); static void smb_browser_infoterm(void); static void smb_browser_infofree(void); + + + void smb_browser_reconfig(void) { @@ -1124,7 +1134,8 @@ smb_browser_init(void) type |= SV_DOMAIN_MEMBER; do { - if (ni.ni_nic.nic_smbflags & SMB_NICF_NBEXCL) + if ((ni.ni_nic.nic_smbflags & SMB_NICF_NBEXCL) || + (ni.ni_nic.nic_smbflags & SMB_NICF_ALIAS)) continue; hinfo = malloc(sizeof (smb_hostinfo_t)); @@ -1312,12 +1323,17 @@ restart: * * Sends SAMLOGON/NETLOGON request for all host/ips, except * aliases, to find a domain controller. + * + * The dc argument will be set if a DC is found. */ -void -smb_browser_netlogon(char *domain) +boolean_t +smb_browser_netlogon(char *domain, char *dc, uint32_t dc_len) { smb_hostinfo_t *hinfo; int protocol; + boolean_t found = B_FALSE; + timestruc_t to; + int err; if (smb_config_getbool(SMB_CI_DOMAIN_MEMB)) protocol = NETLOGON_PROTO_SAMLOGON; @@ -1333,6 +1349,24 @@ smb_browser_netlogon(char *domain) hinfo = list_next(&smb_binfo.bi_hlist, hinfo); } (void) rw_unlock(&smb_binfo.bi_hlist_rwl); + + bzero(dc, dc_len); + to.tv_sec = 30; + to.tv_nsec = 0; + (void) mutex_lock(&ntdomain_mtx); + while (ntdomain_info.n_ipaddr == 0) { + err = cond_reltimedwait(&ntdomain_cv, &ntdomain_mtx, &to); + if (err == ETIME) + break; + } + + if (ntdomain_info.n_ipaddr != 0) { + (void) strlcpy(dc, ntdomain_info.n_name, dc_len); + found = B_TRUE; + } + (void) mutex_unlock(&ntdomain_mtx); + + return (found); } /* @@ -1344,6 +1378,10 @@ smb_browser_netlogon(char *domain) static void smb_browser_infoinit(void) { + (void) mutex_lock(&ntdomain_mtx); + bzero(&ntdomain_info, sizeof (ntdomain_info)); + (void) mutex_unlock(&ntdomain_mtx); + (void) rw_wrlock(&smb_binfo.bi_hlist_rwl); list_create(&smb_binfo.bi_hlist, sizeof (smb_hostinfo_t), offsetof(smb_hostinfo_t, hi_lnd)); diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.h b/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.h index 17f3fdf4a9..67598f7c3b 100644 --- a/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.h +++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _BROWSER_H_ #define _BROWSER_H_ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * NetBIOS name types describe the functionality of the registration. * A following list of NetBIOS suffixes (16th Character of the NetBIOS @@ -182,6 +180,12 @@ extern "C" { #define NETLOGON_PROTO_NETLOGON 0x01 #define NETLOGON_PROTO_SAMLOGON 0x02 +typedef struct smb_ntdomain_t { + char n_domain[SMB_PI_MAX_DOMAIN]; + char n_name[SMB_PI_MAX_DOMAIN]; + uint32_t n_ipaddr; +} smb_ntdomain_t; + #ifdef __cplusplus } #endif diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c index 621c4d68b4..c797dcd037 100644 --- a/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c +++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c @@ -32,42 +32,340 @@ #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> +#include <arpa/nameser.h> +#include <net/if.h> +#include <resolv.h> #include <sys/time.h> #include <unistd.h> #include <string.h> -#include <arpa/nameser.h> -#include <resolv.h> +#include <pthread.h> #include <netdb.h> #include <rpc/rpc.h> #include <syslog.h> #include <gssapi/gssapi.h> #include <kerberosv5/krb5.h> -#include <net/if.h> #include <smbns_dyndns.h> #include <smbns_krb.h> +/* + * The following can be removed once head/arpa/nameser_compat.h + * defines BADSIG, BADKEY and BADTIME. + */ +#ifndef BADSIG +#define BADSIG ns_r_badsig +#endif /* BADSIG */ + +#ifndef BADKEY +#define BADKEY ns_r_badkey +#endif /* BADKEY */ + +#ifndef BADTIME +#define BADTIME ns_r_badtime +#endif /* BADTIME */ + /* internal use, in dyndns_add_entry */ -#define DEL_NONE 2 +#define DEL_NONE 2 + /* Maximum retires if not authoritative */ -#define MAX_AUTH_RETRIES 3 +#define MAX_AUTH_RETRIES 3 + /* Number of times to retry a DNS query */ -#define DYNDNS_MAX_QUERY_RETRIES 3 +#define DYNDNS_MAX_QUERY_RETRIES 3 + /* Timeout value, in seconds, for DNS query responses */ -#define DYNDNS_QUERY_TIMEOUT 2 +#define DYNDNS_QUERY_TIMEOUT 2 static uint16_t dns_msgid; mutex_t dns_msgid_mtx; +#define DYNDNS_OP_CLEAR 1 +#define DYNDNS_OP_UPDATE 2 + +#define DYNDNS_STATE_INIT 0 +#define DYNDNS_STATE_READY 1 +#define DYNDNS_STATE_PUBLISHING 2 +#define DYNDNS_STATE_STOPPING 3 + +typedef struct dyndns_qentry { + list_node_t dqe_lnd; + int dqe_op; + char dqe_fqdn[MAXHOSTNAMELEN]; +} dyndns_qentry_t; + +typedef struct dyndns_queue { + list_t ddq_list; + mutex_t ddq_mtx; + cond_t ddq_cv; + uint32_t ddq_state; +} dyndns_queue_t; + +static dyndns_queue_t dyndns_queue; + +static void dyndns_queue_request(int, const char *); +static void dyndns_queue_flush(list_t *); +static void *dyndns_publisher(void *); +static void dyndns_process(list_t *); +static int dyndns_update_core(char *); +static int dyndns_clear_rev_zone(char *); +static void dyndns_msgid_init(void); +static int dyndns_get_msgid(void); +static void dyndns_syslog(int, int, const char *); + +int +dyndns_start(void) +{ + pthread_t publisher; + pthread_attr_t tattr; + int rc; + + if (!smb_config_getbool(SMB_CI_DYNDNS_ENABLE)) + return (0); + + (void) mutex_lock(&dyndns_queue.ddq_mtx); + if (dyndns_queue.ddq_state != DYNDNS_STATE_INIT) { + (void) mutex_unlock(&dyndns_queue.ddq_mtx); + return (0); + } + + dyndns_msgid_init(); + + list_create(&dyndns_queue.ddq_list, sizeof (dyndns_qentry_t), + offsetof(dyndns_qentry_t, dqe_lnd)); + dyndns_queue.ddq_state = DYNDNS_STATE_READY; + (void) mutex_unlock(&dyndns_queue.ddq_mtx); + + (void) pthread_attr_init(&tattr); + (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); + rc = pthread_create(&publisher, &tattr, dyndns_publisher, 0); + (void) pthread_attr_destroy(&tattr); + return (rc); +} + +void +dyndns_stop(void) +{ + (void) mutex_lock(&dyndns_queue.ddq_mtx); + + switch (dyndns_queue.ddq_state) { + case DYNDNS_STATE_READY: + case DYNDNS_STATE_PUBLISHING: + dyndns_queue.ddq_state = DYNDNS_STATE_STOPPING; + (void) cond_signal(&dyndns_queue.ddq_cv); + break; + default: + break; + } + + (void) mutex_unlock(&dyndns_queue.ddq_mtx); +} + /* - * dns_msgid_init + * Clear all records in both zones. + */ +void +dyndns_clear_zones(void) +{ + char fqdn[MAXHOSTNAMELEN]; + + if (smb_getfqdomainname(fqdn, MAXHOSTNAMELEN) != 0) { + syslog(LOG_ERR, "dyndns: failed to get domainname"); + return; + } + + dyndns_queue_request(DYNDNS_OP_CLEAR, fqdn); +} + +/* + * Update all records in both zones. + */ +void +dyndns_update_zones(void) +{ + char fqdn[MAXHOSTNAMELEN]; + + if (smb_getfqdomainname(fqdn, MAXHOSTNAMELEN) != 0) { + syslog(LOG_ERR, "dyndns: failed to get domainname"); + return; + } + + dyndns_queue_request(DYNDNS_OP_UPDATE, fqdn); +} + +/* + * Add a request to the queue. + */ +static void +dyndns_queue_request(int op, const char *fqdn) +{ + dyndns_qentry_t *entry; + + if (!smb_config_getbool(SMB_CI_DYNDNS_ENABLE)) + return; + + (void) mutex_lock(&dyndns_queue.ddq_mtx); + + switch (dyndns_queue.ddq_state) { + case DYNDNS_STATE_READY: + case DYNDNS_STATE_PUBLISHING: + break; + default: + (void) mutex_unlock(&dyndns_queue.ddq_mtx); + return; + } + + if ((entry = malloc(sizeof (dyndns_qentry_t))) == NULL) { + (void) mutex_unlock(&dyndns_queue.ddq_mtx); + return; + } + + bzero(entry, sizeof (dyndns_qentry_t)); + entry->dqe_op = op; + (void) strlcpy(entry->dqe_fqdn, fqdn, MAXNAMELEN); + + list_insert_tail(&dyndns_queue.ddq_list, entry); + (void) cond_signal(&dyndns_queue.ddq_cv); + (void) mutex_unlock(&dyndns_queue.ddq_mtx); +} + +/* + * Flush all remaining items from the specified list/queue. + */ +static void +dyndns_queue_flush(list_t *lst) +{ + dyndns_qentry_t *entry; + + while ((entry = list_head(lst)) != NULL) { + list_remove(lst, entry); + free(entry); + } +} + +/* + * Dyndns update thread. While running, the thread waits on a condition + * variable until notified that an entry needs to be updated. * + * If the outgoing queue is not empty, the thread wakes up every 60 seconds + * to retry. + */ +/*ARGSUSED*/ +static void * +dyndns_publisher(void *arg) +{ + dyndns_qentry_t *entry; + list_t publist; + + (void) mutex_lock(&dyndns_queue.ddq_mtx); + if (dyndns_queue.ddq_state != DYNDNS_STATE_READY) { + (void) mutex_unlock(&dyndns_queue.ddq_mtx); + return (NULL); + } + dyndns_queue.ddq_state = DYNDNS_STATE_PUBLISHING; + (void) mutex_unlock(&dyndns_queue.ddq_mtx); + + list_create(&publist, sizeof (dyndns_qentry_t), + offsetof(dyndns_qentry_t, dqe_lnd)); + + for (;;) { + (void) mutex_lock(&dyndns_queue.ddq_mtx); + + while (list_is_empty(&dyndns_queue.ddq_list) && + (dyndns_queue.ddq_state == DYNDNS_STATE_PUBLISHING)) { + (void) cond_wait(&dyndns_queue.ddq_cv, + &dyndns_queue.ddq_mtx); + } + + if (dyndns_queue.ddq_state != DYNDNS_STATE_PUBLISHING) { + (void) mutex_unlock(&dyndns_queue.ddq_mtx); + break; + } + + /* + * Transfer queued items to the local list so that + * the mutex can be released. + */ + while ((entry = list_head(&dyndns_queue.ddq_list)) != NULL) { + list_remove(&dyndns_queue.ddq_list, entry); + list_insert_tail(&publist, entry); + } + + (void) mutex_unlock(&dyndns_queue.ddq_mtx); + + dyndns_process(&publist); + } + + (void) mutex_lock(&dyndns_queue.ddq_mtx); + dyndns_queue_flush(&dyndns_queue.ddq_list); + list_destroy(&dyndns_queue.ddq_list); + dyndns_queue.ddq_state = DYNDNS_STATE_INIT; + (void) mutex_unlock(&dyndns_queue.ddq_mtx); + + dyndns_queue_flush(&publist); + list_destroy(&publist); + return (NULL); +} + +/* + * Remove items from the queue and process them. + */ +static void +dyndns_process(list_t *publist) +{ + dyndns_qentry_t *entry; + + while ((entry = list_head(publist)) != NULL) { + (void) mutex_lock(&dyndns_queue.ddq_mtx); + if (dyndns_queue.ddq_state != DYNDNS_STATE_PUBLISHING) { + (void) mutex_unlock(&dyndns_queue.ddq_mtx); + dyndns_queue_flush(publist); + return; + } + (void) mutex_unlock(&dyndns_queue.ddq_mtx); + + list_remove(publist, entry); + + switch (entry->dqe_op) { + case DYNDNS_OP_CLEAR: + (void) dyndns_clear_rev_zone(entry->dqe_fqdn); + break; + case DYNDNS_OP_UPDATE: + (void) dyndns_update_core(entry->dqe_fqdn); + break; + default: + break; + } + + free(entry); + } +} + +/* + * Dynamic DNS update API for kclient. + * + * Returns 0 upon success. Otherwise, returns -1. + */ +int +dyndns_update(char *fqdn) +{ + int rc; + + if (smb_nic_init() != 0) + return (-1); + + dyndns_msgid_init(); + rc = dyndns_update_core(fqdn); + smb_nic_fini(); + return (rc); +} + +/* * Initializes the DNS message ID counter using the algorithm * that resolver library uses to initialize the ID field of any res * structure. */ -void -dns_msgid_init(void) +static void +dyndns_msgid_init(void) { struct timeval now; @@ -78,7 +376,7 @@ dns_msgid_init(void) } static int -dns_get_msgid(void) +dyndns_get_msgid(void) { uint16_t id; @@ -89,81 +387,44 @@ dns_get_msgid(void) } /* - * XXX The following should be removed once head/arpa/nameser_compat.h - * defines BADSIG, BADKEY, BADTIME macros - */ -#ifndef BADSIG -#define BADSIG ns_r_badsig -#endif /* BADSIG */ - -#ifndef BADKEY -#define BADKEY ns_r_badkey -#endif /* BADKEY */ - -#ifndef BADTIME -#define BADTIME ns_r_badtime -#endif /* BADTIME */ - -/* - * dyndns_msg_err - * Display error message for DNS error code found in the DNS header in - * reply message. - * Parameters: - * err: DNS errer code - * Returns: - * None + * Log a DNS error message */ static void -dyndns_msg_err(int err) +dyndns_syslog(int severity, int errnum, const char *text) { - switch (err) { - case NOERROR: - break; - case FORMERR: - syslog(LOG_ERR, "DNS message format error\n"); - break; - case SERVFAIL: - syslog(LOG_ERR, "DNS server internal error\n"); - break; - case NXDOMAIN: - syslog(LOG_ERR, "DNS entry should exist but does not exist\n"); - break; - case NOTIMP: - syslog(LOG_ERR, "DNS opcode not supported\n"); - break; - case REFUSED: - syslog(LOG_ERR, "DNS operation refused\n"); - break; - case YXDOMAIN: - syslog(LOG_ERR, "DNS entry shouldn't exist but does exist\n"); - break; - case YXRRSET: - syslog(LOG_ERR, "DNS RRSet shouldn't exist but does exist\n"); - break; - case NXRRSET: - syslog(LOG_ERR, "DNS RRSet should exist but does not exist\n"); - break; - case NOTAUTH: - syslog(LOG_ERR, "DNS server is not authoritative " - "for specified zone\n"); - break; - case NOTZONE: - syslog(LOG_ERR, "Name in Prereq or Update section not " - "within specified zone\n"); - break; - case BADSIG: - syslog(LOG_ERR, "Bad transaction signature (TSIG)"); - break; - case BADKEY: - syslog(LOG_ERR, "Bad transaction key (TKEY)"); - break; - case BADTIME: - syslog(LOG_ERR, "Time not synchronized"); - break; + struct { + int errnum; + char *errmsg; + } errtab[] = { + { FORMERR, "message format error" }, + { SERVFAIL, "server internal error" }, + { NXDOMAIN, "entry should exist but does not exist" }, + { NOTIMP, "not supported" }, + { REFUSED, "operation refused" }, + { YXDOMAIN, "entry should not exist but does exist" }, + { YXRRSET, "RRSet should not exist but does exist" }, + { NXRRSET, "RRSet should exist but does not exist" }, + { NOTAUTH, "server is not authoritative for specified zone" }, + { NOTZONE, "name not within specified zone" }, + { BADSIG, "bad transaction signature (TSIG)" }, + { BADKEY, "bad transaction key (TKEY)" }, + { BADTIME, "time not synchronized" }, + }; + + char *errmsg = "unknown error"; + int i; - default: - syslog(LOG_ERR, "Unknown DNS error\n"); + if (errnum == NOERROR) + return; + + for (i = 0; i < (sizeof (errtab) / sizeof (errtab[0])); ++i) { + if (errtab[i].errnum == errnum) { + errmsg = errtab[i].errmsg; + break; + } } + + syslog(severity, "dyndns: %s: %s: %d", text, errmsg, errnum); } /* @@ -187,13 +448,13 @@ display_stat(OM_uint32 maj, OM_uint32 min) (void) gss_display_status(&min2, maj, GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &msg); - syslog(LOG_ERR, "dyndns: GSS major status error: %s\n", + syslog(LOG_ERR, "dyndns: GSS major status error: %s", (char *)msg.value); (void) gss_release_buffer(&min2, &msg); (void) gss_display_status(&min2, min, GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &msg); - syslog(LOG_ERR, "dyndns: GSS minor status error: %s\n", + syslog(LOG_ERR, "dyndns: GSS minor status error: %s", (char *)msg.value); (void) gss_release_buffer(&min2, &msg); } @@ -315,7 +576,7 @@ dyndns_build_header(char **ptr, int buf_len, uint16_t msg_id, int query_req, uint16_t opcode; if (buf_len < 12) { - syslog(LOG_ERR, "dyndns: no more buf for header section\n"); + syslog(LOG_ERR, "dyndns header section: buffer too small"); return (-1); } @@ -361,8 +622,7 @@ dyndns_build_quest_zone(char **ptr, int buf_len, char *name, int type, char *zonePtr; if ((strlen(name) + 6) > buf_len) { - syslog(LOG_ERR, "dyndns: no more buf " - "for question/zone section\n"); + syslog(LOG_ERR, "dyndns question section: buffer too small"); return (-1); } @@ -420,7 +680,7 @@ dyndns_build_update(char **ptr, int buf_len, char *name, int type, int class, } if (rec_len + data_len > buf_len) { - syslog(LOG_ERR, "dyndns: no more buf for update section\n"); + syslog(LOG_ERR, "dyndns update section: buffer too small"); return (-1); } @@ -475,7 +735,7 @@ dyndns_build_tkey(char **ptr, int buf_len, char *name, int key_expire, struct timeval tp; if (strlen(name)+2 + 45 + data_size > buf_len) { - syslog(LOG_ERR, "dyndns: no more buf for TKEY record\n"); + syslog(LOG_ERR, "dyndns TKEY: buffer too small"); return (-1); } @@ -539,7 +799,7 @@ dyndns_build_tsig(char **ptr, int buf_len, int msg_id, char *name, rec_len = strlen(name)+2 + 45 + data_size; if (rec_len > buf_len) { - syslog(LOG_ERR, "dyndns: no more buf for TSIG record\n"); + syslog(LOG_ERR, "dyndns TSIG: buffer too small"); return (-1); } @@ -597,14 +857,14 @@ dyndns_open_init_socket(int sock_type, unsigned long dest_addr, int port) struct sockaddr_in serv_addr; if ((s = socket(AF_INET, sock_type, 0)) == -1) { - syslog(LOG_ERR, "dyndns: socket err\n"); + syslog(LOG_ERR, "dyndns: socket error"); return (-1); } l.l_onoff = 0; if (setsockopt(s, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof (l)) == -1) { - syslog(LOG_ERR, "dyndns: setsocket err\n"); + syslog(LOG_ERR, "dyndns: setsockopt error"); (void) close(s); return (-1); } @@ -615,7 +875,7 @@ dyndns_open_init_socket(int sock_type, unsigned long dest_addr, int port) my_addr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(s, (struct sockaddr *)&my_addr, sizeof (my_addr)) < 0) { - syslog(LOG_ERR, "dyndns: client bind err\n"); + syslog(LOG_ERR, "dyndns: client bind error"); (void) close(s); return (-1); } @@ -626,7 +886,7 @@ dyndns_open_init_socket(int sock_type, unsigned long dest_addr, int port) if (connect(s, (struct sockaddr *)&serv_addr, sizeof (struct sockaddr_in)) < 0) { - syslog(LOG_ERR, "dyndns: client connect err (%s)\n", + syslog(LOG_ERR, "dyndns: client connect error (%s)", strerror(errno)); (void) close(s); return (-1); @@ -670,7 +930,7 @@ dyndns_build_tkey_msg(char *buf, char *key_name, uint16_t *id, (void) memset(buf, 0, MAX_TCP_SIZE); bufptr = buf; - *id = dns_get_msgid(); + *id = dyndns_get_msgid(); /* add TCP length info that follows this field */ bufptr = dyndns_put_nshort(bufptr, @@ -736,10 +996,9 @@ dyndns_establish_sec_ctx(gss_ctx_id_t *gss_context, gss_cred_id_t cred_handle, service_sz = strlen(dns_hostname) + 5; service_name = (char *)malloc(sizeof (char) * service_sz); - if (service_name == NULL) { - syslog(LOG_ERR, "Malloc failed for %d bytes ", service_sz); + if (service_name == NULL) return (-1); - } + (void) snprintf(service_name, service_sz, "DNS@%s", dns_hostname); service_buf.value = service_name; service_buf.length = strlen(service_name)+1; @@ -773,7 +1032,7 @@ dyndns_establish_sec_ctx(gss_ctx_id_t *gss_context, gss_cred_id_t cred_handle, if ((maj == GSS_S_COMPLETE) && !(ret_flags & GSS_C_REPLAY_FLAG)) { - syslog(LOG_ERR, "dyndns: No GSS_C_REPLAY_FLAG\n"); + syslog(LOG_ERR, "dyndns: No GSS_C_REPLAY_FLAG"); if (out_tok.length > 0) (void) gss_release_buffer(&min, &out_tok); (void) gss_release_name(&min, &target_name); @@ -782,7 +1041,7 @@ dyndns_establish_sec_ctx(gss_ctx_id_t *gss_context, gss_cred_id_t cred_handle, if ((maj == GSS_S_COMPLETE) && !(ret_flags & GSS_C_MUTUAL_FLAG)) { - syslog(LOG_ERR, "dyndns: No GSS_C_MUTUAL_FLAG\n"); + syslog(LOG_ERR, "dyndns: No GSS_C_MUTUAL_FLAG"); if (out_tok.length > 0) (void) gss_release_buffer(&min, &out_tok); (void) gss_release_name(&min, &target_name); @@ -800,24 +1059,21 @@ dyndns_establish_sec_ctx(gss_ctx_id_t *gss_context, gss_cred_id_t cred_handle, (void) gss_release_buffer(&min, &out_tok); if (send(s, buf, buf_sz, 0) == -1) { - syslog(LOG_ERR, "dyndns: TKEY send error\n"); + syslog(LOG_ERR, "dyndns: TKEY send error"); (void) gss_release_name(&min, &target_name); return (-1); } bzero(buf2, MAX_TCP_SIZE); if (recv(s, buf2, MAX_TCP_SIZE, 0) == -1) { - syslog(LOG_ERR, "dyndns: TKEY " - "reply recv error\n"); + syslog(LOG_ERR, "dyndns: TKEY recv error"); (void) gss_release_name(&min, &target_name); return (-1); } ret = buf2[5] & 0xf; /* error field in TCP */ if (ret != NOERROR) { - syslog(LOG_ERR, "dyndns: Error in " - "TKEY reply: %d: ", ret); - dyndns_msg_err(ret); + dyndns_syslog(LOG_ERR, ret, "TKEY reply"); (void) gss_release_name(&min, &target_name); return (-1); } @@ -875,8 +1131,7 @@ dyndns_get_sec_context(const char *hostname, int dns_ip) hentry = gethostbyaddr((char *)&dns_ip, 4, AF_INET); if (hentry == NULL) { - syslog(LOG_ERR, "dyndns: Can't get DNS " - "hostname from DNS ip.\n"); + syslog(LOG_ERR, "dyndns gethostbyaddr failed"); return (NULL); } (void) strcpy(dns_hostname, hentry->h_name); @@ -950,7 +1205,7 @@ dyndns_build_add_remove_msg(char *buf, int update_zone, const char *hostname, bufptr = buf; if (*id == 0) - *id = dns_get_msgid(); + *id = dyndns_get_msgid(); if (dyndns_build_header(&bufptr, BUFLEN_UDP(bufptr, buf), *id, queryReq, zoneCount, preqCount, updateCount, additionalCount, 0) == -1) { @@ -1160,7 +1415,7 @@ dyndns_udp_send_recv(int s, char *buf, int buf_sz, char *rec_buf) for (i = 0; i <= DYNDNS_MAX_QUERY_RETRIES; i++) { if (send(s, buf, buf_sz, 0) == -1) { - syslog(LOG_ERR, "dyndns: UDP send error (%s)\n", + syslog(LOG_ERR, "dyndns: UDP send error (%s)", strerror(errno)); return (-1); } @@ -1180,7 +1435,7 @@ dyndns_udp_send_recv(int s, char *buf, int buf_sz, char *rec_buf) addr_len = sizeof (struct sockaddr_in); if (recvfrom(s, rec_buf, NS_PACKETSZ, 0, (struct sockaddr *)&from_addr, &addr_len) == -1) { - syslog(LOG_ERR, "dyndns: UDP recv err\n"); + syslog(LOG_ERR, "dyndns: UDP recv error"); return (-1); } break; @@ -1189,7 +1444,7 @@ dyndns_udp_send_recv(int s, char *buf, int buf_sz, char *rec_buf) /* did not receive anything */ if (i == (DYNDNS_MAX_QUERY_RETRIES + 1)) { - syslog(LOG_ERR, "dyndns: max retries for UDP recv reached\n"); + syslog(LOG_ERR, "dyndns: max retries for UDP recv reached"); return (-1); } @@ -1321,8 +1576,7 @@ sec_retry_higher: /* check here for update request is successful */ if (ret != NOERROR) { - syslog(LOG_ERR, "dyndns: Error in TSIG reply: %d: ", ret); - dyndns_msg_err(ret); + dyndns_syslog(LOG_ERR, ret, "TSIG reply"); return (-1); } @@ -1493,12 +1747,10 @@ retry_higher: } if (ret == NOTIMP) { - syslog(LOG_ERR, "dyndns: DNS does not " - "support dynamic update\n"); + dyndns_syslog(LOG_NOTICE, NOTIMP, "dynamic updates"); return (-1); } else if (ret == NOTAUTH) { - syslog(LOG_ERR, "dyndns: DNS is not authoritative for " - "zone name in zone section\n"); + dyndns_syslog(LOG_NOTICE, NOTAUTH, "DNS"); return (-1); } @@ -1533,18 +1785,17 @@ dyndns_add_entry(int update_zone, const char *hostname, const char *ip_addr, int life_time) { char *dns_str; + char *which_zone; struct in_addr ns_list[MAXNS]; int i, cnt; int addr, rc = 0; - if (hostname == NULL || ip_addr == NULL) { + if (hostname == NULL || ip_addr == NULL) return (-1); - } addr = (int)inet_addr(ip_addr); - if ((addr == -1) || (addr == 0)) { + if ((addr == -1) || (addr == 0)) return (-1); - } cnt = smb_get_nameservers(ns_list, MAXNS); @@ -1555,13 +1806,12 @@ dyndns_add_entry(int update_zone, const char *hostname, const char *ip_addr, continue; } - if (update_zone == UPDATE_FORW) { - syslog(LOG_DEBUG, "Dynamic update on forward lookup " - "zone for %s (%s)...\n", hostname, ip_addr); - } else { - syslog(LOG_DEBUG, "Dynamic update on reverse lookup " - "zone for %s (%s)...\n", hostname, ip_addr); - } + which_zone = (update_zone == UPDATE_FORW) ? + "forward" : "reverse"; + + syslog(LOG_DEBUG, "dyndns %s lookup zone update %s (%s)", + which_zone, hostname, ip_addr); + if (dyndns_add_remove_entry(update_zone, hostname, ip_addr, life_time, UPDATE_ADD, DNS_NOCHECK, DEL_NONE, dns_str) != -1) { @@ -1595,6 +1845,7 @@ dyndns_remove_entry(int update_zone, const char *hostname, const char *ip_addr, int del_type) { char *dns_str; + char *which_zone; struct in_addr ns_list[MAXNS]; int i, cnt, scnt; int addr; @@ -1618,27 +1869,19 @@ dyndns_remove_entry(int update_zone, const char *hostname, const char *ip_addr, continue; } - if (update_zone == UPDATE_FORW) { - if (del_type == DEL_ONE) { - syslog(LOG_DEBUG, "Dynamic update " - "on forward lookup " - "zone for %s (%s)...\n", hostname, ip_addr); - } else { - syslog(LOG_DEBUG, "Removing all " - "entries of %s " - "in forward lookup zone...\n", hostname); - } + which_zone = (update_zone == UPDATE_FORW) ? + "forward" : "reverse"; + + if (del_type == DEL_ONE) { + syslog(LOG_DEBUG, + "dyndns %s lookup zone remove %s (%s)", + which_zone, hostname, ip_addr); } else { - if (del_type == DEL_ONE) { - syslog(LOG_DEBUG, "Dynamic update " - "on reverse lookup " - "zone for %s (%s)...\n", hostname, ip_addr); - } else { - syslog(LOG_DEBUG, "Removing all " - "entries of %s " - "in reverse lookup zone...\n", ip_addr); - } + syslog(LOG_DEBUG, + "dyndns %s lookup zone remove all %s", + which_zone, hostname); } + if (dyndns_add_remove_entry(update_zone, hostname, ip_addr, 0, UPDATE_DEL, DNS_NOCHECK, del_type, dns_str) != -1) { scnt++; @@ -1651,27 +1894,6 @@ dyndns_remove_entry(int update_zone, const char *hostname, const char *ip_addr, } /* - * dyndns_update - * - * Dynamic DNS update API for kclient. - * - * Returns 0 upon success. Otherwise, returns -1. - */ -int -dyndns_update(char *fqdn) -{ - int rc; - - if (smb_nic_init() != 0) - return (-1); - - dns_msgid_init(); - rc = dyndns_update_core(fqdn); - smb_nic_fini(); - return (rc); -} - -/* * dyndns_update_core * Perform dynamic update on both forward and reverse lookup zone using * the specified hostname and IP addresses. Before updating DNS, existing @@ -1687,7 +1909,7 @@ dyndns_update(char *fqdn) * -1: some dynamic DNS updates errors * 0: successful or DDNS disabled. */ -int +static int dyndns_update_core(char *fqdn) { int forw_update_ok, error; @@ -1697,6 +1919,9 @@ dyndns_update_core(char *fqdn) int rc; char fqhn[MAXHOSTNAMELEN]; + if (fqdn == NULL || *fqdn == '\0') + return (0); + if (!smb_config_getbool(SMB_CI_DYNDNS_ENABLE)) return (0); @@ -1764,7 +1989,7 @@ dyndns_update_core(char *fqdn) * -1: some dynamic DNS updates errors * 0: successful or DDNS disabled. */ -int +static int dyndns_clear_rev_zone(char *fqdn) { int error; diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_krb.h b/usr/src/lib/smbsrv/libsmbns/common/smbns_krb.h index 0116c8b684..bdc1d46bc1 100644 --- a/usr/src/lib/smbsrv/libsmbns/common/smbns_krb.h +++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_krb.h @@ -26,8 +26,6 @@ #ifndef _SMBSRV_SMB_KRB5_H #define _SMBSRV_SMB_KRB5_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <gssapi/gssapi.h> #include <kerberosv5/krb5.h> @@ -35,7 +33,8 @@ extern "C" { #endif -#define SMBNS_KRB5_KEYTAB "/etc/krb5/krb5.keytab" +#define SMBNS_KRB5_KEYTAB "/etc/krb5/krb5.keytab" +#define SMBNS_KRB5_KEYTAB_TMP "/etc/krb5/krb5.keytab.tmp.XXXXXX" /* core set of SPNs */ typedef enum smb_krb5_spn_idx { @@ -68,9 +67,7 @@ int smb_krb5_get_principals(char *domain, krb5_context ctx, void smb_krb5_free_principals(krb5_context ctx, krb5_principal *krb5princs, size_t num); int smb_krb5_setpwd(krb5_context ctx, krb5_principal princ, char *passwd); -int smb_krb5_remove_keytab_entries(krb5_context ctx, krb5_principal *princs, - char *fname); -int smb_krb5_update_keytab_entries(krb5_context ctx, krb5_principal *princs, +int smb_krb5_add_keytab_entries(krb5_context ctx, krb5_principal *princs, char *fname, krb5_kvno kvno, char *passwd, krb5_enctype *enctypes, int enctype_count); boolean_t smb_krb5_find_keytab_entries(const char *fqhn, char *fname); diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_ksetpwd.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_ksetpwd.c index 1a72947536..6321254c29 100644 --- a/usr/src/lib/smbsrv/libsmbns/common/smbns_ksetpwd.c +++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_ksetpwd.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -49,8 +47,6 @@ static int smb_krb5_open_wrfile(krb5_context ctx, char *fname, static int smb_krb5_ktadd(krb5_context ctx, krb5_keytab kt, const krb5_principal princ, krb5_enctype enctype, krb5_kvno kvno, const char *pw); -static krb5_error_code smb_krb5_ktremove(krb5_context ctx, krb5_keytab kt, - const krb5_principal princ); /* * smb_krb5_get_spn @@ -301,60 +297,23 @@ smb_krb5_open_wrfile(krb5_context ctx, char *fname, krb5_keytab *kt) } /* - * smb_krb5_remove_keytab_entries - * - * Remove the keys from the keytab for the specified principal. - */ -int -smb_krb5_remove_keytab_entries(krb5_context ctx, krb5_principal *princs, - char *fname) -{ - krb5_keytab kt = NULL; - int rc = 0, i; - krb5_error_code code; - - if (smb_krb5_open_wrfile(ctx, fname, &kt) != 0) - return (-1); - - for (i = 0; i < SMBKRB5_SPN_IDX_MAX; i++) { - if ((code = smb_krb5_ktremove(ctx, kt, princs[i])) != 0) { - syslog(LOG_ERR, "smb_krb5_remove_keytab_entries: %s", - error_message(code)); - rc = -1; - break; - } - } - - krb5_kt_close(ctx, kt); - return (rc); -} - -/* - * smb_krb5_update_keytab_entries + * smb_krb5_add_keytab_entries * * Update the keys for the specified principal in the keytab. * Returns 0 on success. Otherwise, returns -1. */ int -smb_krb5_update_keytab_entries(krb5_context ctx, krb5_principal *princs, +smb_krb5_add_keytab_entries(krb5_context ctx, krb5_principal *princs, char *fname, krb5_kvno kvno, char *passwd, krb5_enctype *enctypes, int enctype_count) { krb5_keytab kt = NULL; int i, j; - krb5_error_code code; if (smb_krb5_open_wrfile(ctx, fname, &kt) != 0) return (-1); for (j = 0; j < SMBKRB5_SPN_IDX_MAX; j++) { - if ((code = smb_krb5_ktremove(ctx, kt, princs[j])) != 0) { - syslog(LOG_ERR, "smb_krb5_update_keytab_entries: %s", - error_message(code)); - krb5_kt_close(ctx, kt); - return (-1); - } - for (i = 0; i < enctype_count; i++) { if (smb_krb5_ktadd(ctx, kt, princs[j], enctypes[i], kvno, passwd) != 0) { @@ -413,69 +372,6 @@ smb_krb5_find_keytab_entries(const char *fqhn, char *fname) } /* - * smb_krb5_ktremove - * - * Removes the old entries for the specified principal from the keytab. - * - * Returns 0 upon success. Otherwise, returns KRB5 error code. - */ -static krb5_error_code -smb_krb5_ktremove(krb5_context ctx, krb5_keytab kt, const krb5_principal princ) -{ - krb5_keytab_entry entry; - krb5_kt_cursor cursor; - int code; - - code = krb5_kt_get_entry(ctx, kt, princ, 0, 0, &entry); - if (code != 0) { - if (code == ENOENT || code == KRB5_KT_NOTFOUND) - return (0); - - return (code); - } - - krb5_kt_free_entry(ctx, &entry); - - if ((code = krb5_kt_start_seq_get(ctx, kt, &cursor)) != 0) - return (code); - - while ((code = krb5_kt_next_entry(ctx, kt, &entry, &cursor)) == 0) { - if (krb5_principal_compare(ctx, princ, entry.principal)) { - - code = krb5_kt_end_seq_get(ctx, kt, &cursor); - if (code != 0) { - krb5_kt_free_entry(ctx, &entry); - return (code); - } - - code = krb5_kt_remove_entry(ctx, kt, &entry); - if (code != 0) { - krb5_kt_free_entry(ctx, &entry); - return (code); - } - - code = krb5_kt_start_seq_get(ctx, kt, &cursor); - if (code != 0) { - krb5_kt_free_entry(ctx, &entry); - return (code); - } - - } - krb5_kt_free_entry(ctx, &entry); - } - - if (code && code != KRB5_KT_END) { - (void) krb5_kt_end_seq_get(ctx, kt, &cursor); - return (code); - } - - if ((code = krb5_kt_end_seq_get(ctx, kt, &cursor))) - return (code); - - return (0); -} - -/* * smb_krb5_ktadd * * Add a Keberos key to the keytab file. diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c index 7054d4bfae..fc92a5e36a 100644 --- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c +++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Description: * @@ -4581,7 +4579,8 @@ smb_netbios_name_config(void) return; do { - if (ni.ni_nic.nic_smbflags & SMB_NICF_NBEXCL) + if ((ni.ni_nic.nic_smbflags & SMB_NICF_NBEXCL) || + (ni.ni_nic.nic_smbflags & SMB_NICF_ALIAS)) continue; smb_init_name_struct((unsigned char *)ni.ni_nic.nic_host, diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c index fb68da1dbe..ab1bf3c29d 100644 --- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c +++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c @@ -60,7 +60,13 @@ static void smb_netlogon_send(struct name_entry *name, char *domain, static void smb_netlogon_rdc_rsp(char *src_name, uint32_t src_ipaddr); static int smb_better_dc(uint32_t cur_ip, uint32_t new_ip); -static char resource_domain[SMB_PI_MAX_DOMAIN]; +/* + * ntdomain_info + * Temporary. It should be removed once NBTD is integrated. + */ +extern smb_ntdomain_t ntdomain_info; +extern mutex_t ntdomain_mtx; +extern cond_t ntdomain_cv; /* * smb_netlogon_request @@ -81,17 +87,20 @@ smb_netlogon_request(struct name_entry *server, int protocol, char *domain) if (domain == NULL || *domain == '\0') return; - (void) strlcpy(resource_domain, domain, sizeof (resource_domain)); + (void) mutex_lock(&ntdomain_mtx); + (void) strlcpy(ntdomain_info.n_domain, domain, + sizeof (ntdomain_info.n_domain)); + (void) mutex_unlock(&ntdomain_mtx); - ntdp = nt_domain_lookup_name(resource_domain); + ntdp = nt_domain_lookup_name(domain); if (ntdp && (protocol == NETLOGON_PROTO_SAMLOGON)) smb_netlogon_samlogon(server, MAILSLOT_NETLOGON_SAMLOGON_RDC, - resource_domain); + domain); else smb_netlogon_query(server, MAILSLOT_NETLOGON_RDC, - resource_domain); + domain); } /* @@ -211,12 +220,15 @@ smb_netlogon_receive(struct datagram *datagram, syslog(LOG_DEBUG, "DC Offer Dom=%s PDC=%s From=%s", domain, primary, src_name); - if (strcasecmp(domain, resource_domain)) { + (void) mutex_lock(&ntdomain_mtx); + if (strcasecmp(domain, ntdomain_info.n_domain)) { syslog(LOG_DEBUG, "NetLogonResponse: other domain " - "%s, requested %s", domain, resource_domain); + "%s, requested %s", domain, ntdomain_info.n_domain); smb_msgbuf_term(&mb); + (void) mutex_unlock(&ntdomain_mtx); return; } + (void) mutex_unlock(&ntdomain_mtx); for (i = 0; i < sizeof (netlogon_opt)/sizeof (netlogon_opt[0]); ++i) { if (strcasecmp(netlogon_opt[i].mailslot, mailbox) == 0) { @@ -446,8 +458,8 @@ smb_netlogon_send(struct name_entry *name, dest_dup = smb_netbios_name_dup(dest, 1); smb_name_unlock_name(dest); if (dest_dup) { - (void) smb_netbios_datagram_send(name, dest_dup, - buffer, count); + (void) smb_netbios_datagram_send(name, + dest_dup, buffer, count); free(dest_dup); } } else { @@ -467,7 +479,6 @@ static void smb_netlogon_rdc_rsp(char *src_name, uint32_t src_ipaddr) { static int initialized = 0; - smb_ntdomain_t *pi; uint32_t ipaddr; uint32_t prefer_ipaddr = 0; char ipstr[16]; @@ -489,27 +500,34 @@ smb_netlogon_rdc_rsp(char *src_name, uint32_t src_ipaddr) } } + (void) mutex_lock(&ntdomain_mtx); syslog(LOG_DEBUG, "DC Offer [%s]: %s [%s]", - resource_domain, src_name, srcip); + ntdomain_info.n_domain, src_name, srcip); - if ((pi = smb_getdomaininfo(0)) != 0) { - if (prefer_ipaddr != 0 && prefer_ipaddr == pi->ipaddr) { + if (ntdomain_info.n_ipaddr != 0) { + if (prefer_ipaddr != 0 && prefer_ipaddr == + ntdomain_info.n_ipaddr) { syslog(LOG_DEBUG, "DC for %s: %s [%s]", - resource_domain, src_name, srcip); + ntdomain_info.n_domain, src_name, srcip); + (void) mutex_unlock(&ntdomain_mtx); return; } - ipaddr = pi->ipaddr; + ipaddr = ntdomain_info.n_ipaddr; } else ipaddr = 0; if (smb_better_dc(ipaddr, src_ipaddr) || (prefer_ipaddr != 0 && prefer_ipaddr == src_ipaddr)) { - smb_setdomaininfo(resource_domain, src_name, - src_ipaddr); + /* set nbtd cache */ + (void) strlcpy(ntdomain_info.n_name, src_name, + SMB_PI_MAX_DOMAIN); + ntdomain_info.n_ipaddr = src_ipaddr; + (void) cond_broadcast(&ntdomain_cv); syslog(LOG_DEBUG, "DC discovered for %s: %s [%s]", - resource_domain, src_name, srcip); + ntdomain_info.n_domain, src_name, srcip); } + (void) mutex_unlock(&ntdomain_mtx); } static int @@ -532,54 +550,3 @@ smb_better_dc(uint32_t cur_ip, uint32_t new_ip) */ return (0); } - -/* - * smb_msdcs_lookup_ads - * - * Try to find a domain controller in ADS. - * - * Parameter: - * nbt_domain - NETBIOS name of the domain - * server - the ADS server to be sought. - * - * Returns 1 if a domain controller was found and its name and IP address - * have been updated. Otherwise returns 0. - */ -int -smb_msdcs_lookup_ads(char *nbt_domain, char *server) -{ - smb_ads_host_info_t *hinfo = NULL; - char ads_domain[MAXHOSTNAMELEN]; - char *p; - char *nbt_hostname; - struct in_addr addr; - - if (!nbt_domain) - return (0); - - (void) strlcpy(resource_domain, nbt_domain, SMB_PI_MAX_DOMAIN); - if (smb_resolve_fqdn(nbt_domain, ads_domain, MAXHOSTNAMELEN) != 1) - return (0); - - if ((hinfo = smb_ads_find_host(ads_domain, server)) == NULL) { - syslog(LOG_DEBUG, "msdcsLookupADS: unable to find host"); - return (0); - } - - addr.s_addr = hinfo->ip_addr; - syslog(LOG_DEBUG, "msdcsLookupADS: %s [%s]", hinfo->name, - inet_ntoa(addr)); - - /* - * Remove the domain extension - the - * NetBIOS browser can't handle it. - */ - nbt_hostname = strdup(hinfo->name); - if ((p = strchr(nbt_hostname, '.')) != 0) - *p = '\0'; - - smb_netlogon_rdc_rsp(nbt_hostname, hinfo->ip_addr); - free(nbt_hostname); - - return (1); -} diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/libsmbrdr.h b/usr/src/lib/smbsrv/libsmbrdr/common/libsmbrdr.h index 3c450da186..684b5c51c0 100644 --- a/usr/src/lib/smbsrv/libsmbrdr/common/libsmbrdr.h +++ b/usr/src/lib/smbsrv/libsmbrdr/common/libsmbrdr.h @@ -26,14 +26,18 @@ #ifndef _LIBSMBRDR_H #define _LIBSMBRDR_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <smbsrv/libsmb.h> #ifdef __cplusplus extern "C" { #endif +typedef struct smbrdr_session_info { + int si_server_os; + int si_server_lm; + int si_dc_type; +} smbrdr_session_info_t; + /* * Redirector IPC functions * @@ -44,7 +48,6 @@ extern "C" { extern void smbrdr_ipc_set(char *, unsigned char *); extern void smbrdr_ipc_commit(void); extern void smbrdr_ipc_rollback(void); -extern int smbrdr_ipc_skip_lsa_query(void); extern char *smbrdr_ipc_get_user(void); extern unsigned char *smbrdr_ipc_get_passwd(void); @@ -55,14 +58,14 @@ extern int mlsvc_logon(char *, char *, char *); extern int smbrdr_readx(int, char *, int); -/* Redirector rpcpipe functions */ -extern int mlsvc_open_pipe(char *, char *, char *, char *); -extern int mlsvc_close_pipe(int); +/* Redirector named pipe functions */ +extern int smbrdr_open_pipe(char *, char *, char *, char *); +extern int smbrdr_close_pipe(int); /* Redirector session functions */ extern void smbrdr_init(void); -extern int mlsvc_session_native_values(int, int *, int *, int *); +extern int smbrdr_session_info(int, smbrdr_session_info_t *); extern int mlsvc_echo(char *); extern void mlsvc_disconnect(char *); diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/mapfile-vers b/usr/src/lib/smbsrv/libsmbrdr/common/mapfile-vers index ffa2d56871..212d1ac41a 100644 --- a/usr/src/lib/smbsrv/libsmbrdr/common/mapfile-vers +++ b/usr/src/lib/smbsrv/libsmbrdr/common/mapfile-vers @@ -22,18 +22,14 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# SUNWprivate { global: - mlsvc_close_pipe; mlsvc_disconnect; mlsvc_echo; mlsvc_logon; - mlsvc_open_pipe; - mlsvc_session_native_values; mlsvc_user_getauth; + smbrdr_close_pipe; smbrdr_dump_netuse; smbrdr_dump_ofiles; smbrdr_dump_sessions; @@ -42,9 +38,10 @@ SUNWprivate { smbrdr_ipc_get_user; smbrdr_ipc_rollback; smbrdr_ipc_set; - smbrdr_ipc_skip_lsa_query; smbrdr_ipc_get_passwd; + smbrdr_open_pipe; smbrdr_readx; + smbrdr_session_info; smbrdr_transact; local: *; diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h index 8887e45245..7cf7c5b20d 100644 --- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h +++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h @@ -109,7 +109,9 @@ typedef struct sdb_logon { #define SDB_SLCK_WRITE 2 struct sdb_session { - smb_ntdomain_t di; + char srv_name[MAXHOSTNAMELEN]; + uint32_t srv_ipaddr; + char domain[MAXHOSTNAMELEN]; char scope[SMB_PI_MAX_SCOPE]; char native_os[SMB_PI_MAX_NATIVE_OS]; char native_lanman[SMB_PI_MAX_LANMAN]; @@ -199,7 +201,7 @@ int nb_session_request(int, char *, char *, char *, char *); /* * smbrdr_session.c */ -int smbrdr_negotiate(char *); +int smbrdr_negotiate(char *, char *); struct sdb_session *smbrdr_session_lock(char *, char *, int); void smbrdr_session_unlock(struct sdb_session *); diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.c index 9d2a36e036..6d3638d53e 100644 --- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.c +++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.c @@ -35,7 +35,6 @@ #include <synch.h> #include <smbsrv/libsmbrdr.h> -#include <smbsrv/mlsvc.h> #include <smbsrv/smbinfo.h> #include <smbrdr.h> #include <smbrdr_ipc_util.h> @@ -169,25 +168,3 @@ smbrdr_ipc_get_passwd() (void) rw_unlock(&smbrdr_ipc_lock); return (passwd); } - -/* - * smbrdr_ipc_skip_lsa_query - * - * Determine whether LSA monitor should skip the LSA query due to the - * incomplete authentication information if IPC is configured to be - * authenticated. - */ -int -smbrdr_ipc_skip_lsa_query() -{ - char *user; - unsigned char *pwd; - - - (void) rw_rdlock(&smbrdr_ipc_lock); - user = ipc_info.user; - pwd = ipc_info.passwd; - (void) rw_unlock(&smbrdr_ipc_lock); - - return (!(*user && *pwd)); -} diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_logon.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_logon.c index 206b0f6001..5f6531b8f1 100644 --- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_logon.c +++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_logon.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * SMB session logon and logoff functions. See CIFS section 4.1. */ @@ -39,7 +37,9 @@ #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> +#include <smbsrv/wintypes.h> #include <smbsrv/libsmbrdr.h> +#include <smbsrv/libmlsvc.h> #include <smbsrv/ntstatus.h> #include <smbsrv/smb.h> #include <smbrdr_ipc_util.h> @@ -53,8 +53,7 @@ static boolean_t smbrdr_logon_validate(char *server, char *username); static struct sdb_logon *smbrdr_logon_init(struct sdb_session *session, char *username, unsigned char *pwd); static int smbrdr_logon_user(char *server, char *username, unsigned char *pwd); -static int smbrdr_authenticate(char *primary_domain, char *account_name, - unsigned char *pwd); +static int smbrdr_authenticate(char *, char *, char *, unsigned char *); /* * mlsvc_logon @@ -89,7 +88,7 @@ smbrdr_anonymous_logon(char *domain_controller, char *domain_name) if (smbrdr_logon_validate(domain_controller, MLSVC_ANON_USER)) return (0); - if (smbrdr_negotiate(domain_name) != 0) { + if (smbrdr_negotiate(domain_controller, domain_name) != 0) { syslog(LOG_DEBUG, "smbrdr_anonymous_logon: negotiate failed"); return (-1); } @@ -151,12 +150,13 @@ smbrdr_auth_logon(char *domain_controller, char *domain_name, char *username) if (smbrdr_logon_validate(domain_controller, username)) return (0); - if (smbrdr_negotiate(domain_name) != 0) { + if (smbrdr_negotiate(domain_controller, domain_name) != 0) { syslog(LOG_DEBUG, "smbrdr_auth_logon: negotiate failed"); return (-1); } - erc = smbrdr_authenticate(domain_name, username, pwd_hash); + erc = smbrdr_authenticate(domain_controller, domain_name, username, + pwd_hash); return ((erc == AUTH_USER_GRANT) ? 0 : -1); } @@ -172,44 +172,17 @@ smbrdr_auth_logon(char *domain_controller, char *domain_name, char *username) * (<0) Error */ static int -smbrdr_authenticate(char *primary_domain, char *account_name, - unsigned char *pwd) +smbrdr_authenticate(char *domain_controller, char *primary_domain, + char *account_name, unsigned char *pwd) { - smb_ntdomain_t *di; - if (pwd == NULL) return (AUTH_USER_GRANT | AUTH_IPC_ONLY_GRANT); - - if ((di = smb_getdomaininfo(0)) == 0) { - syslog(LOG_DEBUG, "smbrdr_authenticate[%s]: %s", account_name, - xlate_nt_status(NT_STATUS_CANT_ACCESS_DOMAIN_INFO)); - return (-1); - } - /* * Ensure that the domain name is uppercase. */ (void) utf8_strupr(primary_domain); - - /* - * We can only authenticate a user via a controller in the user's - * primary domain. If the user's domain name doesn't match the - * authenticating server's domain, reject the request before we - * create a logon entry for the user. Although the logon will be - * denied eventually, we don't want a logon structure for a user - * in the resource domain that is pointing to a session structure - * for the account domain. If this happened to be our resource - * domain user, we would not be able to use that account to connect - * to the resource domain. - */ - if (strcasecmp(di->domain, primary_domain)) { - syslog(LOG_DEBUG, "smbrdr_authenticate: %s\\%s: invalid domain", - primary_domain, account_name); - return (-2); - } - - return (smbrdr_logon_user(di->server, account_name, pwd)); + return (smbrdr_logon_user(domain_controller, account_name, pwd)); } /* @@ -231,11 +204,11 @@ smbrdr_logon_user(char *server, char *username, unsigned char *pwd) struct sdb_session *session; struct sdb_logon *logon; struct sdb_logon old_logon; + int ret; if ((server == NULL) || (username == NULL) || - ((strcmp(username, MLSVC_ANON_USER) != 0) && (pwd == NULL))) { + ((strcmp(username, MLSVC_ANON_USER) != 0) && (pwd == NULL))) return (-1); - } session = smbrdr_session_lock(server, 0, SDB_SLCK_WRITE); if (session == NULL) { @@ -273,16 +246,18 @@ smbrdr_logon_user(char *server, char *username, unsigned char *pwd) return (-1); } + + ret = (logon->type == SDB_LOGON_GUEST) + ? AUTH_GUEST_GRANT : AUTH_USER_GRANT; + session->logon = *logon; free(logon); - if (old_logon.type != SDB_LOGON_NONE) { + if (old_logon.type != SDB_LOGON_NONE) (void) smbrdr_logoffx(&old_logon); - } smbrdr_session_unlock(session); - return ((logon->type == SDB_LOGON_GUEST) - ? AUTH_GUEST_GRANT : AUTH_USER_GRANT); + return (ret); } @@ -383,7 +358,7 @@ smbrdr_session_setupx(struct sdb_logon *logon) session->native_lanman); /* NativeLanMan */ } else { data_bytes += strlen_fn(logon->username) + null_size; - data_bytes += strlen_fn(session->di.domain) + null_size; + data_bytes += strlen_fn(session->domain) + null_size; rc = smb_msgbuf_encode(mb, "bb.wwwwlwwllw#c#cuuu.u.", 13, /* smb_wct */ @@ -403,7 +378,7 @@ smbrdr_session_setupx(struct sdb_logon *logon) logon->auth.cs_len, /* cs length spec */ logon->auth.cs, /* CaseSensitivePassword */ logon->username, /* AccountName */ - session->di.domain, /* PrimaryDomain */ + session->domain, /* PrimaryDomain */ session->native_os, /* NativeOS */ session->native_lanman); /* NativeLanMan */ } @@ -584,7 +559,7 @@ smbrdr_logon_init(struct sdb_session *session, char *username, } else { logon->type = SDB_LOGON_USER; rc = smb_auth_set_info(username, 0, pwd, - session->di.domain, session->challenge_key, + session->domain, session->challenge_key, session->challenge_len, smbrdr_lmcompl, &logon->auth); if (rc != 0) { diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_read_andx.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_read_andx.c index 3b2fc4dd7a..e152e5b860 100644 --- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_read_andx.c +++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_read_andx.c @@ -23,10 +23,8 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* - * SMB ReadX functions to support MLRPC. + * SMB ReadX functions. */ #include <syslog.h> @@ -150,7 +148,7 @@ smbrdr_readx(int fid, char *in_buf, int in_len) * * Decode the response from the SMB_COM_READ_ANDX request. The payload * of the response is appended to the end of SmbTransact response data - * in the MLRPC receive buffer. + * in the RPC receive buffer. * * Return -1 on error, 0 upon success. */ diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_rpcpipe.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_rpcpipe.c index 88d4f5ff9f..20fd3f4dd6 100644 --- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_rpcpipe.c +++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_rpcpipe.c @@ -67,13 +67,13 @@ static int mlsvc_pipe_recon_tries = 3; /* - * mlsvc_open_pipe + * smbrdr_open_pipe * * Open an RPC pipe on hostname. On success, return the fid. Otherwise * returns a -ve error code. */ int -mlsvc_open_pipe(char *hostname, char *domain, char *username, char *pipename) +smbrdr_open_pipe(char *hostname, char *domain, char *username, char *pipename) { struct sdb_netuse *netuse; struct sdb_ofile *ofile; @@ -83,6 +83,9 @@ mlsvc_open_pipe(char *hostname, char *domain, char *username, char *pipename) struct timespec st; int i; + if (mlsvc_logon(hostname, domain, username) != 0) + return (-1); + /* * If a stale session is detected, we will attempt to establish a new * session. @@ -166,12 +169,12 @@ mlsvc_open_pipe(char *hostname, char *domain, char *username, char *pipename) } /* - * mlsvc_close_pipe + * smbrdr_close_pipe * * Close the named pipe represented by fid. */ int -mlsvc_close_pipe(int fid) +smbrdr_close_pipe(int fid) { struct sdb_ofile *ofile; unsigned short tid; @@ -255,7 +258,7 @@ smbrdr_ofile_get(int fid) * smbrdr_ofile_end_of_share * * This function can be used when closing a share to ensure that all - * ofiles resources are released. Don't call mlsvc_close_pipe because + * ofiles resources are released. Don't call smbrdr_close_pipe because * that will call mlsvc_smb_tdcon and we don't know what state * the share is in. The server will probably close all files anyway. * We are more interested in releasing the ofile resources. diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c index 86e92764ef..19982ab8d9 100644 --- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c +++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * This module provides the netbios and SMB negotiation, connect and * disconnect interface. @@ -47,9 +45,8 @@ #include <smbsrv/libsmbrdr.h> #include <smbsrv/netbios.h> #include <smbsrv/cifs.h> - #include <smbsrv/ntstatus.h> -#include <smbsrv/mlsvc.h> +#include <smbsrv/libmlsvc.h> #include <smbrdr.h> #include <smbrdr_ipc_util.h> @@ -65,9 +62,9 @@ static struct sdb_session session_table[MLSVC_DOMAIN_MAX]; static mutex_t smbrdr_screate_mtx; static uint32_t session_id = 0; -static struct sdb_session *smbrdr_session_init(smb_ntdomain_t *); +static struct sdb_session *smbrdr_session_init(char *, char *); static int smbrdr_trnsprt_connect(struct sdb_session *, uint16_t); -static int smbrdr_session_connect(smb_ntdomain_t *); +static int smbrdr_session_connect(char *, char *); static int smbrdr_smb_negotiate(struct sdb_session *); static int smbrdr_echo(struct sdb_session *); static void smbrdr_session_disconnect(struct sdb_session *, int); @@ -122,17 +119,10 @@ mlsvc_disconnect(char *server) */ /*ARGSUSED*/ int -smbrdr_negotiate(char *domain) +smbrdr_negotiate(char *domain_controller, char *domain) { struct sdb_session *session = 0; - smb_ntdomain_t *di; - int retry = 1; - int res = 0; - - if ((di = smb_getdomaininfo(0)) == NULL) { - syslog(LOG_DEBUG, "smbrdr_negotiate: cannot access domain"); - return (-1); - } + int rc; /* * The mutex is to make session lookup and create atomic @@ -140,39 +130,28 @@ smbrdr_negotiate(char *domain) * server. */ (void) mutex_lock(&smbrdr_screate_mtx); - while (retry > 0) { - session = smbrdr_session_lock(di->server, 0, SDB_SLCK_WRITE); - if (session != 0) { - if (nb_keep_alive(session->sock, session->port) == 0) { - /* session is good, use it */ - smbrdr_session_unlock(session); - break; - } else { - /* stale session */ - session->state = SDB_SSTATE_STALE; - smbrdr_session_unlock(session); - } - } + session = smbrdr_session_lock(domain_controller, 0, SDB_SLCK_WRITE); + if (session != 0) { + if (nb_keep_alive(session->sock, session->port) == 0) { + /* session is good, use it */ + smbrdr_session_unlock(session); + rc = 0; + goto done; - if (smbrdr_session_connect(di) != 0) { - if (retry > 0) { - di = smb_getdomaininfo(0); - if (di == NULL) { - res = -1; - break; - } - retry--; - } } else { - /* session is created */ - retry = 0; + /* stale session */ + session->state = SDB_SSTATE_STALE; + smbrdr_session_unlock(session); } } + + rc = smbrdr_session_connect(domain_controller, domain); +done: (void) mutex_unlock(&smbrdr_screate_mtx); - if (di == NULL) + if (rc != 0) syslog(LOG_DEBUG, "smbrdr_negotiate: cannot access domain"); - return (res); + return (rc); } /* @@ -185,7 +164,7 @@ smbrdr_negotiate(char *domain) * to the the domain. A null pointer is returned if the connect fails. */ static int -smbrdr_session_connect(smb_ntdomain_t *di) +smbrdr_session_connect(char *domain_controller, char *domain) { struct sdb_session *session; uint16_t port; @@ -196,7 +175,8 @@ smbrdr_session_connect(smb_ntdomain_t *di) * be accessible until it's established otherwise another thread * might get access to a session which is not fully established. */ - if ((session = smbrdr_session_init(di)) == NULL) { + if ((session = smbrdr_session_init(domain_controller, domain)) + == NULL) { syslog(LOG_DEBUG, "smbrdr_session_init failed"); return (-1); } @@ -261,7 +241,7 @@ smbrdr_trnsprt_connect(struct sdb_session *sess, uint16_t port) bzero(&sin, sizeof (struct sockaddr_in)); sin.sin_family = AF_INET; - sin.sin_addr.s_addr = sess->di.ipaddr; + sin.sin_addr.s_addr = sess->srv_ipaddr; sin.sin_port = htons(port); if ((rc = connect(sock, (struct sockaddr *)&sin, sizeof (sin))) < 0) { @@ -272,7 +252,7 @@ smbrdr_trnsprt_connect(struct sdb_session *sess, uint16_t port) return (-1); } - (void) mts_mbstowcs(unicode_server_name, sess->di.server, + (void) mts_mbstowcs(unicode_server_name, sess->srv_name, SMB_PI_MAX_DOMAIN); rc = unicodestooems(server_name, unicode_server_name, SMB_PI_MAX_DOMAIN, cpid); @@ -390,7 +370,7 @@ smbrdr_smb_negotiate(struct sdb_session *sess) (sess->secmode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) { sess->sign_ctx.ssc_flags |= SMB_SCF_REQUIRED; syslog(LOG_DEBUG, "smbrdr: %s: signing required", - sess->di.server); + sess->srv_name); } sess->state = SDB_SSTATE_NEGOTIATED; @@ -408,13 +388,24 @@ smbrdr_smb_negotiate(struct sdb_session *sess) * the pointer. */ static struct sdb_session * -smbrdr_session_init(smb_ntdomain_t *di) +smbrdr_session_init(char *domain_controller, char *domain) { struct sdb_session *session = NULL; - int i; + uint32_t ipaddr; + int i, rc; + struct hostent *h; + + if (domain_controller == NULL || domain == NULL) + return (NULL); - if (di == NULL) + if ((h = smb_gethostbyname(domain_controller, &rc)) == NULL) { + syslog(LOG_DEBUG, "smbrdr: failed to resolve %s to IP (%d)", + domain_controller, rc); return (NULL); + } + + (void) memcpy(&ipaddr, h->h_addr, h->h_length); + freehostent(h); for (i = 0; i < MLSVC_DOMAIN_MAX; ++i) { session = &session_table[i]; @@ -422,9 +413,13 @@ smbrdr_session_init(smb_ntdomain_t *di) (void) rw_wrlock(&session->rwl); if (session->state == SDB_SSTATE_START) { smbrdr_session_clear(session); - bcopy(di, &session->di, sizeof (smb_ntdomain_t)); - (void) utf8_strupr(session->di.domain); - (void) utf8_strupr(session->di.server); + (void) strlcpy(session->srv_name, domain_controller, + MAXHOSTNAMELEN); + (void) utf8_strupr(session->srv_name); + + session->srv_ipaddr = ipaddr; + (void) strlcpy(session->domain, domain, MAXHOSTNAMELEN); + (void) utf8_strupr(session->domain); (void) smb_config_getstr(SMB_CI_NBSCOPE, session->scope, sizeof (session->scope)); @@ -538,7 +533,7 @@ smbrdr_session_lock(char *server, char *username, int lmode) (void) rw_wrlock(&session->rwl); if ((session->state == SDB_SSTATE_NEGOTIATED) && - (strcasecmp(session->di.server, server) == 0)) { + (strcasecmp(session->srv_name, server) == 0)) { if (username) { if (strcasecmp(username, session->logon.username) == 0) @@ -557,35 +552,34 @@ smbrdr_session_lock(char *server, char *username, int lmode) } /* - * mlsvc_session_native_values + * smbrdr_session_info * - * Given a file id (i.e. a named pipe fid), return the remote native - * OS and LM values for the associated session. + * Return session information related to the specified + * named pipe (fid). */ int -mlsvc_session_native_values(int fid, int *remote_os, - int *remote_lm, int *pdc_type) +smbrdr_session_info(int fid, smbrdr_session_info_t *si) { struct sdb_session *session; struct sdb_netuse *netuse; struct sdb_ofile *ofile; - if (remote_os == NULL || remote_lm == NULL) + if (si == NULL) return (-1); - if ((ofile = smbrdr_ofile_get(fid)) == 0) { + if ((ofile = smbrdr_ofile_get(fid)) == NULL) { syslog(LOG_DEBUG, - "mlsvc_session_native_values: unknown file (%d)", fid); + "smbrdr_session_info: unknown file (%d)", fid); return (-1); } netuse = ofile->netuse; session = netuse->session; - *remote_os = session->remote_os; - *remote_lm = session->remote_lm; - if (pdc_type) - *pdc_type = session->pdc_type; + si->si_server_os = session->remote_os; + si->si_server_lm = session->remote_lm; + si->si_dc_type = session->pdc_type; + smbrdr_ofile_put(ofile); return (0); } @@ -609,13 +603,13 @@ smbrdr_dump_sessions(void) (void) rw_rdlock(&session->rwl); if (session->state != SDB_SSTATE_START) { (void) inet_ntop(AF_INET, - (const void *)(&session->di.ipaddr), + (const void *)(&session->srv_ipaddr), ipstr, sizeof (ipstr)); syslog(LOG_DEBUG, "session[%d]: state=%d", i, session->state); syslog(LOG_DEBUG, "session[%d]: %s %s (%s)", i, - session->di.domain, session->di.server, ipstr); + session->domain, session->srv_name, ipstr); syslog(LOG_DEBUG, "session[%d]: %s %s (sock=%d)", i, session->native_os, session->native_lanman, session->sock); diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_transact.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_transact.c index 1fea4e831d..d5e46a953d 100644 --- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_transact.c +++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_transact.c @@ -23,10 +23,8 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* - * SMB transaction functions to support MLRPC. + * SMB transaction functions. */ #include <syslog.h> |