/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ #pragma ident "%Z%%M% %I% %E% SMI" /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /*LINTLIBRARY*/ #include #include #include #include #include #include #include #include char glob_stdout[BUFSIZ]; char glob_stderr[BUFSIZ]; void f_cleanup(FILE *fp, char *tmpf); void fd_cleanup(int fd1, int fd2); static void _freeList(char ***list); extern void **list_append(void **list, void *item); #ifdef MAIN #define THOSTNAME "cherwell" #define TPRINTERNAME "c" int main() { char *host = THOSTNAME; const char *user = "cn=Directory Manager"; const char *passwd = "directorymanager"; int result = 0; result = _updateldap("add", host, user, passwd, "_pmTestAuthToken", NULL, NULL, "new comment", "false"); if (result != 0) { printf("Add 1 failed, err code = %d\n"); } result = _updateldap("delete", host, user, passwd, "_pmTestAuthToken", NULL, NULL, NULL, "false"); if (result != 0) { printf("Delete 1 failed, err code = %d\n"); } result = _updateldap("delete", host, user, passwd, TPRINTERNAME, THOSTNAME, "", "new comment", "true"); if (result != 0) { printf("delete failed, err code = %d\n"); } result = _updateldap("delete", host, user, passwd, "_default", THOSTNAME, "", "new comment", "true"); if (result != 0) { printf("delete failed, err code = %d\n"); } result = _updateldap("add", host, user, passwd, TPRINTERNAME, THOSTNAME, "Solaris", "new comment", "true"); if (result != 0) { printf("add failed, err code = %d\n"); } result = _updateldap("modify", host, user, passwd, TPRINTERNAME, THOSTNAME, "", "modified comment", "true"); if (result != 0) { printf("modify failed, err code = %d\n"); } result = _updateldap("modify", host, user, passwd, TPRINTERNAME, THOSTNAME, "", NULL, "false"); if (result != 0) { printf("modify failed, err code = %d\n"); } exit(0); } #endif int _dorexec( const char *host, const char *user, const char *passwd, const char *cmd, const char *locale) { int ret = 0; int fd = 0; int fd2 = 1; FILE *fderr; char *ferr; (void) memset(glob_stdout, 0, BUFSIZ); (void) memset(glob_stderr, 0, BUFSIZ); /* * Re-direct stderr to a file */ ferr = tempnam(NULL, NULL); if (ferr != NULL) { fderr = freopen(ferr, "w+", stderr); } fd = rexec((char **)&host, htons(512), user, passwd, cmd, &fd2); if (fd > -1) { /* * rexec worked. Clean up stderr file. */ f_cleanup(fderr, ferr); ret = read(fd, glob_stdout, BUFSIZ - 1); if (ret < 0) { (void) strncpy(glob_stderr, strerror(errno), (BUFSIZ - 1)); fd_cleanup(fd, fd2); return (errno); } ret = read(fd2, glob_stderr, BUFSIZ - 1); if (ret < 0) { (void) strncpy(glob_stderr, strerror(errno), (BUFSIZ - 1)); fd_cleanup(fd, fd2); return (errno); } } else { /* * rexec failed. Read from the stderr file. */ if (fderr != NULL) { char tmpbuf[BUFSIZ]; (void) rewind(fderr); strcpy(glob_stderr, ""); while (fgets(tmpbuf, BUFSIZ - 1, fderr) != NULL) { if ((strlen(glob_stderr) + strlen(tmpbuf)) > BUFSIZ - 1) { break; } else { (void) strcat(glob_stderr, tmpbuf); } } } f_cleanup(fderr, ferr); fd_cleanup(fd, fd2); return (1); } fd_cleanup(fd, fd2); return (0); } void fd_cleanup(int fd, int fd2) { if (fd > 0) { (void) close(fd); } if (fd2 > 0) { (void) close(fd2); } } void f_cleanup(FILE *fp, char *tmpf) { if (fp != NULL) { (void) fclose(fp); } if (tmpf != NULL) { (void) unlink(tmpf); (void) free(tmpf); } } struct ns_bsd_addr { char *server; /* server name */ char *printer; /* printer name or NULL */ char *extension; /* RFC-1179 conformance */ char *pname; /* Local printer name */ }; typedef struct ns_bsd_addr ns_bsd_addr_t; /* Key/Value pair structure */ struct ns_kvp { char *key; /* key */ void *value; /* value converted */ }; typedef struct ns_kvp ns_kvp_t; /* * Information needed to update a name service. * Currently only used for ldap. (see lib/print/ns.h) */ /* LDAP bind password security type */ typedef enum NS_PASSWD_TYPE { NS_PW_INSECURE = 0, NS_PW_SECURE = 1 } NS_PASSWD_TYPE; struct ns_cred { char *binddn; char *passwd; char *host; int port; /* LDAP port, 0 = default */ NS_PASSWD_TYPE passwdType; /* password security type */ uchar_t *domainDN; /* NS domain DN */ }; typedef struct ns_cred ns_cred_t; /* LDAP specific NS Data */ typedef struct NS_LDAPDATA { char **attrList; /* list of user defined Key Value Pairs */ } NS_LDAPDATA; /* Printer Object structure */ struct ns_printer { char *name; /* primary name of printer */ char **aliases; /* aliases for printer */ char *source; /* name service derived from */ ns_kvp_t **attributes; /* key/value pairs. */ ns_cred_t *cred; /* info to update name service */ void *nsdata; /* name service specific data */ }; typedef struct ns_printer ns_printer_t; extern ns_printer_t *ns_printer_get_name(const char *, const char *); extern int ns_printer_put(const ns_printer_t *); extern char *ns_get_value_string(const char *, const ns_printer_t *); extern int ns_set_value(const char *, const void *, ns_printer_t *); extern int ns_set_value_from_string(const char *, const char *, ns_printer_t *); extern ns_bsd_addr_t *bsd_addr_create(const char *, const char *, const char *); extern char *bsd_addr_to_string(const ns_bsd_addr_t *); extern void ns_printer_destroy(ns_printer_t *); int _updateoldyp( const char *action, const char *printername, const char *printserver, const char *extensions, const char *comment, const char *isdefault) { ns_printer_t *printer; ns_bsd_addr_t *addr; int status = 0; char mkcmd[BUFSIZ]; char *domain = NULL; char *host = NULL; /* * libprint returns before we know that the printers.conf * map is made. So we'll make it again. */ (void) yp_get_default_domain(&domain); if ((yp_master(domain, "printers.conf.byname", &host) != 0) && (yp_master(domain, "passwd.byname", &host) != 0)) { strcpy(mkcmd, "/usr/bin/sleep 1"); } else { sprintf(mkcmd, "/usr/bin/rsh -n %s 'cd /var/yp; " "/usr/ccs/bin/make -f /var/yp/Makefile " "-f /var/yp/Makefile.print printers.conf " "> /dev/null'", host); } if (strcmp(action, "delete") == 0) { if ((printer = (ns_printer_t *) ns_printer_get_name(printername, "nis")) == NULL) { return (0); } printer->attributes = NULL; status = ns_printer_put(printer); if (status != 0) { (void) free(printer); return (status); } if ((printer = (ns_printer_t *) ns_printer_get_name("_default", "nis")) != NULL) { char *dflt = (char *) ns_get_value_string("use", printer); if ((dflt != NULL) && (strcmp(dflt, printername) == 0)) { printer->attributes = NULL; status = ns_printer_put(printer); if (status != 0) { (void) free(printer); return (status); } } } (void) free(printer); (void) system(mkcmd); return (0); } else if (strcmp(action, "add") == 0) { printer = (ns_printer_t *)malloc(sizeof (*printer)); memset(printer, 0, sizeof (*printer)); printer->name = (char *)printername; printer->source = "nis"; addr = (ns_bsd_addr_t *)malloc(sizeof (*addr)); memset(addr, 0, sizeof (*addr)); addr->printer = (char *)printername; addr->server = (char *)printserver; if ((extensions != NULL) && (strlen(extensions) > 0)) { addr->extension = (char *)extensions; } ns_set_value("bsdaddr", addr, printer); if ((comment != NULL) && (strlen(comment) > 0)) { ns_set_value_from_string("description", comment, printer); } status = ns_printer_put(printer); if (status != 0) { (void) free(addr); (void) free(printer); return (status); } if (strcmp(isdefault, "true") == 0) { printer->name = "_default"; printer->attributes = NULL; ns_set_value_from_string("use", printername, printer); status = ns_printer_put(printer); if (status != 0) { (void) free(addr); (void) free(printer); return (status); } } (void) free(addr); (void) free(printer); (void) system(mkcmd); return (0); } /* * Modify */ if ((printer = (ns_printer_t *) ns_printer_get_name(printername, "nis")) == NULL) { return (1); } if ((comment != NULL) && (strlen(comment) > 0)) { ns_set_value_from_string("description", comment, printer); } else { ns_set_value_from_string("description", NULL, printer); } status = ns_printer_put(printer); if (status != 0) { (void) free(printer); return (status); } if ((printer = (ns_printer_t *) ns_printer_get_name("_default", "nis")) != NULL) { char *dflt = (char *)ns_get_value_string("use", printer); if (strcmp(printername, dflt) == 0) { if (strcmp(isdefault, "false") == 0) { /* * We were the default printer but not * any more. */ printer->attributes = NULL; status = ns_printer_put(printer); if (status != 0) { (void) free(printer); return (status); } } } else { if (strcmp(isdefault, "true") == 0) { ns_set_value_from_string("use", printername, printer); status = ns_printer_put(printer); if (status != 0) { (void) free(printer); return (status); } } } } else { printer = (ns_printer_t *)malloc(sizeof (*printer)); memset(printer, 0, sizeof (*printer)); printer->name = "_default"; printer->source = "nis"; ns_set_value_from_string("use", printername, printer); status = ns_printer_put(printer); if (status != 0) { (void) free(printer); return (status); } } (void) system(mkcmd); return (0); } int _updateldap( const char *action, const char *host, const char *binddn, const char *passwd, const char *printername, const char *printserver, const char *extensions, const char *comment, const char *isdefault) { ns_printer_t *printer; ns_bsd_addr_t *addr; ns_cred_t *cred; char *item = NULL; char **attrList = NULL; int status; if (printserver == NULL) { /* printserver not given so use host */ printserver = host; } cred = (ns_cred_t *)malloc(sizeof (*cred)); (void) memset(cred, '\0', sizeof (*cred)); cred->passwd = strdup((char *)passwd); cred->binddn = strdup((char *)binddn); cred->host = strdup((char *)host); cred->passwdType = NS_PW_INSECURE; /* use default */ cred->port = 0; /* use default */ cred->domainDN = NULL; /* use default */ if (strcmp(action, "delete") == 0) { /* * Delete printer object from LDAP directory DIT */ if ((printer = (ns_printer_t *) ns_printer_get_name(printername, "ldap")) == NULL) { return (0); } printer->attributes = NULL; printer->nsdata = malloc(sizeof (NS_LDAPDATA)); if (printer->nsdata == NULL) { return (1); } ((NS_LDAPDATA *)(printer->nsdata))->attrList = NULL; printer->cred = cred; printer->source = strdup("ldap"); status = ns_printer_put(printer); free(printer->nsdata); (void) ns_printer_destroy(printer); if (status != 0) { return (status); } if ((printer = (ns_printer_t *) ns_printer_get_name("_default", "ldap")) != NULL) { char *dflt = (char *) ns_get_value_string("use", printer); if ((dflt != NULL) && (strcmp(dflt, printername) == 0)) { printer->attributes = NULL; printer->nsdata = malloc(sizeof (NS_LDAPDATA)); if (printer->nsdata == NULL) { (void) ns_printer_destroy(printer); return (1); } ((NS_LDAPDATA *)(printer->nsdata))->attrList = NULL; printer->cred = cred; printer->source = strdup("ldap"); status = ns_printer_put(printer); free(printer->nsdata); if (status != 0) { (void) ns_printer_destroy(printer); return (status); } } (void) ns_printer_destroy(printer); } return (0); } else if (strcmp(action, "add") == 0) { /* * Add new printer object into LDAP directory DIT */ printer = (ns_printer_t *)malloc(sizeof (*printer)); if (printer == NULL) { return (1); } (void) memset(printer, 0, sizeof (*printer)); printer->name = strdup((char *)printername); printer->source = strdup("ldap"); printer->cred = cred; /* set BSD address in attribute list */ if (extensions == NULL) { item = (char *)malloc(strlen("bsdaddr") + strlen(printserver) + strlen(printername) + strlen("Solaris") + 6); } else { item = (char *)malloc(strlen("bsdaddr") + strlen(printserver) + strlen(printername) + strlen(extensions) + 6); } if (item == NULL) { (void) ns_printer_destroy(printer); return (1); } if (extensions == NULL) { sprintf(item, "%s=%s,%s,%s", "bsdaddr", printserver, printername, "Solaris"); } else { sprintf(item, "%s=%s,%s,%s", "bsdaddr", printserver, printername, extensions); } attrList = (char **)list_append((void**)attrList, (void *)item); if ((comment != NULL) && (strlen(comment) > 0)) { item = (char *)malloc(strlen("description") + strlen(comment) + 4); if (item == NULL) { (void) ns_printer_destroy(printer); return (1); } sprintf(item, "%s=%s", "description", comment); attrList = (char **)list_append((void**)attrList, (void *)item); } printer->attributes = NULL; printer->nsdata = malloc(sizeof (NS_LDAPDATA) + 2); if (printer->nsdata == NULL) { (void) ns_printer_destroy(printer); return (1); } ((NS_LDAPDATA *)(printer->nsdata))->attrList = attrList; status = ns_printer_put(printer); _freeList(&attrList); if (status != 0) { free(printer->nsdata); (void) ns_printer_destroy(printer); return (status); } if (strcmp(isdefault, "true") == 0) { (void) free(printer->name); printer->name = strdup("_default"); printer->attributes = NULL; attrList = NULL; item = (char *)malloc(strlen("use") + strlen(printername) + 4); if (item == NULL) { (void) ns_printer_destroy(printer); return (1); } sprintf(item, "%s=%s", "use", printername); attrList = (char **)list_append((void**)attrList, (void *)item); ((NS_LDAPDATA *)(printer->nsdata))->attrList = attrList; status = ns_printer_put(printer); _freeList(&attrList); free(printer->nsdata); if (status != 0) { (void) ns_printer_destroy(printer); return (status); } } (void) ns_printer_destroy(printer); return (0); } /* * Modify printer object in the LDAP directory DIT */ if ((printer = (ns_printer_t *) ns_printer_get_name(printername, "ldap")) == NULL) { return (1); } printer->cred = cred; printer->source = strdup("ldap"); if ((comment != NULL) && (strlen(comment) > 0)) { item = (char *)malloc(strlen("description") + strlen(comment) + 4); if (item == NULL) { (void) ns_printer_destroy(printer); return (1); } sprintf(item, "%s=%s", "description", comment); attrList = (char **)list_append((void**)attrList, (void *)item); } else { item = (char *)malloc(strlen("description") + 4); if (item == NULL) { (void) ns_printer_destroy(printer); return (1); } sprintf(item, "%s=", "description"); attrList = (char **)list_append((void**)attrList, (void *)item); } printer->attributes = NULL; printer->nsdata = malloc(sizeof (NS_LDAPDATA)); if (printer->nsdata == NULL) { (void) ns_printer_destroy(printer); return (1); } ((NS_LDAPDATA *)(printer->nsdata))->attrList = attrList; status = ns_printer_put(printer); _freeList(&attrList); free(printer->nsdata); if (status != 0) { (void) ns_printer_destroy(printer); return (status); } /* * Handle the default printer. */ if ((printer = (ns_printer_t *) ns_printer_get_name("_default", "ldap")) != NULL) { char *dflt = (char *)ns_get_value_string("use", printer); printer->source = strdup("ldap"); printer->cred = cred; if (strcmp(printername, dflt) == 0) { if (strcmp(isdefault, "false") == 0) { /* * We were the default printer but not * any more. So delete the default entry */ printer->attributes = NULL; printer->nsdata = malloc(sizeof (NS_LDAPDATA)); if (printer->nsdata == NULL) { (void) ns_printer_destroy(printer); return (1); } ((NS_LDAPDATA *)(printer->nsdata))->attrList = NULL; status = ns_printer_put(printer); free(printer->nsdata); if (status != 0) { (void) ns_printer_destroy(printer); return (status); } } } else if (strcmp(isdefault, "true") == 0) { /* * Modify this default entry to use us. */ printer->attributes = NULL; printer->nsdata = malloc(sizeof (NS_LDAPDATA)); if (printer->nsdata == NULL) { (void) ns_printer_destroy(printer); return (1); } attrList = NULL; item = (char *)malloc(strlen("use") + strlen(printername) + 4); if (item == NULL) { (void) ns_printer_destroy(printer); return (1); } sprintf(item, "%s=%s", "use", printername); attrList = (char **)list_append((void**)attrList, (void *)item); ((NS_LDAPDATA *)(printer->nsdata))->attrList = attrList; status = ns_printer_put(printer); _freeList(&attrList); free(printer->nsdata); if (status != 0) { (void) ns_printer_destroy(printer); return (status); } } } else if (strcmp(isdefault, "true") == 0) { /* * No default entry existed and we need one. */ printer = (ns_printer_t *)malloc(sizeof (*printer)); (void) memset(printer, 0, sizeof (*printer)); printer->name = strdup("_default"); printer->source = strdup("ldap"); printer->cred = cred; printer->nsdata = malloc(sizeof (NS_LDAPDATA)); if (printer->nsdata == NULL) { (void) ns_printer_destroy(printer); return (1); } attrList = NULL; item = (char *)malloc(strlen("use") + strlen(printername) + 4); if (item == NULL) { (void) ns_printer_destroy(printer); return (1); } sprintf(item, "%s=%s", "use", printername); attrList = (char **)list_append((void**)attrList, (void *)item); ((NS_LDAPDATA *)(printer->nsdata))->attrList = attrList; status = ns_printer_put(printer); _freeList(&attrList); free(printer->nsdata); if (status != 0) { (void) ns_printer_destroy(printer); return (status); } } (void) ns_printer_destroy(printer); return (0); } /* * ***************************************************************************** * * Function: _freeList() * * Description: Free the list created by list_append() where the items in * the list have been strdup'ed. * * Parameters: * Input: char ***list - returned set of kvp values * * Result: void * * ***************************************************************************** */ static void _freeList(char ***list) { int i = 0; /* ------ */ if (list != NULL) { if (*list != NULL) { for (i = 0; (*list)[i] != NULL; i++) { free((*list)[i]); } free(*list); } *list = NULL; } } /* _freeList */