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