Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LDAP support for Browse #338

Closed
michaelrsweet opened this issue Oct 18, 2003 · 10 comments
Closed

LDAP support for Browse #338

michaelrsweet opened this issue Oct 18, 2003 · 10 comments
Labels
enhancement New feature or request
Milestone

Comments

@michaelrsweet
Copy link
Collaborator

Version: 1.2-feature
CUPS.org User: yugami.monochromatic

This patch adds LDAP support to cups Browse functionality.

Apply each of the patches found within, Then edit your cupsd.conf

Added config options are
BrowseProtocol ldap
BrowseLDAPServer (set to a uri like ldapi:/// for local binds or ldap://myserver for remote binds)
BrowseLDAPDN (this is the base dn for searches, and additions dc=arstechnica,dc=com for example)
BrowseLDAPBindDN (who to login to the ldap server as, dn=cupsadmin,dc=arstechnica,dc=com for example)
BrowseLDAPPassword (password for the bind dn) (insecure i know)

Make sure a ou=printers exists under the DN - I'll make this a config option later

your LDAP server must be configured to use the printer.schema found under schemas

add cups-openldap.md4 to your config-scripts under the cups source dir. then rerun autoconf and aclocal and use configre --with-ldap

--- cupsys-1.1.19final-orig/configure.in 2003-10-16 16:19:18.000000000 -0400
+++ cupsys-1.1.19final/configure.in 2003-10-17 08:33:20.000000000 -0400
@@ -48,6 +48,8 @@
sinclude(config-scripts/cups-openssl.m4)
sinclude(config-scripts/cups-pam.m4)

+sinclude(config-scripts/cups-openldap.m4)
+
sinclude(config-scripts/cups-scripting.m4)

AC_OUTPUT(Makedefs cups.list cups.sh cups-config conf/cupsd.conf conf/pam.conf)
--- cupsys-1.1.19final-orig/scheduler/conf.c 2003-10-16 16:19:18.000000000 -0400
+++ cupsys-1.1.19final/scheduler/conf.c 2003-10-17 14:46:26.000000000 -0400
@@ -397,6 +397,11 @@
BrowseTimeout = DEFAULT_TIMEOUT;
Browsing = TRUE;

  • BrowseLDAPServer = NULL;
  • BrowseLDAPDN = NULL;
  • BrowseLDAPBindDN = NULL;
  • BrowseLDAPPassword = NULL;

JobHistory = DEFAULT_HISTORY;
JobFiles = DEFAULT_FILES;
JobAutoPurge = 0;
@@ -918,6 +923,25 @@
value, linenum);
}
#endif /* HAVE_SSL */
+#ifdef HAVE_LIBLDAP

  •   /\* LDAP config stuff */
    
  • else if (strcasecmp(name, "BrowseLDAPServer") == 0)
  •   {
    
  •           BrowseLDAPServer = strdup(value);
    
  •   }
    
  • else if (strcasecmp(name, "BrowseLDAPDN") == 0)
  •   {
    
  •           BrowseLDAPDN = strdup(value);
    
  •   }
    
  • else if (strcasecmp(name, "BrowseLDAPBindDN") == 0)
  •   {
    
  •           BrowseLDAPBindDN = strdup(value);
    
  •   }
    
  • else if (strcasecmp(name, "BrowseLDAPPassword") == 0)
  •   {
    
  •           BrowseLDAPPassword = strdup(value);
    
  •   }
    
    +#endif /* HAVE_LIBLDAP /
    else if (strcasecmp(name, "BrowseAddress") == 0)
    {
    /

    --- cupsys-1.1.19final-orig/configure.in 2003-10-16 16:19:18.000000000 -0400
    +++ cupsys-1.1.19final/configure.in 2003-10-17 08:33:20.000000000 -0400
    @@ -48,6 +48,8 @@
    sinclude(config-scripts/cups-openssl.m4)
    sinclude(config-scripts/cups-pam.m4)

+sinclude(config-scripts/cups-openldap.m4)
+
sinclude(config-scripts/cups-scripting.m4)

AC_OUTPUT(Makedefs cups.list cups.sh cups-config conf/cupsd.conf conf/pam.conf)
yugami@killerloop:/docs/ldap/ldap.ars/cups$ ls
configure.in.patch cups-openldap.m4 dirsrvc-c.patch main.patch
conf.patch CVS dirsrvc-h.patch README
yugami@killerloop:
/docs/ldap/ldap.ars/cups$ cat conf.patch
--- cupsys-1.1.19final-orig/scheduler/conf.c 2003-10-16 16:19:18.000000000 -0400
+++ cupsys-1.1.19final/scheduler/conf.c 2003-10-17 14:46:26.000000000 -0400
@@ -397,6 +397,11 @@
BrowseTimeout = DEFAULT_TIMEOUT;
Browsing = TRUE;

  • BrowseLDAPServer = NULL;
  • BrowseLDAPDN = NULL;
  • BrowseLDAPBindDN = NULL;
  • BrowseLDAPPassword = NULL;

JobHistory = DEFAULT_HISTORY;
JobFiles = DEFAULT_FILES;
JobAutoPurge = 0;
@@ -918,6 +923,25 @@
value, linenum);
}
#endif /* HAVE_SSL */
+#ifdef HAVE_LIBLDAP

  •   /\* LDAP config stuff */
    
  • else if (strcasecmp(name, "BrowseLDAPServer") == 0)

  •   {
    
  •           BrowseLDAPServer = strdup(value);
    
  •   }
    
  • else if (strcasecmp(name, "BrowseLDAPDN") == 0)

  •   {
    
  •           BrowseLDAPDN = strdup(value);
    
  •   }
    
  • else if (strcasecmp(name, "BrowseLDAPBindDN") == 0)

  •   {
    
  •           BrowseLDAPBindDN = strdup(value);
    
  •   }
    
  • else if (strcasecmp(name, "BrowseLDAPPassword") == 0)

  •   {
    
  •           BrowseLDAPPassword = strdup(value);
    
  •   }
    

    +#endif /* HAVE_LIBLDAP /
    else if (strcasecmp(name, "BrowseAddress") == 0)
    {
    /

    yugami@killerloop:/docs/ldap/ldap.ars/cups$ ls
    configure.in.patch cups-openldap.m4 dirsrvc-c.patch main.patch
    conf.patch CVS dirsrvc-h.patch README
    yugami@killerloop:
    /docs/ldap/ldap.ars/cups$ cat dirsrvc-c.patch
    --- cupsys-1.1.19final-orig/scheduler/dirsvc.c 2003-05-12 16:51:53.000000000 -0400
    +++ cupsys-1.1.19final/scheduler/dirsvc.c 2003-10-17 22:07:13.000000000 -0400
    @@ -707,6 +707,11 @@
    {
    int val; /* Socket option value /
    struct sockaddr_in addr; /
    Broadcast address */
    +#ifdef HAVE_LIBLDAP

  •   int             rc;   /\* ldap api call return value */
    
  •   int         version = 3;
    
  •   struct berval bv = {0, ""};
    

    +#endif /* HAVE_LIBLDAP */

    if (!Browsing || !BrowseProtocols)
    @@ -798,6 +803,55 @@
    BrowseSLPRefresh = 0;
    }

    endif /* HAVE_LIBSLP */

    +#ifdef HAVE_LIBLDAP

  •   /\* LDAP stuff, currently only supports ldapi EXTERNAL sasl binds */
    
  •   if (BrowseProtocols & BROWSE_LDAP)
    
  •   {
    
  •           if (BrowseLDAPDN == NULL)
    
  •           {
    
  •                   LogMessage(L_ERROR, "Need to set BrowseLDAPDN if using LDAP");
    
  •                   BrowseProtocols &= ~BROWSE_LDAP;
    
  •                   return;
    
  •           }
    
  •           if (BrowseLDAPServer == NULL ||strcasecmp(BrowseLDAPServer, "localhost") == 0 ||
    
  •              strcasecmp(BrowseLDAPServer, "ldapi:///") == 0)
    
  •           {
    
  •                   rc = ldap_initialize(&BrowseLDAPHandle, "ldapi:///");
    
  •           }
    
  •           else
    
  •                   rc = ldap_initialize(&BrowseLDAPHandle, BrowseLDAPServer);
    
  •           if (rc != LDAP_SUCCESS) {
    
  •                   LogMessage(L_ERROR, "Unable to initialize LDAP; disabling LDAP browsing!");
    
  •                   BrowseProtocols &= ~BROWSE_LDAP;
    
  •           }
    
  •           else
    
  •           {
    
  •                   rc = ldap_set_option(BrowseLDAPHandle, LDAP_OPT_PROTOCOL_VERSION, (const void *)&version);
    
  •                   if (rc != LDAP_SUCCESS) {
    
  •                           ldap_unbind_ext(BrowseLDAPHandle, NULL, NULL);
    
  •                           BrowseLDAPHandle = NULL;
    
  •                           LogMessage(L_ERROR, "Unable to set LDAP protocol version; disabling LDAP browsing!");
    
  •                           BrowseProtocols &= ~BROWSE_LDAP;
    
  •                   }
    
  •                   else
    
  •                   {
    
  •                           if (BrowseLDAPServer == NULL ||strcasecmp(BrowseLDAPServer, "localhost") == 0)
    
  •                                   rc = ldap_sasl_bind_s(BrowseLDAPHandle, NULL, "EXTERNAL", &bv, NULL, NULL, NULL );
    
  •                           else
    
  •                                   rc = ldap_bind_s(BrowseLDAPHandle, BrowseLDAPBindDN, BrowseLDAPPassword, LDAP_AUTH_SIMPLE);
    
  •                           if (rc != LDAP_SUCCESS) {
    
  •                                   LogMessage(L_ERROR, "Unable to bind to LDAP server!; disabling LDAP browsing!");
    
  •                                   ldap_unbind_ext(BrowseLDAPHandle, NULL, NULL);
    
  •                                   BrowseProtocols &= ~BROWSE_LDAP;
    
  •                           }
    
  •                   }
    
  •           }
    
  •           LogMessage(L_DEBUG, "BrowseLDAP Setup....Done");
    
  •   }
    

    +#endif /* HAVE_LIBLDAP */
    }

