updated the 3.0 branch from the head branch - ready for alpha18
[tprouty/samba.git] / source / libads / ldap_printer.c
1 /* 
2    Unix SMB/CIFS implementation.
3    ads (active directory) printer utility library
4    Copyright (C) Jim McDonough 2002
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 #ifdef HAVE_ADS
24
25 /*
26   find a printer given the name and the hostname
27     Note that results "res" may be allocated on return so that the
28     results can be used.  It should be freed using ads_msgfree.
29 */
30 ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res,
31                                       char *printer, char *servername)
32 {
33         ADS_STATUS status;
34         char *srv_dn, **srv_cn, *exp;
35         const char *attrs[] = {"*", "nTSecurityDescriptor", NULL};
36
37         status = ads_find_machine_acct(ads, res, servername);
38         if (!ADS_ERR_OK(status)) {
39                 DEBUG(1, ("ads_add_printer: cannot find host %s in ads\n",
40                           servername));
41                 return status;
42         }
43         srv_dn = ldap_get_dn(ads->ld, *res);
44         srv_cn = ldap_explode_dn(srv_dn, 1);
45         ads_msgfree(ads, *res);
46
47         asprintf(&exp, "(cn=%s-%s)", srv_cn[0], printer);
48         status = ads_search(ads, res, exp, attrs);
49
50         ldap_memfree(srv_dn);
51         ldap_value_free(srv_cn);
52         free(exp);
53         return status;  
54 }
55
56 /*
57   modify an entire printer entry in the directory
58 */
59 ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn,
60                                  const ADS_PRINTER_ENTRY *prt)
61 {
62         ADS_MODLIST mods;
63         ADS_STATUS status;
64         TALLOC_CTX *ctx;
65
66         if (!(ctx = talloc_init_named("mod_printer_entry")))
67                 return ADS_ERROR(LDAP_NO_MEMORY);
68
69         /* allocate the list */
70         mods = ads_init_mods(ctx);
71
72         /* add the attributes to the list - required ones first */
73         ads_mod_str(ctx, &mods, "printerName", prt->printerName);
74         ads_mod_str(ctx, &mods, "serverName", prt->serverName);
75         ads_mod_str(ctx, &mods, "shortServerName", prt->shortServerName);
76         ads_mod_str(ctx, &mods, "uNCName", prt->uNCName);
77         ads_mod_str(ctx, &mods, "versionNumber", prt->versionNumber);
78
79         /* now the optional ones */
80         ads_mod_strlist(ctx, &mods, "description", prt->description);
81         ads_mod_str(ctx, &mods, "assetNumber",prt->assetNumber);
82         ads_mod_str(ctx, &mods, "bytesPerMinute",prt->bytesPerMinute);
83         ads_mod_str(ctx, &mods, "defaultPriority",prt->defaultPriority);
84         ads_mod_str(ctx, &mods, "driverName", prt->driverName);
85         ads_mod_str(ctx, &mods, "driverVersion",prt->driverVersion);
86         ads_mod_str(ctx, &mods, "location", prt->location);
87         ads_mod_str(ctx, &mods, "operatingSystem",prt->operatingSystem);
88         ads_mod_str(ctx, &mods, "operatingSystemHotfix",
89                      prt->operatingSystemHotfix);
90         ads_mod_str(ctx, &mods, "operatingSystemServicePack",
91                      prt->operatingSystemServicePack);
92         ads_mod_str(ctx, &mods, "operatingSystemVersion",
93                      prt->operatingSystemVersion);
94         ads_mod_str(ctx, &mods, "physicalLocationObject",
95                      prt->physicalLocationObject);
96         ads_mod_strlist(ctx, &mods, "portName", prt->portName);
97         ads_mod_str(ctx, &mods, "printStartTime", prt->printStartTime);
98         ads_mod_str(ctx, &mods, "printEndTime", prt->printEndTime);
99         ads_mod_strlist(ctx, &mods, "printBinNames", prt->printBinNames);
100         /*... and many others */
101
102         /* do the ldap modify */
103         status = ads_gen_mod(ads, prt_dn, mods);
104
105         /* free mod list, mods, and values */
106         talloc_destroy(ctx); 
107
108         return status;
109 }
110         
111
112 /*
113   add a printer to the directory
114 */
115 static ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn,
116                                         const ADS_PRINTER_ENTRY *prt)
117 {
118         ADS_STATUS status;
119         TALLOC_CTX *ctx;
120         ADS_MODLIST mods;
121
122         if (!(ctx = talloc_init_named("add_printer_entry")))
123                 return ADS_ERROR(LDAP_NO_MEMORY);
124
125         if (!(mods = ads_init_mods(ctx)))
126                 return ADS_ERROR(LDAP_NO_MEMORY);
127
128         /* These are the fields a printQueue must contain */
129         ads_mod_str(ctx, &mods, "uNCName", prt->uNCName);
130         ads_mod_str(ctx, &mods, "versionNumber", prt->versionNumber);
131         ads_mod_str(ctx, &mods, "serverName", prt->serverName);
132         ads_mod_str(ctx, &mods, "shortServerName", prt->shortServerName);
133         ads_mod_str(ctx, &mods, "printerName", prt->printerName);
134         ads_mod_str(ctx, &mods, "objectClass", "printQueue");
135
136
137         status = ads_gen_add(ads, prt_dn, mods);
138
139         talloc_destroy(ctx);
140
141         return status;
142 }
143
144 /*
145   publish a printer in the ADS
146 */
147
148 ADS_STATUS ads_add_printer(ADS_STRUCT *ads, const ADS_PRINTER_ENTRY *prt)
149 {
150         ADS_STATUS status;
151         void *res;
152         char *host_dn, *prt_dn;
153         const char *attrs[] = {"*", "nTSecurityDescriptor", NULL};
154
155         status = ads_find_machine_acct(ads, (void **)&res,
156                                        prt->shortServerName);
157         if (!ADS_ERR_OK(status)) {
158                 DEBUG(1, ("ads_add_printer: cannot find host %s in ads\n",
159                           prt->shortServerName));
160                 return status;
161         }
162         host_dn = ads_get_dn(ads, res);
163         ads_msgfree(ads, res);
164
165         ads_find_printer_on_server(ads, &res, prt->printerName, 
166                                    prt->shortServerName);
167
168         if (ADS_ERR_OK(status) && ads_count_replies(ads, res)) {
169                 DEBUG(1, ("ads_add_printer: printer %s already exists\n",
170                           prt->printerName));
171                 /* nothing to do, just free results */
172                 ads_msgfree(ads, res);
173         } else {
174                 ads_msgfree(ads, res);
175                 status = ads_add_printer_entry(ads, prt_dn, prt);
176                 if (!ADS_ERR_OK(status)) {
177                         DEBUG(0, ("ads_add_printer: ads_add_printer_entry failed\n"));
178                         return status;
179                 }
180         }
181
182         status = ads_search_dn(ads, &res, prt_dn, attrs);
183
184         if (ADS_ERR_OK(status) && ads_count_replies(ads, res)) {
185                 /* need to retrieve GUID from results
186                    prt->GUID */
187                 status = ads_mod_printer_entry(ads, prt_dn, prt);
188         }
189
190         ads_msgfree(ads, res);
191
192
193         return status;
194 }
195
196 #endif