Hi, a few months ago I posted a message about using LDAP to store rsync secrets
in LDAP. I received a response about patching the rsync source code with a
patch file. I am now finally getting around to doing this, and when I tried to
use the patch command 'patch --verbose ./rsync-2.5.6/authenticate.c
rsync-ldap.patch' , it gives me the following error:
Hmm... Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|diff -ur rsync-2.5.0-ori/authenticate.c rsync-2.5.0-patched/authenticate.c
|--- rsync-2.5.0-ori/authenticate.c Fri Nov 30 01:21:07 2001
|+++ rsync-2.5.0-patched/authenticate.c Wed Dec 12 16:16:58 2001
--------------------------
Patching file ./rsync-2.5.0/authenticate.c using Plan A...
Hunk #1 succeeded at 20.
Hunk #2 FAILED at 84.
Hunk #3 FAILED at 303.
patch: **** malformed patch at line 70:
I was wondering if someone could tell me how to implement the patch, it would be
great (as in the proper patch command or another method of patching). I am
including the transcript of the message from a few months ago for reference.
On Tue, Feb 11, 2003 at 12:25:12PM -0500, Darren Jung
wrote:> Hi,
>
> I'm trying to get rsync 2.5.6 to authenticate users via
openldap-2.0.23.
> I was looking through the mailing list archives and found a patch for
> rsync-2.4.6 that does this for me. I was just wondering if this is still
valid,
> or if there has been a new patch or new implementation that has superceded
this
> patch. Any help would be great. The message I am referring to is as
follows:
Here is the newest (?) version of the
"storing rsyncd authentication secrets in ldap" Patch.
Please don't call it ldap-authentication for rsync :-)
We are using it with 2.5.5 at the moment but 2.5.6 doesn't seem to be a
problem.
There are no bigger changes since the first release.
cu, Stefan
diff -ur rsync-2.5.0-ori/authenticate.c rsync-2.5.0-patched/authenticate.c
--- rsync-2.5.0-ori/authenticate.c Fri Nov 30 01:21:07 2001
+++ rsync-2.5.0-patched/authenticate.c Wed Dec 12 16:16:58 2001
@@ -20,6 +20,11 @@
/* support rsync authentication */
#include "rsync.h"
+#ifdef WITH_LDAP
+#include <lber.h>
+#include <ldap.h>
+#endif
+
/***************************************************************************
encode a buffer using base64 - simple and slow algorithm. null terminates
the result.
@@ -79,9 +84,23 @@
STRUCT_STAT st;
int ok = 1;
extern int am_root;
+ char *users, *tok;
if (!fname || !*fname) return 0;
+ /* this code was in auth_server() */
+ users = strdup(lp_auth_users(module));
+ if (!users) return 0;
+
+ for (tok=strtok(users," ,\t"); tok; tok = strtok(NULL,"
,\t")) {
+ if (fnmatch(tok, user, 0) == 0) break;
+ }
+ free(users);
+
+ if (!tok) {
+ return 0;
+ }
+
fd = open(fname,O_RDONLY);
if (fd == -1) return 0;
@@ -133,6 +152,84 @@
return 1;
}
+#ifdef WITH_LDAP
+/* return the secret for a user from the ldap server. maximum length
+ is len. null terminate it */
+static int get_ldap_secret(int module, char *user, char *secret, int len)
+{
+ LDAP *ld;
+ LDAPMessage *result, *entry;
+ char *attrs[2], *dn, **vals;
+ char filter[512], *c;
+ char *group=lp_ldap_auth_usergroup(module);
+ int l=0, ok=0;
+
+ /* password attribute to get as result */
+ attrs[0]=lp_ldap_passwd_attribute(module); attrs[1]=NULL;
+
+ /* find nasty character in user that would mess up the ldap filter */
+ for (c="()!&|*=<>~"; *c; c++) {
+ if (strchr(user, *c)) {
+ return 0;
+ }
+ }
+
+ /* $filter=&lp_ldap_filter($module))=~s/%u/$user/g; :-) */
+ memset(filter, 0, sizeof(filter));
+ for (c=lp_ldap_filter(module); *c && l < sizeof(filter) - 1;
c++) {
+ if (*c=='%' && *(c+1)=='u') {
+ char *b;
+ for (b=user; *b && l < sizeof(filter) - 1;
b++) {
+ filter[l++]=*b;
+ }
+ c++;
+ } else {
+ filter[l++]=*c;
+ }
+ }
+
+ if ((ld=ldap_init(lp_ldap_server(), lp_ldap_port())) == NULL) {
+ rprintf(FERROR,"ldap: init failed (%s:%d)\n",
lp_ldap_server(),
+lp_ldap_port());
+ } else {
+ if (ldap_simple_bind_s(ld, lp_ldap_root(),
lp_ldap_root_passwd()) !=
+LDAP_SUCCESS) {
+ rprintf(FERROR,"ldap: bind failed %s\n",
lp_ldap_root());
+ } else {
+ if (ldap_search_s(ld, lp_ldap_suffix(), LDAP_SCOPE_SUBTREE,
filter,
+attrs, 0, &result) != LDAP_SUCCESS) {
+ rprintf(FERROR,"ldap: search_s failed\n");
+ } else {
+ if (!(entry=ldap_first_entry(ld, result))) {
+ rprintf(FERROR,"ldap: first_entry failed or no user
found\n");
+ } else {
+ if (!(dn=ldap_get_dn(ld, entry))) {
+ rprintf(FERROR,"ldap: get_dn failed\n");
+ } else {
+ if (ldap_compare_s(ld, group,
lp_ldap_auth_users_attribute(module),
+dn) != LDAP_COMPARE_TRUE) {
+ rprintf(FERROR,"ldap: compare_s failed or
\"%s\" is not member
+of \"%s\"\n", dn, group);
+ } else {
+ if (!(vals=ldap_get_values(ld, result, attrs[0])) || !vals[0] ||
+vals[1]) {
+ rprintf(FERROR,"ldap: \"%s\" has no valid
password\n", dn);
+ if (vals) ldap_value_free(vals);
+ } else {
+ memset(secret, 0, sizeof(secret)); /* paranoid */
+ strlcpy(secret, vals[0], len);
+ ok=1;
+ ldap_value_free(vals);
+ } /* get_values */
+ } /* compare_s */
+ free(dn);
+ } /* get_dn */
+ ldap_msgfree(entry);
+ } /* first_entry */
+ ldap_msgfree(result);
+ } /* search */
+ } /* bind */
+ } /* init */
+ ldap_unbind(ld);
+
+ return ok;
+}
+#endif
+
static char *getpassf(char *filename)
{
char buffer[100];
@@ -206,6 +303,7 @@
char *auth_server(int fd, int module, char *addr, char *leader)
{
char *users = lp_auth_users(module);
+ char *group = lp_ldap_auth_usergroup(module);
char challenge[16];
char b64_challenge[30];
char line[MAXPATHLEN];
@@ -213,10 +311,19 @@
char secret[100];
char pass[30];
char pass2[30];
- char *tok;
/* if no auth list then allow anyone in! */
- if (!users || !*users) return "";
+#ifdef WITH_LDAP
+ if ((!users || !*users) && (!group || !*group)) return
"";
+#else
+ if (!users || !*users) {
+ if (group && *group) {
+ rprintf(FERROR,"no ldap support: unset \"ldap
auth usergroup\"
+for anonymous access\n");
+ return NULL;
+ }
+ return "";
+ }
+#endif
gen_challenge(addr, challenge);
@@ -234,24 +341,39 @@
if (sscanf(line,"%99s %29s", user, pass) != 2) {
return NULL;
}
-
- users = strdup(users);
- if (!users) return NULL;
- for (tok=strtok(users," ,\t"); tok; tok = strtok(NULL,"
,\t")) {
- if (fnmatch(tok, user, 0) == 0) break;
+#ifdef WITH_MANGLE_USER
+ /* foreach $pattern (split(/[ ,\t]+/, &lp_mangle_user($module)){
+$user=~s/^$pattern//;warn "bla";last} */
+ if (lp_mangle_user(module)) {
+ char *prefix, *tofree;
+ prefix = tofree = strdup(lp_mangle_user(module));
+ if(!prefix) return NULL; /* strdup may fail */
+ for (prefix=strtok(prefix, " ,\t"); prefix;
prefix=strtok(NULL, "
+,\t")) {
+ if (strstr(user, prefix) == user) {
+ char *p = user + strlen(prefix);
+ rprintf(FINFO,"mangle user: rewriting
\"%s\" to
+\"%s\"\n", user, p);
+ memmove(user, p, strlen(p) + 1);
+ break;
+ }
+ }
+ free(tofree);
}
- free(users);
+#endif
+ /* checking if user is in "auth users" now happens in
get_secret() */
- if (!tok) {
+ memset(secret, 0, sizeof(secret));
+#ifdef WITH_LDAP
+ if (!(users && *users && get_secret(module, user,
secret, sizeof(secret)-1) ||
+ group && *group && get_ldap_secret(module, user,
secret,
+sizeof(secret)-1))) {
+ memset(secret, 0, sizeof(secret));
return NULL;
}
-
- memset(secret, 0, sizeof(secret));
+#else
if (!get_secret(module, user, secret, sizeof(secret)-1)) {
memset(secret, 0, sizeof(secret));
return NULL;
}
+#endif
generate_hash(secret, b64_challenge, pass2);
memset(secret, 0, sizeof(secret));
@@ -261,7 +383,6 @@
return NULL;
}
-
void auth_client(int fd, char *user, char *challenge)
{
diff -ur rsync-2.5.0-ori/loadparm.c rsync-2.5.0-patched/loadparm.c
--- rsync-2.5.0-ori/loadparm.c Fri Nov 30 01:21:08 2001
+++ rsync-2.5.0-patched/loadparm.c Wed Dec 12 15:56:07 2001
@@ -49,6 +49,12 @@
*/
#include "rsync.h"
+
+#ifdef WITH_LDAP
+#include <lber.h>
+#include <ldap.h>
+#endif
+
#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((char *)(p1)) - (char *)(p2)))
#define strequal(a,b) (strcasecmp(a,b)==0)
#define BOOLSTR(b) ((b) ? "Yes" : "No")
@@ -101,6 +107,11 @@
char *pid_file;
int syslog_facility;
char *socket_options;
+ char *ldap_server;
+ int ldap_port;
+ char *ldap_root;
+ char *ldap_root_passwd;
+ char *ldap_suffix;
} global;
static global Globals;
@@ -138,6 +149,13 @@
int timeout;
int max_connections;
BOOL ignore_nonreadable;
+ char *ldap_filter;
+ char *ldap_passwd_attribute;
+ char *ldap_auth_usergroup;
+ char *ldap_auth_users_attribute;
+#ifdef WITH_MANGLE_USER
+ char *mangle_user;
+#endif
} service;
@@ -169,7 +187,15 @@
"*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz", /*
dont compress */
0, /* timeout */
0, /* max connections */
- False /* ignore nonreadable */
+ False, /* ignore nonreadable */
+ NULL, /* ldap filter */
+ NULL, /* ldap passwd attribute */
+ NULL, /* ldap auth usergroup */
+ "uniquemember" /* ldap auth users attribute */
+#ifdef WITH_MANGLE_USER
+ ,
+ NULL /* mangle user */
+#endif
};
@@ -257,6 +283,11 @@
{"socket options", P_STRING, P_GLOBAL,
&Globals.socket_options,NULL, 0},
{"log file", P_STRING, P_GLOBAL, &Globals.log_file,
NULL, 0},
{"pid file", P_STRING, P_GLOBAL, &Globals.pid_file,
NULL, 0},
+ {"ldap server", P_STRING, P_GLOBAL, &Globals.ldap_server,
NULL, 0},
+ {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port,
NULL, 0},
+ {"ldap root", P_STRING, P_GLOBAL, &Globals.ldap_root,
NULL, 0},
+ {"ldap root passwd", P_STRING, P_GLOBAL,
&Globals.ldap_root_passwd,NULL,0},
+ {"ldap suffix", P_STRING, P_GLOBAL, &Globals.ldap_suffix,
NULL, 0},
{"timeout", P_INTEGER, P_LOCAL, &sDefault.timeout,
NULL, 0},
{"max connections", P_INTEGER, P_LOCAL,
&sDefault.max_connections,NULL, 0},
@@ -284,6 +315,13 @@
{"log format", P_STRING, P_LOCAL, &sDefault.log_format,
NULL, 0},
{"refuse options", P_STRING, P_LOCAL,
&sDefault.refuse_options,NULL, 0},
{"dont compress", P_STRING, P_LOCAL,
&sDefault.dont_compress,NULL, 0},
+ {"ldap filter", P_STRING, P_LOCAL,
&sDefault.ldap_filter, NULL, 0},
+ {"ldap passwd
attribute",P_STRING,P_LOCAL,&sDefault.ldap_passwd_attribute,NULL,0},
+ {"ldap auth usergroup",P_STRING,P_LOCAL,
&sDefault.ldap_auth_usergroup, NULL,0},
+ {"ldap auth users
attribute",P_STRING,P_LOCAL,&sDefault.ldap_auth_users_attribute,
+NULL,0},
+#ifdef WITH_MANGLE_USER
+ {"mangle user", P_STRING, P_LOCAL,
&sDefault.mangle_user, NULL, 0},
+#endif
{NULL, P_BOOL, P_NONE, NULL, NULL, 0}
};
@@ -297,6 +335,9 @@
#ifdef LOG_DAEMON
Globals.syslog_facility = LOG_DAEMON;
#endif
+#ifdef WITH_LDAP
+ Globals.ldap_port = LDAP_PORT;
+#endif
}
/***************************************************************************
@@ -363,6 +404,21 @@
FN_LOCAL_STRING(lp_dont_compress, dont_compress)
FN_LOCAL_INTEGER(lp_timeout, timeout)
FN_LOCAL_INTEGER(lp_max_connections, max_connections)
+
+FN_GLOBAL_STRING(lp_ldap_server, &Globals.ldap_server)
+FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
+FN_GLOBAL_STRING(lp_ldap_root, &Globals.ldap_root)
+FN_GLOBAL_STRING(lp_ldap_root_passwd, &Globals.ldap_root_passwd)
+FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.ldap_suffix)
+
+FN_LOCAL_STRING(lp_ldap_filter, ldap_filter)
+FN_LOCAL_STRING(lp_ldap_passwd_attribute, ldap_passwd_attribute)
+FN_LOCAL_STRING(lp_ldap_auth_usergroup, ldap_auth_usergroup)
+FN_LOCAL_STRING(lp_ldap_auth_users_attribute, ldap_auth_users_attribute)
+
+#ifdef WITH_MANGLE_USER
+FN_LOCAL_STRING(lp_mangle_user, mangle_user)
+#endif
/* local prototypes */
static int strwicmp( char *psz1, char *psz2 );
--
To unsubscribe or change options: http://lists.samba.org/mailman/listinfo/rsync
Before posting, read: http://www.tuxedo.org/~esr/faqs/smart-questions.html
Thanks,
Darren