@@ -1015,6 +1069,14 @@
SLPClose(BrowseSLPHandle);
}
#endif /* HAVE_LIBSLP */
+
+#ifdef HAVE_LIBLDAP

  •   if(BrowseProtocols & BROWSE_LDAP)
    
  •   {
    
  •           if(BrowseLDAPHandle)
    
  •                   ldap_unbind(BrowseLDAPHandle);
    
  •   }
    
    +#endif /* HAVE_LIBLDAP */
    }

@@ -1898,6 +1960,185 @@
}
#endif /* HAVE_LIBSLP */

+#ifdef HAVE_LIBLDAP
+
+static char *CupsAttrs[] = { "printerDescription", "printerURI",

  •                                                     "printerLocation", "printerMakeAndModel", NULL };
    
    +/* the different attributes we want to pull during our search */
    +
    +void
    +UpdateLDAPBrowse(void)
    +{
  •   char    _uri;                   /_ Pointer to printer URI */
    
  •   char    _location;      /_ Pointer to printer location string */
    
  •   char    _info;  /_ Pointer to printer information string (description) */
    
  •   char    _make_model;    /_ Pointer to printer make and model string */
    
  •   char    *_value;        /_ Holds the returned data from LDAP */
    
  •   int rc; /\* return code from LDAP calls */
    
  •   int limit = 0; /\* total number of chars, or upper bounds */
    
  •   char method[HTTP_MAX_URI],      /\* Method portion of URI */
    
  •            username[HTTP_MAX_URI],                /\* Username portion of URI */
    
  •            host[HTTP_MAX_URI],            /\* Host portion of URI */
    
  •            resource[HTTP_MAX_URI];            /\* Resource portion of URI */
    
  •   int port; /\* port from URI */
    
  • LDAPMessage res = NULL, / identifier for LDAP search */
  •                   _e; /_ current entry from search */
    
  •   LogMessage(L_DEBUG2, "UpdateLDAPBrowse() %s Start...", ServerName);
    
  •   BrowseLDAPRefresh = time(NULL) + BrowseInterval;
    
  • rc = ldap_search_s(BrowseLDAPHandle, BrowseLDAPDN, LDAP_SCOPE_SUBTREE,
  •                   "(objectclass=cupsPrinter)", CupsAttrs, 0, &res);
    
  • if (rc != LDAP_SUCCESS)
  •   {
    
  •           LogMessage(L_ERROR, "Search Returned ERROR(%i): %s", rc, ldap_err2string(rc));
    
  •           return;
    
  •   }
    
  •   limit = ldap_count_entries(BrowseLDAPHandle, res);
    
  •   LogMessage(L_DEBUG, "LDAP Search returned %i entries", limit);
    
  •   if (limit < 1)
    
  •           return;
    
  • e = ldap_first_entry(BrowseLDAPHandle, res);
  • if (e == NULL) {
  •           LogMessage(L_ERROR, "Unable to get LDAP entry.");
    
  •           return;
    
  • }
  •   while (e != NULL)
    
  •   {
    
  •           value = ldap_get_values(BrowseLDAPHandle, e, "printerDescription");
    
  •           limit = strlen((const char_)_value);
    
  •           info = malloc(sizeof(char) \* (limit + 1));
    
  •           strcpy(info, (const char_)_value);
    
  •           ldap_value_free(value);
    
  •           value = ldap_get_values(BrowseLDAPHandle, e, "printerURI");
    
  •           limit = strlen((const char_)_value);
    
  •           uri = malloc(sizeof(char) \* limit + 1);
    
  •           strcpy(uri, (const char_)_value);
    
  •           ldap_value_free(value);
    
  •           value = ldap_get_values(BrowseLDAPHandle, e, "printerLocation");
    
  •           limit = strlen((const char_)_value);
    
  •           location = malloc(sizeof(char) \* (limit + 1));
    
  •           strcpy(location, (const char_)_value);
    
  •           ldap_value_free(value);
    
  •           value = ldap_get_values(BrowseLDAPHandle, e, "printerMakeAndModel");
    
  •           limit = strlen((const char_)_value);
    
  •           make_model = malloc(sizeof(char) \* (limit + 1));
    
  •           strcpy(make_model, (const char_)_value);
    
  •           ldap_value_free(value);
    
  •           /*
    
  •              seems sometimes we can add printers that we advertise
    
  •              so check to see if this printer is one of ours and
    
  •              skip if it is
    
  •           */
    
  •           httpSeparate(uri, method, username, host, &port, resource);
    
  •           if (strcasecmp(host, ServerName) == 0)
    
  •           {
    
  •                   LogMessage(L_DEBUG2, "Printer %s is our printer, skipping...", resource);
    
  •                   e = ldap_next_entry(BrowseLDAPHandle, e);
    
  •                   continue;
    
  •           }
    
  •           LogMessage(L_DEBUG2, "PrinterName: %s", info);
    
  •           LogMessage(L_DEBUG2, "PrinterURI: %s", uri);
    
  •           LogMessage(L_DEBUG2, "PrinterLocation: %s", location);
    
  •           LogMessage(L_DEBUG2, "PrinterMakeAndModel: %s", make_model);
    
  •           ProcessBrowseData(uri, 0, IPP_PRINTER_IDLE,
    
  •                                             location, info, make_model);
    
  •           e = ldap_next_entry(BrowseLDAPHandle, e);
    
  •   }
    
  •   LogMessage(L_DEBUG2, "UpdateLDAPBrowse() ...Finish");
    

    +}
    +
    +void
    +SendLDAPBrowse(printer_t p) / I - Printer to register */
    +{

  •   LDAPMod mods[6]; /\* the 6 attributes we will be adding */
    
  •   LDAPMod _pmods[7]; /_ pointers to the 6 attributes + NULL */
    
  • LDAPMessage res = NULL; / search result token */

  •   char\* dn; /\* dn of the printer we are adding */
    
  •   char *objectClass_values[] = { "top", "device", "cupsPrinter", NULL };
    
  •   /\* the 3 objectClass's we use in our LDAP entries */
    
  •   /\* everything in ldap is *\* so we fudge around it */
    
  •   char *cn_value[] = { p->info, NULL };
    
  •   char *uri[] = { p->uri, NULL};
    
  •   char *info[] = { p->info, NULL};
    
  •   char *location[] = { p->location, NULL};
    
  •   char *make_model[] = { p->make_model, NULL};
    
  •   char fltr[256]; /\* search filter, test for possible UPDATEs */
    
  •   int count = 0; /\* for loop counter */
    
  •   int rc; /\* return code from LDAP calls */
    
  •   LogMessage(L_DEBUG2, "SendLDAPBrowse() Start...");
    
  •   snprintf(fltr, 255,"(&(objectclass=cupsPrinter)(printerDescription~=%s))", p->info);
    
  • rc = ldap_search_s(BrowseLDAPHandle, BrowseLDAPDN, LDAP_SCOPE_SUBTREE, fltr, CupsAttrs, 0, &res);

  •   LogMessage(L_DEBUG, "Searching: %s", fltr);
    
  •   mods[0].mod_type = "cn";
    
  •   mods[0].mod_values = cn_value;
    
  •   mods[1].mod_type = CupsAttrs[0];
    
  •   mods[1].mod_values = info;
    
  •   mods[2].mod_type = CupsAttrs[1];
    
  •   mods[2].mod_values = uri;
    
  •   mods[3].mod_type = CupsAttrs[2];
    
  •   mods[3].mod_values = location;
    
  •   mods[4].mod_type = CupsAttrs[3];
    
  •   mods[4].mod_values = make_model;
    
  •   mods[5].mod_type = "objectClass";
    
  •   mods[5].mod_values = objectClass_values;
    
  •   dn = malloc(sizeof(char) \* 256);
    
  •   sprintf(dn, "cn=%s,ou=printers,%s", p->info, BrowseLDAPDN);
    
  •   LogMessage(L_DEBUG, "Using dn=%s for entry", dn);
    
  •   if (ldap_count_entries(BrowseLDAPHandle, res) > 0)
    
  •   {
    
  •           /\* this is where we compare to see if any settings have changed,
    
  •              and only modify if they have */
    
  •           LogMessage(L_DEBUG2, "Replacing entry");
    
  •           for(; count < 6; count++)
    
  •           {
    
  •                   pmods[count] = &mods[count];
    
  •                   pmods[count]->mod_op = LDAP_MOD_REPLACE;
    
  •           }
    
  •           pmods[5] = NULL;
    
  •   }
    
  •   else
    
  •   {
    
  •           for(count = 0; count < 6; count++)
    
  •           {
    
  •                   pmods[count] = &mods[count];
    
  •                   pmods[count]->mod_op = LDAP_MOD_ADD;
    
  •           }
    
  •           pmods[6] = NULL;
    
  •           if ((rc = ldap_add_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS)
    
  •           {
    
  •                   LogMessage(L_ERROR, "Adding Entry failed: %i = %s", rc, ldap_err2string(rc));
    
  •           }
    
  •   }
    
  •   LogMessage(L_DEBUG2, "SendLDAPBrowse() ...Finish");
    

    +}
    +
    +#endif /* HAVE_LIBLDAP */

    /*

    • End of "$Id: dirsrvc-c.patch,v 1.3 2003/10/18 02:12:55 ars Exp $".
      --- cupsys-1.1.19final-orig/scheduler/dirsvc.h 2003-03-31 11:31:36.000000000 -0500
      +++ cupsys-1.1.19final/scheduler/dirsvc.h 2003-10-17 21:58:30.000000000 -0400
      @@ -31,6 +31,9 @@

      include <slp.h>

      #endif /* HAVE_LIBSLP */

+#ifdef HAVE_LIBLDAP
+# include <ldap.h>
+#endif /* HAVE_LIBLDAP */

/*

  • Browse protocols...
    @@ -38,7 +41,7 @@

    define BROWSE_CUPS 1 /* CUPS */

    define BROWSE_SLP 2 /* SLPv2 */

    -#define BROWSE_LDAP 4 /* LDAP (not supported yet) /
    +#define BROWSE_LDAP 4 /
    LDAP */

    define BROWSE_ALL 7 /* All protocols */

@@ -118,6 +121,20 @@
/* Next SLP refresh time /
#endif /
HAVE_LIBSLP */

+#ifdef HAVE_LIBLDAP
+VAR LDAP* BrowseLDAPHandle VALUE(NULL);

  •     /\* Handle to LDAP server */
    

    +VAR time_t BrowseLDAPRefresh VALUE(0);

  •     /\* next refresh time */
    

    +VAR char *BrowseLDAPServer,

  •               /\* LDAP Server to use for BrowseProtocol = ldap */
    
  •        *BrowseLDAPDN,
    
  •               /\* LDAP DN to use for base of searchs */
    
  •        *BrowseLDAPBindDN,
    
  •               /\* LDAP DN to use for logon */
    
  •        *BrowseLDAPPassword;
    
  •               /* Password to use with BindDN */
    

    +#endif /* HAVE_LIBLDAP */

    /*

    • Prototypes...
      @@ -129,6 +146,7 @@
      extern void SendBrowseList(void);
      extern void SendCUPSBrowse(printer_t *p);
      extern void SendSLPBrowse(printer_t *p);
      +extern void SendLDAPBrowse(printer_t *p);
      extern void StartBrowsing(void);
      extern void StartPolling(void);
      extern void StopBrowsing(void);
      @@ -136,6 +154,7 @@
      extern void UpdateCUPSBrowse(void);
      extern void UpdatePolling(void);
      extern void UpdateSLPBrowse(void);
      +extern void UpdateLDAPBrowse(void);

    /*
    --- cupsys-1.1.19final-orig/scheduler/main.c 2003-05-09 11:11:13.000000000 -0400
    +++ cupsys-1.1.19final/scheduler/main.c 2003-10-17 14:41:35.000000000 -0400
    @@ -638,6 +638,11 @@
    UpdateSLPBrowse();

    endif /* HAVE_LIBSLP */

+#ifdef HAVE_LIBLDAP

  •     if((BrowseProtocols & BROWSE_LDAP) && BrowseLDAPRefresh <= time(NULL))
    
  •             UpdateLDAPBrowse();
    
    +#endif /* HAVE_LIBLDAP */
    +
    SendBrowseList();
    }
