1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <project.h> 29 #include "ldap_common.h" 30 31 /* Project attributes filters */ 32 #define _PROJ_NAME "SolarisProjectName" 33 #define _PROJ_PROJID "SolarisProjectID" 34 #define _PROJ_DESCR "description" 35 #define _PROJ_USERS "memberUid" 36 #define _PROJ_GROUPS "memberGid" 37 #define _PROJ_ATTR "SolarisProjectAttr" 38 39 #define _F_GETPROJNAME "(&(objectClass=SolarisProject)(SolarisProjectName=%s))" 40 #define _F_GETPROJID "(&(objectClass=SolarisProject)(SolarisProjectID=%ld))" 41 42 static const char *project_attrs[] = { 43 _PROJ_NAME, 44 _PROJ_PROJID, 45 _PROJ_DESCR, 46 _PROJ_USERS, 47 _PROJ_GROUPS, 48 _PROJ_ATTR, 49 (char *)NULL 50 }; 51 52 /* 53 * _nss_ldap_proj2str is the data marshalling method for the project getXbyY 54 * (getprojbyname, getprojbyid, getprojent) backend processes. This method 55 * is called after a successful ldap search has been performed. This method 56 * will parse the ldap search values into the file format. 57 * e.g. 58 * 59 * system:0:System::: 60 * 61 * beatles:100:The Beatles:john,paul,george,ringo::task.max-lwps= 62 * (privileged,100,signal=SIGTERM),(privileged,110,deny) 63 * 64 * (All in one line) 65 */ 66 static int 67 _nss_ldap_proj2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) 68 { 69 int i; 70 int nss_result; 71 int buflen = 0, len; 72 int firsttime; 73 char *buffer, *comment, *attr_str; 74 ns_ldap_result_t *result = be->result; 75 char **name, **id, **descr, **attr; 76 ns_ldap_attr_t *users, *groups; 77 78 if (result == NULL) 79 return (NSS_STR_PARSE_PARSE); 80 buflen = argp->buf.buflen; 81 82 if (argp->buf.result != NULL) { 83 /* In all cases it must be deallocated by caller */ 84 if ((be->buffer = calloc(1, buflen)) == NULL) { 85 nss_result = NSS_STR_PARSE_PARSE; 86 goto result_proj2str; 87 } 88 buffer = be->buffer; 89 } else 90 buffer = argp->buf.buffer; 91 92 nss_result = NSS_STR_PARSE_SUCCESS; 93 (void) memset(buffer, 0, buflen); 94 95 name = __ns_ldap_getAttr(result->entry, _PROJ_NAME); 96 if (name == NULL || name[0] == NULL || (strlen(name[0]) < 1)) { 97 nss_result = NSS_STR_PARSE_PARSE; 98 goto result_proj2str; 99 } 100 id = __ns_ldap_getAttr(result->entry, _PROJ_PROJID); 101 if (id == NULL || id[0] == NULL || (strlen(id[0]) < 1)) { 102 nss_result = NSS_STR_PARSE_PARSE; 103 goto result_proj2str; 104 } 105 descr = __ns_ldap_getAttr(result->entry, _PROJ_DESCR); 106 if (descr == NULL || descr[0] == NULL || (strlen(descr[0]) < 1)) 107 comment = _NO_VALUE; 108 else 109 comment = descr[0]; 110 len = snprintf(buffer, buflen, "%s:%s:%s:", name[0], id[0], 111 comment); 112 TEST_AND_ADJUST(len, buffer, buflen, result_proj2str); 113 114 users = __ns_ldap_getAttrStruct(result->entry, _PROJ_USERS); 115 if (!(users == NULL || users->attrvalue == NULL)) { 116 firsttime = 1; 117 for (i = 0; i < users->value_count; i++) { 118 if (users->attrvalue[i] == NULL) { 119 nss_result = NSS_STR_PARSE_PARSE; 120 goto result_proj2str; 121 } 122 if (firsttime) { 123 len = snprintf(buffer, buflen, "%s", 124 users->attrvalue[i]); 125 firsttime = 0; 126 } else { 127 len = snprintf(buffer, buflen, ",%s", 128 users->attrvalue[i]); 129 } 130 TEST_AND_ADJUST(len, buffer, buflen, result_proj2str); 131 } 132 } 133 len = snprintf(buffer, buflen, ":"); 134 TEST_AND_ADJUST(len, buffer, buflen, result_proj2str); 135 136 groups = __ns_ldap_getAttrStruct(result->entry, _PROJ_GROUPS); 137 if (!(groups == NULL || groups->attrvalue == NULL)) { 138 firsttime = 1; 139 for (i = 0; i < groups->value_count; i++) { 140 if (groups->attrvalue[i] == NULL) { 141 nss_result = NSS_STR_PARSE_PARSE; 142 goto result_proj2str; 143 } 144 if (firsttime) { 145 len = snprintf(buffer, buflen, "%s", 146 groups->attrvalue[i]); 147 firsttime = 0; 148 } else { 149 len = snprintf(buffer, buflen, ",%s", 150 groups->attrvalue[i]); 151 } 152 TEST_AND_ADJUST(len, buffer, buflen, result_proj2str); 153 } 154 } 155 156 attr = __ns_ldap_getAttr(result->entry, _PROJ_ATTR); 157 if (attr == NULL || attr[0] == NULL || (strlen(attr[0]) < 1)) 158 attr_str = _NO_VALUE; 159 160 else 161 attr_str = attr[0]; 162 len = snprintf(buffer, buflen, ":%s", attr_str); 163 TEST_AND_ADJUST(len, buffer, buflen, result_proj2str); 164 165 /* The front end marshaller doesn't need the trailing nulls */ 166 if (argp->buf.result != NULL) 167 be->buflen = strlen(be->buffer); 168 result_proj2str: 169 (void) __ns_ldap_freeResult(&be->result); 170 return ((int)nss_result); 171 } 172 173 174 /* 175 * getbyname gets a project entry by name. This function constructs an ldap 176 * search filter using the name invocation parameter and the getprojname search 177 * filter defined. Once the filter is constructed, we search for a matching 178 * entry and marshal the data results into struct project for the frontend 179 * process. The function _nss_ldap_proj2ent performs the data marshaling. 180 */ 181 static nss_status_t 182 getbyname(ldap_backend_ptr be, void *a) 183 { 184 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 185 char searchfilter[SEARCHFILTERLEN]; 186 187 if (snprintf(searchfilter, SEARCHFILTERLEN, 188 _F_GETPROJNAME, argp->key.name) < 0) 189 return (NSS_NOTFOUND); 190 return (_nss_ldap_lookup(be, argp, _PROJECT, searchfilter, NULL, NULL, 191 NULL)); 192 } 193 194 195 /* 196 * getbyprojid gets a project entry by number. This function constructs an ldap 197 * search filter using the name invocation parameter and the getprojid search 198 * filter defined. Once the filter is constructed, we search for a matching 199 * entry and marshal the data results into struct project for the frontend 200 * process. The function _nss_ldap_proj2ent performs the data marshaling. 201 */ 202 static nss_status_t 203 getbyprojid(ldap_backend_ptr be, void *a) 204 { 205 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 206 char searchfilter[SEARCHFILTERLEN]; 207 208 if (snprintf(searchfilter, SEARCHFILTERLEN, _F_GETPROJID, 209 (long)argp->key.projid) < 0) 210 return (NSS_NOTFOUND); 211 return (_nss_ldap_lookup(be, argp, _PROJECT, searchfilter, NULL, NULL, 212 NULL)); 213 } 214 215 static ldap_backend_op_t project_ops[] = { 216 _nss_ldap_destr, 217 _nss_ldap_endent, 218 _nss_ldap_setent, 219 _nss_ldap_getent, 220 getbyname, 221 getbyprojid 222 }; 223 224 225 /*ARGSUSED0*/ 226 nss_backend_t * 227 _nss_ldap_project_constr(const char *dummy1, const char *dummy2, 228 const char *dummy3) 229 { 230 return (_nss_ldap_constr(project_ops, 231 sizeof (project_ops) / sizeof (project_ops[0]), 232 _PROJECT, project_attrs, _nss_ldap_proj2str)); 233 } 234