4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
32 #include <sys/types.h>
33 #include <nss_dbdefs.h>
36 #include <sys/systeminfo.h>
40 #include <prof_attr.h>
41 #include <exec_attr.h>
43 /* externs from libc */
44 extern void _nss_db_state_destr(struct nss_db_state
*);
46 /* externs from parse.c */
47 extern char *_strtok_escape(char *, char *, char **);
48 extern char *_strdup_null(char *);
49 /* extern from getprofattr.c */
50 extern int str2profattr(const char *, int, void *, char *, int);
52 char *_exec_wild_id(char *, const char *);
53 execstr_t
*_dup_execstr(execstr_t
*);
54 void _free_execstr(execstr_t
*);
56 static char *_nsw_search_path
= NULL
;
59 * Unsynchronized, but it affects only efficiency, not correctness
62 static DEFINE_NSS_DB_ROOT(exec_root
);
63 static DEFINE_NSS_GETENT(context
);
66 _nss_initf_execattr(nss_db_params_t
*p
)
68 p
->name
= NSS_DBNAM_EXECATTR
;
69 p
->config_name
= NSS_DBNAM_PROFATTR
; /* use config for "prof_attr" */
73 _nsw_initf_execattr(nss_db_params_t
*p
)
75 p
->name
= NSS_DBNAM_EXECATTR
;
76 p
->flags
|= NSS_USE_DEFAULT_CONFIG
;
77 p
->default_config
= _nsw_search_path
;
81 _nsw_initf_profattr(nss_db_params_t
*p
)
83 p
->name
= NSS_DBNAM_PROFATTR
;
84 p
->flags
|= NSS_USE_DEFAULT_CONFIG
;
85 p
->default_config
= _nsw_search_path
;
89 * Return values: 0 = success, 1 = parse error, 2 = erange ... The structure
90 * pointer passed in is a structure in the caller's space wherein the field
91 * pointers would be set to areas in the buffer if need be. instring and buffer
92 * should be separate areas.
95 str2execattr(const char *instr
, int lenstr
, void *ent
, char *buffer
, int buflen
)
98 char *sep
= KV_TOKEN_DELIMIT
;
99 execstr_t
*exec
= (execstr_t
*)ent
;
101 if (lenstr
>= buflen
)
102 return (NSS_STR_PARSE_ERANGE
);
105 (void) strncpy(buffer
, instr
, buflen
);
108 * Remove newline that nis (yp_match) puts at the
109 * end of the entry it retrieves from the map.
111 if (buffer
[lenstr
] == '\n') {
112 buffer
[lenstr
] = '\0';
115 /* quick exit do not entry fill if not needed */
117 return (NSS_STR_PARSE_SUCCESS
);
119 exec
->name
= _strtok_escape(buffer
, sep
, &last
);
120 exec
->policy
= _strtok_escape(NULL
, sep
, &last
);
121 exec
->type
= _strtok_escape(NULL
, sep
, &last
);
122 exec
->res1
= _strtok_escape(NULL
, sep
, &last
);
123 exec
->res2
= _strtok_escape(NULL
, sep
, &last
);
124 exec
->id
= _strtok_escape(NULL
, sep
, &last
);
125 exec
->attr
= _strtok_escape(NULL
, sep
, &last
);
128 return (NSS_STR_PARSE_SUCCESS
);
135 nss_setent(&exec_root
, _nss_initf_execattr
, &context
);
142 nss_endent(&exec_root
, _nss_initf_execattr
, &context
);
143 nss_delete(&exec_root
);
148 _getexecattr(execstr_t
*result
, char *buffer
, int buflen
, int *errnop
)
153 NSS_XbyY_INIT(&arg
, result
, buffer
, buflen
, str2execattr
);
154 res
= nss_getent(&exec_root
, _nss_initf_execattr
, &context
, &arg
);
156 *errnop
= arg
.h_errno
;
158 return ((execstr_t
*)NSS_XbyY_FINI(&arg
));
162 _getexecprof(char *name
,
172 char policy_buf
[BUFSIZ
];
173 nss_status_t res
= NSS_NOTFOUND
;
175 _priv_execattr _priv_exec
;
176 static mutex_t _nsw_exec_lock
= DEFAULTMUTEX
;
178 if ((name
!= NULL
) && (id
!= NULL
)) {
179 getby_flag
= NSS_DBOP_EXECATTR_BYNAMEID
;
180 } else if (name
!= NULL
) {
181 getby_flag
= NSS_DBOP_EXECATTR_BYNAME
;
182 } else if (id
!= NULL
) {
183 getby_flag
= NSS_DBOP_EXECATTR_BYID
;
188 NSS_XbyY_INIT(&arg
, result
, buffer
, buflen
, str2execattr
);
190 _priv_exec
.name
= name
;
191 _priv_exec
.type
= type
;
194 if (sysinfo(SI_SECPOLICY
, policy_buf
, BUFSIZ
) == -1)
195 #endif /* SI_SECPOLICY */
196 (void) strncpy(policy_buf
, DEFAULT_POLICY
, BUFSIZ
);
199 _priv_exec
.policy
= IS_SEARCH_ALL(search_flag
) ? NULL
: policy_buf
;
200 _priv_exec
.search_flag
= search_flag
;
201 _priv_exec
.head_exec
= NULL
;
202 _priv_exec
.prev_exec
= NULL
;
204 arg
.key
.attrp
= &(_priv_exec
);
206 switch (getby_flag
) {
207 case NSS_DBOP_EXECATTR_BYID
:
208 res
= nss_search(&exec_root
, _nss_initf_execattr
, getby_flag
,
211 case NSS_DBOP_EXECATTR_BYNAMEID
:
212 case NSS_DBOP_EXECATTR_BYNAME
:
214 char pbuf
[NSS_BUFLEN_PROFATTR
];
217 nss_XbyY_args_t parg
;
218 enum __nsw_parse_err pserr
;
219 struct __nsw_lookup
*lookups
= NULL
;
220 struct __nsw_switchconfig
*conf
= NULL
;
222 if (conf
= __nsw_getconfig(NSS_DBNAM_PROFATTR
, &pserr
))
223 if ((lookups
= conf
->lookups
) == NULL
)
225 NSS_XbyY_INIT(&parg
, &prof
, pbuf
, NSS_BUFLEN_PROFATTR
,
227 parg
.key
.name
= name
;
230 * search the exec_attr entry only in the scope
231 * that we find the profile in.
232 * if conf = NULL, search in local files only,
233 * as we were not able to read nsswitch.conf.
235 DEFINE_NSS_DB_ROOT(prof_root
);
236 if (mutex_lock(&_nsw_exec_lock
) != 0)
238 _nsw_search_path
= (conf
== NULL
)
240 : lookups
->service_name
;
241 pres
= nss_search(&prof_root
,
243 NSS_DBOP_PROFATTR_BYNAME
, &parg
);
244 if (pres
== NSS_SUCCESS
) {
245 DEFINE_NSS_DB_ROOT(pexec_root
);
246 res
= nss_search(&pexec_root
,
247 _nsw_initf_execattr
, getby_flag
,
249 if (pexec_root
.s
!= NULL
)
253 if (prof_root
.s
!= NULL
)
254 _nss_db_state_destr(prof_root
.s
);
255 (void) mutex_unlock(&_nsw_exec_lock
);
256 if ((pres
== NSS_SUCCESS
) || (conf
== NULL
))
258 } while (lookups
&& (lookups
= lookups
->next
));
267 * If we can't find an entry for the current default policy
268 * fall back to the old "suser" policy. The nameservice is
269 * shared between different OS releases.
271 if (!IS_SEARCH_ALL(search_flag
) &&
272 (res
== NSS_NOTFOUND
&& strcmp(policy_buf
, DEFAULT_POLICY
) == 0)) {
273 (void) strlcpy(policy_buf
, SUSER_POLICY
, BUFSIZ
);
279 return ((execstr_t
*)NSS_XbyY_FINI(&arg
));
284 _doexeclist(nss_XbyY_args_t
*argp
)
287 _priv_execattr
*_priv_exec
= (_priv_execattr
*)(argp
->key
.attrp
);
288 execstr_t
*exec
= (execstr_t
*)((argp
->buf
.result
));
290 if (_priv_exec
->head_exec
== NULL
) {
291 if (_priv_exec
->head_exec
= _dup_execstr(exec
))
292 _priv_exec
->prev_exec
= _priv_exec
->head_exec
;
296 if (_priv_exec
->prev_exec
->next
= _dup_execstr(exec
))
297 _priv_exec
->prev_exec
= _priv_exec
->prev_exec
->next
;
301 (void) memset(argp
->buf
.buffer
, 0, argp
->buf
.buflen
);
309 * Converts id to a wildcard string. e.g.:
310 * For type = KV_COMMAND: /usr/ccs/bin/what ---> /usr/ccs/bin/\* ---> \*
311 * For type = KV_ACTION: Dtfile;*;*;*;0 ---> *;*;*;*;*
313 * Returns NULL if id is already a wild-card.
316 _exec_wild_id(char *id
, const char *type
)
321 if ((id
== NULL
) || (type
== NULL
))
324 if (strcmp(type
, KV_ACTION
) == 0) {
325 return ((strcmp(id
, KV_ACTION_WILDCARD
) == 0) ? NULL
:
327 } else if (strcmp(type
, KV_COMMAND
) == 0) {
328 if ((pchar
= rindex(id
, c_id
)) == NULL
)
333 else if (*(++pchar
) == KV_WILDCHAR
)
335 * id = /usr/ccs/bin/\*
339 * id = /usr/ccs/bin/what
341 (void) strcpy(pchar
, KV_WILDCARD
);
351 _dup_execstr(execstr_t
*old_exec
)
353 execstr_t
*new_exec
= NULL
;
355 if (old_exec
== NULL
)
357 if ((new_exec
= malloc(sizeof (execstr_t
))) != NULL
) {
358 new_exec
->name
= _strdup_null(old_exec
->name
);
359 new_exec
->type
= _strdup_null(old_exec
->type
);
360 new_exec
->policy
= _strdup_null(old_exec
->policy
);
361 new_exec
->res1
= _strdup_null(old_exec
->res1
);
362 new_exec
->res2
= _strdup_null(old_exec
->res2
);
363 new_exec
->id
= _strdup_null(old_exec
->id
);
364 new_exec
->attr
= _strdup_null(old_exec
->attr
);
365 new_exec
->next
= old_exec
->next
;
371 _free_execstr(execstr_t
*exec
)
381 _free_execstr(exec
->next
);
387 _exec_cleanup(nss_status_t res
, nss_XbyY_args_t
*argp
)
389 _priv_execattr
*_priv_exec
= (_priv_execattr
*)(argp
->key
.attrp
);
391 if (res
== NSS_SUCCESS
) {
392 if (_priv_exec
->head_exec
!= NULL
) {
393 argp
->buf
.result
= _priv_exec
->head_exec
;
394 argp
->returnval
= argp
->buf
.result
;
397 if (_priv_exec
->head_exec
!= NULL
)
398 _free_execstr(_priv_exec
->head_exec
);
399 argp
->returnval
= NULL
;