@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Reassigned to CUPS 1.2; this won't go into 1.1.x...

Thanks!

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: claus.rosenberger.rocnet

is that code included in 1.2cvs?
if not, when the code will be included?

regards

claus

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

We are now working on integrating this patch (a long time, I know! :)

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: olo

This would be great if it made to the 1.2 release.

Support for storing printers configuration in LDAP directory would make CUPS much more viable for medium and large scale organizations.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Fixed in Subversion repository.

I updated the code to conform to our coding standards, fixed several memory leaks, and added a call to ldap_modify_s() when the printer definition was just updated, not added.

Please open a new STR if you find any problems with the code.

Thanks!

@michaelrsweet
Copy link
Collaborator Author

"conf.patch":

--- cupsys-1.1.19final-orig/scheduler/conf.c 2003-10-16 16:19:18.000000000 -0400
+++ cupsys-1.1.19final/scheduler/conf.c 2003-10-17 14:46:26.000000000 -0400
@@ -397,6 +397,11 @@
BrowseTimeout = DEFAULT_TIMEOUT;
Browsing = TRUE;

  • BrowseLDAPServer = NULL;
  • BrowseLDAPDN = NULL;
  • BrowseLDAPBindDN = NULL;
  • BrowseLDAPPassword = NULL;

JobHistory = DEFAULT_HISTORY;
JobFiles = DEFAULT_FILES;
JobAutoPurge = 0;
@@ -918,6 +923,25 @@
value, linenum);
}
#endif /* HAVE_SSL */
+#ifdef HAVE_LIBLDAP

  • /* LDAP config stuff */
  • else if (strcasecmp(name, "BrowseLDAPServer") == 0)
  • {
  •   BrowseLDAPServer = strdup(value);
    
  • }
  • else if (strcasecmp(name, "BrowseLDAPDN") == 0)
  • {
  •   BrowseLDAPDN = strdup(value);
    
  • }
  • else if (strcasecmp(name, "BrowseLDAPBindDN") == 0)
  • {
  •   BrowseLDAPBindDN = strdup(value);
    
  • }
  • else if (strcasecmp(name, "BrowseLDAPPassword") == 0)
  • {
  •   BrowseLDAPPassword = strdup(value);
    
  • }
    +#endif /* HAVE_LIBLDAP /
    else if (strcasecmp(name, "BrowseAddress") == 0)
    {
    /

@michaelrsweet
Copy link
Collaborator Author

"configure.in.patch":

--- cupsys-1.1.19final-orig/configure.in 2003-10-16 16:19:18.000000000 -0400
+++ cupsys-1.1.19final/configure.in 2003-10-17 08:33:20.000000000 -0400
@@ -48,6 +48,8 @@
sinclude(config-scripts/cups-openssl.m4)
sinclude(config-scripts/cups-pam.m4)

+sinclude(config-scripts/cups-openldap.m4)
+
sinclude(config-scripts/cups-scripting.m4)

AC_OUTPUT(Makedefs cups.list cups.sh cups-config conf/cupsd.conf conf/pam.conf)

@michaelrsweet
Copy link
Collaborator Author

"dirsrvc-c.patch":

--- cupsys-1.1.19final-orig/scheduler/dirsvc.c 2003-05-12 16:51:53.000000000 -0400
+++ cupsys-1.1.19final/scheduler/dirsvc.c 2003-10-17 22:07:13.000000000 -0400
@@ -707,6 +707,11 @@
{
int val; /* Socket option value /
struct sockaddr_in addr; /
Broadcast address */
+#ifdef HAVE_LIBLDAP

  • int rc; /* ldap api call return value */
  • int version = 3;
  • struct berval bv = {0, ""};
    +#endif /* HAVE_LIBLDAP */

if (!Browsing || !BrowseProtocols)
@@ -798,6 +803,55 @@
BrowseSLPRefresh = 0;
}
#endif /* HAVE_LIBSLP */
+#ifdef HAVE_LIBLDAP

  • /* LDAP stuff, currently only supports ldapi EXTERNAL sasl binds */
  • if (BrowseProtocols & BROWSE_LDAP)
  • {
  •   if (BrowseLDAPDN == NULL) 
    
  •   {
    
  •       LogMessage(L_ERROR, "Need to set BrowseLDAPDN if using LDAP");
    
  •       BrowseProtocols &= ~BROWSE_LDAP;
    
  •       return;
    
  •   }
    
  •   if (BrowseLDAPServer == NULL ||strcasecmp(BrowseLDAPServer, "localhost") == 0 ||
    
  •      strcasecmp(BrowseLDAPServer, "ldapi:///") == 0) 
    
  •   {
    
  •       rc = ldap_initialize(&BrowseLDAPHandle, "ldapi:///");
    
  •   }
    
  •   else  
    
  •       rc = ldap_initialize(&BrowseLDAPHandle, BrowseLDAPServer);
    
  •   if (rc != LDAP_SUCCESS) {
    
  •       LogMessage(L_ERROR, "Unable to initialize LDAP; disabling LDAP browsing!");
    
  •       BrowseProtocols &= ~BROWSE_LDAP;
    
  •   }
    
  •   else
    
  •   {
    
  •       rc = ldap_set_option(BrowseLDAPHandle, LDAP_OPT_PROTOCOL_VERSION, (const void *)&version);
    
  •       if (rc != LDAP_SUCCESS) {
    
  •           ldap_unbind_ext(BrowseLDAPHandle, NULL, NULL);
    
  •           BrowseLDAPHandle = NULL;
    
  •           LogMessage(L_ERROR, "Unable to set LDAP protocol version; disabling LDAP browsing!");
    
  •           BrowseProtocols &= ~BROWSE_LDAP;
    
  •       }
    
  •       else
    
  •       {
    
  •           if (BrowseLDAPServer == NULL ||strcasecmp(BrowseLDAPServer, "localhost") == 0)
    
  •               rc = ldap_sasl_bind_s(BrowseLDAPHandle, NULL, "EXTERNAL", &bv, NULL, NULL, NULL );
    
  •           else
    
  •               rc = ldap_bind_s(BrowseLDAPHandle, BrowseLDAPBindDN, BrowseLDAPPassword, LDAP_AUTH_SIMPLE);
    
  •           if (rc != LDAP_SUCCESS) {
    
  •               LogMessage(L_ERROR, "Unable to bind to LDAP server!; disabling LDAP browsing!");
    
  •               ldap_unbind_ext(BrowseLDAPHandle, NULL, NULL);
    
  •               BrowseProtocols &= ~BROWSE_LDAP;
    
  •           }
    
  •       }
    
  •   }
    
  •   LogMessage(L_DEBUG, "BrowseLDAP Setup....Done");
    
  • }
    +#endif /* HAVE_LIBLDAP */
    }

