Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
path: root/nslcd/common.h
blob: 5bd98ea16e6e3cf77d88a7058468839cb41b6914 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*
   common.h - common server code routines
   This file is part of the nss-pam-ldapd library.

   Copyright (C) 2006 West Consulting
   Copyright (C) 2006, 2007, 2008, 2009, 2010 Arthur de Jong

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   02110-1301 USA
*/

#ifndef NSLCD__COMMON_H
#define NSLCD__COMMON_H 1

#include <errno.h>

#include "nslcd.h"
#include "common/nslcd-prot.h"
#include "common/tio.h"
#include "compat/attrs.h"
#include "myldap.h"

/* macros for basic read and write operations, the following
   ERROR_OUT* marcos define the action taken on errors
   the stream is not closed because the caller closes the
   stream */

#define ERROR_OUT_WRITEERROR(fp) \
  log_log(LOG_WARNING,"error writing to client: %s",strerror(errno)); \
  return -1;

#define ERROR_OUT_READERROR(fp) \
  log_log(LOG_WARNING,"error reading from client: %s",strerror(errno)); \
  return -1;

#define ERROR_OUT_BUFERROR(fp) \
  log_log(LOG_WARNING,"client supplied argument %d bytes too large",tmpint32); \
  return -1;

/* a simple wrapper around snprintf,
   returns 0 if ok, -1 on error */
int mysnprintf(char *buffer,size_t buflen,const char *format, ...)
  LIKE_PRINTF(3,4);

/* This tries to get the user password attribute from the entry.
   It will try to return an encrypted password as it is used in /etc/passwd,
   /etc/group or /etc/shadow depending upon what is in the directory.
   This function will return NULL if no passwd is found and will return the
   literal value in the directory if conversion is not possible. */
const char *get_userpassword(MYLDAP_ENTRY *entry,const char *attr,
                             char *buffer,size_t buflen);

/* write out an address, parsing the addr value */
int write_address(TFILE *fp,const char *addr);

/* a helper macro to write out addresses and bail out on errors */
#define WRITE_ADDRESS(fp,addr) \
  if (write_address(fp,addr)) \
    return -1;

/* read an address from the stream */
int read_address(TFILE *fp,char *addr,int *addrlen,int *af);

/* helper macro to read an address from the stream */
#define READ_ADDRESS(fp,addr,len,af) \
  len=(int)sizeof(addr); \
  if (read_address(fp,addr,&(len),&(af))) \
    return -1;

/* checks to see if the specified string is a valid user or group name */
MUST_USE int isvalidname(const char *name);

/* Perform an LDAP lookup to translate the DN into a uid.
   This function either returns NULL or a strdup()ed string. */
MUST_USE char *lookup_dn2uid(MYLDAP_SESSION *session,const char *dn,int *rcp,char *buf,size_t buflen);

/* transforms the DN info a uid doing an LDAP lookup if needed */
MUST_USE char *dn2uid(MYLDAP_SESSION *session,const char *dn,char *buf,size_t buflen);

/* use the user id to lookup an LDAP entry */
MYLDAP_ENTRY *uid2entry(MYLDAP_SESSION *session,const char *uid,int *rcp);

/* transforms the uid into a DN by doing an LDAP lookup */
MUST_USE char *uid2dn(MYLDAP_SESSION *session,const char *uid,char *buf,size_t buflen);

/* try to update the shadowLastChange attribute of the entry if possible */
int update_lastchange(MYLDAP_SESSION *session,const char *userdn);

/* these are the functions for initialising the database specific
   modules */
void alias_init(void);
void ether_init(void);
void group_init(void);
void host_init(void);
void netgroup_init(void);
void network_init(void);
void passwd_init(void);
void protocol_init(void);
void rpc_init(void);
void service_init(void);
void shadow_init(void);

/* these are the different functions that handle the database
   specific actions, see nslcd.h for the action descriptions */
int nslcd_alias_byname(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_alias_all(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_ether_byname(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_ether_byether(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_ether_all(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_group_byname(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_group_bygid(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_group_bymember(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_group_all(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_host_byname(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_host_byaddr(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_host_all(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_netgroup_byname(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_network_byname(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_network_byaddr(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_network_all(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_passwd_byname(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid);
int nslcd_passwd_byuid(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid);
int nslcd_passwd_all(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid);
int nslcd_protocol_byname(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_protocol_bynumber(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_protocol_all(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_rpc_byname(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_rpc_bynumber(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_rpc_all(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_service_byname(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_service_bynumber(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_service_all(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_shadow_byname(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_shadow_all(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_pam_authc(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid);
int nslcd_pam_authz(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_pam_sess_o(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_pam_sess_c(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_pam_pwmod(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid);

/* macros for generating service handling code */
#define NSLCD_HANDLE(db,fn,readfn,action,mkfilter,writefn) \
  int nslcd_##db##_##fn(TFILE *fp,MYLDAP_SESSION *session) \
  NSLCD_HANDLE_BODY(db,fn,readfn,action,mkfilter,writefn)
#define NSLCD_HANDLE_UID(db,fn,readfn,action,mkfilter,writefn) \
  int nslcd_##db##_##fn(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid) \
  NSLCD_HANDLE_BODY(db,fn,readfn,action,mkfilter,writefn)
#define NSLCD_HANDLE_BODY(db,fn,readfn,action,mkfilter,writefn) \
  { \
    /* define common variables */ \
    int32_t tmpint32; \
    MYLDAP_SEARCH *search; \
    MYLDAP_ENTRY *entry; \
    const char *base; \
    int rc,i; \
    /* read request parameters */ \
    readfn; \
    /* write the response header */ \
    WRITE_INT32(fp,NSLCD_VERSION); \
    WRITE_INT32(fp,action); \
    /* prepare the search filter */ \
    if (mkfilter) \
    { \
      log_log(LOG_WARNING,"nslcd_" __STRING(db) "_" __STRING(fn) "(): filter buffer too small"); \
      return -1; \
    } \
    /* perform a search for each search base */ \
    for (i=0; (base=db##_bases[i])!=NULL; i++) \
    { \
      /* do the LDAP search */ \
      if ((search=myldap_search(session,base,db##_scope,filter,db##_attrs,NULL))==NULL) \
        return -1; \
      /* go over results */ \
      while ((entry=myldap_get_entry(search,&rc))!=NULL) \
      { \
        if (writefn) \
          return -1; \
      } \
    } \
    /* write the final result code */ \
    if (rc==LDAP_SUCCESS) \
    { \
      WRITE_INT32(fp,NSLCD_RESULT_END); \
    } \
    return 0; \
  }

#endif /* not NSLCD__COMMON_H */