1/* $NetBSD: netgroup.c,v 1.3 2021/08/14 16:14:52 christos Exp $ */ 2 3/* netgroup.c - netgroup lookup routines */ 4/* $OpenLDAP$ */ 5/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 2008-2021 The OpenLDAP Foundation. 8 * Portions Copyright 2008 by Howard Chu, Symas Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted only as authorized by the OpenLDAP 13 * Public License. 14 * 15 * A copy of this license is available in the file LICENSE in the 16 * top-level directory of the distribution or, alternatively, at 17 * <http://www.OpenLDAP.org/license.html>. 18 */ 19/* ACKNOWLEDGEMENTS: 20 * This code references portions of the nss-ldapd package 21 * written by Arthur de Jong. The nss-ldapd code was forked 22 * from the nss-ldap library written by Luke Howard. 23 */ 24 25#include "nssov.h" 26#include <ac/ctype.h> 27 28/* ( nisSchema.2.8 NAME 'nisNetgroup' SUP top STRUCTURAL 29 * DESC 'Abstraction of a netgroup. May refer to other netgroups' 30 * MUST cn 31 * MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) ) 32 */ 33 34/* the basic search filter for searches */ 35static struct berval netgroup_filter = BER_BVC("(objectClass=nisNetgroup)"); 36 37/* the attributes to request with searches */ 38static struct berval netgroup_keys[] = { 39 BER_BVC("cn"), 40 BER_BVC("nisNetgroupTriple"), 41 BER_BVC("memberNisNetgroup"), 42 BER_BVNULL 43}; 44 45NSSOV_INIT(netgroup) 46 47NSSOV_CBPRIV(netgroup, 48 char buf[256]; 49 struct berval name;); 50 51static int write_string_stripspace_len(TFILE *fp,const char *str,int len) 52{ 53 int32_t tmpint32; 54 int i,j; 55 DEBUG_PRINT("WRITE_STRING: var="__STRING(str)" string=\"%s\"",str); 56 if (str==NULL) 57 { 58 WRITE_INT32(fp,0); 59 } 60 else 61 { 62 /* skip leading spaces */ 63 for (i=0;(str[i]!='\0')&&(isspace(str[i]));i++) 64 /* nothing else to do */ ; 65 /* skip trailing spaces */ 66 for (j=len;(j>i)&&(isspace(str[j-1]));j--) 67 /* nothing else to do */ ; 68 /* write length of string */ 69 WRITE_INT32(fp,j-i); 70 /* write string itself */ 71 if (j>i) 72 { 73 WRITE(fp,str+i,j-i); 74 } 75 } 76 /* we're done */ 77 return 0; 78} 79 80#define WRITE_STRING_STRIPSPACE_LEN(fp,str,len) \ 81 if (write_string_stripspace_len(fp,str,len)) \ 82 return -1; 83 84#define WRITE_STRING_STRIPSPACE(fp,str) \ 85 WRITE_STRING_STRIPSPACE_LEN(fp,str,strlen(str)) 86 87static int write_netgroup_triple(TFILE *fp,const char *triple) 88{ 89 int32_t tmpint32; 90 int i; 91 int hostb,hoste,userb,usere,domainb,domaine; 92 /* skip leading spaces */ 93 for (i=0;(triple[i]!='\0')&&(isspace(triple[i]));i++) 94 /* nothing else to do */ ; 95 /* we should have a bracket now */ 96 if (triple[i]!='(') 97 { 98 Debug(LDAP_DEBUG_ANY,"write_netgroup_triple(): entry does not begin with '(' (entry skipped)\n" ); 99 return 0; 100 } 101 i++; 102 hostb=i; 103 /* find comma (end of host string) */ 104 for (;(triple[i]!='\0')&&(triple[i]!=',');i++) 105 /* nothing else to do */ ; 106 if (triple[i]!=',') 107 { 108 Debug(LDAP_DEBUG_ANY,"write_netgroup_triple(): missing ',' (entry skipped)\n" ); 109 return 0; 110 } 111 hoste=i; 112 i++; 113 userb=i; 114 /* find comma (end of user string) */ 115 for (;(triple[i]!='\0')&&(triple[i]!=',');i++) 116 /* nothing else to do */ ; 117 if (triple[i]!=',') 118 { 119 Debug(LDAP_DEBUG_ANY,"write_netgroup_triple(): missing ',' (entry skipped)\n" ); 120 return 0; 121 } 122 usere=i; 123 i++; 124 domainb=i; 125 /* find closing bracket (end of domain string) */ 126 for (;(triple[i]!='\0')&&(triple[i]!=')');i++) 127 /* nothing else to do */ ; 128 if (triple[i]!=')') 129 { 130 Debug(LDAP_DEBUG_ANY,"write_netgroup_triple(): missing ')' (entry skipped)\n" ); 131 return 0; 132 } 133 domaine=i; 134 i++; 135 /* skip trailing spaces */ 136 for (;(triple[i]!='\0')&&(isspace(triple[i]));i++) 137 /* nothing else to do */ ; 138 /* if anything is left in the string we have a problem */ 139 if (triple[i]!='\0') 140 { 141 Debug(LDAP_DEBUG_ANY,"write_netgroup_triple(): string contains trailing data (entry skipped)\n" ); 142 return 0; 143 } 144 /* write strings */ 145 WRITE_INT32(fp,NSLCD_RESULT_BEGIN); 146 WRITE_INT32(fp,NSLCD_NETGROUP_TYPE_TRIPLE); 147 WRITE_STRING_STRIPSPACE_LEN(fp,triple+hostb,hoste-hostb) 148 WRITE_STRING_STRIPSPACE_LEN(fp,triple+userb,usere-userb) 149 WRITE_STRING_STRIPSPACE_LEN(fp,triple+domainb,domaine-domainb) 150 /* we're done */ 151 return 0; 152} 153 154static int write_netgroup(nssov_netgroup_cbp *cbp,Entry *entry) 155{ 156 int32_t tmpint32; 157 int i; 158 Attribute *a; 159 160 /* get the netgroup triples and member */ 161 a = attr_find(entry->e_attrs,cbp->mi->mi_attrs[1].an_desc); 162 if ( a ) { 163 /* write the netgroup triples */ 164 for (i=0;i<a->a_numvals;i++) 165 { 166 if (write_netgroup_triple(cbp->fp, a->a_vals[i].bv_val)) 167 return -1; 168 } 169 } 170 a = attr_find(entry->e_attrs,cbp->mi->mi_attrs[2].an_desc); 171 if ( a ) { 172 /* write netgroup members */ 173 for (i=0;i<a->a_numvals;i++) 174 { 175 /* write the result code */ 176 WRITE_INT32(cbp->fp,NSLCD_RESULT_BEGIN); 177 /* write triple indicator */ 178 WRITE_INT32(cbp->fp,NSLCD_NETGROUP_TYPE_NETGROUP); 179 /* write netgroup name */ 180 if (write_string_stripspace_len(cbp->fp,a->a_vals[i].bv_val,a->a_vals[i].bv_len)) 181 return -1; 182 } 183 } 184 /* we're done */ 185 return 0; 186} 187 188NSSOV_CB(netgroup) 189 190NSSOV_HANDLE( 191 netgroup,byname, 192 char fbuf[1024]; 193 struct berval filter = {sizeof(fbuf)}; 194 filter.bv_val = fbuf; 195 READ_STRING(fp,cbp.buf);, 196 cbp.name.bv_len = tmpint32; 197 cbp.name.bv_val = cbp.buf; 198 Debug(LDAP_DEBUG_TRACE,"nssov_netgroup_byname(%s)\n",cbp.name.bv_val);, 199 NSLCD_ACTION_NETGROUP_BYNAME, 200 nssov_filter_byname(cbp.mi,0,&cbp.name,&filter) 201) 202