@@ -1015,6 +1069,14 @@
SLPClose(BrowseSLPHandle);
}
#endif /* HAVE_LIBSLP */
+
+#ifdef HAVE_LIBLDAP

  • if(BrowseProtocols & BROWSE_LDAP)
  • {
  •   if(BrowseLDAPHandle)
    
  •       ldap_unbind(BrowseLDAPHandle);
    
  • }
    +#endif /* HAVE_LIBLDAP */
    }

@@ -1898,6 +1960,185 @@
}
#endif /* HAVE_LIBSLP */

+#ifdef HAVE_LIBLDAP
+
+static char *CupsAttrs[] = { "printerDescription", "printerURI",

  •                         "printerLocation", "printerMakeAndModel", NULL };
    
    +/* the different attributes we want to pull during our search */
    +
    +void
    +UpdateLDAPBrowse(void)
    +{
  • char uri; / Pointer to printer URI */
  • char location; / Pointer to printer location string */
  • char info; / Pointer to printer information string (description) */
  • char make_model; / Pointer to printer make and model string */
  • char *value; / Holds the returned data from LDAP */
  • int rc; /* return code from LDAP calls */
  • int limit = 0; /* total number of chars, or upper bounds */
  • char method[HTTP_MAX_URI], /* Method portion of URI */
  •    username[HTTP_MAX_URI],        /\* Username portion of URI */
    
  •    host[HTTP_MAX_URI],        /\* Host portion of URI */
    
  •    resource[HTTP_MAX_URI];        /\* Resource portion of URI */
    
  • int port; /* port from URI */
  • LDAPMessage res = NULL, / identifier for LDAP search */
  •           _e; /_ current entry from search */
    
  • LogMessage(L_DEBUG2, "UpdateLDAPBrowse() %s Start...", ServerName);
  • BrowseLDAPRefresh = time(NULL) + BrowseInterval;
  • rc = ldap_search_s(BrowseLDAPHandle, BrowseLDAPDN, LDAP_SCOPE_SUBTREE,
  •                   "(objectclass=cupsPrinter)", CupsAttrs, 0, &res);
    
  • if (rc != LDAP_SUCCESS)
  • {
  •   LogMessage(L_ERROR, "Search Returned ERROR(%i): %s", rc, ldap_err2string(rc));
    
  •   return;
    
  • }
  • limit = ldap_count_entries(BrowseLDAPHandle, res);
  • LogMessage(L_DEBUG, "LDAP Search returned %i entries", limit);
  • if (limit < 1)
  •   return;
    
  • e = ldap_first_entry(BrowseLDAPHandle, res);
  • if (e == NULL) {
  •   LogMessage(L_ERROR, "Unable to get LDAP entry.");
    
  •   return;
    
  • }
  • while (e != NULL)
  • {
  •   value = ldap_get_values(BrowseLDAPHandle, e, "printerDescription");
    
  •   limit = strlen((const char_)_value);
    
  •   info = malloc(sizeof(char) \* (limit + 1));
    
  •   strcpy(info, (const char_)_value);
    
  •   ldap_value_free(value);
    
  •   value = ldap_get_values(BrowseLDAPHandle, e, "printerURI");
    
  •   limit = strlen((const char_)_value);
    
  •   uri = malloc(sizeof(char) \* limit + 1);
    
  •   strcpy(uri, (const char_)_value);
    
  •   ldap_value_free(value);
    
  •   value = ldap_get_values(BrowseLDAPHandle, e, "printerLocation");
    
  •   limit = strlen((const char_)_value);
    
  •   location = malloc(sizeof(char) \* (limit + 1));
    
  •   strcpy(location, (const char_)_value);
    
  •   ldap_value_free(value);
    
  •   value = ldap_get_values(BrowseLDAPHandle, e, "printerMakeAndModel");
    
  •   limit = strlen((const char_)_value);
    
  •   make_model = malloc(sizeof(char) \* (limit + 1));
    
  •   strcpy(make_model, (const char_)_value);
    
  •   ldap_value_free(value);
    
  •   /\* 
    
  •      seems sometimes we can add printers that we advertise
    
  •      so check to see if this printer is one of ours and
    
  •      skip if it is
    
  •   */
    
  •   httpSeparate(uri, method, username, host, &port, resource);
    
  •   if (strcasecmp(host, ServerName) == 0)
    
  •   {
    
  •       LogMessage(L_DEBUG2, "Printer %s is our printer, skipping...", resource);
    
  •       e = ldap_next_entry(BrowseLDAPHandle, e);
    
  •       continue;
    
  •   }
    
  •   LogMessage(L_DEBUG2, "PrinterName: %s", info);
    
  •   LogMessage(L_DEBUG2, "PrinterURI: %s", uri);
    
  •   LogMessage(L_DEBUG2, "PrinterLocation: %s", location);
    
  •   LogMessage(L_DEBUG2, "PrinterMakeAndModel: %s", make_model);
    
  •   ProcessBrowseData(uri, 0, IPP_PRINTER_IDLE,
    
  •                     location, info, make_model);
    
  •   e = ldap_next_entry(BrowseLDAPHandle, e);
    
  • }
  • LogMessage(L_DEBUG2, "UpdateLDAPBrowse() ...Finish");
    +}

