17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5d3186a0eSjeanm * Common Development and Distribution License (the "License"). 6d3186a0eSjeanm * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22ceeba6f9Srui zang - Sun Microsystems - Beijing China * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 25134a1f4eSCasper H.S. Dik #include <alloca.h> 267c478bd9Sstevel@tonic-gate #include <stdio.h> 277c478bd9Sstevel@tonic-gate #include <stdlib.h> 287c478bd9Sstevel@tonic-gate #include <string.h> 297c478bd9Sstevel@tonic-gate #include <sys/stat.h> 30499fd601Sgww #include <pwd.h> 31499fd601Sgww #include <nss_dbdefs.h> 327c478bd9Sstevel@tonic-gate #include <deflt.h> 337c478bd9Sstevel@tonic-gate #include <auth_attr.h> 347c478bd9Sstevel@tonic-gate #include <prof_attr.h> 357c478bd9Sstevel@tonic-gate #include <user_attr.h> 367c478bd9Sstevel@tonic-gate 37134a1f4eSCasper H.S. Dik #define COPYTOSTACK(dst, csrc) { \ 38134a1f4eSCasper H.S. Dik size_t len = strlen(csrc) + 1; \ 39134a1f4eSCasper H.S. Dik dst = alloca(len); \ 40134a1f4eSCasper H.S. Dik (void) memcpy(dst, csrc, len); \ 41134a1f4eSCasper H.S. Dik } 427c478bd9Sstevel@tonic-gate 43134a1f4eSCasper H.S. Dik static kva_t *get_default_attrs(const char *); 44134a1f4eSCasper H.S. Dik static void free_default_attrs(kva_t *); 45134a1f4eSCasper H.S. Dik 46134a1f4eSCasper H.S. Dik /* 47134a1f4eSCasper H.S. Dik * Enumeration functions for auths and profiles; the enumeration functions 48134a1f4eSCasper H.S. Dik * take a callback with four arguments: 49134a1f4eSCasper H.S. Dik * const char * profile name (or NULL unless wantattr is false) 50134a1f4eSCasper H.S. Dik * kva_t * attributes (or NULL unless wantattr is true) 51134a1f4eSCasper H.S. Dik * void * context 52134a1f4eSCasper H.S. Dik * void * pointer to the result 53134a1f4eSCasper H.S. Dik * When the call back returns non-zero, the enumeration ends. 54134a1f4eSCasper H.S. Dik * The function might be NULL but only for profiles as we are always collecting 55134a1f4eSCasper H.S. Dik * all the profiles. 56134a1f4eSCasper H.S. Dik * Both the auths and the profiles arguments may be NULL. 57134a1f4eSCasper H.S. Dik * 58134a1f4eSCasper H.S. Dik * These should be the only implementation of the algorithm of "finding me 59134a1f4eSCasper H.S. Dik * all the profiles/athorizations/keywords/etc. 60134a1f4eSCasper H.S. Dik */ 61134a1f4eSCasper H.S. Dik 62134a1f4eSCasper H.S. Dik #define CONSUSER_PROFILE_KW "consprofile" 63134a1f4eSCasper H.S. Dik #define DEF_LOCK_AFTER_RETRIES "LOCK_AFTER_RETRIES=" 64134a1f4eSCasper H.S. Dik 65134a1f4eSCasper H.S. Dik static struct dfltplcy { 66134a1f4eSCasper H.S. Dik char *attr; 67134a1f4eSCasper H.S. Dik const char *defkw; 68134a1f4eSCasper H.S. Dik } dfltply[] = { 69134a1f4eSCasper H.S. Dik /* CONSUSER MUST BE FIRST! */ 70134a1f4eSCasper H.S. Dik { CONSUSER_PROFILE_KW, DEF_CONSUSER}, 71134a1f4eSCasper H.S. Dik { PROFATTR_AUTHS_KW, DEF_AUTH}, 72134a1f4eSCasper H.S. Dik { PROFATTR_PROFS_KW, DEF_PROF}, 73134a1f4eSCasper H.S. Dik { USERATTR_LIMPRIV_KW, DEF_LIMITPRIV}, 74134a1f4eSCasper H.S. Dik { USERATTR_DFLTPRIV_KW, DEF_DFLTPRIV}, 75134a1f4eSCasper H.S. Dik { USERATTR_LOCK_AFTER_RETRIES_KW, DEF_LOCK_AFTER_RETRIES} 76134a1f4eSCasper H.S. Dik }; 77134a1f4eSCasper H.S. Dik 78134a1f4eSCasper H.S. Dik #define NDFLTPLY (sizeof (dfltply)/sizeof (struct dfltplcy)) 79134a1f4eSCasper H.S. Dik #define GETCONSPROF(a) (kva_match((a), CONSUSER_PROFILE_KW)) 80134a1f4eSCasper H.S. Dik #define GETPROF(a) (kva_match((a), PROFATTR_PROFS_KW)) 81134a1f4eSCasper H.S. Dik 82134a1f4eSCasper H.S. Dik /* 83134a1f4eSCasper H.S. Dik * Enumerate profiles from listed profiles. 84134a1f4eSCasper H.S. Dik */ 857c478bd9Sstevel@tonic-gate int 86134a1f4eSCasper H.S. Dik _enum_common_p(const char *cprofiles, 87134a1f4eSCasper H.S. Dik int (*cb)(const char *, kva_t *, void *, void *), 88134a1f4eSCasper H.S. Dik void *ctxt, void *pres, boolean_t wantattr, 89134a1f4eSCasper H.S. Dik int *pcnt, char *profs[MAXPROFS]) 907c478bd9Sstevel@tonic-gate { 91134a1f4eSCasper H.S. Dik char *prof, *last; 927c478bd9Sstevel@tonic-gate char *profiles; 937c478bd9Sstevel@tonic-gate profattr_t *pa; 947c478bd9Sstevel@tonic-gate int i; 95134a1f4eSCasper H.S. Dik int res = 0; 967c478bd9Sstevel@tonic-gate 97134a1f4eSCasper H.S. Dik if (cprofiles == NULL) 987c478bd9Sstevel@tonic-gate return (0); 99134a1f4eSCasper H.S. Dik 100134a1f4eSCasper H.S. Dik if (*pcnt > 0 && strcmp(profs[*pcnt - 1], PROFILE_STOP) == NULL) 101134a1f4eSCasper H.S. Dik return (0); 102134a1f4eSCasper H.S. Dik 103134a1f4eSCasper H.S. Dik COPYTOSTACK(profiles, cprofiles) 104134a1f4eSCasper H.S. Dik 105134a1f4eSCasper H.S. Dik while (prof = strtok_r(profiles, KV_SEPSTR, &last)) { 106134a1f4eSCasper H.S. Dik 107134a1f4eSCasper H.S. Dik profiles = NULL; /* For next iterations of strtok_r */ 108134a1f4eSCasper H.S. Dik 109134a1f4eSCasper H.S. Dik for (i = 0; i < *pcnt; i++) 110134a1f4eSCasper H.S. Dik if (strcmp(profs[i], prof) == 0) 111134a1f4eSCasper H.S. Dik goto cont; 112134a1f4eSCasper H.S. Dik 113134a1f4eSCasper H.S. Dik if (*pcnt >= MAXPROFS) /* oops: too many profs */ 114134a1f4eSCasper H.S. Dik return (-1); 115134a1f4eSCasper H.S. Dik 116134a1f4eSCasper H.S. Dik /* Add it */ 117134a1f4eSCasper H.S. Dik profs[(*pcnt)++] = strdup(prof); 118134a1f4eSCasper H.S. Dik 119134a1f4eSCasper H.S. Dik if (strcmp(profs[*pcnt - 1], PROFILE_STOP) == 0) 120134a1f4eSCasper H.S. Dik break; 121134a1f4eSCasper H.S. Dik 122134a1f4eSCasper H.S. Dik /* find the profiles for this profile */ 123134a1f4eSCasper H.S. Dik pa = getprofnam(prof); 124134a1f4eSCasper H.S. Dik 125134a1f4eSCasper H.S. Dik if (cb != NULL && (!wantattr || pa != NULL && pa->attr != NULL)) 126134a1f4eSCasper H.S. Dik res = cb(prof, pa ? pa->attr : NULL, ctxt, pres); 127134a1f4eSCasper H.S. Dik 128134a1f4eSCasper H.S. Dik if (pa != NULL) { 129134a1f4eSCasper H.S. Dik if (res == 0 && pa->attr != NULL) { 130134a1f4eSCasper H.S. Dik res = _enum_common_p(GETPROF(pa->attr), cb, 131134a1f4eSCasper H.S. Dik ctxt, pres, wantattr, pcnt, profs); 132134a1f4eSCasper H.S. Dik } 133134a1f4eSCasper H.S. Dik free_profattr(pa); 134134a1f4eSCasper H.S. Dik } 135134a1f4eSCasper H.S. Dik if (res != 0) 136134a1f4eSCasper H.S. Dik return (res); 137134a1f4eSCasper H.S. Dik cont: 138134a1f4eSCasper H.S. Dik continue; 139134a1f4eSCasper H.S. Dik } 140134a1f4eSCasper H.S. Dik return (res); 141134a1f4eSCasper H.S. Dik } 142134a1f4eSCasper H.S. Dik 143134a1f4eSCasper H.S. Dik /* 144134a1f4eSCasper H.S. Dik * Enumerate all attributes associated with a username and the profiles 145134a1f4eSCasper H.S. Dik * associated with the user. 146134a1f4eSCasper H.S. Dik */ 147134a1f4eSCasper H.S. Dik static int 148134a1f4eSCasper H.S. Dik _enum_common(const char *username, 149134a1f4eSCasper H.S. Dik int (*cb)(const char *, kva_t *, void *, void *), 150134a1f4eSCasper H.S. Dik void *ctxt, void *pres, boolean_t wantattr) 151134a1f4eSCasper H.S. Dik { 152134a1f4eSCasper H.S. Dik userattr_t *ua; 153134a1f4eSCasper H.S. Dik int res = 0; 154134a1f4eSCasper H.S. Dik int cnt = 0; 155134a1f4eSCasper H.S. Dik char *profs[MAXPROFS]; 156134a1f4eSCasper H.S. Dik kva_t *kattrs; 157134a1f4eSCasper H.S. Dik 158134a1f4eSCasper H.S. Dik if (cb == NULL) 159134a1f4eSCasper H.S. Dik return (-1); 160134a1f4eSCasper H.S. Dik 161134a1f4eSCasper H.S. Dik ua = getusernam(username); 162134a1f4eSCasper H.S. Dik 163134a1f4eSCasper H.S. Dik if (ua != NULL) { 164134a1f4eSCasper H.S. Dik if (ua->attr != NULL) { 165134a1f4eSCasper H.S. Dik if (wantattr) 166134a1f4eSCasper H.S. Dik res = cb(NULL, ua->attr, ctxt, pres); 167134a1f4eSCasper H.S. Dik if (res == 0) { 168134a1f4eSCasper H.S. Dik res = _enum_common_p(GETPROF(ua->attr), 169134a1f4eSCasper H.S. Dik cb, ctxt, pres, wantattr, &cnt, profs); 170134a1f4eSCasper H.S. Dik } 171134a1f4eSCasper H.S. Dik } 172134a1f4eSCasper H.S. Dik free_userattr(ua); 173*bf859931SCasper H.S. Dik if (res != 0) { 174*bf859931SCasper H.S. Dik free_proflist(profs, cnt); 175134a1f4eSCasper H.S. Dik return (res); 176134a1f4eSCasper H.S. Dik } 177*bf859931SCasper H.S. Dik } 178134a1f4eSCasper H.S. Dik 179134a1f4eSCasper H.S. Dik if ((cnt == 0 || strcmp(profs[cnt-1], PROFILE_STOP) != 0) && 180134a1f4eSCasper H.S. Dik (kattrs = get_default_attrs(username)) != NULL) { 181134a1f4eSCasper H.S. Dik 182134a1f4eSCasper H.S. Dik res = _enum_common_p(GETCONSPROF(kattrs), cb, ctxt, pres, 183134a1f4eSCasper H.S. Dik wantattr, &cnt, profs); 184134a1f4eSCasper H.S. Dik 185134a1f4eSCasper H.S. Dik if (res == 0) { 186134a1f4eSCasper H.S. Dik res = _enum_common_p(GETPROF(kattrs), cb, ctxt, pres, 187134a1f4eSCasper H.S. Dik wantattr, &cnt, profs); 188134a1f4eSCasper H.S. Dik } 189134a1f4eSCasper H.S. Dik 190134a1f4eSCasper H.S. Dik if (res == 0 && wantattr) 191134a1f4eSCasper H.S. Dik res = cb(NULL, kattrs, ctxt, pres); 192134a1f4eSCasper H.S. Dik 193134a1f4eSCasper H.S. Dik free_default_attrs(kattrs); 194134a1f4eSCasper H.S. Dik } 195134a1f4eSCasper H.S. Dik 196134a1f4eSCasper H.S. Dik free_proflist(profs, cnt); 197134a1f4eSCasper H.S. Dik 198134a1f4eSCasper H.S. Dik return (res); 199134a1f4eSCasper H.S. Dik } 200134a1f4eSCasper H.S. Dik 201134a1f4eSCasper H.S. Dik /* 202134a1f4eSCasper H.S. Dik * Enumerate profiles with a username argument. 203134a1f4eSCasper H.S. Dik */ 204134a1f4eSCasper H.S. Dik int 205134a1f4eSCasper H.S. Dik _enum_profs(const char *username, 206134a1f4eSCasper H.S. Dik int (*cb)(const char *, kva_t *, void *, void *), 207134a1f4eSCasper H.S. Dik void *ctxt, void *pres) 208134a1f4eSCasper H.S. Dik { 209134a1f4eSCasper H.S. Dik return (_enum_common(username, cb, ctxt, pres, B_FALSE)); 210134a1f4eSCasper H.S. Dik } 211134a1f4eSCasper H.S. Dik 212134a1f4eSCasper H.S. Dik /* 213134a1f4eSCasper H.S. Dik * Enumerate attributes with a username argument. 214134a1f4eSCasper H.S. Dik */ 215134a1f4eSCasper H.S. Dik int 216134a1f4eSCasper H.S. Dik _enum_attrs(const char *username, 217134a1f4eSCasper H.S. Dik int (*cb)(const char *, kva_t *, void *, void *), 218134a1f4eSCasper H.S. Dik void *ctxt, void *pres) 219134a1f4eSCasper H.S. Dik { 220134a1f4eSCasper H.S. Dik return (_enum_common(username, cb, ctxt, pres, B_TRUE)); 221134a1f4eSCasper H.S. Dik } 222134a1f4eSCasper H.S. Dik 223134a1f4eSCasper H.S. Dik 224134a1f4eSCasper H.S. Dik /* 225134a1f4eSCasper H.S. Dik * Enumerate authorizations in the "auths" argument. 226134a1f4eSCasper H.S. Dik */ 227134a1f4eSCasper H.S. Dik static int 228134a1f4eSCasper H.S. Dik _enum_auths_a(const char *cauths, int (*cb)(const char *, void *, void *), 229134a1f4eSCasper H.S. Dik void *ctxt, void *pres) 230134a1f4eSCasper H.S. Dik { 231134a1f4eSCasper H.S. Dik char *auth, *last, *auths; 232134a1f4eSCasper H.S. Dik int res = 0; 233134a1f4eSCasper H.S. Dik 234134a1f4eSCasper H.S. Dik if (cauths == NULL || cb == NULL) 235134a1f4eSCasper H.S. Dik return (0); 236134a1f4eSCasper H.S. Dik 237134a1f4eSCasper H.S. Dik COPYTOSTACK(auths, cauths) 238134a1f4eSCasper H.S. Dik 239134a1f4eSCasper H.S. Dik while (auth = strtok_r(auths, KV_SEPSTR, &last)) { 240134a1f4eSCasper H.S. Dik auths = NULL; /* For next iterations of strtok_r */ 241134a1f4eSCasper H.S. Dik 242134a1f4eSCasper H.S. Dik res = cb(auth, ctxt, pres); 243134a1f4eSCasper H.S. Dik 244134a1f4eSCasper H.S. Dik if (res != 0) 245134a1f4eSCasper H.S. Dik return (res); 246134a1f4eSCasper H.S. Dik } 247134a1f4eSCasper H.S. Dik return (res); 248134a1f4eSCasper H.S. Dik } 249134a1f4eSCasper H.S. Dik 250134a1f4eSCasper H.S. Dik /* 251134a1f4eSCasper H.S. Dik * Magic struct and function to allow using the _enum_attrs functions to 252134a1f4eSCasper H.S. Dik * enumerate the authorizations. 253134a1f4eSCasper H.S. Dik */ 254134a1f4eSCasper H.S. Dik typedef struct ccomm2auth { 255134a1f4eSCasper H.S. Dik int (*cb)(const char *, void *, void *); 256134a1f4eSCasper H.S. Dik void *ctxt; 257134a1f4eSCasper H.S. Dik } ccomm2auth; 258134a1f4eSCasper H.S. Dik 259134a1f4eSCasper H.S. Dik /*ARGSUSED*/ 260134a1f4eSCasper H.S. Dik static int 261134a1f4eSCasper H.S. Dik comm2auth(const char *name, kva_t *attr, void *ctxt, void *pres) 262134a1f4eSCasper H.S. Dik { 263134a1f4eSCasper H.S. Dik ccomm2auth *ca = ctxt; 264134a1f4eSCasper H.S. Dik char *auths; 265134a1f4eSCasper H.S. Dik 266134a1f4eSCasper H.S. Dik /* Note: PROFATTR_AUTHS_KW is equal to USERATTR_AUTHS_KW */ 267134a1f4eSCasper H.S. Dik auths = kva_match(attr, PROFATTR_AUTHS_KW); 268134a1f4eSCasper H.S. Dik return (_enum_auths_a(auths, ca->cb, ca->ctxt, pres)); 269134a1f4eSCasper H.S. Dik } 270134a1f4eSCasper H.S. Dik 271134a1f4eSCasper H.S. Dik /* 272134a1f4eSCasper H.S. Dik * Enumerate authorizations for username. 273134a1f4eSCasper H.S. Dik */ 274134a1f4eSCasper H.S. Dik int 275134a1f4eSCasper H.S. Dik _enum_auths(const char *username, 276134a1f4eSCasper H.S. Dik int (*cb)(const char *, void *, void *), 277134a1f4eSCasper H.S. Dik void *ctxt, void *pres) 278134a1f4eSCasper H.S. Dik { 279134a1f4eSCasper H.S. Dik ccomm2auth c2a; 280134a1f4eSCasper H.S. Dik 281134a1f4eSCasper H.S. Dik if (cb == NULL) 282134a1f4eSCasper H.S. Dik return (-1); 283134a1f4eSCasper H.S. Dik 284134a1f4eSCasper H.S. Dik c2a.cb = cb; 285134a1f4eSCasper H.S. Dik c2a.ctxt = ctxt; 286134a1f4eSCasper H.S. Dik 287134a1f4eSCasper H.S. Dik return (_enum_common(username, comm2auth, &c2a, pres, B_TRUE)); 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate int 2917c478bd9Sstevel@tonic-gate _auth_match(const char *pattern, const char *auth) 2927c478bd9Sstevel@tonic-gate { 2937c478bd9Sstevel@tonic-gate size_t len; 2947c478bd9Sstevel@tonic-gate char *grant; 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate len = strlen(pattern); 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate /* 2997c478bd9Sstevel@tonic-gate * If the wildcard is not in the last position in the string, don't 3007c478bd9Sstevel@tonic-gate * match against it. 3017c478bd9Sstevel@tonic-gate */ 302134a1f4eSCasper H.S. Dik if (pattern[len-1] != KV_WILDCHAR) 3037c478bd9Sstevel@tonic-gate return (0); 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate /* 3067c478bd9Sstevel@tonic-gate * If the strings are identical up to the wildcard and auth does not 3077c478bd9Sstevel@tonic-gate * end in "grant", then we have a match. 3087c478bd9Sstevel@tonic-gate */ 3097c478bd9Sstevel@tonic-gate if (strncmp(pattern, auth, len-1) == 0) { 3107c478bd9Sstevel@tonic-gate grant = strrchr(auth, '.'); 3117c478bd9Sstevel@tonic-gate if (grant != NULL) { 3127c478bd9Sstevel@tonic-gate if (strncmp(grant + 1, "grant", 5) != NULL) 3137c478bd9Sstevel@tonic-gate return (1); 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate return (0); 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate static int 321134a1f4eSCasper H.S. Dik _is_authorized(const char *auth, void *authname, void *res) 3227c478bd9Sstevel@tonic-gate { 323134a1f4eSCasper H.S. Dik int *resp = res; 3247c478bd9Sstevel@tonic-gate 325134a1f4eSCasper H.S. Dik if (strcmp(authname, auth) == 0 || 326134a1f4eSCasper H.S. Dik (strchr(auth, KV_WILDCHAR) != NULL && 327134a1f4eSCasper H.S. Dik _auth_match(auth, authname))) { 328134a1f4eSCasper H.S. Dik *resp = 1; 329134a1f4eSCasper H.S. Dik return (1); 3307c478bd9Sstevel@tonic-gate } 3317c478bd9Sstevel@tonic-gate 332134a1f4eSCasper H.S. Dik return (0); 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate 335134a1f4eSCasper H.S. Dik int 336134a1f4eSCasper H.S. Dik chkauthattr(const char *authname, const char *username) 3377c478bd9Sstevel@tonic-gate { 338134a1f4eSCasper H.S. Dik int auth_granted = 0; 3397c478bd9Sstevel@tonic-gate 340134a1f4eSCasper H.S. Dik if (authname == NULL || username == NULL) 3417c478bd9Sstevel@tonic-gate return (0); 3427c478bd9Sstevel@tonic-gate 343134a1f4eSCasper H.S. Dik (void) _enum_auths(username, _is_authorized, (char *)authname, 344134a1f4eSCasper H.S. Dik &auth_granted); 3457c478bd9Sstevel@tonic-gate 346134a1f4eSCasper H.S. Dik return (auth_granted); 3477c478bd9Sstevel@tonic-gate } 348499fd601Sgww 349ceeba6f9Srui zang - Sun Microsystems - Beijing China #define CONSOLE_USER_LINK "/dev/vt/console_user" 350499fd601Sgww 351499fd601Sgww static int 352499fd601Sgww is_cons_user(const char *user) 353499fd601Sgww { 354499fd601Sgww struct stat cons; 355499fd601Sgww struct passwd pw; 356499fd601Sgww char pwbuf[NSS_BUFLEN_PASSWD]; 357499fd601Sgww 358499fd601Sgww if (user == NULL) { 359499fd601Sgww return (0); 360499fd601Sgww } 361ceeba6f9Srui zang - Sun Microsystems - Beijing China if (stat(CONSOLE_USER_LINK, &cons) == -1) { 362499fd601Sgww return (0); 363499fd601Sgww } 364499fd601Sgww if (getpwnam_r(user, &pw, pwbuf, sizeof (pwbuf)) == NULL) { 365499fd601Sgww return (0); 366499fd601Sgww } 367499fd601Sgww 368499fd601Sgww return (pw.pw_uid == cons.st_uid); 369499fd601Sgww } 370499fd601Sgww 371134a1f4eSCasper H.S. Dik static void 372134a1f4eSCasper H.S. Dik free_default_attrs(kva_t *kva) 373499fd601Sgww { 374134a1f4eSCasper H.S. Dik int i; 375134a1f4eSCasper H.S. Dik 376134a1f4eSCasper H.S. Dik for (i = 0; i < kva->length; i++) 377134a1f4eSCasper H.S. Dik free(kva->data[i].value); 378134a1f4eSCasper H.S. Dik 379134a1f4eSCasper H.S. Dik free(kva); 380134a1f4eSCasper H.S. Dik } 381134a1f4eSCasper H.S. Dik 382134a1f4eSCasper H.S. Dik /* 383134a1f4eSCasper H.S. Dik * Return the default attributes; this are ignored when a STOP profile 384134a1f4eSCasper H.S. Dik * was found. 385134a1f4eSCasper H.S. Dik */ 386134a1f4eSCasper H.S. Dik static kva_t * 387134a1f4eSCasper H.S. Dik get_default_attrs(const char *user) 388134a1f4eSCasper H.S. Dik { 389b9175c69SKenjiro Tsuji void *defp; 390134a1f4eSCasper H.S. Dik kva_t *kva; 391134a1f4eSCasper H.S. Dik int i; 392499fd601Sgww 393134a1f4eSCasper H.S. Dik kva = malloc(sizeof (kva_t) + sizeof (kv_t) * NDFLTPLY); 394134a1f4eSCasper H.S. Dik 395134a1f4eSCasper H.S. Dik if (kva == NULL) 396134a1f4eSCasper H.S. Dik return (NULL); 397134a1f4eSCasper H.S. Dik 398134a1f4eSCasper H.S. Dik kva->data = (kv_t *)(void *)&kva[1]; 399134a1f4eSCasper H.S. Dik kva->length = 0; 400134a1f4eSCasper H.S. Dik 401134a1f4eSCasper H.S. Dik if ((defp = defopen_r(AUTH_POLICY)) == NULL) 402134a1f4eSCasper H.S. Dik goto return_null; 403134a1f4eSCasper H.S. Dik 404134a1f4eSCasper H.S. Dik for (i = is_cons_user(user) ? 0 : 1; i < NDFLTPLY; i++) { 405134a1f4eSCasper H.S. Dik char *cp = defread_r(dfltply[i].defkw, defp); 406134a1f4eSCasper H.S. Dik 407134a1f4eSCasper H.S. Dik if (cp == NULL) 408134a1f4eSCasper H.S. Dik continue; 409134a1f4eSCasper H.S. Dik if ((cp = strdup(cp)) == NULL) 410134a1f4eSCasper H.S. Dik goto return_null; 411134a1f4eSCasper H.S. Dik 412134a1f4eSCasper H.S. Dik kva->data[kva->length].key = dfltply[i].attr; 413134a1f4eSCasper H.S. Dik kva->data[kva->length++].value = cp; 414499fd601Sgww } 415499fd601Sgww 416134a1f4eSCasper H.S. Dik (void) defclose_r(defp); 417134a1f4eSCasper H.S. Dik return (kva); 418499fd601Sgww 419134a1f4eSCasper H.S. Dik return_null: 420134a1f4eSCasper H.S. Dik if (defp != NULL) 421134a1f4eSCasper H.S. Dik (void) defclose_r(defp); 422499fd601Sgww 423134a1f4eSCasper H.S. Dik free_default_attrs(kva); 424134a1f4eSCasper H.S. Dik return (NULL); 425499fd601Sgww } 426