diff options
author | joyce mcintosh <Joyce.McIntosh@Sun.COM> | 2010-07-26 15:02:13 -0700 |
---|---|---|
committer | joyce mcintosh <Joyce.McIntosh@Sun.COM> | 2010-07-26 15:02:13 -0700 |
commit | 1fdeec650620e8498c06f832ea4bd2292f7e9632 (patch) | |
tree | 93e66a90f7f7260ca1086e7701a6c8dc1e46c5fb /usr/src/lib | |
parent | 1a024a4828552f36f41749085bad547c64a0f0a6 (diff) | |
download | illumos-joyent-1fdeec650620e8498c06f832ea4bd2292f7e9632.tar.gz |
6779186 need domain controller hot failover
6970986 Level II oplocks - smb_oplock_grant_t shouldn't be dynamically allocated
6971031 Unable add ACL on the share which has only the default owner tab by ZFS
6971899 OpenSSL not MT-safe and takes down smbd
6936762 libidmap should transparently handle interruption in connection to idmapd
6954902 mapping to unknown type does not use directory-based mapping information
--HG--
rename : usr/src/lib/libidmap/common/idmap_priv.h => usr/src/cmd/idmap/idmap/namemaps.h
Diffstat (limited to 'usr/src/lib')
22 files changed, 348 insertions, 461 deletions
diff --git a/usr/src/lib/libidmap/common/idmap.h b/usr/src/lib/libidmap/common/idmap.h index 400f67c755..3a3af0d32c 100644 --- a/usr/src/lib/libidmap/common/idmap.h +++ b/usr/src/lib/libidmap/common/idmap.h @@ -46,9 +46,6 @@ typedef int32_t idmap_stat; typedef uint32_t idmap_rid_t; -/* Opaque client handle */ -typedef struct idmap_handle idmap_handle_t; - /* Opaque "get-mapping" handle */ typedef struct idmap_get_handle idmap_get_handle_t; @@ -58,14 +55,9 @@ typedef void (*idmap_logger_t)(int, const char *, ...); /* * Setup API */ -/* Create/Init handle for userland clients */ -extern idmap_stat idmap_init(idmap_handle_t **); - -/* Finalize/close handle */ -extern idmap_stat idmap_fini(idmap_handle_t *); /* Status code to string */ -extern const char *idmap_stat2string(idmap_handle_t *, idmap_stat); +extern const char *idmap_stat2string(idmap_stat); /* Free memory allocated by the API */ extern void idmap_free(void *); @@ -83,7 +75,7 @@ extern void idmap_free(void *); * API to batch SID to UID/GID mapping requests */ /* Create handle */ -extern idmap_stat idmap_get_create(idmap_handle_t *, idmap_get_handle_t **); +extern idmap_stat idmap_get_create(idmap_get_handle_t **); /* Given SID, get UID */ extern idmap_stat idmap_get_uidbysid(idmap_get_handle_t *, char *, diff --git a/usr/src/lib/libidmap/common/idmap_api.c b/usr/src/lib/libidmap/common/idmap_api.c index e31ff1ffc3..e3ae017357 100644 --- a/usr/src/lib/libidmap/common/idmap_api.c +++ b/usr/src/lib/libidmap/common/idmap_api.c @@ -38,7 +38,6 @@ #include <sys/stat.h> #include <dlfcn.h> #include <libintl.h> -#include <ucontext.h> #include <syslog.h> #include <assert.h> #include "idmap_impl.h" @@ -49,11 +48,7 @@ static struct timeval TIMEOUT = { 25, 0 }; static int idmap_stat2errno(idmap_stat); static idmap_stat idmap_strdupnull(char **, const char *); -#define __ITER_CREATE(itera, argu, handl, ityp)\ - if (handl == NULL) {\ - errno = EINVAL;\ - return (IDMAP_ERR_ARG);\ - }\ +#define __ITER_CREATE(itera, argu, ityp)\ itera = calloc(1, sizeof (*itera));\ if (itera == NULL) {\ errno = ENOMEM;\ @@ -65,7 +60,6 @@ static idmap_stat idmap_strdupnull(char **, const char *); errno = ENOMEM;\ return (IDMAP_ERR_MEMORY);\ }\ - itera->ih = handl;\ itera->type = ityp;\ itera->retcode = IDMAP_NEXT;\ itera->limit = 1024;\ @@ -105,136 +99,30 @@ idmap_free(void *ptr) } -#define MIN_STACK_NEEDS 65536 - -/* - * Create and Initialize idmap client handle for rpc/doors - * - * Output: - * handle - idmap handle - */ -idmap_stat -idmap_init(idmap_handle_t **handle) -{ - CLIENT *clnt = NULL; - struct idmap_handle *hptr; - uint_t sendsz = 0; - stack_t st; - - *handle = NULL; - hptr = (struct idmap_handle *)calloc(1, sizeof (*hptr)); - if (hptr == NULL) - return (IDMAP_ERR_MEMORY); - - /* - * clnt_door_call() alloca()s sendsz bytes (twice too, once for - * the call args buffer and once for the call result buffer), so - * we want to pick a sendsz that will be large enough, but not - * too large. - */ - if (stack_getbounds(&st) == 0) { - /* - * Estimate how much stack space is left; - * st.ss_sp is the top of stack. - */ - if ((char *)&sendsz < (char *)st.ss_sp) - /* stack grows up */ - sendsz = ((char *)st.ss_sp - (char *)&sendsz); - else - /* stack grows down */ - sendsz = ((char *)&sendsz - (char *)st.ss_sp); - - if (sendsz <= MIN_STACK_NEEDS) { - sendsz = 0; /* RPC call may fail */ - } else { - /* Leave 64Kb (just a guess) for our needs */ - sendsz -= MIN_STACK_NEEDS; - - /* Divide the stack space left by two */ - sendsz = RNDUP(sendsz / 2); - - /* Limit sendsz to 256KB */ - if (sendsz > IDMAP_MAX_DOOR_RPC) - sendsz = IDMAP_MAX_DOOR_RPC; - } - } - - clnt = clnt_door_create(IDMAP_PROG, IDMAP_V1, sendsz); - if (clnt == NULL) { - free(hptr); - return (IDMAP_ERR_RPC); - } - hptr->type = _IDMAP_HANDLE_RPC_DOORS; - hptr->privhandle = clnt; - *handle = hptr; - return (IDMAP_SUCCESS); -} - - -/* - * Finalize idmap handle - * - * Input: - * handle - idmap handle - */ -idmap_stat -idmap_fini(idmap_handle_t *handle) -{ - CLIENT *clnt; - struct idmap_handle *hptr; - - if (handle == NULL) - return (IDMAP_SUCCESS); - - hptr = (struct idmap_handle *)handle; - - switch (hptr->type) { - case _IDMAP_HANDLE_RPC_DOORS: - clnt = (CLIENT *)hptr->privhandle; - if (clnt) { - if (clnt->cl_auth) - auth_destroy(clnt->cl_auth); - clnt_destroy(clnt); - } - break; - default: - break; - } - free(hptr); - return (IDMAP_SUCCESS); -} - - static idmap_stat -idmap_get_prop(idmap_handle_t *handle, idmap_prop_type pr, idmap_prop_res *res) +idmap_get_prop(idmap_prop_type pr, idmap_prop_res *res) { - CLIENT *clnt; - enum clnt_stat clntstat; - + idmap_stat retcode; (void) memset(res, 0, sizeof (*res)); - _IDMAP_GET_CLIENT_HANDLE(handle, clnt); - clntstat = clnt_call(clnt, IDMAP_GET_PROP, + retcode = _idmap_clnt_call(IDMAP_GET_PROP, (xdrproc_t)xdr_idmap_prop_type, (caddr_t)&pr, (xdrproc_t)xdr_idmap_prop_res, (caddr_t)res, TIMEOUT); - - if (clntstat != RPC_SUCCESS) { - return (_idmap_rpc2stat(clnt)); - } + if (retcode != IDMAP_SUCCESS) + return (retcode); return (res->retcode); /* This might not be IDMAP_SUCCESS! */ } idmap_stat -idmap_get_prop_ds(idmap_handle_t *handle, idmap_prop_type pr, - idmap_ad_disc_ds_t *dc) +idmap_get_prop_ds(idmap_prop_type pr, idmap_ad_disc_ds_t *dc) { idmap_prop_res res; idmap_stat rc = IDMAP_SUCCESS; - rc = idmap_get_prop(handle, pr, &res); + rc = idmap_get_prop(pr, &res); if (rc < 0) return (rc); @@ -254,12 +142,12 @@ idmap_get_prop_ds(idmap_handle_t *handle, idmap_prop_type pr, * otherwise IDMAP_SUCCESS is returned. */ idmap_stat -idmap_get_prop_str(idmap_handle_t *handle, idmap_prop_type pr, char **str) +idmap_get_prop_str(idmap_prop_type pr, char **str) { idmap_prop_res res; idmap_stat rc = IDMAP_SUCCESS; - rc = idmap_get_prop(handle, pr, &res); + rc = idmap_get_prop(pr, &res); if (rc < 0) return (rc); @@ -274,11 +162,11 @@ idmap_get_prop_str(idmap_handle_t *handle, idmap_prop_type pr, char **str) * udthandle - update handle */ idmap_stat -idmap_udt_create(idmap_handle_t *handle, idmap_udt_handle_t **udthandle) +idmap_udt_create(idmap_udt_handle_t **udthandle) { idmap_udt_handle_t *tmp; - if (handle == NULL || udthandle == NULL) { + if (udthandle == NULL) { errno = EINVAL; return (IDMAP_ERR_ARG); } @@ -287,7 +175,6 @@ idmap_udt_create(idmap_handle_t *handle, idmap_udt_handle_t **udthandle) return (IDMAP_ERR_MEMORY); } - tmp->ih = handle; *udthandle = tmp; return (IDMAP_SUCCESS); } @@ -306,8 +193,6 @@ idmap_udt_create(idmap_handle_t *handle, idmap_udt_handle_t **udthandle) idmap_stat idmap_udt_commit(idmap_udt_handle_t *udthandle) { - CLIENT *clnt; - enum clnt_stat clntstat; idmap_update_res res; idmap_stat retcode; @@ -318,16 +203,12 @@ idmap_udt_commit(idmap_udt_handle_t *udthandle) (void) memset(&res, 0, sizeof (res)); - _IDMAP_GET_CLIENT_HANDLE(udthandle->ih, clnt); - clntstat = clnt_call(clnt, IDMAP_UPDATE, + retcode = _idmap_clnt_call(IDMAP_UPDATE, (xdrproc_t)xdr_idmap_update_batch, (caddr_t)&udthandle->batch, (xdrproc_t)xdr_idmap_update_res, (caddr_t)&res, TIMEOUT); - - if (clntstat != RPC_SUCCESS) { - retcode = _idmap_rpc2stat(clnt); + if (retcode != IDMAP_SUCCESS) goto out; - } retcode = udthandle->commit_stat = res.retcode; udthandle->error_index = res.error_index; @@ -692,7 +573,7 @@ idmap_iter_set_limit(idmap_iter_t *iter, uint64_t limit) * iter - iterator */ idmap_stat -idmap_iter_namerules(idmap_handle_t *handle, const char *windomain, +idmap_iter_namerules(const char *windomain, boolean_t is_user, boolean_t is_wuser, const char *winname, const char *unixname, idmap_iter_t **iter) { @@ -702,7 +583,7 @@ idmap_iter_namerules(idmap_handle_t *handle, const char *windomain, idmap_namerule *rule; idmap_retcode retcode; - __ITER_CREATE(tmpiter, arg, handle, IDMAP_LIST_NAMERULES); + __ITER_CREATE(tmpiter, arg, IDMAP_LIST_NAMERULES); rule = &arg->rule; rule->is_user = is_user; @@ -847,12 +728,12 @@ errout: * iter - iterator */ idmap_stat -idmap_iter_mappings(idmap_handle_t *handle, idmap_iter_t **iter, int flag) +idmap_iter_mappings(idmap_iter_t **iter, int flag) { idmap_iter_t *tmpiter; idmap_list_mappings_1_argument *arg = NULL; - __ITER_CREATE(tmpiter, arg, handle, IDMAP_LIST_MAPPINGS); + __ITER_CREATE(tmpiter, arg, IDMAP_LIST_MAPPINGS); arg->flag = flag; *iter = tmpiter; @@ -1055,23 +936,16 @@ idmap_iter_destroy(idmap_iter_t *iter) * gh - "get mapping" handle */ idmap_stat -idmap_get_create(idmap_handle_t *handle, idmap_get_handle_t **gh) +idmap_get_create(idmap_get_handle_t **gh) { idmap_get_handle_t *tmp; - /* sanity checks */ - if (handle == NULL || gh == NULL) { - errno = EINVAL; - return (IDMAP_ERR_ARG); - } - /* allocate the handle */ if ((tmp = calloc(1, sizeof (*tmp))) == NULL) { errno = ENOMEM; return (IDMAP_ERR_MEMORY); } - tmp->ih = handle; *gh = tmp; return (IDMAP_SUCCESS); } @@ -1557,8 +1431,6 @@ errout: idmap_stat idmap_get_mappings(idmap_get_handle_t *gh) { - CLIENT *clnt; - enum clnt_stat clntstat; idmap_retcode retcode; idmap_ids_res res; idmap_id *res_id; @@ -1570,17 +1442,15 @@ idmap_get_mappings(idmap_get_handle_t *gh) errno = EINVAL; return (IDMAP_ERR_ARG); } - _IDMAP_GET_CLIENT_HANDLE(gh->ih, clnt); (void) memset(&res, 0, sizeof (idmap_ids_res)); - clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_IDS, + retcode = _idmap_clnt_call(IDMAP_GET_MAPPED_IDS, (xdrproc_t)xdr_idmap_mapping_batch, (caddr_t)&gh->batch, (xdrproc_t)xdr_idmap_ids_res, (caddr_t)&res, TIMEOUT); - if (clntstat != RPC_SUCCESS) { - retcode = _idmap_rpc2stat(clnt); + if (retcode != IDMAP_SUCCESS) { goto out; } if (res.retcode != IDMAP_SUCCESS) { @@ -1726,25 +1596,16 @@ idmap_get_destroy(idmap_get_handle_t *gh) * Get windows to unix mapping */ idmap_stat -idmap_get_w2u_mapping(idmap_handle_t *handle, +idmap_get_w2u_mapping( const char *sidprefix, idmap_rid_t *rid, const char *winname, const char *windomain, int flag, int *is_user, int *is_wuser, uid_t *pid, char **unixname, int *direction, idmap_info *info) { - CLIENT *clnt; - enum clnt_stat clntstat; idmap_mapping request, *mapping; idmap_mappings_res result; idmap_retcode retcode, rc; - if (handle == NULL) { - errno = EINVAL; - return (IDMAP_ERR_ARG); - } - - _IDMAP_GET_CLIENT_HANDLE(handle, clnt); - (void) memset(&request, 0, sizeof (request)); (void) memset(&result, 0, sizeof (result)); @@ -1789,13 +1650,13 @@ idmap_get_w2u_mapping(idmap_handle_t *handle, else request.id1.idtype = IDMAP_SID; - clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_ID_BY_NAME, + retcode = _idmap_clnt_call(IDMAP_GET_MAPPED_ID_BY_NAME, (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request, (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result, TIMEOUT); - if (clntstat != RPC_SUCCESS) - return (_idmap_rpc2stat(clnt)); + if (retcode != IDMAP_SUCCESS) + return (retcode); retcode = result.retcode; @@ -1849,26 +1710,17 @@ out: * Get unix to windows mapping */ idmap_stat -idmap_get_u2w_mapping(idmap_handle_t *handle, +idmap_get_u2w_mapping( uid_t *pid, const char *unixname, int flag, int is_user, int *is_wuser, char **sidprefix, idmap_rid_t *rid, char **winname, char **windomain, int *direction, idmap_info *info) { - CLIENT *clnt; - enum clnt_stat clntstat; idmap_mapping request, *mapping; idmap_mappings_res result; idmap_retcode retcode, rc; - if (handle == NULL) { - errno = EINVAL; - return (IDMAP_ERR_ARG); - } - - _IDMAP_GET_CLIENT_HANDLE(handle, clnt); - if (sidprefix) *sidprefix = NULL; if (winname) @@ -1905,13 +1757,13 @@ idmap_get_u2w_mapping(idmap_handle_t *handle, else if (*is_wuser == 1) request.id2.idtype = IDMAP_USID; - clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_ID_BY_NAME, + retcode = _idmap_clnt_call(IDMAP_GET_MAPPED_ID_BY_NAME, (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request, (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result, TIMEOUT); - if (clntstat != RPC_SUCCESS) - return (_idmap_rpc2stat(clnt)); + if (retcode != IDMAP_SUCCESS) + return (retcode); retcode = result.retcode; @@ -2060,9 +1912,8 @@ static stat_table_t stattable[] = { * Return Value: * human-readable localized description of idmap_stat */ -/* ARGSUSED */ const char * -idmap_stat2string(idmap_handle_t *handle, idmap_stat status) +idmap_stat2string(idmap_stat status) { int i; @@ -2258,7 +2109,6 @@ idmap_stat idmap_getuidbywinname(const char *name, const char *domain, int flag, uid_t *uid) { - idmap_handle_t *ih; idmap_retcode rc; int is_user = 1; int is_wuser = -1; @@ -2273,11 +2123,8 @@ idmap_getuidbywinname(const char *name, const char *domain, int flag, return (rc); } /* Get mapping */ - if ((rc = idmap_init(&ih)) != IDMAP_SUCCESS) - return (rc); - rc = idmap_get_w2u_mapping(ih, NULL, NULL, name, domain, flag, + rc = idmap_get_w2u_mapping(NULL, NULL, name, domain, flag, &is_user, &is_wuser, uid, NULL, &direction, NULL); - (void) idmap_fini(ih); if (rc == IDMAP_SUCCESS && (flag & IDMAP_REQ_FLG_USE_CACHE)) { /* If we have not got the domain don't store UID to winname */ @@ -2297,7 +2144,6 @@ idmap_stat idmap_getgidbywinname(const char *name, const char *domain, int flag, gid_t *gid) { - idmap_handle_t *ih; idmap_retcode rc; int is_user = 0; int is_wuser = -1; @@ -2313,11 +2159,8 @@ idmap_getgidbywinname(const char *name, const char *domain, int flag, } /* Get mapping */ - if ((rc = idmap_init(&ih)) != IDMAP_SUCCESS) - return (rc); - rc = idmap_get_w2u_mapping(ih, NULL, NULL, name, domain, flag, + rc = idmap_get_w2u_mapping(NULL, NULL, name, domain, flag, &is_user, &is_wuser, gid, NULL, &direction, NULL); - (void) idmap_fini(ih); if (rc == IDMAP_SUCCESS && (flag & IDMAP_REQ_FLG_USE_CACHE)) { /* If we have not got the domain don't store GID to winname */ @@ -2337,7 +2180,6 @@ static idmap_retcode idmap_getwinnamebypid(uid_t pid, int is_user, int flag, char **name, char **domain) { - idmap_handle_t *ih; idmap_retcode rc; int len; char *winname, *windomain; @@ -2360,11 +2202,8 @@ idmap_getwinnamebypid(uid_t pid, int is_user, int flag, char **name, } /* Get mapping */ - if ((rc = idmap_init(&ih)) != IDMAP_SUCCESS) - return (rc); - rc = idmap_get_u2w_mapping(ih, &pid, NULL, flag, is_user, NULL, + rc = idmap_get_u2w_mapping(&pid, NULL, flag, is_user, NULL, NULL, NULL, &winname, &windomain, &direction, NULL); - (void) idmap_fini(ih); /* Return on error */ if (rc != IDMAP_SUCCESS) @@ -2429,23 +2268,17 @@ idmap_getwinnamebygid(gid_t gid, int flag, char **name, char **domain) } idmap_stat -idmap_flush(idmap_handle_t *handle, idmap_flush_op op) +idmap_flush(idmap_flush_op op) { - CLIENT *clnt; - enum clnt_stat clntstat; - idmap_retcode res; + idmap_retcode rc1, rc2; - res = IDMAP_SUCCESS; - _IDMAP_GET_CLIENT_HANDLE(handle, clnt); - - clntstat = clnt_call(clnt, IDMAP_FLUSH, + rc1 = _idmap_clnt_call(IDMAP_FLUSH, (xdrproc_t)xdr_idmap_flush_op, (caddr_t)&op, - (xdrproc_t)xdr_idmap_retcode, (caddr_t)&res, TIMEOUT); + (xdrproc_t)xdr_idmap_retcode, (caddr_t)&rc2, TIMEOUT); - if (clntstat != RPC_SUCCESS) { - return (_idmap_rpc2stat(clnt)); - } - return (res); + if (rc1 != IDMAP_SUCCESS) + return (rc1); + return (rc2); } diff --git a/usr/src/lib/libidmap/common/idmap_impl.h b/usr/src/lib/libidmap/common/idmap_impl.h index 0c4aba0abb..8dd4a7efb2 100644 --- a/usr/src/lib/libidmap/common/idmap_impl.h +++ b/usr/src/lib/libidmap/common/idmap_impl.h @@ -43,25 +43,7 @@ extern "C" { #endif -#define _IDMAP_HANDLE_RPC_DOORS 1 - -#define _IDMAP_GET_CLIENT_HANDLE(h, clnt) \ - if (h == NULL) \ - return (IDMAP_ERR_CLIENT_HANDLE);\ - if (h->type != _IDMAP_HANDLE_RPC_DOORS) \ - return (IDMAP_ERR_NOTSUPPORTED);\ - clnt = (CLIENT *)h->privhandle;\ - if (clnt == NULL)\ - return (IDMAP_ERR_RPC_HANDLE); - -struct idmap_handle { - int type; - void *privhandle; - /* locks */ -}; - struct idmap_udt_handle { - struct idmap_handle *ih; idmap_update_batch batch; uint64_t next; int64_t error_index; @@ -90,7 +72,6 @@ typedef struct idmap_get_res { } idmap_get_res_t; struct idmap_get_handle { - struct idmap_handle *ih; idmap_mapping_batch batch; idmap_get_res_t *retlist; uint64_t next; @@ -104,7 +85,6 @@ struct idmap_get_handle { gh->next = 0; struct idmap_iter { - struct idmap_handle *ih; int type; uint64_t limit; void *arg; @@ -122,11 +102,15 @@ typedef struct stat_table { typedef idmap_retcode _idmap_stat; +extern idmap_stat _idmap_clnt_call(const rpcproc_t, + const xdrproc_t, const caddr_t, + const xdrproc_t, caddr_t out, + const struct timeval); + extern idmap_retcode _udt_extend_batch(idmap_udt_handle_t *); extern idmap_retcode _get_ids_extend_batch(idmap_get_handle_t *); extern idmap_stat _iter_get_next_list(int, idmap_iter_t *, void *, uchar_t **, size_t, xdrproc_t, xdrproc_t); -extern idmap_stat _idmap_rpc2stat(CLIENT *); extern idmap_logger_t logger; diff --git a/usr/src/lib/libidmap/common/idmap_priv.h b/usr/src/lib/libidmap/common/idmap_priv.h index 30547b881d..2b28b219be 100644 --- a/usr/src/lib/libidmap/common/idmap_priv.h +++ b/usr/src/lib/libidmap/common/idmap_priv.h @@ -68,8 +68,7 @@ typedef struct idmap_iter idmap_iter_t; */ /* Create handle for updates */ -extern idmap_stat idmap_udt_create(idmap_handle_t *, - idmap_udt_handle_t **); +extern idmap_stat idmap_udt_create(idmap_udt_handle_t **); /* Commit */ extern idmap_stat idmap_udt_commit(idmap_udt_handle_t *); @@ -100,15 +99,14 @@ extern idmap_stat idmap_udt_rm_namerule(idmap_udt_handle_t *, boolean_t, extern idmap_stat idmap_udt_flush_namerules(idmap_udt_handle_t *); /* Flush caches */ -extern idmap_stat idmap_flush(idmap_handle_t *, idmap_flush_op); +extern idmap_stat idmap_flush(idmap_flush_op); /* * Iterator API */ /* Create a iterator to get SID to UID/GID mappings */ -extern idmap_stat idmap_iter_mappings(idmap_handle_t *, idmap_iter_t **, - int flag); +extern idmap_stat idmap_iter_mappings(idmap_iter_t **, int flag); /* Iterate through the SID to UID/GID mappings */ extern idmap_stat idmap_iter_next_mapping(idmap_iter_t *, char **, @@ -116,7 +114,7 @@ extern idmap_stat idmap_iter_next_mapping(idmap_iter_t *, char **, boolean_t *, int *, idmap_info *); /* Create a iterator to get name-based mapping rules */ -extern idmap_stat idmap_iter_namerules(idmap_handle_t *, const char *, +extern idmap_stat idmap_iter_namerules(const char *, boolean_t, boolean_t, const char *, const char *, idmap_iter_t **); /* Iterate through the name-based mapping rules */ @@ -133,11 +131,11 @@ extern void idmap_iter_destroy(idmap_iter_t *); /* * Get mapping */ -extern idmap_stat idmap_get_w2u_mapping(idmap_handle_t *, const char *, +extern idmap_stat idmap_get_w2u_mapping(const char *, idmap_rid_t *, const char *, const char *, int, int *, int *, uid_t *, char **, int *, idmap_info *); -extern idmap_stat idmap_get_u2w_mapping(idmap_handle_t *, uid_t *, +extern idmap_stat idmap_get_u2w_mapping(uid_t *, const char *, int, int, int *, char **, idmap_rid_t *, char **, char **, int *, idmap_info *); @@ -188,10 +186,8 @@ extern idmap_stat idmap_getext_sidbygid(idmap_get_handle_t *, gid_t, int, char **, idmap_rid_t *, idmap_info *, idmap_stat *); /* Properties */ -extern idmap_stat idmap_get_prop_ds(idmap_handle_t *, idmap_prop_type, - idmap_ad_disc_ds_t *); -extern idmap_stat idmap_get_prop_str(idmap_handle_t *, idmap_prop_type, - char **); +extern idmap_stat idmap_get_prop_ds(idmap_prop_type, idmap_ad_disc_ds_t *); +extern idmap_stat idmap_get_prop_str(idmap_prop_type, char **); /* * Trace diff --git a/usr/src/lib/libidmap/common/mapfile-vers b/usr/src/lib/libidmap/common/mapfile-vers index cee7740d55..7a57d184c9 100644 --- a/usr/src/lib/libidmap/common/mapfile-vers +++ b/usr/src/lib/libidmap/common/mapfile-vers @@ -60,7 +60,6 @@ SYMBOL_VERSION SUNWprivate { directory_sid_from_group_name; directory_sid_from_name; directory_sid_from_user_name; - idmap_fini; idmap_flush; idmap_free; idmap_get_create; @@ -87,7 +86,6 @@ SYMBOL_VERSION SUNWprivate { idmap_how_clear; idmap_info_free; idmap_info_mov; - idmap_init; idmap_iter_destroy; idmap_iter_mappings; idmap_iter_namerules; diff --git a/usr/src/lib/libidmap/common/utils.c b/usr/src/lib/libidmap/common/utils.c index 1c073b75d6..1068e0aa2c 100644 --- a/usr/src/lib/libidmap/common/utils.c +++ b/usr/src/lib/libidmap/common/utils.c @@ -19,12 +19,9 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Utility routines */ @@ -33,6 +30,9 @@ #include <stdlib.h> #include <errno.h> #include <libintl.h> +#include <assert.h> +#include <ucontext.h> +#include <pthread.h> #include "idmap_impl.h" #define _UDT_SIZE_INCR 1 @@ -41,6 +41,21 @@ static struct timeval TIMEOUT = { 25, 0 }; +struct idmap_handle { + CLIENT *client; + boolean_t failed; + rwlock_t lock; +}; + +static struct idmap_handle idmap_handle = { + NULL, /* client */ + B_TRUE, /* failed */ + DEFAULTRWLOCK, /* lock */ +}; + +static idmap_stat _idmap_clnt_connect(void); +static void _idmap_clnt_disconnect(void); + idmap_retcode _udt_extend_batch(idmap_udt_handle_t *udthandle) { @@ -103,13 +118,10 @@ _iter_get_next_list(int type, idmap_iter_t *iter, void *arg, uchar_t **list, size_t valsize, xdrproc_t xdr_arg_proc, xdrproc_t xdr_res_proc) { - - CLIENT *clnt; - enum clnt_stat clntstat; + idmap_stat rc; iter->next = 0; iter->retlist = NULL; - _IDMAP_GET_CLIENT_HANDLE(iter->ih, clnt); /* init the result */ if (*list) { @@ -122,20 +134,25 @@ _iter_get_next_list(int type, idmap_iter_t *iter, } (void) memset(*list, 0, valsize); - clntstat = clnt_call(clnt, type, + rc = _idmap_clnt_call(type, xdr_arg_proc, (caddr_t)arg, xdr_res_proc, (caddr_t)*list, TIMEOUT); - if (clntstat != RPC_SUCCESS) { + if (rc != IDMAP_SUCCESS) { free(*list); - return (_idmap_rpc2stat(clnt)); + return (rc); } iter->retlist = *list; return (IDMAP_SUCCESS); } +/* + * Convert the return values from an RPC request into an idmap return code. + * Set errno on error. + */ +static idmap_stat -_idmap_rpc2stat(CLIENT *clnt) +_idmap_rpc2stat(enum clnt_stat clntstat, CLIENT *clnt) { /* * We only deal with door_call(3C) errors here. We look at @@ -144,19 +161,191 @@ _idmap_rpc2stat(CLIENT *clnt) * and others. */ struct rpc_err r_err; - if (clnt) { - clnt_geterr(clnt, &r_err); - errno = r_err.re_errno; - switch (r_err.re_errno) { - case ENOMEM: - return (IDMAP_ERR_MEMORY); - case EBADF: - return (IDMAP_ERR_RPC_HANDLE); - default: - return (IDMAP_ERR_RPC); + + if (clntstat == RPC_SUCCESS) + return (IDMAP_SUCCESS); + + clnt_geterr(clnt, &r_err); + errno = r_err.re_errno; + switch (r_err.re_errno) { + case ENOMEM: + return (IDMAP_ERR_MEMORY); + case EBADF: + return (IDMAP_ERR_RPC_HANDLE); + default: + return (IDMAP_ERR_RPC); + } +} + +/* + * Management of the connection to idmapd. + * + * The intent is that connections to idmapd are automatically maintained, + * reconnecting if necessary. No attempt is made to retry connnection + * attempts; a failure to connect yields an immediate error return. + * + * State of the connection is maintained through the "client" and "failed" + * elements of the handle structure: + * + * client failed + * NULL true Failed on a previous request and was not recovered. + * NULL false Should never happen. + * nonNULL true Structure exists, but an error has occurred. Waiting + * for a chance to attempt to reconnect. + * nonNULL false Connection is good. + * + * Note that the initial state is NULL/true, so that the first request + * will establish the initial connection. + * + * Concurrency is managed through the rw lock "lock". Only the writer is + * allowed to connect or disconnect, and thus only the writer can set + * "failed" to "false". Readers are allowed to use the "client" pointer, + * and to set "failed" to "true", indicating that they have encountered a + * failure. The "client" pointer is only valid while one holds a reader + * lock. Once "failed" has been set to "true", all requests (including + * the retry of the failing request) will attempt to gain the writer lock. + * When they succeed, indicating that there are no requests in flight and + * thus no outstanding references to the CLIENT structure, they check + * again to see if the connection is still failed (since another thread + * might have fixed it), and then if it is still failed they disconnect + * and reconnect. + */ + +/* + * Make an RPC call. Automatically reconnect if the connection to idmapd + * fails. Convert RPC results to idmap return codes. + */ +idmap_stat +_idmap_clnt_call( + const rpcproc_t procnum, + const xdrproc_t inproc, + const caddr_t in, + const xdrproc_t outproc, + caddr_t out, + const struct timeval tout) +{ + enum clnt_stat clntstat; + idmap_stat rc; + + (void) rw_rdlock(&idmap_handle.lock); + for (;;) { + if (idmap_handle.failed) { + /* No connection. Bid to see if we should fix it. */ + (void) rw_unlock(&idmap_handle.lock); + /* Somebody else might fix it here. */ + (void) rw_wrlock(&idmap_handle.lock); + /* + * At this point, everybody else is asleep waiting + * for us. Check to see if somebody else has already + * fixed the problem. + */ + if (idmap_handle.failed) { + /* It's our job to fix. */ + _idmap_clnt_disconnect(); + rc = _idmap_clnt_connect(); + if (rc != IDMAP_SUCCESS) { + /* We couldn't fix it. */ + assert(idmap_handle.failed); + assert(idmap_handle.client == NULL); + break; + } + /* We fixed it. */ + idmap_handle.failed = B_FALSE; + } + + /* It's fixed now. */ + (void) rw_unlock(&idmap_handle.lock); + /* + * Starting here, somebody might declare it failed + * again. + */ + (void) rw_rdlock(&idmap_handle.lock); + continue; + } + + clntstat = clnt_call(idmap_handle.client, procnum, inproc, in, + outproc, out, tout); + rc = _idmap_rpc2stat(clntstat, idmap_handle.client); + if (rc == IDMAP_ERR_RPC_HANDLE) { + /* Failed. Needs to be reconnected. */ + idmap_handle.failed = B_TRUE; + continue; + } + + /* Success or unrecoverable failure. */ + break; + } + (void) rw_unlock(&idmap_handle.lock); + return (rc); +} + +#define MIN_STACK_NEEDS 65536 + +/* + * Connect to idmapd. + * Must be single-threaded through rw_wrlock(&idmap_handle.lock). + */ +static +idmap_stat +_idmap_clnt_connect(void) +{ + uint_t sendsz = 0; + stack_t st; + + /* + * clnt_door_call() alloca()s sendsz bytes (twice too, once for + * the call args buffer and once for the call result buffer), so + * we want to pick a sendsz that will be large enough, but not + * too large. + */ + if (stack_getbounds(&st) == 0) { + /* + * Estimate how much stack space is left; + * st.ss_sp is the top of stack. + */ + if ((char *)&sendsz < (char *)st.ss_sp) + /* stack grows up */ + sendsz = ((char *)st.ss_sp - (char *)&sendsz); + else + /* stack grows down */ + sendsz = ((char *)&sendsz - (char *)st.ss_sp); + + if (sendsz <= MIN_STACK_NEEDS) { + sendsz = 0; /* RPC call may fail */ + } else { + /* Leave 64Kb (just a guess) for our needs */ + sendsz -= MIN_STACK_NEEDS; + + /* Divide the stack space left by two */ + sendsz = RNDUP(sendsz / 2); + + /* Limit sendsz to 256KB */ + if (sendsz > IDMAP_MAX_DOOR_RPC) + sendsz = IDMAP_MAX_DOOR_RPC; } } - /* null handle */ - return (IDMAP_ERR_RPC_HANDLE); + idmap_handle.client = clnt_door_create(IDMAP_PROG, IDMAP_V1, sendsz); + if (idmap_handle.client == NULL) + return (IDMAP_ERR_RPC); + + return (IDMAP_SUCCESS); +} + +/* + * Disconnect from idmapd, if we're connected. + */ +static +void +_idmap_clnt_disconnect(void) +{ + CLIENT *clnt; + + clnt = idmap_handle.client; + if (clnt != NULL) { + if (clnt->cl_auth) + auth_destroy(clnt->cl_auth); + clnt_destroy(clnt); + idmap_handle.client = NULL; + } } diff --git a/usr/src/lib/libsec/common/acltext.c b/usr/src/lib/libsec/common/acltext.c index 952ea28c64..f270503433 100644 --- a/usr/src/lib/libsec/common/acltext.c +++ b/usr/src/lib/libsec/common/acltext.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved. */ /*LINTLIBRARY*/ @@ -120,7 +119,6 @@ prgname(gid_t gid, char *gidp, size_t buflen, int noresolve) static int getsidname(uid_t who, boolean_t user, char **sidp, boolean_t noresolve) { - idmap_handle_t *idmap_hdl = NULL; idmap_get_handle_t *get_hdl = NULL; idmap_stat status; idmap_rid_t rid; @@ -144,8 +142,7 @@ getsidname(uid_t who, boolean_t user, char **sidp, boolean_t noresolve) IDMAP_REQ_FLG_USE_CACHE, &name, &domain); } if (error != IDMAP_SUCCESS) { - if (idmap_init(&idmap_hdl) == IDMAP_SUCCESS && - idmap_get_create(idmap_hdl, &get_hdl) == IDMAP_SUCCESS) { + if (idmap_get_create(&get_hdl) == IDMAP_SUCCESS) { if (user) error = idmap_get_sidbyuid(get_hdl, who, IDMAP_REQ_FLG_USE_CACHE, &domain, &rid, @@ -168,8 +165,6 @@ getsidname(uid_t who, boolean_t user, char **sidp, boolean_t noresolve) } if (get_hdl) idmap_get_destroy(get_hdl); - if (idmap_hdl) - (void) idmap_fini(idmap_hdl); } else { int len; diff --git a/usr/src/lib/libsec/common/aclutils.c b/usr/src/lib/libsec/common/aclutils.c index afe36a3aaa..ba7117c7f7 100644 --- a/usr/src/lib/libsec/common/aclutils.c +++ b/usr/src/lib/libsec/common/aclutils.c @@ -740,7 +740,6 @@ acl_error(const char *fmt, ...) int sid_to_id(char *sid, boolean_t user, uid_t *id) { - idmap_handle_t *idmap_hdl = NULL; idmap_get_handle_t *get_hdl = NULL; char *rid_start = NULL; idmap_stat status; @@ -757,8 +756,7 @@ sid_to_id(char *sid, boolean_t user, uid_t *id) errno = 0; rid = strtoul(rid_start--, &end, 10); if (errno == 0 && *end == '\0') { - if (idmap_init(&idmap_hdl) == IDMAP_SUCCESS && - idmap_get_create(idmap_hdl, &get_hdl) == + if (idmap_get_create(&get_hdl) == IDMAP_SUCCESS) { if (user) error = idmap_get_uidbysid(get_hdl, @@ -781,8 +779,6 @@ sid_to_id(char *sid, boolean_t user, uid_t *id) } if (get_hdl) idmap_get_destroy(get_hdl); - if (idmap_hdl) - (void) idmap_fini(idmap_hdl); } else { error = 1; } diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c index b23c45f354..bb3dd9e7da 100644 --- a/usr/src/lib/libzfs/common/libzfs_dataset.c +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c @@ -2201,14 +2201,11 @@ static int idmap_id_to_numeric_domain_rid(uid_t id, boolean_t isuser, char **domainp, idmap_rid_t *ridp) { - idmap_handle_t *idmap_hdl = NULL; idmap_get_handle_t *get_hdl = NULL; idmap_stat status; int err = EINVAL; - if (idmap_init(&idmap_hdl) != IDMAP_SUCCESS) - goto out; - if (idmap_get_create(idmap_hdl, &get_hdl) != IDMAP_SUCCESS) + if (idmap_get_create(&get_hdl) != IDMAP_SUCCESS) goto out; if (isuser) { @@ -2227,8 +2224,6 @@ idmap_id_to_numeric_domain_rid(uid_t id, boolean_t isuser, out: if (get_hdl) idmap_get_destroy(get_hdl); - if (idmap_hdl) - (void) idmap_fini(idmap_hdl); return (err); } diff --git a/usr/src/lib/nsswitch/ad/common/ad_common.h b/usr/src/lib/nsswitch/ad/common/ad_common.h index a328b00b9a..7592d3613b 100644 --- a/usr/src/lib/nsswitch/ad/common/ad_common.h +++ b/usr/src/lib/nsswitch/ad/common/ad_common.h @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _AD_COMMON_H @@ -82,7 +81,6 @@ struct ad_backend { fnf adobj2str; char *buffer; int buflen; - idmap_handle_t *ih; uid_t uid; adutils_result_t *result; nss_ad_db_type_t db_type; diff --git a/usr/src/lib/nsswitch/ad/common/getgrent.c b/usr/src/lib/nsswitch/ad/common/getgrent.c index b5f70666ba..84481bb09f 100644 --- a/usr/src/lib/nsswitch/ad/common/getgrent.c +++ b/usr/src/lib/nsswitch/ad/common/getgrent.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <grp.h> @@ -72,7 +71,6 @@ getbynam(ad_backend_ptr be, void *a) idmap_stat idmaprc; gid_t gid; int is_user, is_wuser; - idmap_handle_t *ih; be->db_type = NSS_AD_DB_GROUP_BYNAME; @@ -89,14 +87,10 @@ getbynam(ad_backend_ptr be, void *a) /* * Map the name to gid using idmap service. */ - idmaprc = idmap_init(&ih); - if (idmaprc != IDMAP_SUCCESS) - return ((nss_status_t)NSS_NOTFOUND); is_wuser = -1; is_user = 0; /* Map name to gid */ - idmaprc = idmap_get_w2u_mapping(ih, NULL, NULL, name, dname, + idmaprc = idmap_get_w2u_mapping(NULL, NULL, name, dname, 0, &is_user, &is_wuser, &gid, NULL, NULL, NULL); - (void) idmap_fini(ih); if (idmaprc != IDMAP_SUCCESS) { RESET_ERRNO(); return ((nss_status_t)NSS_NOTFOUND); @@ -134,9 +128,7 @@ getbygid(ad_backend_ptr be, void *a) goto out; /* Map the given GID to a SID using the idmap service */ - if (idmap_init(&be->ih) != 0) - goto out; - if (idmap_get_u2w_mapping(be->ih, &argp->key.gid, NULL, 0, + if (idmap_get_u2w_mapping(&argp->key.gid, NULL, 0, 0, NULL, NULL, NULL, &winname, &windomain, NULL, NULL) != 0) { RESET_ERRNO(); @@ -161,8 +153,6 @@ getbygid(ad_backend_ptr be, void *a) out: idmap_free(winname); idmap_free(windomain); - (void) idmap_fini(be->ih); - be->ih = NULL; return (stat); } diff --git a/usr/src/lib/nsswitch/ad/common/getpwnam.c b/usr/src/lib/nsswitch/ad/common/getpwnam.c index ece50a54b0..ff2140b59b 100644 --- a/usr/src/lib/nsswitch/ad/common/getpwnam.c +++ b/usr/src/lib/nsswitch/ad/common/getpwnam.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <pwd.h> @@ -192,9 +191,7 @@ _nss_ad_passwd2str(ad_backend_ptr be, nss_XbyY_args_t *argp) nss_result = NSS_STR_PARSE_PARSE; /* Create handles for idmap service */ - if (be->ih == NULL && idmap_init(&be->ih) != 0) - goto result_pwd2str; - if (idmap_get_create(be->ih, &ig) != 0) + if (idmap_get_create(&ig) != 0) goto result_pwd2str; /* Get name */ @@ -278,8 +275,6 @@ _nss_ad_passwd2str(ad_backend_ptr be, nss_XbyY_args_t *argp) result_pwd2str: idmap_get_destroy(ig); - (void) idmap_fini(be->ih); - be->ih = NULL; (void) adutils_freeresult(&be->result); free(domain); if (homedir != NULL_STR && homedir_v != NULL && @@ -310,7 +305,6 @@ getbyname(ad_backend_ptr be, void *a) uid_t uid; gid_t gid; int is_user, is_wuser, try_idmap; - idmap_handle_t *ih; be->db_type = NSS_AD_DB_PASSWD_BYNAME; @@ -329,17 +323,13 @@ getbyname(ad_backend_ptr be, void *a) * call fails then this will save us doing AD discovery and * AD lookup here. */ - if (idmap_init(&be->ih) != IDMAP_SUCCESS) - return ((nss_status_t)NSS_NOTFOUND); flag = (strcasecmp(dname, WK_DOMAIN) == 0) ? IDMAP_REQ_FLG_WK_OR_LOCAL_SIDS_ONLY : 0; is_wuser = -1; is_user = 1; - if (idmap_get_w2u_mapping(be->ih, NULL, NULL, name, + if (idmap_get_w2u_mapping(NULL, NULL, name, dname, flag, &is_user, &is_wuser, &be->uid, NULL, NULL, NULL) != IDMAP_SUCCESS) { - (void) idmap_fini(be->ih); - be->ih = NULL; RESET_ERRNO(); return ((nss_status_t)NSS_NOTFOUND); } @@ -357,11 +347,8 @@ getbyname(ad_backend_ptr be, void *a) dname, &try_idmap); free(searchfilter); - if (!try_idmap) { - (void) idmap_fini(be->ih); - be->ih = NULL; + if (!try_idmap) return (stat); - } } @@ -372,10 +359,8 @@ getbyname(ad_backend_ptr be, void *a) */ is_wuser = -1; is_user = 0; /* Map name to primary gid */ - idmaprc = idmap_get_w2u_mapping(be->ih, NULL, NULL, name, dname, + idmaprc = idmap_get_w2u_mapping(NULL, NULL, name, dname, flag, &is_user, &is_wuser, &gid, NULL, NULL, NULL); - (void) idmap_fini(be->ih); - be->ih = NULL; if (idmaprc != IDMAP_SUCCESS) { RESET_ERRNO(); return ((nss_status_t)NSS_NOTFOUND); @@ -424,9 +409,7 @@ getbyuid(ad_backend_ptr be, void *a) goto out; /* Map the given UID to a SID using the idmap service */ - if (idmap_init(&be->ih) != 0) - goto out; - if (idmap_get_u2w_mapping(be->ih, &argp->key.uid, NULL, 0, + if (idmap_get_u2w_mapping(&argp->key.uid, NULL, 0, 1, NULL, &sidprefix, &rid, &winname, &windomain, NULL, NULL) != 0) { RESET_ERRNO(); @@ -461,13 +444,10 @@ getbyuid(ad_backend_ptr be, void *a) /* Map winname to primary gid using idmap service */ is_user = 0; is_wuser = -1; - idmaprc = idmap_get_w2u_mapping(be->ih, NULL, NULL, + idmaprc = idmap_get_w2u_mapping(NULL, NULL, winname, windomain, 0, &is_user, &is_wuser, &gid, NULL, NULL, NULL); - (void) idmap_fini(be->ih); - be->ih = NULL; - if (idmaprc != IDMAP_SUCCESS) { RESET_ERRNO(); goto out; @@ -486,8 +466,6 @@ out: idmap_free(sidprefix); idmap_free(winname); idmap_free(windomain); - (void) idmap_fini(be->ih); - be->ih = NULL; return (stat); } diff --git a/usr/src/lib/nsswitch/ad/common/getspent.c b/usr/src/lib/nsswitch/ad/common/getspent.c index 257540c8db..a66d8b122b 100644 --- a/usr/src/lib/nsswitch/ad/common/getspent.c +++ b/usr/src/lib/nsswitch/ad/common/getspent.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <shadow.h> @@ -80,7 +79,6 @@ getbynam(ad_backend_ptr be, void *a) idmap_stat idmaprc; uid_t uid; int is_user, is_wuser; - idmap_handle_t *ih; be->db_type = NSS_AD_DB_SHADOW_BYNAME; @@ -98,14 +96,10 @@ getbynam(ad_backend_ptr be, void *a) * Use idmap service to verify that the given * name is a valid Windows name. */ - idmaprc = idmap_init(&ih); - if (idmaprc != IDMAP_SUCCESS) - return ((nss_status_t)NSS_NOTFOUND); is_wuser = -1; is_user = 1; - idmaprc = idmap_get_w2u_mapping(ih, NULL, NULL, name, dname, + idmaprc = idmap_get_w2u_mapping(NULL, NULL, name, dname, 0, &is_user, &is_wuser, &uid, NULL, NULL, NULL); - (void) idmap_fini(ih); if (idmaprc != IDMAP_SUCCESS) { RESET_ERRNO(); return ((nss_status_t)NSS_NOTFOUND); diff --git a/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c b/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c index 9c36e26f91..95f96d0a97 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -78,3 +77,20 @@ dssetup_get_domain_info(ds_primary_domain_info_t *ds_info) ndr_rpc_unbind(&handle); return (0); } + +int +dssetup_check_service(void) +{ + ds_primary_domain_info_t ds_info; + int rc; + + bzero(&ds_info, sizeof (ds_primary_domain_info_t)); + + if ((rc = dssetup_get_domain_info(&ds_info)) == 0) { + free(ds_info.nt_domain); + free(ds_info.dns_domain); + free(ds_info.forest); + } + + return (rc); +} diff --git a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h index 267c78fe12..03603a61aa 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h +++ b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h @@ -60,11 +60,11 @@ uint32_t lsa_lookup_sid(smb_sid_t *, smb_account_t *); extern boolean_t smb_locate_dc(char *, char *, smb_domainex_t *); +extern int dssetup_check_service(void); extern void dssetup_clear_domain_info(void); extern void mlsvc_disconnect(const char *); extern int mlsvc_init(void); extern void mlsvc_fini(void); -extern int mlsvc_ping(const char *); extern DWORD mlsvc_netlogon(char *, char *); extern DWORD mlsvc_join(smb_domainex_t *, char *, char *); diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers b/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers index c3af6a8f20..bb9cd09573 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers +++ b/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers @@ -42,6 +42,7 @@ SYMBOL_VERSION SUNWprivate { global: dfs_get_referrals; dfs_info_free; + dssetup_check_service; dssetup_clear_domain_info; lsa_lookup_name; lsa_lookup_sid; diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c index be1dcb8a52..f835934e5e 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -142,12 +141,6 @@ mlsvc_join(smb_domainex_t *dxi, char *user, char *plain_text) return (status); } -int -mlsvc_ping(const char *server) -{ - return (smbrdr_echo(server)); -} - void mlsvc_disconnect(const char *server) { diff --git a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c index 46e7117f92..1e346ab41e 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c @@ -151,18 +151,11 @@ netlogon_logon(smb_logon_t *user_info, smb_token_t *token) mlsvc_handle_t netr_handle; smb_domainex_t di; uint32_t status; - int retries = 0, server_changed = 0; + int retries = 0; (void) smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN); - if (!smb_domain_getinfo(&di)) - return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); - - if (mlsvc_ping(di.d_dc) < 0) { - /* - * We had a session to the DC but it's not responding. - * So drop the credential chain. - */ + if (!smb_domain_getinfo(&di)) { netr_invalidate_chain(); return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); } @@ -175,12 +168,12 @@ netlogon_logon(smb_logon_t *user_info, smb_token_t *token) if (di.d_dc && (*netr_global_info.server != '\0')) { (void) snprintf(server, sizeof (server), "\\\\%s", di.d_dc); - server_changed = strncasecmp(netr_global_info.server, - server, strlen(server)); + if (strncasecmp(netr_global_info.server, + server, strlen(server)) != 0) + netr_invalidate_chain(); } - if (server_changed || - (netr_global_info.flags & NETR_FLG_VALID) == 0 || + if ((netr_global_info.flags & NETR_FLG_VALID) == 0 || !smb_match_netlogon_seqnum()) { status = netlogon_auth(di.d_dc, &netr_handle, NETR_FLG_NULL); diff --git a/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c b/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c index 850b8f5858..71b6f278d6 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <unistd.h> @@ -136,7 +135,7 @@ static int smb_token_sids2ids(smb_token_t *token) { idmap_stat stat; - int nmaps, retries = 0; + int nmaps; smb_idmap_batch_t sib; /* @@ -148,21 +147,19 @@ smb_token_sids2ids(smb_token_t *token) else nmaps = token->tkn_win_grps.i_cnt + 3; - do { - stat = smb_idmap_batch_create(&sib, nmaps, SMB_IDMAP_SID2ID); - if (stat != IDMAP_SUCCESS) - return (-1); - - stat = smb_token_idmap(token, &sib); - if (stat != IDMAP_SUCCESS) { - smb_idmap_batch_destroy(&sib); - return (-1); - } + stat = smb_idmap_batch_create(&sib, nmaps, SMB_IDMAP_SID2ID); + if (stat != IDMAP_SUCCESS) + return (-1); - stat = smb_idmap_batch_getmappings(&sib); + stat = smb_token_idmap(token, &sib); + if (stat != IDMAP_SUCCESS) { smb_idmap_batch_destroy(&sib); - smb_idmap_check("smb_idmap_batch_getmappings", stat); - } while (stat == IDMAP_ERR_RPC_HANDLE && retries++ < 3); + return (-1); + } + + stat = smb_idmap_batch_getmappings(&sib); + smb_idmap_batch_destroy(&sib); + smb_idmap_check("smb_idmap_batch_getmappings", stat); return (stat == IDMAP_SUCCESS ? 0 : -1); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c index b2897c48cc..8630e5d10c 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c @@ -168,11 +168,17 @@ static ndr_service_t spoolss_service = { spoolss_stub_table /* stub_table */ }; +/* + * Defer calling spoolss_cups_init() until something actually + * needs access to CUPS due to the libcups dependency on OpenSSL. + * OpenSSL is not MT-safe and initializing CUPS here can crash + * OpenSSL if it collides with other threads that are in other + * libraries that are attempting to use OpenSSL. + */ void spoolss_initialize(void) { (void) ndr_svc_register(&spoolss_service); - (void) spoolss_cups_init(); } void diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c b/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c index deee29188d..8201db46aa 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c @@ -19,37 +19,17 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <syslog.h> #include <strings.h> -#include <synch.h> #include <smbsrv/libsmb.h> -static idmap_handle_t *smb_idmap_hd; -static mutex_t smb_idmap_mutex; - static int smb_idmap_batch_binsid(smb_idmap_batch_t *sib); -static void -smb_idmap_reset(void) -{ - (void) mutex_lock(&smb_idmap_mutex); - - if (smb_idmap_hd != NULL) { - (void) idmap_fini(smb_idmap_hd); - smb_idmap_hd = NULL; - } - - (void) mutex_unlock(&smb_idmap_mutex); -} - /* - * Report an idmap error. If the error appears to be connection - * related, use fini to reset. A new handle will be generated on - * the next open. + * Report an idmap error. */ void smb_idmap_check(const char *s, idmap_stat stat) @@ -58,44 +38,8 @@ smb_idmap_check(const char *s, idmap_stat stat) if (s == NULL) s = "smb_idmap_check"; - syslog(LOG_ERR, "%s: %s", s, idmap_stat2string(NULL, stat)); - - switch (stat) { - case IDMAP_ERR_RPC_HANDLE: - case IDMAP_ERR_RPC: - case IDMAP_ERR_CLIENT_HANDLE: - smb_idmap_reset(); - break; - default: - break; - } - } -} - -static idmap_handle_t * -smb_idmap_enter(void) -{ - idmap_stat stat; - - (void) mutex_lock(&smb_idmap_mutex); - - if (smb_idmap_hd == NULL) { - if ((stat = idmap_init(&smb_idmap_hd)) < 0) { - syslog(LOG_ERR, - "smb_idmap_enter: idmap_init failed: %s", - idmap_stat2string(NULL, stat)); - (void) mutex_unlock(&smb_idmap_mutex); - return (NULL); - } + syslog(LOG_ERR, "%s: %s", s, idmap_stat2string(stat)); } - - return (smb_idmap_hd); -} - -static void -smb_idmap_exit(void) -{ - (void) mutex_unlock(&smb_idmap_mutex); } /* @@ -180,18 +124,13 @@ smb_idmap_getid(smb_sid_t *sid, uid_t *id, int *id_type) idmap_stat smb_idmap_batch_create(smb_idmap_batch_t *sib, uint16_t nmap, int flags) { - idmap_handle_t *hd; idmap_stat stat; if (!sib) return (IDMAP_ERR_ARG); - if ((hd = smb_idmap_enter()) == NULL) - return (IDMAP_ERR_OTHER); - bzero(sib, sizeof (smb_idmap_batch_t)); - stat = idmap_get_create(hd, &sib->sib_idmaph); - smb_idmap_exit(); + stat = idmap_get_create(&sib->sib_idmaph); if (stat != IDMAP_SUCCESS) { smb_idmap_check("idmap_get_create", stat); @@ -380,10 +319,8 @@ smb_idmap_batch_getmappings(smb_idmap_batch_t *sib) smb_idmap_t *sim; int i; - (void) mutex_lock(&smb_idmap_mutex); if ((stat = idmap_get_mappings(sib->sib_idmaph)) != IDMAP_SUCCESS) { smb_idmap_check("idmap_get_mappings", stat); - (void) mutex_unlock(&smb_idmap_mutex); return (stat); } @@ -396,7 +333,6 @@ smb_idmap_batch_getmappings(smb_idmap_batch_t *sib) smb_tracef("[%d] %d (%d)", sim->sim_idtype, sim->sim_rid, sim->sim_stat); } - (void) mutex_unlock(&smb_idmap_mutex); return (sim->sim_stat); } } @@ -404,7 +340,6 @@ smb_idmap_batch_getmappings(smb_idmap_batch_t *sib) if (smb_idmap_batch_binsid(sib) != 0) stat = IDMAP_ERR_OTHER; - (void) mutex_unlock(&smb_idmap_mutex); return (stat); } diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_sd.c b/usr/src/lib/smbsrv/libsmb/common/smb_sd.c index 1f36038f53..231c0f6932 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_sd.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_sd.c @@ -29,6 +29,7 @@ #include <strings.h> #include <assert.h> +#include <errno.h> #include <smbsrv/ntifs.h> #include <smbsrv/smb_idmap.h> #include <smbsrv/libsmb.h> @@ -156,11 +157,18 @@ smb_sd_read_acl(char *path, smb_fssd_t *fs_sd) ace_t *z_ace; fs_sd->sd_gid = fs_sd->sd_uid = 0; - if (acl_trivial(path) != 1) - return (NT_STATUS_INTERNAL_ERROR); - if (acl_get(path, ACL_NO_TRIVIAL, &z_acl) != 0) - return (NT_STATUS_INTERNAL_ERROR); + errno = 0; + if (acl_get(path, 0, &z_acl) != 0) { + switch (errno) { + case EACCES: + return (NT_STATUS_ACCESS_DENIED); + case ENOENT: + return (NT_STATUS_OBJECT_PATH_NOT_FOUND); + default: + return (NT_STATUS_INTERNAL_ERROR); + } + } if ((z_ace = (ace_t *)z_acl->acl_aclp) == NULL) return (NT_STATUS_INVALID_ACL); |