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