talloc'ify ads modify functions.
[amitay/samba.git] / source3 / 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, *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         ads_msgfree(ads, *res);
45
46         asprintf(&exp, "(printerName=%s)", printer);
47         status = ads_do_search(ads, srv_dn, LDAP_SCOPE_SUBTREE, 
48                                exp, attrs, res);
49
50         free(exp);
51         return status;  
52 }
53
54 /*
55   modify an entire printer entry in the directory
56 */
57 ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn,
58                                  const ADS_PRINTER_ENTRY *prt)
59 {
60         ADS_MODLIST mods;
61         ADS_STATUS status;
62         TALLOC_CTX *ctx;
63
64         if (!(ctx = talloc_init_named("mod_printer_entry")))
65                 return ADS_ERROR(LDAP_NO_MEMORY);
66
67         /* allocate the list */
68         mods = ads_init_mods(ctx);
69
70         /* add the attributes to the list - required ones first */
71         ads_mod_repl(ctx, &mods, "printerName", prt->printerName);
72         ads_mod_repl(ctx, &mods, "serverName", prt->serverName);
73         ads_mod_repl(ctx, &mods, "shortServerName", prt->shortServerName);
74         ads_mod_repl(ctx, &mods, "uNCName", prt->uNCName);
75         ads_mod_repl(ctx, &mods, "versionNumber", prt->versionNumber);
76
77         /* now the optional ones */
78         ads_mod_repl_list(ctx, &mods, "description", prt->description);
79         ads_mod_repl(ctx, &mods, "assetNumber",prt->assetNumber);
80         ads_mod_repl(ctx, &mods, "bytesPerMinute",prt->bytesPerMinute);
81         ads_mod_repl(ctx, &mods, "defaultPriority",prt->defaultPriority);
82         ads_mod_repl(ctx, &mods, "driverName", prt->driverName);
83         ads_mod_repl(ctx, &mods, "driverVersion",prt->driverVersion);
84         ads_mod_repl(ctx, &mods, "location", prt->location);
85         ads_mod_repl(ctx, &mods, "operatingSystem",prt->operatingSystem);
86         ads_mod_repl(ctx, &mods, "operatingSystemHotfix",
87                      prt->operatingSystemHotfix);
88         ads_mod_repl(ctx, &mods, "operatingSystemServicePack",
89                      prt->operatingSystemServicePack);
90         ads_mod_repl(ctx, &mods, "operatingSystemVersion",
91                      prt->operatingSystemVersion);
92         ads_mod_repl(ctx, &mods, "physicalLocationObject",
93                      prt->physicalLocationObject);
94         ads_mod_repl_list(ctx, &mods, "portName", prt->portName);
95         ads_mod_repl(ctx, &mods, "printStartTime", prt->printStartTime);
96         ads_mod_repl(ctx, &mods, "printEndTime", prt->printEndTime);
97         ads_mod_repl_list(ctx, &mods, "printBinNames", prt->printBinNames);
98         /*... and many others */
99
100         /* do the ldap modify */
101         status = ads_gen_mod(ads, prt_dn, mods);
102
103         /* free mod list, mods, and values */
104         talloc_destroy(ctx); 
105
106         return status;
107 }
108         
109
110 /*
111   add a printer to the directory
112 */
113 static ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn,
114                                         const ADS_PRINTER_ENTRY *prt)
115 {
116         ADS_STATUS status;
117         TALLOC_CTX *ctx;
118         ADS_MODLIST mods;
119
120         if (!(ctx = talloc_init_named("add_printer_entry")))
121                 return ADS_ERROR(LDAP_NO_MEMORY);
122
123         if (!(mods = ads_init_mods(ctx)))
124                 return ADS_ERROR(LDAP_NO_MEMORY);
125
126         /* These are the fields a printQueue must contain */
127         ads_mod_add(ctx, &mods, "uNCName", prt->uNCName);
128         ads_mod_add(ctx, &mods, "versionNumber", prt->versionNumber);
129         ads_mod_add(ctx, &mods, "serverName", prt->serverName);
130         ads_mod_add(ctx, &mods, "shortServerName", prt->shortServerName);
131         ads_mod_add(ctx, &mods, "printerName", prt->printerName);
132         ads_mod_add(ctx, &mods, "objectClass", "printQueue");
133
134
135         status = ads_gen_add(ads, prt_dn, mods);
136
137         talloc_destroy(ctx);
138
139         return status;
140 }
141
142 /*
143   publish a printer in the ADS
144 */
145
146 ADS_STATUS ads_add_printer(ADS_STRUCT *ads, const ADS_PRINTER_ENTRY *prt)
147 {
148         ADS_STATUS status;
149         void *res;
150         char *host_dn, *prt_dn;
151         const char *attrs[] = {"*", "nTSecurityDescriptor", NULL};
152
153         status = ads_find_machine_acct(ads, (void **)&res,
154                                        prt->shortServerName);
155         if (!ADS_ERR_OK(status)) {
156                 DEBUG(1, ("ads_add_printer: cannot find host %s in ads\n",
157                           prt->shortServerName));
158                 return status;
159         }
160         host_dn = ldap_get_dn(ads->ld, res);
161         ads_msgfree(ads, res);
162
163         /* printer dn is cn=server-printer followed by host dn */
164         asprintf(&prt_dn, "cn=%s-%s,%s", prt->shortServerName,
165                  prt->printerName, host_dn);
166
167         status = ads_search_dn(ads, &res, prt_dn, attrs);
168
169         if (ADS_ERR_OK(status) && ads_count_replies(ads, res)) {
170                 DEBUG(1, ("ads_add_printer: printer %s already exists\n",
171                           prt->printerName));
172                 /* nothing to do, just free results */
173                 ads_msgfree(ads, res);
174         } else {
175                 ads_msgfree(ads, res);
176                 status = ads_add_printer_entry(ads, prt_dn, prt);
177                 if (!ADS_ERR_OK(status)) {
178                         DEBUG(0, ("ads_add_printer: ads_add_printer_entry failed\n"));
179                         return status;
180                 }
181         }
182
183         status = ads_search_dn(ads, &res, prt_dn, attrs);
184
185         if (ADS_ERR_OK(status) && ads_count_replies(ads, res)) {
186                 /* need to retrieve GUID from results
187                    prt->GUID */
188                 status = ads_mod_printer_entry(ads, prt_dn, prt);
189         }
190
191         ads_msgfree(ads, res);
192
193
194         return status;
195 }
196
197 #endif