1/* $NetBSD: passwd-shell.c,v 1.1.1.3 2010/12/12 15:23:50 adam Exp $ */ 2 3/* passwd-shell.c - passwd(5) shell-based backend for slapd(8) */ 4/* OpenLDAP: pkg/ldap/servers/slapd/shell-backends/passwd-shell.c,v 1.14.2.6 2010/04/13 20:23:49 kurt Exp */ 5/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 1998-2010 The OpenLDAP Foundation. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted only as authorized by the OpenLDAP 12 * Public License. 13 * 14 * A copy of this license is available in the file LICENSE in the 15 * top-level directory of the distribution or, alternatively, at 16 * <http://www.OpenLDAP.org/license.html>. 17 */ 18/* Portions Copyright (c) 1995 Regents of the University of Michigan. 19 * All rights reserved. 20 * 21 * Redistribution and use in source and binary forms are permitted 22 * provided that this notice is preserved and that due credit is given 23 * to the University of Michigan at Ann Arbor. The name of the University 24 * may not be used to endorse or promote products derived from this 25 * software without specific prior written permission. This software 26 * is provided ``as is'' without express or implied warranty. 27 */ 28/* ACKNOWLEDGEMENTS: 29 * This work was originally developed by the University of Michigan 30 * (as part of U-MICH LDAP). 31 */ 32 33 34#include "portable.h" 35 36#include <stdio.h> 37 38#include <ac/stdlib.h> 39 40#include <ac/string.h> 41#include <ac/unistd.h> 42 43#include <pwd.h> 44 45#include <lber.h> 46#include <ldap.h> 47 48#include "shellutil.h" 49 50static void pwdfile_search LDAP_P(( struct ldop *op, FILE *ofp )); 51static struct ldentry *pw2entry LDAP_P(( struct ldop *op, struct passwd *pw )); 52 53static char tmpbuf[ MAXLINELEN * 2 ]; 54 55 56int 57main( int argc, char **argv ) 58{ 59 int c, errflg; 60 struct ldop op; 61 62 if (( progname = strrchr( argv[ 0 ], '/' )) == NULL ) { 63 progname = estrdup( argv[ 0 ] ); 64 } else { 65 progname = estrdup( progname + 1 ); 66 } 67 68 errflg = debugflg = 0; 69 70 while (( c = getopt( argc, argv, "d" )) != EOF ) { 71 switch( c ) { 72 case 'd': 73#ifdef LDAP_DEBUG 74 ++debugflg; 75#else /* LDAP_DEBUG */ 76 fprintf( stderr, "%s: compile with -DLDAP_DEBUG for debugging\n", 77 progname ); 78#endif /* LDAP_DEBUG */ 79 break; 80 default: 81 ++errflg; 82 } 83 } 84 85 if ( errflg || optind < argc ) { 86 fprintf( stderr, "usage: %s [-d]\n", progname ); 87 exit( EXIT_FAILURE ); 88 } 89 90 debug_printf( "started\n" ); 91 92 (void) memset( (char *)&op, '\0', sizeof( op )); 93 94 if ( parse_input( stdin, stdout, &op ) < 0 ) { 95 exit( EXIT_SUCCESS ); 96 } 97 98 if ( op.ldop_op != LDOP_SEARCH ) { 99 write_result( stdout, LDAP_UNWILLING_TO_PERFORM, NULL, 100 "Command Not Implemented" ); 101 exit( EXIT_SUCCESS ); 102 } 103 104#ifdef LDAP_DEBUG 105 dump_ldop( &op ); 106#endif /* LDAP_DEBUG */ 107 108 pwdfile_search( &op, stdout ); 109 110 exit( EXIT_SUCCESS ); 111} 112 113 114static void 115pwdfile_search( struct ldop *op, FILE *ofp ) 116{ 117 struct passwd *pw; 118 struct ldentry *entry; 119 int oneentry; 120 121 oneentry = ( strchr( op->ldop_dn, '@' ) != NULL ); 122 123 for ( pw = getpwent(); pw != NULL; pw = getpwent()) { 124 if (( entry = pw2entry( op, pw )) != NULL ) { 125 if ( oneentry ) { 126 if ( strcasecmp( op->ldop_dn, entry->lde_dn ) == 0 ) { 127 write_entry( op, entry, ofp ); 128 break; 129 } 130 } else if ( test_filter( op, entry ) == LDAP_COMPARE_TRUE ) { 131 write_entry( op, entry, ofp ); 132 } 133 free_entry( entry ); 134 } 135 } 136 endpwent(); 137 138 write_result( ofp, LDAP_SUCCESS, NULL, NULL ); 139} 140 141 142static struct ldentry * 143pw2entry( struct ldop *op, struct passwd *pw ) 144{ 145 struct ldentry *entry; 146 struct ldattr *attr; 147 int i; 148 149 /* 150 * construct the DN from pw_name 151 */ 152 if ( strchr( op->ldop_suffixes[ 0 ], '=' ) != NULL ) { 153 /* 154 * X.500 style DN 155 */ 156 i = snprintf( tmpbuf, sizeof( tmpbuf ), "cn=%s, %s", pw->pw_name, op->ldop_suffixes[ 0 ] ); 157 } else { 158 /* 159 * RFC-822 style DN 160 */ 161 i = snprintf( tmpbuf, sizeof( tmpbuf ), "%s@%s", pw->pw_name, op->ldop_suffixes[ 0 ] ); 162 } 163 164 if ( i < 0 || i >= sizeof( tmpbuf ) ) { 165 return NULL; 166 } 167 168 entry = (struct ldentry *) ecalloc( 1, sizeof( struct ldentry )); 169 entry->lde_dn = estrdup( tmpbuf ); 170 171 /* 172 * for now, we simply derive the LDAP attribute values as follows: 173 * objectClass = person 174 * uid = pw_name 175 * sn = pw_name 176 * cn = pw_name 177 * cn = pw_gecos (second common name) 178 */ 179 entry->lde_attrs = (struct ldattr **)ecalloc( 5, sizeof( struct ldattr * )); 180 i = 0; 181 attr = (struct ldattr *)ecalloc( 1, sizeof( struct ldattr )); 182 attr->lda_name = estrdup( "objectClass" ); 183 attr->lda_values = (char **)ecalloc( 2, sizeof( char * )); 184 attr->lda_values[ 0 ] = estrdup( "person" ); 185 entry->lde_attrs[ i++ ] = attr; 186 187 attr = (struct ldattr *)ecalloc( 1, sizeof( struct ldattr )); 188 attr->lda_name = estrdup( "uid" ); 189 attr->lda_values = (char **)ecalloc( 2, sizeof( char * )); 190 attr->lda_values[ 0 ] = estrdup( pw->pw_name ); 191 entry->lde_attrs[ i++ ] = attr; 192 193 attr = (struct ldattr *)ecalloc( 1, sizeof( struct ldattr )); 194 attr->lda_name = estrdup( "sn" ); 195 attr->lda_values = (char **)ecalloc( 2, sizeof( char * )); 196 attr->lda_values[ 0 ] = estrdup( pw->pw_name ); 197 entry->lde_attrs[ i++ ] = attr; 198 199 attr = (struct ldattr *)ecalloc( 1, sizeof( struct ldattr )); 200 attr->lda_name = estrdup( "cn" ); 201 attr->lda_values = (char **)ecalloc( 3, sizeof( char * )); 202 attr->lda_values[ 0 ] = estrdup( pw->pw_name ); 203 if ( pw->pw_gecos != NULL && *pw->pw_gecos != '\0' ) { 204 attr->lda_values[ 1 ] = estrdup( pw->pw_gecos ); 205 } 206 entry->lde_attrs[ i++ ] = attr; 207 208 return( entry ); 209} 210