+void
+SendLDAPBrowse(printer_t p) / I - Printer to register */
+{

  •   LDAPMod mods[6]; /\* the 6 attributes we will be adding */
    
  • LDAPMod pmods[7]; / pointers to the 6 attributes + NULL */
  • LDAPMessage res = NULL; / search result token */
  • char* dn; /* dn of the printer we are adding */
  • char *objectClass_values[] = { "top", "device", "cupsPrinter", NULL };
  • /* the 3 objectClass's we use in our LDAP entries */
  • /* everything in ldap is ** so we fudge around it */
  • char *cn_value[] = { p->info, NULL };
  • char *uri[] = { p->uri, NULL};
  • char *info[] = { p->info, NULL};
  • char *location[] = { p->location, NULL};
  • char *make_model[] = { p->make_model, NULL};
  • char fltr[256]; /* search filter, test for possible UPDATEs */
  •   int count = 0; /\* for loop counter */
    
  • int rc; /* return code from LDAP calls */
  • LogMessage(L_DEBUG2, "SendLDAPBrowse() Start...");
  • snprintf(fltr, 255,"(&(objectclass=cupsPrinter)(printerDescription~=%s))", p->info);
  • rc = ldap_search_s(BrowseLDAPHandle, BrowseLDAPDN, LDAP_SCOPE_SUBTREE, fltr, CupsAttrs, 0, &res);
  • LogMessage(L_DEBUG, "Searching: %s", fltr);
  • mods[0].mod_type = "cn";
  • mods[0].mod_values = cn_value;
  • mods[1].mod_type = CupsAttrs[0];
  • mods[1].mod_values = info;
  • mods[2].mod_type = CupsAttrs[1];
  • mods[2].mod_values = uri;
  • mods[3].mod_type = CupsAttrs[2];
  • mods[3].mod_values = location;
  • mods[4].mod_type = CupsAttrs[3];
  • mods[4].mod_values = make_model;
  • mods[5].mod_type = "objectClass";
  • mods[5].mod_values = objectClass_values;
  • dn = malloc(sizeof(char) * 256);
  • sprintf(dn, "cn=%s,ou=printers,%s", p->info, BrowseLDAPDN);
  • LogMessage(L_DEBUG, "Using dn=%s for entry", dn);
  • if (ldap_count_entries(BrowseLDAPHandle, res) > 0)
  • {
  •   /\* this is where we compare to see if any settings have changed, 
    
  •      and only modify if they have */
    
  •   LogMessage(L_DEBUG2, "Replacing entry");
    
  •   for(; count < 6; count++)
    
  •   {
    
  •       pmods[count] = &mods[count];
    
  •       pmods[count]->mod_op = LDAP_MOD_REPLACE;
    
  •   }
    
  •   pmods[5] = NULL;
    
  • }
  • else
  • {
  •   for(count = 0; count < 6; count++)
    
  •   {
    
  •       pmods[count] = &mods[count];
    
  •       pmods[count]->mod_op = LDAP_MOD_ADD;
    
  •   }
    
  •   pmods[6] = NULL;
    
  •   if ((rc = ldap_add_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS)
    
  •   {
    
  •       LogMessage(L_ERROR, "Adding Entry failed: %i = %s", rc, ldap_err2string(rc));
    
  •   }
    
  • }
  • LogMessage(L_DEBUG2, "SendLDAPBrowse() ...Finish");
    +}

+#endif /* HAVE_LIBLDAP */

/*

  • End of "$Id: dirsrvc-c.patch,v 1.3 2003/10/18 02:12:55 ars Exp $".

@michaelrsweet
Copy link
Collaborator Author

"dirsrvc-h.patch":

--- cupsys-1.1.19final-orig/scheduler/dirsvc.h 2003-03-31 11:31:36.000000000 -0500
+++ cupsys-1.1.19final/scheduler/dirsvc.h 2003-10-17 21:58:30.000000000 -0400
@@ -31,6 +31,9 @@

include <slp.h>

#endif /* HAVE_LIBSLP */

+#ifdef HAVE_LIBLDAP
+# include <ldap.h>
+#endif /* HAVE_LIBLDAP */

/*

  • Browse protocols...
    @@ -38,7 +41,7 @@

    #define BROWSE_CUPS 1 /* CUPS /
    #define BROWSE_SLP 2 /
    SLPv2 /
    -#define BROWSE_LDAP 4 /
    LDAP (not supported yet) /
    +#define BROWSE_LDAP 4 /
    LDAP /
    #define BROWSE_ALL 7 /
    All protocols */

@@ -118,6 +121,20 @@
/* Next SLP refresh time /
#endif /
HAVE_LIBSLP */

+#ifdef HAVE_LIBLDAP
+VAR LDAP* BrowseLDAPHandle VALUE(NULL);

  •     /\* Handle to LDAP server */
    

    +VAR time_t BrowseLDAPRefresh VALUE(0);

  •     /\* next refresh time */
    

    +VAR char *BrowseLDAPServer,

  •               /\* LDAP Server to use for BrowseProtocol = ldap */
    
  •        *BrowseLDAPDN,
    
  •               /\* LDAP DN to use for base of searchs */
    
  •        *BrowseLDAPBindDN,
    
  •               /\* LDAP DN to use for logon */
    
  •        *BrowseLDAPPassword;
    
  •               /* Password to use with BindDN */
    

    +#endif /* HAVE_LIBLDAP */

    /*

    • Prototypes...
      @@ -129,6 +146,7 @@
      extern void SendBrowseList(void);
      extern void SendCUPSBrowse(printer_t *p);
      extern void SendSLPBrowse(printer_t *p);
      +extern void SendLDAPBrowse(printer_t *p);
      extern void StartBrowsing(void);
      extern void StartPolling(void);
      extern void StopBrowsing(void);
      @@ -136,6 +154,7 @@
      extern void UpdateCUPSBrowse(void);
      extern void UpdatePolling(void);
      extern void UpdateSLPBrowse(void);
      +extern void UpdateLDAPBrowse(void);

    /*

@michaelrsweet
Copy link
Collaborator Author

"main.patch":

--- cupsys-1.1.19final-orig/scheduler/main.c 2003-05-09 11:11:13.000000000 -0400
+++ cupsys-1.1.19final/scheduler/main.c 2003-10-17 14:41:35.000000000 -0400
@@ -638,6 +638,11 @@
UpdateSLPBrowse();
#endif /* HAVE_LIBSLP */

+#ifdef HAVE_LIBLDAP

  • if((BrowseProtocols & BROWSE_LDAP) && BrowseLDAPRefresh <= time(NULL))
    
  •     UpdateLDAPBrowse();
    
    +#endif /* HAVE_LIBLDAP */
    +
    SendBrowseList();
    }

@michaelrsweet michaelrsweet added the enhancement New feature or request label Mar 17, 2016
@michaelrsweet michaelrsweet added this to the Stable milestone Mar 17, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant