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
|
/*
common.c - common server code routines
This file is part of the nss-ldapd library.
Copyright (C) 2006 West Consulting
Copyright (C) 2006, 2007 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
*/
#include "config.h"
#include <stdio.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <strings.h>
#include "nslcd.h"
#include "common.h"
#include "log.h"
/* simple wrapper around snptintf() to return non-0 in case
of any failure (but always keep string 0-terminated) */
int mysnprintf(char *buffer,size_t buflen,const char *format, ...)
{
int res;
va_list ap;
/* do snprintf */
va_start(ap,format);
res=vsnprintf(buffer,buflen,format,ap);
/* NULL-terminate the string just to be on the safe side */
buffer[buflen-1]='\0';
/* check if the string was completely written */
return ((res<0)||(((size_t)res)>=buflen));
}
/* 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 and will return the literal
value in the directory if conversion is not possible. */
const char *get_userpassword(MYLDAP_ENTRY *entry,const char *attr)
{
const char **values;
int i;
/* get the entries */
values=myldap_get_values(entry,attr);
if ((values==NULL)||(values[0]==NULL))
return NULL;
/* go over the entries and return the remainder of the value if it
starts with {crypt} or crypt$ */
for (i=0;values[i]!=NULL;i++)
{
if (strncasecmp(values[i],"{crypt}",7)==0)
return values[i]+7;
if (strncasecmp(values[i],"crypt$",6)==0)
return values[i]+7;
}
/* just return the first value completely */
return values[0];
/* TODO: support more password formats e.g. SMD5
(which is $1$ but in a different format)
(any code for this is more than welcome) */
}
/* this writes a single address to the stream */
int write_address(TFILE *fp,const char *addr)
{
int32_t tmpint32;
struct in_addr ipv4addr;
struct in6_addr ipv6addr;
/* try to parse the address as IPv4 first, fall back to IPv6 */
if (inet_pton(AF_INET,addr,&ipv4addr)>0)
{
/* write address type */
WRITE_INT32(fp,AF_INET);
/* write the address length */
WRITE_INT32(fp,sizeof(struct in_addr));
/* write the address itself (in network byte order) */
WRITE_TYPE(fp,ipv4addr,struct in_addr);
}
else if (inet_pton(AF_INET6,addr,&ipv6addr)>0)
{
/* write address type */
WRITE_INT32(fp,AF_INET6);
/* write the address length */
WRITE_INT32(fp,sizeof(struct in6_addr));
/* write the address itself (in network byte order) */
WRITE_TYPE(fp,ipv6addr,struct in6_addr);
}
else
{
/* failure, log but write simple invalid address
(otherwise the address list is messed up) */
/* TODO: have error message in correct format */
log_log(LOG_WARNING,"unparseble address: %s",addr);
/* write an illegal address type */
WRITE_INT32(fp,-1);
/* write an emtpy address */
WRITE_INT32(fp,0);
}
/* we're done */
return 0;
}
int read_address(TFILE *fp,char *addr,int *addrlen,int *af)
{
int32_t tmpint32;
int len;
/* read address family */
READ_INT32(fp,*af);
if ((*af!=AF_INET)&&(*af!=AF_INET6))
{
log_log(LOG_WARNING,"incorrect address family specified: %d",*af);
return -1;
}
/* read address length */
READ_INT32(fp,len);
if ((len>*addrlen)||(len<=0))
{
log_log(LOG_WARNING,"address length incorrect: %d",len);
return -1;
}
*addrlen=len;
/* read address */
READ(fp,addr,len);
/* we're done */
return 0;
}
|